Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions decoder/expr_any_ref_origins.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,12 +156,13 @@ func (a Any) refOriginsForNonComplexExpr(ctx context.Context) reference.Origins
}

allowSelfRefs := schema.ActiveSelfRefsFromContext(ctx)
rootBlockRange, _ := RootBlockRangeFromContext(ctx)
te, ok := a.expr.(*hclsyntax.ScopeTraversalExpr)
if ok {
oCons := reference.OriginConstraints{
{OfType: a.cons.OfType},
}
origin, ok := reference.TraversalToLocalOrigin(te.Traversal, oCons, allowSelfRefs)
origin, ok := reference.TraversalToLocalOrigin(te.Traversal, oCons, allowSelfRefs, rootBlockRange)
if ok {
return reference.Origins{origin}
}
Expand All @@ -177,7 +178,7 @@ func (a Any) refOriginsForNonComplexExpr(ctx context.Context) reference.Origins
oCons := reference.OriginConstraints{
{OfType: cty.DynamicPseudoType},
}
origin, ok := reference.TraversalToLocalOrigin(traversal, oCons, allowSelfRefs)
origin, ok := reference.TraversalToLocalOrigin(traversal, oCons, allowSelfRefs, rootBlockRange)
if ok {
origins = append(origins, origin)
}
Expand Down
15 changes: 15 additions & 0 deletions decoder/expr_any_ref_origins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,11 @@ func TestCollectRefOrigins_exprAny_forExpr_forEach(t *testing.T) {
Start: hcl.Pos{Line: 2, Column: 25, Byte: 56},
End: hcl.Pos{Line: 2, Column: 33, Byte: 64},
},
RootBlockRange: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 3, Column: 2, Byte: 82},
},
Constraints: reference.OriginConstraints{
{OfType: cty.List(cty.DynamicPseudoType)},
{OfType: cty.Set(cty.DynamicPseudoType)},
Expand Down Expand Up @@ -1383,6 +1388,11 @@ func TestCollectRefOrigins_exprAny_forExpr_forEach(t *testing.T) {
Start: hcl.Pos{Line: 2, Column: 36, Byte: 67},
End: hcl.Pos{Line: 2, Column: 42, Byte: 73},
},
RootBlockRange: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 3, Column: 2, Byte: 82},
},
Constraints: reference.OriginConstraints{
{OfType: cty.String},
{OfType: cty.String},
Expand All @@ -1398,6 +1408,11 @@ func TestCollectRefOrigins_exprAny_forExpr_forEach(t *testing.T) {
Start: hcl.Pos{Line: 2, Column: 46, Byte: 77},
End: hcl.Pos{Line: 2, Column: 47, Byte: 78},
},
RootBlockRange: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
End: hcl.Pos{Line: 3, Column: 2, Byte: 82},
},
Constraints: reference.OriginConstraints{
{OfType: cty.DynamicPseudoType},
{OfType: cty.String},
Expand Down
8 changes: 5 additions & 3 deletions decoder/expr_reference_ref_origins.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ import (

func (ref Reference) ReferenceOrigins(ctx context.Context) reference.Origins {
allowSelfRefs := schema.ActiveSelfRefsFromContext(ctx)
rootBlockRange, _ := RootBlockRangeFromContext(ctx)

// deal with native HCL syntax first
te, ok := ref.expr.(*hclsyntax.ScopeTraversalExpr)
if ok {
origin, ok := reference.TraversalToLocalOrigin(te.Traversal, originConstraintsFromCons(ref.cons), allowSelfRefs)
origin, ok := reference.TraversalToLocalOrigin(te.Traversal, originConstraintsFromCons(ref.cons), allowSelfRefs, rootBlockRange)
if ok {
return reference.Origins{origin}
}
Expand Down Expand Up @@ -48,7 +50,7 @@ func (ref Reference) ReferenceOrigins(ctx context.Context) reference.Origins {
}

if rangesEqual(expectedExprRange, ref.expr.Range()) {
origin, ok := reference.TraversalToLocalOrigin(vars[0], originConstraintsFromCons(ref.cons), allowSelfRefs)
origin, ok := reference.TraversalToLocalOrigin(vars[0], originConstraintsFromCons(ref.cons), allowSelfRefs, rootBlockRange)
if ok {
return reference.Origins{origin}
}
Expand All @@ -75,7 +77,7 @@ func (ref Reference) ReferenceOrigins(ctx context.Context) reference.Origins {
if diags.HasErrors() {
return reference.Origins{}
}
origin, ok := reference.TraversalToLocalOrigin(traversal, originConstraintsFromCons(ref.cons), allowSelfRefs)
origin, ok := reference.TraversalToLocalOrigin(traversal, originConstraintsFromCons(ref.cons), allowSelfRefs, rootBlockRange)
if ok {
return reference.Origins{origin}
}
Expand Down
11 changes: 11 additions & 0 deletions decoder/path_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,14 @@ func PathCtx(ctx context.Context) (*PathContext, error) {
}
return pathCtx, nil
}

type rootBlockRangeCtxKey struct{}

func WithRootBlockRange(ctx context.Context, rootBlockRange hcl.Range) context.Context {
return context.WithValue(ctx, rootBlockRangeCtxKey{}, rootBlockRange)
}

func RootBlockRangeFromContext(ctx context.Context) (hcl.Range, bool) {
rootBlockRange, ok := ctx.Value(rootBlockRangeCtxKey{}).(hcl.Range)
return rootBlockRange, ok
}
5 changes: 3 additions & 2 deletions decoder/reference_origin.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import (
)

type ReferenceOrigin struct {
Path lang.Path
Range hcl.Range
Path lang.Path
Range hcl.Range
RootBlockRange hcl.Range
}

type ReferenceOrigins []ReferenceOrigin
48 changes: 34 additions & 14 deletions decoder/reference_origins.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ func (d *Decoder) ReferenceOriginsTargetingPos(path lang.Path, file string, pos
rawOrigins := pathCtx.ReferenceOrigins.Match(p, target, path)
for _, origin := range rawOrigins {
origins = append(origins, ReferenceOrigin{
Path: p,
Range: origin.OriginRange(),
Path: p,
Range: origin.OriginRange(),
RootBlockRange: origin.RootBlockOriginRange(),
})
}
}
Expand Down Expand Up @@ -78,7 +79,7 @@ func (d *PathDecoder) CollectReferenceOrigins() (reference.Origins, error) {
continue
}

os, ios := d.referenceOriginsInBody(f.Body, d.pathCtx.Schema)
os, ios := d.referenceOriginsInBody(f.Body, d.pathCtx.Schema, nil)
refOrigins = append(refOrigins, os...)
impliedOrigins = append(impliedOrigins, ios...)
}
Expand All @@ -89,9 +90,10 @@ func (d *PathDecoder) CollectReferenceOrigins() (reference.Origins, error) {

if ok && localOrigin.Addr.Equals(impliedOrigin.OriginAddress) {
refOrigins = append(refOrigins, reference.PathOrigin{
Range: origin.OriginRange(),
TargetAddr: impliedOrigin.TargetAddress,
TargetPath: impliedOrigin.Path,
Range: origin.OriginRange(),
RootBlockRange: origin.RootBlockOriginRange(),
TargetAddr: impliedOrigin.TargetAddress,
TargetPath: impliedOrigin.Path,
Constraints: reference.OriginConstraints{
{
OfScopeId: impliedOrigin.Constraints.ScopeId,
Expand All @@ -113,7 +115,7 @@ func (d *PathDecoder) CollectReferenceOrigins() (reference.Origins, error) {
return refOrigins, nil
}

func (d *PathDecoder) referenceOriginsInBody(body hcl.Body, bodySchema *schema.BodySchema) (reference.Origins, []schema.ImpliedOrigin) {
func (d *PathDecoder) referenceOriginsInBody(body hcl.Body, bodySchema *schema.BodySchema, rootBlockRange *hcl.Range) (reference.Origins, []schema.ImpliedOrigin) {
origins := make(reference.Origins, 0)
impliedOrigins := make([]schema.ImpliedOrigin, 0)

Expand Down Expand Up @@ -144,13 +146,20 @@ func (d *PathDecoder) referenceOriginsInBody(body hcl.Body, bodySchema *schema.B
}
}

var rootBlockRng hcl.Range
if rootBlockRange != nil {
rootBlockRng = *rootBlockRange
}

if aSchema.OriginForTarget != nil {
targetAddr, ok := resolveAttributeAddress(attr, aSchema.OriginForTarget.Address)
if ok {

origins = append(origins, reference.PathOrigin{
Range: attr.NameRange,
TargetAddr: targetAddr,
TargetPath: aSchema.OriginForTarget.Path,
Range: attr.NameRange,
RootBlockRange: rootBlockRng,
TargetAddr: targetAddr,
TargetPath: aSchema.OriginForTarget.Path,
Constraints: reference.OriginConstraints{
{
OfScopeId: aSchema.OriginForTarget.Constraints.ScopeId,
Expand All @@ -162,16 +171,19 @@ func (d *PathDecoder) referenceOriginsInBody(body hcl.Body, bodySchema *schema.B
}

if aSchema.IsDepKey && bodySchema.Targets != nil {

origins = append(origins, reference.DirectOrigin{
Range: attr.Expr.Range(),
TargetPath: bodySchema.Targets.Path,
TargetRange: bodySchema.Targets.Range,
Range: attr.Expr.Range(),
RootBlockRange: rootBlockRng,
TargetPath: bodySchema.Targets.Path,
TargetRange: bodySchema.Targets.Range,
})
}

if bodySchema.Extensions != nil && bodySchema.Extensions.SelfRefs {
ctx = schema.WithActiveSelfRefs(ctx)
}
ctx = WithRootBlockRange(ctx, rootBlockRng)
expr := d.newExpression(attr.Expr, aSchema.Constraint)
if eType, ok := expr.(ReferenceOriginsExpression); ok {
origins = append(origins, eType.ReferenceOrigins(ctx)...)
Expand All @@ -187,7 +199,15 @@ func (d *PathDecoder) referenceOriginsInBody(body hcl.Body, bodySchema *schema.B
}
mergedSchema, _ := schemahelper.MergeBlockBodySchemas(block.Block, bSchema)

os, ios := d.referenceOriginsInBody(block.Body, mergedSchema)
// If rootBlockRange is nil, use the current block's range as the root block range.
// Otherwise, pass the existing rootBlockRange down to preserve the root context.
var nextRootBlockRange *hcl.Range
if rootBlockRange == nil {
nextRootBlockRange = &block.Range
} else {
nextRootBlockRange = rootBlockRange
}
os, ios := d.referenceOriginsInBody(block.Body, mergedSchema, nextRootBlockRange)
origins = append(origins, os...)
impliedOrigins = append(impliedOrigins, ios...)
}
Expand Down
78 changes: 78 additions & 0 deletions decoder/reference_origins_collect_hcl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,19 @@ attr3 = onestep`,
Byte: 26,
},
},
RootBlockRange: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 1,
Byte: 0,
},
End: hcl.Pos{
Line: 3,
Column: 2,
Byte: 28,
},
},
},
},
},
Expand Down Expand Up @@ -337,6 +350,19 @@ attr3 = onestep`,
Byte: 26,
},
},
RootBlockRange: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 1,
Byte: 0,
},
End: hcl.Pos{
Line: 3,
Column: 2,
Byte: 28,
},
},
},
},
},
Expand Down Expand Up @@ -396,6 +422,19 @@ attr3 = onestep`,
Byte: 40,
},
},
RootBlockRange: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 1,
Byte: 0,
},
End: hcl.Pos{
Line: 4,
Column: 2,
Byte: 66,
},
},
},
reference.LocalOrigin{
Addr: lang.Address{
Expand All @@ -416,6 +455,19 @@ attr3 = onestep`,
Byte: 64,
},
},
RootBlockRange: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 1,
Byte: 0,
},
End: hcl.Pos{
Line: 4,
Column: 2,
Byte: 66,
},
},
},
},
},
Expand Down Expand Up @@ -475,6 +527,19 @@ attr3 = onestep`,
Byte: 42,
},
},
RootBlockRange: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 1,
Byte: 0,
},
End: hcl.Pos{
Line: 4,
Column: 2,
Byte: 68,
},
},
},
},
},
Expand Down Expand Up @@ -1081,6 +1146,19 @@ func TestCollectReferenceOrigins_hcl_path(t *testing.T) {
Byte: 47,
},
},
RootBlockRange: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 1,
Byte: 0,
},
End: hcl.Pos{
Line: 4,
Column: 2,
Byte: 58,
},
},
},
},
},
Expand Down
Loading