diff options
Diffstat (limited to 'vendor/github.com/hashicorp/hil/ast/index.go')
-rw-r--r-- | vendor/github.com/hashicorp/hil/ast/index.go | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/hil/ast/index.go b/vendor/github.com/hashicorp/hil/ast/index.go new file mode 100644 index 0000000..860c25f --- /dev/null +++ b/vendor/github.com/hashicorp/hil/ast/index.go | |||
@@ -0,0 +1,76 @@ | |||
1 | package ast | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "strings" | ||
6 | ) | ||
7 | |||
8 | // Index represents an indexing operation into another data structure | ||
9 | type Index struct { | ||
10 | Target Node | ||
11 | Key Node | ||
12 | Posx Pos | ||
13 | } | ||
14 | |||
15 | func (n *Index) Accept(v Visitor) Node { | ||
16 | n.Target = n.Target.Accept(v) | ||
17 | n.Key = n.Key.Accept(v) | ||
18 | return v(n) | ||
19 | } | ||
20 | |||
21 | func (n *Index) Pos() Pos { | ||
22 | return n.Posx | ||
23 | } | ||
24 | |||
25 | func (n *Index) String() string { | ||
26 | return fmt.Sprintf("Index(%s, %s)", n.Target, n.Key) | ||
27 | } | ||
28 | |||
29 | func (n *Index) Type(s Scope) (Type, error) { | ||
30 | variableAccess, ok := n.Target.(*VariableAccess) | ||
31 | if !ok { | ||
32 | return TypeInvalid, fmt.Errorf("target is not a variable") | ||
33 | } | ||
34 | |||
35 | variable, ok := s.LookupVar(variableAccess.Name) | ||
36 | if !ok { | ||
37 | return TypeInvalid, fmt.Errorf("unknown variable accessed: %s", variableAccess.Name) | ||
38 | } | ||
39 | |||
40 | switch variable.Type { | ||
41 | case TypeList: | ||
42 | return n.typeList(variable, variableAccess.Name) | ||
43 | case TypeMap: | ||
44 | return n.typeMap(variable, variableAccess.Name) | ||
45 | default: | ||
46 | return TypeInvalid, fmt.Errorf("invalid index operation into non-indexable type: %s", variable.Type) | ||
47 | } | ||
48 | } | ||
49 | |||
50 | func (n *Index) typeList(variable Variable, variableName string) (Type, error) { | ||
51 | // We assume type checking has already determined that this is a list | ||
52 | list := variable.Value.([]Variable) | ||
53 | |||
54 | return VariableListElementTypesAreHomogenous(variableName, list) | ||
55 | } | ||
56 | |||
57 | func (n *Index) typeMap(variable Variable, variableName string) (Type, error) { | ||
58 | // We assume type checking has already determined that this is a map | ||
59 | vmap := variable.Value.(map[string]Variable) | ||
60 | |||
61 | return VariableMapValueTypesAreHomogenous(variableName, vmap) | ||
62 | } | ||
63 | |||
64 | func reportTypes(typesFound map[Type]struct{}) string { | ||
65 | stringTypes := make([]string, len(typesFound)) | ||
66 | i := 0 | ||
67 | for k, _ := range typesFound { | ||
68 | stringTypes[0] = k.String() | ||
69 | i++ | ||
70 | } | ||
71 | return strings.Join(stringTypes, ", ") | ||
72 | } | ||
73 | |||
74 | func (n *Index) GoString() string { | ||
75 | return fmt.Sprintf("*%#v", *n) | ||
76 | } | ||