This fixes a bug in the flattener so that objects are flattened as one list object
This commit is contained in:
parent
2deb1d1db2
commit
2f117c801c
@ -1,8 +1,6 @@
|
||||
package parser
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/hcl/hcl/ast"
|
||||
)
|
||||
import "github.com/hashicorp/hcl/hcl/ast"
|
||||
|
||||
// flattenObjects takes an AST node, walks it, and flattens
|
||||
func flattenObjects(node ast.Node) {
|
||||
@ -60,25 +58,14 @@ func flattenListType(
|
||||
|
||||
// Great! We have a match go through all the items and flatten
|
||||
for _, elem := range ot.List {
|
||||
// This won't fail since we verified it earlier
|
||||
ot := elem.(*ast.ObjectType)
|
||||
|
||||
// Go over all the subitems and merge them in
|
||||
for _, subitem := range ot.List.Items {
|
||||
// Copy the new key
|
||||
keys := make([]*ast.ObjectKey, len(item.Keys)+len(subitem.Keys))
|
||||
copy(keys, item.Keys)
|
||||
copy(keys[len(item.Keys):], subitem.Keys)
|
||||
|
||||
// Add it to the frontier so that we can recurse
|
||||
frontier = append(frontier, &ast.ObjectItem{
|
||||
Keys: keys,
|
||||
Assign: item.Assign,
|
||||
Val: subitem.Val,
|
||||
LeadComment: item.LeadComment,
|
||||
LineComment: item.LineComment,
|
||||
})
|
||||
}
|
||||
// Add it to the frontier so that we can recurse
|
||||
frontier = append(frontier, &ast.ObjectItem{
|
||||
Keys: item.Keys,
|
||||
Assign: item.Assign,
|
||||
Val: elem,
|
||||
LeadComment: item.LeadComment,
|
||||
LineComment: item.LineComment,
|
||||
})
|
||||
}
|
||||
|
||||
return items, frontier
|
||||
|
@ -178,6 +178,60 @@ func TestObjectType(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFlattenObjects(t *testing.T) {
|
||||
var literals = []struct {
|
||||
src string
|
||||
nodeType []ast.Node
|
||||
}{
|
||||
{
|
||||
`{
|
||||
"foo": [
|
||||
{
|
||||
"foo": "svh",
|
||||
"bar": "fatih"
|
||||
}
|
||||
]
|
||||
}`,
|
||||
[]ast.Node{
|
||||
&ast.ObjectType{},
|
||||
&ast.LiteralType{},
|
||||
&ast.LiteralType{},
|
||||
&ast.ListType{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, l := range literals {
|
||||
t.Logf("Testing:\n%s\n", l.src)
|
||||
|
||||
f, err := Parse([]byte(l.src))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// the first object is always an ObjectList so just assert that one
|
||||
// so we can use it as such
|
||||
obj, ok := f.Node.(*ast.ObjectList)
|
||||
if !ok {
|
||||
t.Errorf("node should be *ast.ObjectList, got: %T", f.Node)
|
||||
}
|
||||
|
||||
// check if the types are correct
|
||||
var i int
|
||||
for _, item := range obj.Items {
|
||||
equals(t, reflect.TypeOf(l.nodeType[i]), reflect.TypeOf(item.Val))
|
||||
i++
|
||||
|
||||
if obj, ok := item.Val.(*ast.ObjectType); ok {
|
||||
for _, item := range obj.List.Items {
|
||||
equals(t, reflect.TypeOf(l.nodeType[i]), reflect.TypeOf(item.Val))
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestObjectKey(t *testing.T) {
|
||||
keys := []struct {
|
||||
exp []token.Type
|
||||
@ -225,6 +279,10 @@ func TestParse(t *testing.T) {
|
||||
Name string
|
||||
Err bool
|
||||
}{
|
||||
{
|
||||
"array.json",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"basic.json",
|
||||
false,
|
||||
@ -233,10 +291,6 @@ func TestParse(t *testing.T) {
|
||||
"object.json",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"array.json",
|
||||
false,
|
||||
},
|
||||
{
|
||||
"types.json",
|
||||
false,
|
||||
|
Loading…
Reference in New Issue
Block a user