diff options
| -rw-r--r-- | ext/dynblock/expand_spec.go | 5 | ||||
| -rw-r--r-- | hcl/diagnostic.go | 14 | ||||
| -rw-r--r-- | hcl/hclsyntax/diagnostics.go | 5 | ||||
| -rw-r--r-- | hcl/hclsyntax/expression.go | 30 | ||||
| -rw-r--r-- | hcl/hclsyntax/expression_ops.go | 5 | ||||
| -rw-r--r-- | hcl/hclsyntax/expression_template.go | 4 | ||||
| -rw-r--r-- | hcl/json/structure.go | 6 |
7 files changed, 52 insertions, 17 deletions
diff --git a/ext/dynblock/expand_spec.go b/ext/dynblock/expand_spec.go index a0734f6..be76cd0 100644 --- a/ext/dynblock/expand_spec.go +++ b/ext/dynblock/expand_spec.go @@ -47,6 +47,7 @@ func (b *expandBody) decodeSpec(blockS *hcl.BlockHeaderSchema, rawSpec *hcl.Bloc Summary: "Invalid dynamic for_each value", Detail: fmt.Sprintf("Cannot use a value of type %s in for_each. An iterable collection is required.", eachVal.Type()), Subject: eachAttr.Expr.Range().Ptr(), + Expression: eachAttr.Expr, EvalContext: b.forEachCtx, }) return nil, diags @@ -57,6 +58,7 @@ func (b *expandBody) decodeSpec(blockS *hcl.BlockHeaderSchema, rawSpec *hcl.Bloc Summary: "Invalid dynamic for_each value", Detail: "Cannot use a null value in for_each.", Subject: eachAttr.Expr.Range().Ptr(), + Expression: eachAttr.Expr, EvalContext: b.forEachCtx, }) return nil, diags @@ -165,6 +167,7 @@ func (s *expandSpec) newBlock(i *iteration, ctx *hcl.EvalContext) (*hcl.Block, h Summary: "Invalid dynamic block label", Detail: fmt.Sprintf("Cannot use this value as a dynamic block label: %s.", convErr), Subject: labelExpr.Range().Ptr(), + Expression: labelExpr, EvalContext: lCtx, }) return nil, diags @@ -175,6 +178,7 @@ func (s *expandSpec) newBlock(i *iteration, ctx *hcl.EvalContext) (*hcl.Block, h Summary: "Invalid dynamic block label", Detail: "Cannot use a null value as a dynamic block label.", Subject: labelExpr.Range().Ptr(), + Expression: labelExpr, EvalContext: lCtx, }) return nil, diags @@ -185,6 +189,7 @@ func (s *expandSpec) newBlock(i *iteration, ctx *hcl.EvalContext) (*hcl.Block, h Summary: "Invalid dynamic block label", Detail: "This value is not yet known. Dynamic block labels must be immediately-known values.", Subject: labelExpr.Range().Ptr(), + Expression: labelExpr, EvalContext: lCtx, }) return nil, diags diff --git a/hcl/diagnostic.go b/hcl/diagnostic.go index cea2843..c320961 100644 --- a/hcl/diagnostic.go +++ b/hcl/diagnostic.go @@ -46,22 +46,22 @@ type Diagnostic struct { Subject *Range Context *Range - // For diagnostics that occur when evaluating an expression, EvalContext - // may point to the EvalContext that was active when evaluating that - // expression, which may allow for the inclusion of additional useful - // information when rendering a diagnostic message to the user. + // For diagnostics that occur when evaluating an expression, Expression + // may refer to that expression and EvalContext may point to the + // EvalContext that was active when evaluating it. This may allow for the + // inclusion of additional useful information when rendering a diagnostic + // message to the user. // // It is not always possible to select a single EvalContext for a // diagnostic, and so in some cases this field may be nil even when an - // expression causes a problem. Therefore it is not valid to use the - // nil-ness of this field to definitively decide whether a diagnostic - // relates to an expression. + // expression causes a problem. // // EvalContexts form a tree, so the given EvalContext may refer to a parent // which in turn refers to another parent, etc. For a full picture of all // of the active variables and functions the caller must walk up this // chain, preferring definitions that are "closer" to the expression in // case of colliding names. + Expression Expression EvalContext *EvalContext } diff --git a/hcl/hclsyntax/diagnostics.go b/hcl/hclsyntax/diagnostics.go index 53d4ec0..94eaf58 100644 --- a/hcl/hclsyntax/diagnostics.go +++ b/hcl/hclsyntax/diagnostics.go @@ -13,9 +13,10 @@ import ( // been seen by a caller. Its purpose is to apply additional context to a // set of diagnostics produced by a "deeper" component as the stack unwinds // during expression evaluation. -func setDiagEvalContext(diags hcl.Diagnostics, ctx *hcl.EvalContext) { +func setDiagEvalContext(diags hcl.Diagnostics, expr hcl.Expression, ctx *hcl.EvalContext) { for _, diag := range diags { - if diag.EvalContext == nil { + if diag.Expression == nil { + diag.Expression = expr diag.EvalContext = ctx } } diff --git a/hcl/hclsyntax/expression.go b/hcl/hclsyntax/expression.go index 7984103..ce7e351 100644 --- a/hcl/hclsyntax/expression.go +++ b/hcl/hclsyntax/expression.go @@ -106,7 +106,7 @@ func (e *ScopeTraversalExpr) walkChildNodes(w internalWalkFunc) { func (e *ScopeTraversalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { val, diags := e.Traversal.TraverseAbs(ctx) - setDiagEvalContext(diags, ctx) + setDiagEvalContext(diags, e, ctx) return val, diags } @@ -138,7 +138,7 @@ func (e *RelativeTraversalExpr) walkChildNodes(w internalWalkFunc) { func (e *RelativeTraversalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { src, diags := e.Source.Value(ctx) ret, travDiags := e.Traversal.TraverseRel(src) - setDiagEvalContext(travDiags, ctx) + setDiagEvalContext(travDiags, e, ctx) diags = append(diags, travDiags...) return ret, diags } @@ -214,6 +214,7 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti Summary: "Function calls not allowed", Detail: "Functions may not be called here.", Subject: e.Range().Ptr(), + Expression: e, EvalContext: ctx, }, } @@ -235,6 +236,7 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti Detail: fmt.Sprintf("There is no function named %q.%s", e.Name, suggestion), Subject: &e.NameRange, Context: e.Range().Ptr(), + Expression: e, EvalContext: ctx, }, } @@ -263,8 +265,9 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti Severity: hcl.DiagError, Summary: "Invalid expanding argument value", Detail: "The expanding argument (indicated by ...) must not be null.", - Context: expandExpr.Range().Ptr(), - Subject: e.Range().Ptr(), + Subject: expandExpr.Range().Ptr(), + Context: e.Range().Ptr(), + Expression: expandExpr, EvalContext: ctx, }) return cty.DynamicVal, diags @@ -289,8 +292,9 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti Severity: hcl.DiagError, Summary: "Invalid expanding argument value", Detail: "The expanding argument (indicated by ...) must be of a tuple, list, or set type.", - Context: expandExpr.Range().Ptr(), - Subject: e.Range().Ptr(), + Subject: expandExpr.Range().Ptr(), + Context: e.Range().Ptr(), + Expression: expandExpr, EvalContext: ctx, }) return cty.DynamicVal, diags @@ -313,6 +317,7 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti ), Subject: &e.CloseParenRange, Context: e.Range().Ptr(), + Expression: e, EvalContext: ctx, }, } @@ -329,6 +334,7 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti ), Subject: args[len(params)].StartRange().Ptr(), Context: e.Range().Ptr(), + Expression: e, EvalContext: ctx, }, } @@ -361,6 +367,7 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti ), Subject: argExpr.StartRange().Ptr(), Context: e.Range().Ptr(), + Expression: argExpr, EvalContext: ctx, }) } @@ -399,6 +406,7 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti ), Subject: argExpr.StartRange().Ptr(), Context: e.Range().Ptr(), + Expression: argExpr, EvalContext: ctx, }) @@ -412,6 +420,7 @@ func (e *FunctionCallExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti ), Subject: e.StartRange().Ptr(), Context: e.Range().Ptr(), + Expression: e, EvalContext: ctx, }) } @@ -481,6 +490,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic ), Subject: hcl.RangeBetween(e.TrueResult.Range(), e.FalseResult.Range()).Ptr(), Context: &e.SrcRange, + Expression: e, EvalContext: ctx, }, } @@ -495,6 +505,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic Detail: "The condition value is null. Conditions must either be true or false.", Subject: e.Condition.Range().Ptr(), Context: &e.SrcRange, + Expression: e.Condition, EvalContext: ctx, }) return cty.UnknownVal(resultType), diags @@ -510,6 +521,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic Detail: fmt.Sprintf("The condition expression must be of type bool."), Subject: e.Condition.Range().Ptr(), Context: &e.SrcRange, + Expression: e.Condition, EvalContext: ctx, }) return cty.UnknownVal(resultType), diags @@ -531,6 +543,7 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic ), Subject: e.TrueResult.Range().Ptr(), Context: &e.SrcRange, + Expression: e.TrueResult, EvalContext: ctx, }) trueResult = cty.UnknownVal(resultType) @@ -551,8 +564,9 @@ func (e *ConditionalExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostic "The false result value has the wrong type: %s.", err.Error(), ), - Subject: e.TrueResult.Range().Ptr(), + Subject: e.FalseResult.Range().Ptr(), Context: &e.SrcRange, + Expression: e.FalseResult, EvalContext: ctx, }) falseResult = cty.UnknownVal(resultType) @@ -697,6 +711,7 @@ func (e *ObjectConsExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics Summary: "Null value as key", Detail: "Can't use a null value as a key.", Subject: item.ValueExpr.Range().Ptr(), + Expression: item.KeyExpr, EvalContext: ctx, }) known = false @@ -711,6 +726,7 @@ func (e *ObjectConsExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics Summary: "Incorrect key type", Detail: fmt.Sprintf("Can't use this value as a key: %s.", err.Error()), Subject: item.ValueExpr.Range().Ptr(), + Expression: item.ValueExpr, EvalContext: ctx, }) known = false diff --git a/hcl/hclsyntax/expression_ops.go b/hcl/hclsyntax/expression_ops.go index 4cf0ccd..ee96a0d 100644 --- a/hcl/hclsyntax/expression_ops.go +++ b/hcl/hclsyntax/expression_ops.go @@ -154,6 +154,7 @@ func (e *BinaryOpExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) Detail: fmt.Sprintf("Unsuitable value for left operand: %s.", err), Subject: e.LHS.Range().Ptr(), Context: &e.SrcRange, + Expression: e.LHS, EvalContext: ctx, }) } @@ -165,6 +166,7 @@ func (e *BinaryOpExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) Detail: fmt.Sprintf("Unsuitable value for right operand: %s.", err), Subject: e.RHS.Range().Ptr(), Context: &e.SrcRange, + Expression: e.RHS, EvalContext: ctx, }) } @@ -184,6 +186,7 @@ func (e *BinaryOpExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) Summary: "Operation failed", Detail: fmt.Sprintf("Error during operation: %s.", err), Subject: &e.SrcRange, + Expression: e, EvalContext: ctx, }) return cty.UnknownVal(e.Op.Type), diags @@ -227,6 +230,7 @@ func (e *UnaryOpExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { Detail: fmt.Sprintf("Unsuitable value for unary operand: %s.", err), Subject: e.Val.Range().Ptr(), Context: &e.SrcRange, + Expression: e.Val, EvalContext: ctx, }) } @@ -246,6 +250,7 @@ func (e *UnaryOpExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { Summary: "Operation failed", Detail: fmt.Sprintf("Error during operation: %s.", err), Subject: &e.SrcRange, + Expression: e, EvalContext: ctx, }) return cty.UnknownVal(e.Op.Type), diags diff --git a/hcl/hclsyntax/expression_template.go b/hcl/hclsyntax/expression_template.go index 10a3c73..6aa6b60 100644 --- a/hcl/hclsyntax/expression_template.go +++ b/hcl/hclsyntax/expression_template.go @@ -39,6 +39,7 @@ func (e *TemplateExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) ), Subject: part.Range().Ptr(), Context: &e.SrcRange, + Expression: part, EvalContext: ctx, }) continue @@ -64,6 +65,7 @@ func (e *TemplateExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) ), Subject: part.Range().Ptr(), Context: &e.SrcRange, + Expression: part, EvalContext: ctx, }) continue @@ -130,6 +132,7 @@ func (e *TemplateJoinExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti "An iteration result is null. Cannot include a null value in a string template.", ), Subject: e.Range().Ptr(), + Expression: e, EvalContext: ctx, }) continue @@ -147,6 +150,7 @@ func (e *TemplateJoinExpr) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnosti err.Error(), ), Subject: e.Range().Ptr(), + Expression: e, EvalContext: ctx, }) continue diff --git a/hcl/json/structure.go b/hcl/json/structure.go index 0f2b201..1e9d4b5 100644 --- a/hcl/json/structure.go +++ b/hcl/json/structure.go @@ -432,7 +432,8 @@ func (e *expression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { Value: jsonAttr.Name, SrcRange: jsonAttr.NameRange, }}).Value(ctx) - val, valDiags := (&expression{src: jsonAttr.Value}).Value(ctx) + valExpr := &expression{src: jsonAttr.Value} + val, valDiags := valExpr.Value(ctx) diags = append(diags, nameDiags...) diags = append(diags, valDiags...) @@ -444,6 +445,7 @@ func (e *expression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { Summary: "Invalid object key expression", Detail: fmt.Sprintf("Cannot use this expression as an object key: %s.", err), Subject: &jsonAttr.NameRange, + Expression: valExpr, EvalContext: ctx, }) continue @@ -454,6 +456,7 @@ func (e *expression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { Summary: "Invalid object key expression", Detail: "Cannot use null value as an object key.", Subject: &jsonAttr.NameRange, + Expression: valExpr, EvalContext: ctx, }) continue @@ -477,6 +480,7 @@ func (e *expression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) { Summary: "Duplicate object attribute", Detail: fmt.Sprintf("An attribute named %q was already defined at %s.", nameStr, attrRanges[nameStr]), Subject: &jsonAttr.NameRange, + Expression: e, EvalContext: ctx, }) continue |
