diff --git a/ast/ast.go b/ast/ast.go index 51a9b4a..84ebd5e 100644 --- a/ast/ast.go +++ b/ast/ast.go @@ -42,7 +42,7 @@ type Visitor interface { // syntax level. type ObjectNode struct { K string - Elem []KeyedNode + Elem []AssignmentNode } // AssignmentNode represents a direct assignment with an equals @@ -82,12 +82,7 @@ func (n ObjectNode) Get(k string, insensitive bool) []Node { } } - switch n := elem.(type) { - case AssignmentNode: - result = append(result, n.Value) - default: - panic("unknown type") - } + result = append(result, elem.Value) } return result @@ -121,6 +116,19 @@ func (n ListNode) Accept(v Visitor) { } } +func (n ListNode) Flatten() ListNode { + var elem []Node + for _, e := range n.Elem { + if ln, ok := e.(ListNode); ok { + elem = append(elem, ln.Flatten().Elem...) + } else { + elem = append(elem, e) + } + } + + return ListNode{Elem: elem} +} + func (n LiteralNode) Accept(v Visitor) { v.Visit(n) } diff --git a/ast/ast_test.go b/ast/ast_test.go index 16d4881..d4ff289 100644 --- a/ast/ast_test.go +++ b/ast/ast_test.go @@ -49,7 +49,7 @@ func TestListNode_accept(t *testing.T) { func TestObjectNode_accept(t *testing.T) { n := ObjectNode{ K: "foo", - Elem: []KeyedNode{ + Elem: []AssignmentNode{ AssignmentNode{K: "foo", Value: LiteralNode{Value: "foo"}}, AssignmentNode{K: "bar", Value: LiteralNode{Value: "bar"}}, }, @@ -58,9 +58,9 @@ func TestObjectNode_accept(t *testing.T) { expected := []Node{ n, n.Elem[0], - n.Elem[0].(AssignmentNode).Value, + n.Elem[0].Value, n.Elem[1], - n.Elem[1].(AssignmentNode).Value, + n.Elem[1].Value, } v := new(MockVisitor) @@ -74,7 +74,7 @@ func TestObjectNode_accept(t *testing.T) { func TestObjectNodeGet(t *testing.T) { n := ObjectNode{ K: "foo", - Elem: []KeyedNode{ + Elem: []AssignmentNode{ AssignmentNode{K: "foo", Value: LiteralNode{Value: "foo"}}, AssignmentNode{K: "bar", Value: LiteralNode{Value: "bar"}}, AssignmentNode{K: "foo", Value: LiteralNode{Value: "baz"}}, diff --git a/decoder.go b/decoder.go index 5676821..08634fc 100644 --- a/decoder.go +++ b/decoder.go @@ -202,8 +202,7 @@ func (d *decoder) decodeMap(name string, raw ast.Node, result reflect.Value) err } // Go through each element and decode it. - for _, elem := range obj.Elem { - n := elem.(ast.AssignmentNode) + for _, n := range obj.Elem { objValue := n.Value // If we have an object node, expand to a list of objects diff --git a/hcl/parse.y b/hcl/parse.y index 8300c4c..07470fe 100644 --- a/hcl/parse.y +++ b/hcl/parse.y @@ -15,8 +15,8 @@ import ( %union { item ast.Node list []ast.Node - klist []ast.KeyedNode - kitem ast.KeyedNode + alist []ast.AssignmentNode + aitem ast.AssignmentNode listitem ast.Node num int obj ast.ObjectNode @@ -25,8 +25,8 @@ import ( %type number %type list -%type objectlist -%type objectitem block +%type objectlist +%type objectitem block %type listitem %type int %type object @@ -50,7 +50,7 @@ top: objectlist: objectitem { - $$ = []ast.KeyedNode{$1} + $$ = []ast.AssignmentNode{$1} } | objectitem objectlist { @@ -118,7 +118,7 @@ block: { obj := ast.ObjectNode{ K: $2.Key(), - Elem: []ast.KeyedNode{$2}, + Elem: []ast.AssignmentNode{$2}, } $$ = ast.AssignmentNode{ diff --git a/hcl/y.go b/hcl/y.go index f7d28ec..c7a81fb 100644 --- a/hcl/y.go +++ b/hcl/y.go @@ -16,8 +16,8 @@ type hclSymType struct { yys int item ast.Node list []ast.Node - klist []ast.KeyedNode - kitem ast.KeyedNode + alist []ast.AssignmentNode + aitem ast.AssignmentNode listitem ast.Node num int obj ast.ObjectNode @@ -363,23 +363,23 @@ hcldefault: { hclResult = &ast.ObjectNode{ K: "", - Elem: hclS[hclpt-0].klist, + Elem: hclS[hclpt-0].alist, } } case 2: //line parse.y:52 { - hclVAL.klist = []ast.KeyedNode{hclS[hclpt-0].kitem} + hclVAL.alist = []ast.AssignmentNode{hclS[hclpt-0].aitem} } case 3: //line parse.y:56 { - hclVAL.klist = append(hclS[hclpt-0].klist, hclS[hclpt-1].kitem) + hclVAL.alist = append(hclS[hclpt-0].alist, hclS[hclpt-1].aitem) } case 4: //line parse.y:62 { - hclVAL.obj = ast.ObjectNode{Elem: hclS[hclpt-1].klist} + hclVAL.obj = ast.ObjectNode{Elem: hclS[hclpt-1].alist} } case 5: //line parse.y:66 @@ -389,7 +389,7 @@ hcldefault: case 6: //line parse.y:72 { - hclVAL.kitem = ast.AssignmentNode{ + hclVAL.aitem = ast.AssignmentNode{ K: hclS[hclpt-2].str, Value: hclS[hclpt-0].item, } @@ -397,7 +397,7 @@ hcldefault: case 7: //line parse.y:79 { - hclVAL.kitem = ast.AssignmentNode{ + hclVAL.aitem = ast.AssignmentNode{ K: hclS[hclpt-2].str, Value: ast.LiteralNode{ Type: ast.ValueTypeString, @@ -408,7 +408,7 @@ hcldefault: case 8: //line parse.y:89 { - hclVAL.kitem = ast.AssignmentNode{ + hclVAL.aitem = ast.AssignmentNode{ K: hclS[hclpt-2].str, Value: hclS[hclpt-0].obj, } @@ -416,7 +416,7 @@ hcldefault: case 9: //line parse.y:96 { - hclVAL.kitem = ast.AssignmentNode{ + hclVAL.aitem = ast.AssignmentNode{ K: hclS[hclpt-4].str, Value: ast.ListNode{Elem: hclS[hclpt-1].list}, } @@ -424,12 +424,12 @@ hcldefault: case 10: //line parse.y:103 { - hclVAL.kitem = hclS[hclpt-0].kitem + hclVAL.aitem = hclS[hclpt-0].aitem } case 11: //line parse.y:109 { - hclVAL.kitem = ast.AssignmentNode{ + hclVAL.aitem = ast.AssignmentNode{ K: hclS[hclpt-1].str, Value: ast.ListNode{ Elem: []ast.Node{hclS[hclpt-0].obj}, @@ -440,11 +440,11 @@ hcldefault: //line parse.y:118 { obj := ast.ObjectNode{ - K: hclS[hclpt-0].kitem.Key(), - Elem: []ast.KeyedNode{hclS[hclpt-0].kitem}, + K: hclS[hclpt-0].aitem.Key(), + Elem: []ast.AssignmentNode{hclS[hclpt-0].aitem}, } - hclVAL.kitem = ast.AssignmentNode{ + hclVAL.aitem = ast.AssignmentNode{ K: hclS[hclpt-1].str, Value: ast.ListNode{ Elem: []ast.Node{obj}, diff --git a/json/parse.y b/json/parse.y index bb06be1..a1c565f 100644 --- a/json/parse.y +++ b/json/parse.y @@ -16,7 +16,7 @@ import ( array ast.ListNode assign ast.AssignmentNode item ast.Node - klist []ast.KeyedNode + klist []ast.AssignmentNode list []ast.Node num int str string @@ -59,7 +59,7 @@ object: members: pair { - $$ = []ast.KeyedNode{$1} + $$ = []ast.AssignmentNode{$1} } | pair COMMA members { diff --git a/json/y.go b/json/y.go index 1a2ed97..4d31508 100644 --- a/json/y.go +++ b/json/y.go @@ -17,7 +17,7 @@ type jsonSymType struct { array ast.ListNode assign ast.AssignmentNode item ast.Node - klist []ast.KeyedNode + klist []ast.AssignmentNode list []ast.Node num int str string @@ -385,7 +385,7 @@ jsondefault: case 4: //line parse.y:61 { - jsonVAL.klist = []ast.KeyedNode{jsonS[jsonpt-0].assign} + jsonVAL.klist = []ast.AssignmentNode{jsonS[jsonpt-0].assign} } case 5: //line parse.y:65