4 "github.com/hashicorp/hcl2/hcl"
7 // Variables returns all of the variables referenced within a given experssion.
9 // This is the implementation of the "Variables" method on every native
11 func Variables(expr Expression) []hcl.Traversal {
12 var vars []hcl.Traversal
14 walker := &variablesWalker{
15 Callback: func(t hcl.Traversal) {
16 vars = append(vars, t)
25 // variablesWalker is a Walker implementation that calls its callback for any
26 // root scope traversal found while walking.
27 type variablesWalker struct {
28 Callback func(hcl.Traversal)
29 localScopes []map[string]struct{}
32 func (w *variablesWalker) Enter(n Node) hcl.Diagnostics {
33 switch tn := n.(type) {
34 case *ScopeTraversalExpr:
37 // Check if the given root name appears in any of the active
38 // local scopes. We don't want to return local variables here, since
39 // the goal of walking variables is to tell the calling application
40 // which names it needs to populate in the _root_ scope.
42 for _, names := range w.localScopes {
43 if _, localized := names[name]; localized {
50 w.localScopes = append(w.localScopes, tn.LocalNames)
55 func (w *variablesWalker) Exit(n Node) hcl.Diagnostics {
58 // pop the latest local scope, assuming that the walker will
59 // behave symmetrically as promised.
60 w.localScopes = w.localScopes[:len(w.localScopes)-1]
65 // ChildScope is a synthetic AST node that is visited during a walk to
66 // indicate that its descendent will be evaluated in a child scope, which
67 // may mask certain variables from the parent scope as locals.
69 // ChildScope nodes don't really exist in the AST, but are rather synthesized
70 // on the fly during walk. Therefore it doesn't do any good to transform them;
71 // instead, transform either parent node that created a scope or the expression
72 // that the child scope struct wraps.
73 type ChildScope struct {
74 LocalNames map[string]struct{}
78 func (e ChildScope) walkChildNodes(w internalWalkFunc) {
82 // Range returns the range of the expression that the ChildScope is
83 // encapsulating. It isn't really very useful to call Range on a ChildScope.
84 func (e ChildScope) Range() hcl.Range {