hcldec: Variables must visit deeply-nested specifications
Previously this implementation was doing only one level of recursion in its walk, which gave the appearance of working until the transform/container-type specs (DefaultSpec, TransformSpec, ...) were introduced, creating the possibility of "same body children" being more than one level away from the initial spec. It's still correct to only process the schema and content once, because ImpliedSchema is already collecting all of the requirements from the "same body children", and so our content object will include everything that the nested specs should need to analyze needed variables.
This commit is contained in:
parent
81d2277300
commit
36446359d2
@ -15,20 +15,22 @@ import (
|
||||
// be incomplete, but that's assumed to be okay because the eventual call
|
||||
// to Decode will produce error diagnostics anyway.
|
||||
func Variables(body hcl.Body, spec Spec) []hcl.Traversal {
|
||||
schema := ImpliedSchema(spec)
|
||||
|
||||
content, _, _ := body.PartialContent(schema)
|
||||
|
||||
var vars []hcl.Traversal
|
||||
schema := ImpliedSchema(spec)
|
||||
content, _, _ := body.PartialContent(schema)
|
||||
|
||||
if vs, ok := spec.(specNeedingVariables); ok {
|
||||
vars = append(vars, vs.variablesNeeded(content)...)
|
||||
}
|
||||
spec.visitSameBodyChildren(func(s Spec) {
|
||||
|
||||
var visitFn visitFunc
|
||||
visitFn = func(s Spec) {
|
||||
if vs, ok := s.(specNeedingVariables); ok {
|
||||
vars = append(vars, vs.variablesNeeded(content)...)
|
||||
}
|
||||
})
|
||||
s.visitSameBodyChildren(visitFn)
|
||||
}
|
||||
spec.visitSameBodyChildren(visitFn)
|
||||
|
||||
return vars
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
||||
"github.com/hashicorp/hcl2/hcl"
|
||||
"github.com/hashicorp/hcl2/hcl/hclsyntax"
|
||||
)
|
||||
|
||||
func TestVariables(t *testing.T) {
|
||||
@ -42,6 +42,37 @@ func TestVariables(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"a = foo\nb = bar\n",
|
||||
&DefaultSpec{
|
||||
Primary: &AttrSpec{
|
||||
Name: "a",
|
||||
},
|
||||
Default: &AttrSpec{
|
||||
Name: "b",
|
||||
},
|
||||
},
|
||||
[]hcl.Traversal{
|
||||
{
|
||||
hcl.TraverseRoot{
|
||||
Name: "foo",
|
||||
SrcRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
|
||||
End: hcl.Pos{Line: 1, Column: 8, Byte: 7},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
hcl.TraverseRoot{
|
||||
Name: "bar",
|
||||
SrcRange: hcl.Range{
|
||||
Start: hcl.Pos{Line: 2, Column: 5, Byte: 12},
|
||||
End: hcl.Pos{Line: 2, Column: 8, Byte: 15},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"a = foo\n",
|
||||
&ObjectSpec{
|
||||
|
Loading…
Reference in New Issue
Block a user