148 } |
148 } |
149 |
149 |
150 // CheckExpression takes a top-level node and checks that it does not contain |
150 // CheckExpression takes a top-level node and checks that it does not contain |
151 // keys that have been seen in previous calls, and validates that types are |
151 // keys that have been seen in previous calls, and validates that types are |
152 // consistent. |
152 // consistent. |
153 func (s *SeenTracker) CheckExpression(node *ast.Node) error { |
153 func (s *SeenTracker) CheckExpression(node *unstable.Node) error { |
154 if s.entries == nil { |
154 if s.entries == nil { |
155 s.reset() |
155 s.reset() |
156 } |
156 } |
157 switch node.Kind { |
157 switch node.Kind { |
158 case ast.KeyValue: |
158 case unstable.KeyValue: |
159 return s.checkKeyValue(node) |
159 return s.checkKeyValue(node) |
160 case ast.Table: |
160 case unstable.Table: |
161 return s.checkTable(node) |
161 return s.checkTable(node) |
162 case ast.ArrayTable: |
162 case unstable.ArrayTable: |
163 return s.checkArrayTable(node) |
163 return s.checkArrayTable(node) |
164 default: |
164 default: |
165 panic(fmt.Errorf("this should not be a top level node type: %s", node.Kind)) |
165 panic(fmt.Errorf("this should not be a top level node type: %s", node.Kind)) |
166 } |
166 } |
167 } |
167 } |
168 |
168 |
169 func (s *SeenTracker) checkTable(node *ast.Node) error { |
169 func (s *SeenTracker) checkTable(node *unstable.Node) error { |
170 if s.currentIdx >= 0 { |
170 if s.currentIdx >= 0 { |
171 s.setExplicitFlag(s.currentIdx) |
171 s.setExplicitFlag(s.currentIdx) |
172 } |
172 } |
173 |
173 |
174 it := node.Key() |
174 it := node.Key() |
295 s.entries[parentIdx].kind = valueKind |
295 s.entries[parentIdx].kind = valueKind |
296 |
296 |
297 value := node.Value() |
297 value := node.Value() |
298 |
298 |
299 switch value.Kind { |
299 switch value.Kind { |
300 case ast.InlineTable: |
300 case unstable.InlineTable: |
301 return s.checkInlineTable(value) |
301 return s.checkInlineTable(value) |
302 case ast.Array: |
302 case unstable.Array: |
303 return s.checkArray(value) |
303 return s.checkArray(value) |
304 } |
304 } |
305 |
305 |
306 return nil |
306 return nil |
307 } |
307 } |
308 |
308 |
309 func (s *SeenTracker) checkArray(node *ast.Node) error { |
309 func (s *SeenTracker) checkArray(node *unstable.Node) error { |
310 it := node.Children() |
310 it := node.Children() |
311 for it.Next() { |
311 for it.Next() { |
312 n := it.Node() |
312 n := it.Node() |
313 switch n.Kind { |
313 switch n.Kind { |
314 case ast.InlineTable: |
314 case unstable.InlineTable: |
315 err := s.checkInlineTable(n) |
315 err := s.checkInlineTable(n) |
316 if err != nil { |
316 if err != nil { |
317 return err |
317 return err |
318 } |
318 } |
319 case ast.Array: |
319 case unstable.Array: |
320 err := s.checkArray(n) |
320 err := s.checkArray(n) |
321 if err != nil { |
321 if err != nil { |
322 return err |
322 return err |
323 } |
323 } |
324 } |
324 } |
325 } |
325 } |
326 return nil |
326 return nil |
327 } |
327 } |
328 |
328 |
329 func (s *SeenTracker) checkInlineTable(node *ast.Node) error { |
329 func (s *SeenTracker) checkInlineTable(node *unstable.Node) error { |
330 if pool.New == nil { |
330 if pool.New == nil { |
331 pool.New = func() interface{} { |
331 pool.New = func() interface{} { |
332 return &SeenTracker{} |
332 return &SeenTracker{} |
333 } |
333 } |
334 } |
334 } |