Skip to content

Commit

Permalink
fix: handle nil expr for reference origins and semantic tokens
Browse files Browse the repository at this point in the history
  • Loading branch information
ansgarm committed Feb 20, 2024
1 parent 67882ed commit d8bcca3
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 1 deletion.
5 changes: 5 additions & 0 deletions decoder/reference_origins.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,11 @@ func (d *PathDecoder) referenceOriginsInBody(body hcl.Body, bodySchema *schema.B
}
}

// skip if the attribute Expr is nil as all following origins are based on the expression
if attr.Expr == nil {
continue
}

if aSchema.IsDepKey && bodySchema.Targets != nil {
origins = append(origins, reference.DirectOrigin{
Range: attr.Expr.Range(),
Expand Down
28 changes: 28 additions & 0 deletions decoder/reference_origins_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/hcl-lang/lang"
"github.com/hashicorp/hcl-lang/reference"
"github.com/hashicorp/hcl-lang/schema"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
"github.com/zclconf/go-cty-debug/ctydebug"
"github.com/zclconf/go-cty/cty"
)
Expand Down Expand Up @@ -763,3 +765,29 @@ func TestReferenceOriginsTargetingPos(t *testing.T) {
})
}
}

func TestCollectReferenceOrigins_nil_expr(t *testing.T) {
// provider:: is not a traversal expression, so hcl will return a nil expression which needs to be
// handled gracefully
f, _ := hclsyntax.ParseConfig([]byte(`attr = provider::`), "test.tf", hcl.InitialPos)

d := testPathDecoder(t, &PathContext{
Schema: &schema.BodySchema{
Attributes: map[string]*schema.AttributeSchema{
"attr": {Constraint: schema.AnyExpression{OfType: cty.DynamicPseudoType}},
},
},
Files: map[string]*hcl.File{
"test.tf": f,
},
})

targets, err := d.CollectReferenceOrigins()
if err != nil {
t.Fatal("unexpected error when collecting reference origins while there was no expr in one of them")
}

if len(targets) != 0 {
t.Fatalf("expected no targets, got %d", len(targets))
}
}
5 changes: 4 additions & 1 deletion decoder/semantic_tokens.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ func (d *PathDecoder) tokensForBody(ctx context.Context, body *hclsyntax.Body, b
Range: attr.NameRange,
})

tokens = append(tokens, d.newExpression(attr.Expr, attrSchema.Constraint).SemanticTokens(ctx)...)
// Invalid expressions may be nil, and we don't want to panic further down the line
if attr.Expr != nil {
tokens = append(tokens, d.newExpression(attr.Expr, attrSchema.Constraint).SemanticTokens(ctx)...)
}
}

for _, block := range body.Blocks {
Expand Down
49 changes: 49 additions & 0 deletions decoder/semantic_tokens_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,55 @@ resource "vault_auth_backend" "blah" {
}
}

func TestDecoder_SemanticTokensInFile_nil_expr(t *testing.T) {
// provider:: is not a traversal expression, so hcl will return a nil expression which needs to be
// handled gracefully
f, _ := hclsyntax.ParseConfig([]byte(`attr = provider::`), "test.tf", hcl.InitialPos)

d := testPathDecoder(t, &PathContext{
Schema: &schema.BodySchema{
Attributes: map[string]*schema.AttributeSchema{
"attr": {Constraint: schema.AnyExpression{OfType: cty.DynamicPseudoType}},
},
},
Files: map[string]*hcl.File{
"test.tf": f,
},
})

ctx := context.Background()

tokens, err := d.SemanticTokensInFile(ctx, "test.tf")
if err != nil {
t.Fatal(err)
}

expectedTokens := []lang.SemanticToken{
{
Type: "hcl-attrName",
Modifiers: lang.SemanticTokenModifiers{},
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{
Line: 1,
Column: 1,
Byte: 0,
},
End: hcl.Pos{
Line: 1,
Column: 5,
Byte: 4,
},
},
},
}

diff := cmp.Diff(expectedTokens, tokens)
if diff != "" {
t.Fatalf("unexpected tokens: %s", diff)
}
}

func TestDecoder_SemanticTokensInFile_dependentSchema(t *testing.T) {
bodySchema := &schema.BodySchema{
Blocks: map[string]*schema.BlockSchema{
Expand Down

0 comments on commit d8bcca3

Please sign in to comment.