From 57adfe53f67c6a553ee8100e1dff98d17ddb662d Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 14 Jan 2015 20:58:46 -0800 Subject: [PATCH] config/lang: use the new AST stuff --- config/lang/builtins.go | 12 ++-- config/lang/check_identifier.go | 2 +- config/lang/check_identifier_test.go | 44 +++++++-------- config/lang/check_types.go | 4 +- config/lang/check_types_test.go | 82 ++++++++++++++-------------- config/lang/engine.go | 51 +++++------------ config/lang/engine_test.go | 32 +++++------ config/lang/lang.y | 10 ++-- config/lang/parse_test.go | 28 +++++----- config/lang/types.go | 53 ------------------ config/lang/types_test.go | 74 ------------------------- config/lang/y.go | 10 ++-- 12 files changed, 125 insertions(+), 277 deletions(-) delete mode 100644 config/lang/types.go delete mode 100644 config/lang/types_test.go diff --git a/config/lang/builtins.go b/config/lang/builtins.go index edeee29f2..ecc9d4a47 100644 --- a/config/lang/builtins.go +++ b/config/lang/builtins.go @@ -8,16 +8,16 @@ import ( // NOTE: All builtins are tested in engine_test.go -func registerBuiltins(scope *Scope) { +func registerBuiltins(scope *ast.BasicScope) { if scope.FuncMap == nil { - scope.FuncMap = make(map[string]Function) + scope.FuncMap = make(map[string]ast.Function) } scope.FuncMap["__builtin_IntToString"] = builtinIntToString() scope.FuncMap["__builtin_StringToInt"] = builtinStringToInt() } -func builtinIntToString() Function { - return Function{ +func builtinIntToString() ast.Function { + return ast.Function{ ArgTypes: []ast.Type{ast.TypeInt}, ReturnType: ast.TypeString, Callback: func(args []interface{}) (interface{}, error) { @@ -26,8 +26,8 @@ func builtinIntToString() Function { } } -func builtinStringToInt() Function { - return Function{ +func builtinStringToInt() ast.Function { + return ast.Function{ ArgTypes: []ast.Type{ast.TypeInt}, ReturnType: ast.TypeString, Callback: func(args []interface{}) (interface{}, error) { diff --git a/config/lang/check_identifier.go b/config/lang/check_identifier.go index 10ee2267d..a50673a2d 100644 --- a/config/lang/check_identifier.go +++ b/config/lang/check_identifier.go @@ -11,7 +11,7 @@ import ( // resolve properly and that the right number of arguments are passed // to functions. type IdentifierCheck struct { - Scope *Scope + Scope ast.Scope err error lock sync.Mutex diff --git a/config/lang/check_identifier_test.go b/config/lang/check_identifier_test.go index 526128424..1ed52580e 100644 --- a/config/lang/check_identifier_test.go +++ b/config/lang/check_identifier_test.go @@ -9,20 +9,20 @@ import ( func TestIdentifierCheck(t *testing.T) { cases := []struct { Input string - Scope *Scope + Scope ast.Scope Error bool }{ { "foo", - &Scope{}, + &ast.BasicScope{}, false, }, { "foo ${bar} success", - &Scope{ - VarMap: map[string]Variable{ - "bar": Variable{ + &ast.BasicScope{ + VarMap: map[string]ast.Variable{ + "bar": ast.Variable{ Value: "baz", Type: ast.TypeString, }, @@ -33,15 +33,15 @@ func TestIdentifierCheck(t *testing.T) { { "foo ${bar}", - &Scope{}, + &ast.BasicScope{}, true, }, { "foo ${rand()} success", - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ReturnType: ast.TypeString, Callback: func([]interface{}) (interface{}, error) { return "42", nil @@ -54,15 +54,15 @@ func TestIdentifierCheck(t *testing.T) { { "foo ${rand()}", - &Scope{}, + &ast.BasicScope{}, true, }, { "foo ${rand(42)} ", - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ReturnType: ast.TypeString, Callback: func([]interface{}) (interface{}, error) { return "42", nil @@ -75,9 +75,9 @@ func TestIdentifierCheck(t *testing.T) { { "foo ${rand()} ", - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ReturnType: ast.TypeString, Variadic: true, VariadicType: ast.TypeInt, @@ -92,9 +92,9 @@ func TestIdentifierCheck(t *testing.T) { { "foo ${rand(42)} ", - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ReturnType: ast.TypeString, Variadic: true, VariadicType: ast.TypeInt, @@ -109,9 +109,9 @@ func TestIdentifierCheck(t *testing.T) { { "foo ${rand(\"foo\", 42)} ", - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ArgTypes: []ast.Type{ast.TypeString}, ReturnType: ast.TypeString, Variadic: true, diff --git a/config/lang/check_types.go b/config/lang/check_types.go index 4491ea496..882c64ca3 100644 --- a/config/lang/check_types.go +++ b/config/lang/check_types.go @@ -16,7 +16,7 @@ import ( // this structure but we'd rather do that than duplicate the type checking // logic multiple times. type TypeCheck struct { - Scope *Scope + Scope ast.Scope // Implicit is a map of implicit type conversions that we can do, // and that shouldn't error. The key of the first map is the from type, @@ -140,7 +140,7 @@ func (v *TypeCheck) visitConcat(n *ast.Concat) { } func (v *TypeCheck) visitLiteral(n *ast.LiteralNode) { - v.stackPush(n.Type) + v.stackPush(n.Typex) } func (v *TypeCheck) visitVariableAccess(n *ast.VariableAccess) { diff --git a/config/lang/check_types_test.go b/config/lang/check_types_test.go index 292d9255d..eb108044e 100644 --- a/config/lang/check_types_test.go +++ b/config/lang/check_types_test.go @@ -9,20 +9,20 @@ import ( func TestTypeCheck(t *testing.T) { cases := []struct { Input string - Scope *Scope + Scope ast.Scope Error bool }{ { "foo", - &Scope{}, + &ast.BasicScope{}, false, }, { "foo ${bar}", - &Scope{ - VarMap: map[string]Variable{ - "bar": Variable{ + &ast.BasicScope{ + VarMap: map[string]ast.Variable{ + "bar": ast.Variable{ Value: "baz", Type: ast.TypeString, }, @@ -33,9 +33,9 @@ func TestTypeCheck(t *testing.T) { { "foo ${rand()}", - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ReturnType: ast.TypeString, Callback: func([]interface{}) (interface{}, error) { return "42", nil @@ -48,9 +48,9 @@ func TestTypeCheck(t *testing.T) { { `foo ${rand("42")}`, - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ArgTypes: []ast.Type{ast.TypeString}, ReturnType: ast.TypeString, Callback: func([]interface{}) (interface{}, error) { @@ -64,9 +64,9 @@ func TestTypeCheck(t *testing.T) { { `foo ${rand(42)}`, - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ArgTypes: []ast.Type{ast.TypeString}, ReturnType: ast.TypeString, Callback: func([]interface{}) (interface{}, error) { @@ -80,9 +80,9 @@ func TestTypeCheck(t *testing.T) { { `foo ${rand()}`, - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ArgTypes: nil, ReturnType: ast.TypeString, Variadic: true, @@ -98,9 +98,9 @@ func TestTypeCheck(t *testing.T) { { `foo ${rand("42")}`, - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ArgTypes: nil, ReturnType: ast.TypeString, Variadic: true, @@ -116,9 +116,9 @@ func TestTypeCheck(t *testing.T) { { `foo ${rand("42", 42)}`, - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ArgTypes: nil, ReturnType: ast.TypeString, Variadic: true, @@ -134,9 +134,9 @@ func TestTypeCheck(t *testing.T) { { "foo ${bar}", - &Scope{ - VarMap: map[string]Variable{ - "bar": Variable{ + &ast.BasicScope{ + VarMap: map[string]ast.Variable{ + "bar": ast.Variable{ Value: 42, Type: ast.TypeInt, }, @@ -147,9 +147,9 @@ func TestTypeCheck(t *testing.T) { { "foo ${rand()}", - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ReturnType: ast.TypeInt, Callback: func([]interface{}) (interface{}, error) { return 42, nil @@ -184,14 +184,14 @@ func TestTypeCheck_implicit(t *testing.T) { cases := []struct { Input string - Scope *Scope + Scope *ast.BasicScope Error bool }{ { "foo ${bar}", - &Scope{ - VarMap: map[string]Variable{ - "bar": Variable{ + &ast.BasicScope{ + VarMap: map[string]ast.Variable{ + "bar": ast.Variable{ Value: 42, Type: ast.TypeInt, }, @@ -202,9 +202,9 @@ func TestTypeCheck_implicit(t *testing.T) { { "foo ${foo(42)}", - &Scope{ - FuncMap: map[string]Function{ - "foo": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "foo": ast.Function{ ArgTypes: []ast.Type{ast.TypeString}, ReturnType: ast.TypeString, }, @@ -215,9 +215,9 @@ func TestTypeCheck_implicit(t *testing.T) { { `foo ${foo("42", 42)}`, - &Scope{ - FuncMap: map[string]Function{ - "foo": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "foo": ast.Function{ ArgTypes: []ast.Type{ast.TypeString}, Variadic: true, VariadicType: ast.TypeString, @@ -237,9 +237,9 @@ func TestTypeCheck_implicit(t *testing.T) { // Modify the scope to add our conversion functions. if tc.Scope.FuncMap == nil { - tc.Scope.FuncMap = make(map[string]Function) + tc.Scope.FuncMap = make(map[string]ast.Function) } - tc.Scope.FuncMap["intToString"] = Function{ + tc.Scope.FuncMap["intToString"] = ast.Function{ ArgTypes: []ast.Type{ast.TypeInt}, ReturnType: ast.TypeString, } diff --git a/config/lang/engine.go b/config/lang/engine.go index 9bcdb5563..380f4db1c 100644 --- a/config/lang/engine.go +++ b/config/lang/engine.go @@ -12,7 +12,7 @@ import ( // prior to running Execute. type Engine struct { // GlobalScope is the global scope of execution for this engine. - GlobalScope *Scope + GlobalScope *ast.BasicScope // SemanticChecks is a list of additional semantic checks that will be run // on the tree prior to executing it. The type checker, identifier checker, @@ -61,8 +61,8 @@ func (e *Engine) Execute(root ast.Node) (interface{}, ast.Type, error) { return v.Visit(root) } -func (e *Engine) scope() *Scope { - var scope Scope +func (e *Engine) scope() ast.Scope { + var scope ast.BasicScope if e.GlobalScope != nil { scope = *e.GlobalScope } @@ -75,7 +75,7 @@ func (e *Engine) scope() *Scope { // a program. Note at this point it is assumed that the types check out // and the identifiers exist. type executeVisitor struct { - Scope *Scope + Scope ast.Scope stack EngineStack err error @@ -102,7 +102,12 @@ func (v *executeVisitor) Visit(root ast.Node) (interface{}, ast.Type, error) { v.stack.Reset() v.err = nil - return result.Value, result.Type, resultErr + t, err := result.Type(v.Scope) + if err != nil { + return nil, ast.TypeInvalid, err + } + + return result.Value, t, resultErr } func (v *executeVisitor) visit(raw ast.Node) ast.Node { @@ -151,7 +156,7 @@ func (v *executeVisitor) visitCall(n *ast.Call) { // Push the result v.stack.Push(&ast.LiteralNode{ Value: result, - Type: function.ReturnType, + Typex: function.ReturnType, }) } @@ -170,7 +175,7 @@ func (v *executeVisitor) visitConcat(n *ast.Concat) { v.stack.Push(&ast.LiteralNode{ Value: buf.String(), - Type: ast.TypeString, + Typex: ast.TypeString, }) } @@ -188,7 +193,7 @@ func (v *executeVisitor) visitVariableAccess(n *ast.VariableAccess) { v.stack.Push(&ast.LiteralNode{ Value: variable.Value, - Type: variable.Type, + Typex: variable.Type, }) } @@ -218,33 +223,3 @@ func (s *EngineStack) Pop() *ast.LiteralNode { func (s *EngineStack) Reset() { s.stack = nil } - -// Scope represents a lookup scope for execution. -type Scope struct { - // VarMap and FuncMap are the mappings of identifiers to functions - // and variable values. - VarMap map[string]Variable - FuncMap map[string]Function -} - -// LookupFunc will look up a variable by name. -// TODO test -func (s *Scope) LookupFunc(n string) (Function, bool) { - if s == nil { - return Function{}, false - } - - v, ok := s.FuncMap[n] - return v, ok -} - -// LookupVar will look up a variable by name. -// TODO test -func (s *Scope) LookupVar(n string) (Variable, bool) { - if s == nil { - return Variable{}, false - } - - v, ok := s.VarMap[n] - return v, ok -} diff --git a/config/lang/engine_test.go b/config/lang/engine_test.go index 488d56be7..a1e5aaba2 100644 --- a/config/lang/engine_test.go +++ b/config/lang/engine_test.go @@ -11,7 +11,7 @@ import ( func TestEngineExecute(t *testing.T) { cases := []struct { Input string - Scope *Scope + Scope *ast.BasicScope Error bool Result interface{} ResultType ast.Type @@ -26,9 +26,9 @@ func TestEngineExecute(t *testing.T) { { "foo ${bar}", - &Scope{ - VarMap: map[string]Variable{ - "bar": Variable{ + &ast.BasicScope{ + VarMap: map[string]ast.Variable{ + "bar": ast.Variable{ Value: "baz", Type: ast.TypeString, }, @@ -41,9 +41,9 @@ func TestEngineExecute(t *testing.T) { { "foo ${rand()}", - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ReturnType: ast.TypeString, Callback: func([]interface{}) (interface{}, error) { return "42", nil @@ -58,9 +58,9 @@ func TestEngineExecute(t *testing.T) { { `foo ${rand("foo", "bar")}`, - &Scope{ - FuncMap: map[string]Function{ - "rand": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "rand": ast.Function{ ReturnType: ast.TypeString, Variadic: true, VariadicType: ast.TypeString, @@ -83,9 +83,9 @@ func TestEngineExecute(t *testing.T) { { "foo ${bar}", - &Scope{ - VarMap: map[string]Variable{ - "bar": Variable{ + &ast.BasicScope{ + VarMap: map[string]ast.Variable{ + "bar": ast.Variable{ Value: 42, Type: ast.TypeInt, }, @@ -98,9 +98,9 @@ func TestEngineExecute(t *testing.T) { { `foo ${foo("42")}`, - &Scope{ - FuncMap: map[string]Function{ - "foo": Function{ + &ast.BasicScope{ + FuncMap: map[string]ast.Function{ + "foo": ast.Function{ ArgTypes: []ast.Type{ast.TypeInt}, ReturnType: ast.TypeString, Callback: func(args []interface{}) (interface{}, error) { diff --git a/config/lang/lang.y b/config/lang/lang.y index fffe53089..4ee47fb54 100644 --- a/config/lang/lang.y +++ b/config/lang/lang.y @@ -33,7 +33,7 @@ top: { parserResult = &ast.LiteralNode{ Value: "", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, } } @@ -50,7 +50,7 @@ top: // it makes for an easy literal check later (to check if a string // has any interpolations). if _, ok := $1.(*ast.Concat); !ok { - if n, ok := $1.(*ast.LiteralNode); !ok || n.Type != ast.TypeString { + if n, ok := $1.(*ast.LiteralNode); !ok || n.Typex != ast.TypeString { parserResult = &ast.Concat{ Exprs: []ast.Node{$1}, Posx: $1.Pos(), @@ -104,7 +104,7 @@ expr: { $$ = &ast.LiteralNode{ Value: $1.Value.(int), - Type: ast.TypeInt, + Typex: ast.TypeInt, Posx: $1.Pos, } } @@ -112,7 +112,7 @@ expr: { $$ = &ast.LiteralNode{ Value: $1.Value.(float64), - Type: ast.TypeFloat, + Typex: ast.TypeFloat, Posx: $1.Pos, } } @@ -143,7 +143,7 @@ literal: { $$ = &ast.LiteralNode{ Value: $1.Value.(string), - Type: ast.TypeString, + Typex: ast.TypeString, Posx: $1.Pos, } } diff --git a/config/lang/parse_test.go b/config/lang/parse_test.go index a176da7f9..3d158d667 100644 --- a/config/lang/parse_test.go +++ b/config/lang/parse_test.go @@ -18,7 +18,7 @@ func TestParse(t *testing.T) { false, &ast.LiteralNode{ Value: "", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, }, }, @@ -28,7 +28,7 @@ func TestParse(t *testing.T) { false, &ast.LiteralNode{ Value: "foo", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, }, }, @@ -38,7 +38,7 @@ func TestParse(t *testing.T) { false, &ast.LiteralNode{ Value: "${var.foo}", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, }, }, @@ -51,7 +51,7 @@ func TestParse(t *testing.T) { Exprs: []ast.Node{ &ast.LiteralNode{ Value: "foo ", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, }, &ast.VariableAccess{ @@ -70,7 +70,7 @@ func TestParse(t *testing.T) { Exprs: []ast.Node{ &ast.LiteralNode{ Value: "foo ", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, }, &ast.VariableAccess{ @@ -79,7 +79,7 @@ func TestParse(t *testing.T) { }, &ast.LiteralNode{ Value: " baz", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 15, Line: 1}, }, }, @@ -94,12 +94,12 @@ func TestParse(t *testing.T) { Exprs: []ast.Node{ &ast.LiteralNode{ Value: "foo ", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, }, &ast.LiteralNode{ Value: "bar", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 7, Line: 1}, }, }, @@ -114,12 +114,12 @@ func TestParse(t *testing.T) { Exprs: []ast.Node{ &ast.LiteralNode{ Value: "foo ", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, }, &ast.LiteralNode{ Value: 42, - Type: ast.TypeInt, + Typex: ast.TypeInt, Posx: ast.Pos{Column: 7, Line: 1}, }, }, @@ -134,12 +134,12 @@ func TestParse(t *testing.T) { Exprs: []ast.Node{ &ast.LiteralNode{ Value: "foo ", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, }, &ast.LiteralNode{ Value: 3.14159, - Type: ast.TypeFloat, + Typex: ast.TypeFloat, Posx: ast.Pos{Column: 7, Line: 1}, }, }, @@ -239,7 +239,7 @@ func TestParse(t *testing.T) { Exprs: []ast.Node{ &ast.LiteralNode{ Value: "foo ", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, }, &ast.Concat{ @@ -247,7 +247,7 @@ func TestParse(t *testing.T) { Exprs: []ast.Node{ &ast.LiteralNode{ Value: "bar ", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 7, Line: 1}, }, &ast.VariableAccess{ diff --git a/config/lang/types.go b/config/lang/types.go deleted file mode 100644 index 8adfcd05e..000000000 --- a/config/lang/types.go +++ /dev/null @@ -1,53 +0,0 @@ -package lang - -import ( - "fmt" - - "github.com/hashicorp/terraform/config/lang/ast" -) - -// LookupType looks up the type of the given node with the given scope. -func LookupType(raw ast.Node, scope *Scope) (ast.Type, error) { - switch n := raw.(type) { - case *ast.LiteralNode: - return typedLiteralNode{n}.Type(scope) - case *ast.VariableAccess: - return typedVariableAccess{n}.Type(scope) - default: - if t, ok := raw.(TypedNode); ok { - return t.Type(scope) - } - - return ast.TypeInvalid, fmt.Errorf( - "unknown node to get type of: %T", raw) - } -} - -// TypedNode is an interface that custom AST nodes should implement -// if they want to work with LookupType. All the builtin AST nodes have -// implementations of this. -type TypedNode interface { - Type(*Scope) (ast.Type, error) -} - -type typedLiteralNode struct { - n *ast.LiteralNode -} - -func (n typedLiteralNode) Type(s *Scope) (ast.Type, error) { - return n.n.Type, nil -} - -type typedVariableAccess struct { - n *ast.VariableAccess -} - -func (n typedVariableAccess) Type(s *Scope) (ast.Type, error) { - v, ok := s.LookupVar(n.n.Name) - if !ok { - return ast.TypeInvalid, fmt.Errorf( - "%s: couldn't find variable %s", n.n.Pos(), n.n.Name) - } - - return v.Type, nil -} diff --git a/config/lang/types_test.go b/config/lang/types_test.go deleted file mode 100644 index 74513e24a..000000000 --- a/config/lang/types_test.go +++ /dev/null @@ -1,74 +0,0 @@ -package lang - -import ( - "testing" - - "github.com/hashicorp/terraform/config/lang/ast" -) - -func TestLookupType(t *testing.T) { - cases := []struct { - Input ast.Node - Scope *Scope - Output ast.Type - Error bool - }{ - { - &customUntyped{}, - nil, - ast.TypeInvalid, - true, - }, - - { - &customTyped{}, - nil, - ast.TypeString, - false, - }, - - { - &ast.LiteralNode{ - Value: 42, - Type: ast.TypeInt, - }, - nil, - ast.TypeInt, - false, - }, - - { - &ast.VariableAccess{ - Name: "foo", - }, - &Scope{ - VarMap: map[string]Variable{ - "foo": Variable{Type: ast.TypeInt}, - }, - }, - ast.TypeInt, - false, - }, - } - - for _, tc := range cases { - actual, err := LookupType(tc.Input, tc.Scope) - if (err != nil) != tc.Error { - t.Fatalf("bad: %s\n\nInput: %#v", err, tc.Input) - } - if actual != tc.Output { - t.Fatalf("bad: %s\n\nInput: %#v", actual, tc.Input) - } - } -} - -type customUntyped struct{} - -func (n customUntyped) Accept(ast.Visitor) ast.Node { return n } -func (n customUntyped) Pos() (v ast.Pos) { return } - -type customTyped struct{} - -func (n customTyped) Accept(ast.Visitor) ast.Node { return n } -func (n customTyped) Pos() (v ast.Pos) { return } -func (n customTyped) Type(*Scope) (ast.Type, error) { return ast.TypeString, nil } diff --git a/config/lang/y.go b/config/lang/y.go index 6d3a456a6..de1ce7501 100644 --- a/config/lang/y.go +++ b/config/lang/y.go @@ -346,7 +346,7 @@ parserdefault: { parserResult = &ast.LiteralNode{ Value: "", - Type: ast.TypeString, + Typex: ast.TypeString, Posx: ast.Pos{Column: 1, Line: 1}, } } @@ -364,7 +364,7 @@ parserdefault: // it makes for an easy literal check later (to check if a string // has any interpolations). if _, ok := parserS[parserpt-0].node.(*ast.Concat); !ok { - if n, ok := parserS[parserpt-0].node.(*ast.LiteralNode); !ok || n.Type != ast.TypeString { + if n, ok := parserS[parserpt-0].node.(*ast.LiteralNode); !ok || n.Typex != ast.TypeString { parserResult = &ast.Concat{ Exprs: []ast.Node{parserS[parserpt-0].node}, Posx: parserS[parserpt-0].node.Pos(), @@ -417,7 +417,7 @@ parserdefault: { parserVAL.node = &ast.LiteralNode{ Value: parserS[parserpt-0].token.Value.(int), - Type: ast.TypeInt, + Typex: ast.TypeInt, Posx: parserS[parserpt-0].token.Pos, } } @@ -426,7 +426,7 @@ parserdefault: { parserVAL.node = &ast.LiteralNode{ Value: parserS[parserpt-0].token.Value.(float64), - Type: ast.TypeFloat, + Typex: ast.TypeFloat, Posx: parserS[parserpt-0].token.Pos, } } @@ -460,7 +460,7 @@ parserdefault: { parserVAL.node = &ast.LiteralNode{ Value: parserS[parserpt-0].token.Value.(string), - Type: ast.TypeString, + Typex: ast.TypeString, Posx: parserS[parserpt-0].token.Pos, } }