AbsTraversalForExpr attempts to interpret the given expression as an absolute traversal, or returns error diagnostic(s) if that is not possible for the given expression. A particular Expression implementation can support this function by offering a method called AsTraversal that takes no arguments
(expr Expression)
| 21 | // to the variables themselves rather than to their values. An implementer |
| 22 | // of this function should at least support attribute and index steps. |
| 23 | func AbsTraversalForExpr(expr Expression) (Traversal, Diagnostics) { |
| 24 | type asTraversal interface { |
| 25 | AsTraversal() Traversal |
| 26 | } |
| 27 | |
| 28 | physExpr := UnwrapExpressionUntil(expr, func(expr Expression) bool { |
| 29 | _, supported := expr.(asTraversal) |
| 30 | return supported |
| 31 | }) |
| 32 | |
| 33 | if asT, supported := physExpr.(asTraversal); supported { |
| 34 | if traversal := asT.AsTraversal(); traversal != nil { |
| 35 | return traversal, nil |
| 36 | } |
| 37 | } |
| 38 | return nil, Diagnostics{ |
| 39 | &Diagnostic{ |
| 40 | Severity: DiagError, |
| 41 | Summary: "Invalid expression", |
| 42 | Detail: "A single static variable reference is required: only attribute access and indexing with constant keys. No calculations, function calls, template expressions, etc are allowed here.", |
| 43 | Subject: expr.Range().Ptr(), |
| 44 | }, |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | // RelTraversalForExpr is similar to AbsTraversalForExpr but it returns |
| 49 | // a relative traversal instead. Due to the nature of HCL expressions, the |