@@ -64,7 +64,7 @@ type parser struct {
64
64
position int
65
65
current token
66
66
strict bool
67
- types map [ string ] Type
67
+ types typesTable
68
68
}
69
69
70
70
// OptionFn for configuring parser.
@@ -81,7 +81,7 @@ func Parse(input string, ops ...OptionFn) (Node, error) {
81
81
input : input ,
82
82
tokens : tokens ,
83
83
current : tokens [0 ],
84
- types : make (map [ string ] Type ),
84
+ types : make (typesTable ),
85
85
}
86
86
87
87
for _ , op := range ops {
@@ -116,60 +116,69 @@ func Define(name string, t interface{}) OptionFn {
116
116
}
117
117
118
118
// With sets variables for type checks during parsing.
119
- // If struct is passed, all fields will be treated as variables.
119
+ // If struct is passed, all fields will be treated as variables,
120
+ // as well as all fields of embedded structs.
121
+ //
120
122
// If map is passed, all items will be treated as variables
121
123
// (key as name, value as type).
122
124
func With (i interface {}) OptionFn {
123
125
return func (p * parser ) {
124
126
p .strict = true
125
- v := reflect .ValueOf (i )
126
- t := reflect .TypeOf (i )
127
- t = dereference (t )
128
- if t == nil {
129
- return
127
+ for k , v := range p .createTypesTable (i ) {
128
+ p .types [k ] = v
130
129
}
130
+ }
131
+ }
131
132
132
- switch t .Kind () {
133
- case reflect .Struct :
134
- for i := 0 ; i < t .NumField (); i ++ {
135
- f := t .Field (i )
136
- p .types [f .Name ] = f .Type
133
+ func (p * parser ) createTypesTable (i interface {}) typesTable {
134
+ types := make (typesTable )
135
+ v := reflect .ValueOf (i )
136
+ t := reflect .TypeOf (i )
137
137
138
- for name , typ := range p .findEmbeddedFieldNames (f .Type ) {
139
- p .types [name ] = typ
140
- }
141
- }
142
- case reflect .Map :
143
- for _ , key := range v .MapKeys () {
144
- value := v .MapIndex (key )
145
- if key .Kind () == reflect .String && value .IsValid () && value .CanInterface () {
146
- p .types [key .String ()] = reflect .TypeOf (value .Interface ())
147
- }
138
+ t = dereference (t )
139
+ if t == nil {
140
+ return types
141
+ }
142
+
143
+ switch t .Kind () {
144
+ case reflect .Struct :
145
+ types = p .fromStruct (t )
146
+
147
+ case reflect .Map :
148
+ for _ , key := range v .MapKeys () {
149
+ value := v .MapIndex (key )
150
+ if key .Kind () == reflect .String && value .IsValid () && value .CanInterface () {
151
+ types [key .String ()] = reflect .TypeOf (value .Interface ())
148
152
}
149
153
}
150
154
}
155
+
156
+ return types
151
157
}
152
158
153
- func (p * parser ) findEmbeddedFieldNames (t reflect.Type ) map [string ]Type {
159
+ func (p * parser ) fromStruct (t reflect.Type ) typesTable {
160
+ types := make (typesTable )
154
161
t = dereference (t )
162
+ if t == nil {
163
+ return types
164
+ }
155
165
156
- res := make ( map [ string ] Type )
157
- if t . Kind () == reflect .Struct {
166
+ switch t . Kind () {
167
+ case reflect .Struct :
158
168
for i := 0 ; i < t .NumField (); i ++ {
159
169
f := t .Field (i )
160
170
161
- fType := dereference (f .Type )
162
- if fType .Kind () == reflect .Struct && f .Anonymous && fType .Name () == f .Name {
163
- for name , typ := range p .findEmbeddedFieldNames (fType ) {
164
- res [name ] = typ
171
+ if f .Anonymous {
172
+ for name , typ := range p .fromStruct (f .Type ) {
173
+ types [name ] = typ
165
174
}
175
+ } else {
176
+ types [f .Name ] = f .Type
166
177
}
167
-
168
- res [f .Name ] = fType
169
178
}
170
179
}
171
180
172
- return res
181
+ return types
173
182
}
174
183
175
184
func (p * parser ) errorf (format string , args ... interface {}) * syntaxError {
0 commit comments