From e678222d5687fdc19ff1ea12f191795e0312eb7f Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 14 Oct 2016 10:13:50 -0700 Subject: [PATCH] vendor: update HIL to support more eval in indexes, implicit conversion --- vendor/github.com/hashicorp/hil/ast/index.go | 7 +-- .../github.com/hashicorp/hil/check_types.go | 34 ++++++++---- vendor/github.com/hashicorp/hil/eval.go | 55 +++++++------------ vendor/vendor.json | 12 ++-- 4 files changed, 51 insertions(+), 57 deletions(-) diff --git a/vendor/github.com/hashicorp/hil/ast/index.go b/vendor/github.com/hashicorp/hil/ast/index.go index 51bef51c7..860c25fd2 100644 --- a/vendor/github.com/hashicorp/hil/ast/index.go +++ b/vendor/github.com/hashicorp/hil/ast/index.go @@ -13,11 +13,8 @@ type Index struct { } func (n *Index) Accept(v Visitor) Node { - // the Key may have further interpolations - switch n.Key.(type) { - case *Call, *VariableAccess: - n.Key = n.Key.Accept(v) - } + n.Target = n.Target.Accept(v) + n.Key = n.Key.Accept(v) return v(n) } diff --git a/vendor/github.com/hashicorp/hil/check_types.go b/vendor/github.com/hashicorp/hil/check_types.go index 4b35d1142..1c8cb0a07 100644 --- a/vendor/github.com/hashicorp/hil/check_types.go +++ b/vendor/github.com/hashicorp/hil/check_types.go @@ -305,30 +305,35 @@ type typeCheckIndex struct { } func (tc *typeCheckIndex) TypeCheck(v *TypeCheck) (ast.Node, error) { + keyType := v.StackPop() + targetType := v.StackPop() + // Ensure we have a VariableAccess as the target varAccessNode, ok := tc.n.Target.(*ast.VariableAccess) if !ok { - return nil, fmt.Errorf("target of an index must be a VariableAccess node, was %T", tc.n.Target) + return nil, fmt.Errorf( + "target of an index must be a VariableAccess node, was %T", tc.n.Target) } // Get the variable variable, ok := v.Scope.LookupVar(varAccessNode.Name) if !ok { - return nil, fmt.Errorf("unknown variable accessed: %s", varAccessNode.Name) + return nil, fmt.Errorf( + "unknown variable accessed: %s", varAccessNode.Name) } - keyType, err := tc.n.Key.Type(v.Scope) - if err != nil { - return nil, err - } - - switch variable.Type { + switch targetType { case ast.TypeList: if keyType != ast.TypeInt { - return nil, fmt.Errorf("key of an index must be an int, was %s", keyType) + tc.n.Key = v.ImplicitConversion(keyType, ast.TypeInt, tc.n.Key) + if tc.n.Key == nil { + return nil, fmt.Errorf( + "key of an index must be an int, was %s", keyType) + } } - valType, err := ast.VariableListElementTypesAreHomogenous(varAccessNode.Name, variable.Value.([]ast.Variable)) + valType, err := ast.VariableListElementTypesAreHomogenous( + varAccessNode.Name, variable.Value.([]ast.Variable)) if err != nil { return tc.n, err } @@ -337,10 +342,15 @@ func (tc *typeCheckIndex) TypeCheck(v *TypeCheck) (ast.Node, error) { return tc.n, nil case ast.TypeMap: if keyType != ast.TypeString { - return nil, fmt.Errorf("key of an index must be a string, was %s", keyType) + tc.n.Key = v.ImplicitConversion(keyType, ast.TypeString, tc.n.Key) + if tc.n.Key == nil { + return nil, fmt.Errorf( + "key of an index must be a string, was %s", keyType) + } } - valType, err := ast.VariableMapValueTypesAreHomogenous(varAccessNode.Name, variable.Value.(map[string]ast.Variable)) + valType, err := ast.VariableMapValueTypesAreHomogenous( + varAccessNode.Name, variable.Value.(map[string]ast.Variable)) if err != nil { return tc.n, err } diff --git a/vendor/github.com/hashicorp/hil/eval.go b/vendor/github.com/hashicorp/hil/eval.go index 9be0d59f6..de999480d 100644 --- a/vendor/github.com/hashicorp/hil/eval.go +++ b/vendor/github.com/hashicorp/hil/eval.go @@ -244,39 +244,20 @@ func (v *evalCall) Eval(s ast.Scope, stack *ast.Stack) (interface{}, ast.Type, e type evalIndex struct{ *ast.Index } func (v *evalIndex) Eval(scope ast.Scope, stack *ast.Stack) (interface{}, ast.Type, error) { - evalVarAccess, err := evalNode(v.Target) - if err != nil { - return nil, ast.TypeInvalid, err - } - target, targetType, err := evalVarAccess.Eval(scope, stack) - - evalKey, err := evalNode(v.Key) - if err != nil { - return nil, ast.TypeInvalid, err - } - - key, keyType, err := evalKey.Eval(scope, stack) - if err != nil { - return nil, ast.TypeInvalid, err - } + key := stack.Pop().(*ast.LiteralNode) + target := stack.Pop().(*ast.LiteralNode) variableName := v.Index.Target.(*ast.VariableAccess).Name - switch targetType { + switch target.Typex { case ast.TypeList: - if keyType != ast.TypeInt { - return nil, ast.TypeInvalid, fmt.Errorf("key for indexing list %q must be an int, is %s", variableName, keyType) - } - - return v.evalListIndex(variableName, target, key) + return v.evalListIndex(variableName, target.Value, key.Value) case ast.TypeMap: - if keyType != ast.TypeString { - return nil, ast.TypeInvalid, fmt.Errorf("key for indexing map %q must be a string, is %s", variableName, keyType) - } - - return v.evalMapIndex(variableName, target, key) + return v.evalMapIndex(variableName, target.Value, key.Value) default: - return nil, ast.TypeInvalid, fmt.Errorf("target %q for indexing must be ast.TypeList or ast.TypeMap, is %s", variableName, targetType) + return nil, ast.TypeInvalid, fmt.Errorf( + "target %q for indexing must be ast.TypeList or ast.TypeMap, is %s", + variableName, target.Typex) } } @@ -285,12 +266,14 @@ func (v *evalIndex) evalListIndex(variableName string, target interface{}, key i // is a list and key is an int list, ok := target.([]ast.Variable) if !ok { - return nil, ast.TypeInvalid, fmt.Errorf("cannot cast target to []Variable") + return nil, ast.TypeInvalid, fmt.Errorf( + "cannot cast target to []Variable, is: %T", target) } keyInt, ok := key.(int) if !ok { - return nil, ast.TypeInvalid, fmt.Errorf("cannot cast key to int") + return nil, ast.TypeInvalid, fmt.Errorf( + "cannot cast key to int, is: %T", key) } if len(list) == 0 { @@ -298,12 +281,13 @@ func (v *evalIndex) evalListIndex(variableName string, target interface{}, key i } if keyInt < 0 || len(list) < keyInt+1 { - return nil, ast.TypeInvalid, fmt.Errorf("index %d out of range for list %s (max %d)", keyInt, variableName, len(list)) + return nil, ast.TypeInvalid, fmt.Errorf( + "index %d out of range for list %s (max %d)", + keyInt, variableName, len(list)) } returnVal := list[keyInt].Value returnType := list[keyInt].Type - return returnVal, returnType, nil } @@ -312,12 +296,14 @@ func (v *evalIndex) evalMapIndex(variableName string, target interface{}, key in // is a map and key is a string vmap, ok := target.(map[string]ast.Variable) if !ok { - return nil, ast.TypeInvalid, fmt.Errorf("cannot cast target to map[string]Variable") + return nil, ast.TypeInvalid, fmt.Errorf( + "cannot cast target to map[string]Variable, is: %T", target) } keyString, ok := key.(string) if !ok { - return nil, ast.TypeInvalid, fmt.Errorf("cannot cast key to string") + return nil, ast.TypeInvalid, fmt.Errorf( + "cannot cast key to string, is: %T", key) } if len(vmap) == 0 { @@ -326,7 +312,8 @@ func (v *evalIndex) evalMapIndex(variableName string, target interface{}, key in value, ok := vmap[keyString] if !ok { - return nil, ast.TypeInvalid, fmt.Errorf("key %q does not exist in map %s", keyString, variableName) + return nil, ast.TypeInvalid, fmt.Errorf( + "key %q does not exist in map %s", keyString, variableName) } return value.Value, value.Type, nil diff --git a/vendor/vendor.json b/vendor/vendor.json index a04d20b26..1a9920146 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -1232,16 +1232,16 @@ "revisionTime": "2016-10-08T07:35:57Z" }, { - "checksumSHA1": "OrnLOmhc0FcHYs02wtbu1siIsnM=", + "checksumSHA1": "RYz/9y1RMZfg+oMgEyJIWiSl1dU=", "path": "github.com/hashicorp/hil", - "revision": "37d5c183ca6a28a9177e5a375a3f0f3663160742", - "revisionTime": "2016-10-12T19:56:11Z" + "revision": "3e00ff29065d64c0f8e9ef7efed82686bbda81ca", + "revisionTime": "2016-10-14T17:08:44Z" }, { - "checksumSHA1": "2NAuBxZXtp0e9orDclwc5ucnTSw=", + "checksumSHA1": "WYIQ+nJPa191qpQIUsauF4wXYSw=", "path": "github.com/hashicorp/hil/ast", - "revision": "37d5c183ca6a28a9177e5a375a3f0f3663160742", - "revisionTime": "2016-10-12T19:56:11Z" + "revision": "3e00ff29065d64c0f8e9ef7efed82686bbda81ca", + "revisionTime": "2016-10-14T17:08:44Z" }, { "path": "github.com/hashicorp/logutils",