Skip to content

Commit f07d82d

Browse files
committed
Allow custom types to be used for Pos, EndPos and Token.
Specifically, these fields can now be of any type that is convertible from the internal Participle types.
1 parent 4ddfe8b commit f07d82d

3 files changed

Lines changed: 256 additions & 231 deletions

File tree

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -596,13 +596,15 @@ There are a few areas where Participle can provide useful feedback to users of y
596596
1. Of type [Error](https://pkg.go.dev/github.com/alecthomas/participle/v2#Error). This will contain positional information where available.
597597
2. May either be [ParseError](https://pkg.go.dev/github.com/alecthomas/participle/v2#ParseError) or [lexer.Error](https://pkg.go.dev/github.com/alecthomas/participle/v2/lexer#Error)
598598
2. Participle will make a best effort to return as much of the AST up to the error location as possible.
599-
3. Any node in the AST containing a field `Pos lexer.Position` will be automatically
599+
3. Any node in the AST containing a field `Pos lexer.Position` [^1] will be automatically
600600
populated from the nearest matching token.
601-
4. Any node in the AST containing a field `EndPos lexer.Position` will be
601+
4. Any node in the AST containing a field `EndPos lexer.Position` [^1] will be
602602
automatically populated from the token at the end of the node.
603-
5. Any node in the AST containing a field `Tokens []lexer.Token` will be automatically
603+
5. Any node in the AST containing a field `Tokens []lexer.Token` [^1] will be automatically
604604
populated with _all_ tokens captured by the node, _including_ elided tokens.
605605

606+
[^1]: Either the concrete type or a type convertible to it, allowing user defined types to be used.
607+
606608
These related pieces of information can be combined to provide fairly comprehensive error reporting.
607609

608610
## Comments

nodes.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -131,11 +131,11 @@ func newStrct(typ reflect.Type) *strct {
131131
usages: 1,
132132
}
133133
field, ok := typ.FieldByName("Pos")
134-
if ok && field.Type == positionType {
134+
if ok && positionType.ConvertibleTo(field.Type) {
135135
s.posFieldIndex = field.Index
136136
}
137137
field, ok = typ.FieldByName("EndPos")
138-
if ok && field.Type == positionType {
138+
if ok && positionType.ConvertibleTo(field.Type) {
139139
s.endPosFieldIndex = field.Index
140140
}
141141
field, ok = typ.FieldByName("Tokens")
@@ -172,14 +172,16 @@ func (s *strct) maybeInjectStartToken(token *lexer.Token, v reflect.Value) {
172172
if s.posFieldIndex == nil {
173173
return
174174
}
175-
v.FieldByIndex(s.posFieldIndex).Set(reflect.ValueOf(token.Pos))
175+
f := v.FieldByIndex(s.posFieldIndex)
176+
f.Set(reflect.ValueOf(token.Pos).Convert(f.Type()))
176177
}
177178

178179
func (s *strct) maybeInjectEndToken(token *lexer.Token, v reflect.Value) {
179180
if s.endPosFieldIndex == nil {
180181
return
181182
}
182-
v.FieldByIndex(s.endPosFieldIndex).Set(reflect.ValueOf(token.Pos))
183+
f := v.FieldByIndex(s.endPosFieldIndex)
184+
f.Set(reflect.ValueOf(token.Pos).Convert(f.Type()))
183185
}
184186

185187
func (s *strct) maybeInjectTokens(tokens []lexer.Token, v reflect.Value) {

0 commit comments

Comments
 (0)