zcl: TraverseAbs through parent scopes

An EvalContext can have a parent, so it's necessary to walk up until
the root is reached in case a parent scope defines the name we're
looking for.
This commit is contained in:
Martin Atkins 2017-06-14 08:54:12 -07:00
parent 51945b4e0c
commit 9340e6da4e
1 changed files with 27 additions and 19 deletions

View File

@ -79,28 +79,36 @@ func (t Traversal) TraverseAbs(ctx *EvalContext) (cty.Value, Diagnostics) {
}
}
val, exists := ctx.Variables[name]
if !exists {
suggestions := make([]string, 0, len(ctx.Variables))
for k := range ctx.Variables {
suggestions = append(suggestions, k)
}
suggestion := nameSuggestion(name, suggestions)
if suggestion != "" {
suggestion = fmt.Sprintf(" Did you mean %q?", suggestion)
}
return cty.DynamicVal, Diagnostics{
{
Severity: DiagError,
Summary: "Unknown variable",
Detail: fmt.Sprintf("There is no variable named %q.%s", name, suggestion),
Subject: &root.SrcRange,
},
thisCtx := ctx
for thisCtx != nil {
val, exists := thisCtx.Variables[name]
if exists {
return split.Rel.TraverseRel(val)
}
thisCtx = thisCtx.parent
}
return split.Rel.TraverseRel(val)
suggestions := make([]string, 0, len(ctx.Variables))
thisCtx = ctx
for thisCtx != nil {
for k := range thisCtx.Variables {
suggestions = append(suggestions, k)
}
thisCtx = thisCtx.parent
}
suggestion := nameSuggestion(name, suggestions)
if suggestion != "" {
suggestion = fmt.Sprintf(" Did you mean %q?", suggestion)
}
return cty.DynamicVal, Diagnostics{
{
Severity: DiagError,
Summary: "Unknown variable",
Detail: fmt.Sprintf("There is no variable named %q.%s", name, suggestion),
Subject: &root.SrcRange,
},
}
}
// IsRelative returns true if the receiver is a relative traversal, or false