Skip to content

Commit

Permalink
Fix prefix completion in TemplateWrapExpr (#371)
Browse files Browse the repository at this point in the history
* decoder: Test cases for prefix in template wrap

* decoder: Improve prefix detection for TemplateWrapExpr
  • Loading branch information
dbanck authored Feb 7, 2024
1 parent 6a6bede commit e8e6de1
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 2 deletions.
88 changes: 87 additions & 1 deletion decoder/expr_any_completion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4806,7 +4806,7 @@ func TestCompletionAtPos_exprAny_template(t *testing.T) {
expectedCandidates lang.Candidates
}{
{
"simple empty template",
"simple empty template (wrapped)",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.AnyExpression{
Expand Down Expand Up @@ -4923,6 +4923,92 @@ func TestCompletionAtPos_exprAny_template(t *testing.T) {
},
}),
},
{
"simple empty template with prefix (wrapped)",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.AnyExpression{
OfType: cty.String,
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "bar"},
},
RangePtr: &hcl.Range{
Filename: "variables.tf",
Start: hcl.Pos{Line: 2, Column: 1, Byte: 17},
End: hcl.Pos{Line: 2, Column: 3, Byte: 19},
},
Type: cty.String,
},
},
`attr = "${v}"
`,
hcl.Pos{Line: 1, Column: 12, Byte: 11},
lang.CompleteCandidates([]lang.Candidate{
{
Label: "var.bar",
Detail: "string",
Kind: lang.ReferenceCandidateKind,
TextEdit: lang.TextEdit{
NewText: "var.bar",
Snippet: "var.bar",
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{Line: 1, Column: 11, Byte: 10},
End: hcl.Pos{Line: 1, Column: 12, Byte: 11},
},
},
},
}),
},
{
"simple empty template with prefix trailing dot (wrapped)",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.AnyExpression{
OfType: cty.String,
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "bar"},
},
RangePtr: &hcl.Range{
Filename: "variables.tf",
Start: hcl.Pos{Line: 2, Column: 1, Byte: 17},
End: hcl.Pos{Line: 2, Column: 3, Byte: 19},
},
Type: cty.String,
},
},
`attr = "${var.}"
`,
hcl.Pos{Line: 1, Column: 15, Byte: 14},
lang.CompleteCandidates([]lang.Candidate{
{
Label: "var.bar",
Detail: "string",
Kind: lang.ReferenceCandidateKind,
TextEdit: lang.TextEdit{
NewText: "var.bar",
Snippet: "var.bar",
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{Line: 1, Column: 11, Byte: 10},
End: hcl.Pos{Line: 1, Column: 15, Byte: 14},
},
},
},
}),
},
{
"multi line template",
map[string]*schema.AttributeSchema{
Expand Down
15 changes: 14 additions & 1 deletion decoder/expr_any_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,26 @@ func (a Any) completeTemplateExprAtPos(ctx context.Context, pos hcl.Pos) ([]lang

return candidates, false
case *hclsyntax.TemplateWrapExpr:
if eType.Wrapped.Range().ContainsPos(pos) {
if eType.Wrapped.Range().ContainsPos(pos) || eType.Wrapped.Range().End.Byte == pos.Byte {
cons := schema.AnyExpression{
OfType: cty.String,
}
return newExpression(a.pathCtx, eType.Wrapped, cons).CompletionAtPos(ctx, pos), true
}

// Trailing dot may be ignored by the parser so we attempt to recover it
if pos.Byte-eType.Wrapped.Range().End.Byte == 1 {
fileBytes := a.pathCtx.Files[eType.Wrapped.Range().Filename].Bytes
trailingRune := fileBytes[eType.Wrapped.Range().End.Byte:pos.Byte][0]

if trailingRune == '.' {
cons := schema.AnyExpression{
OfType: cty.String,
}
return newExpression(a.pathCtx, eType.Wrapped, cons).CompletionAtPos(ctx, pos), true
}
}

return candidates, false
case *hclsyntax.TemplateJoinExpr:
// TODO: implement when support for expressions https://github.com/hashicorp/terraform-ls/issues/527 lands
Expand Down

0 comments on commit e8e6de1

Please sign in to comment.