Skip to content

Commit

Permalink
decoder: Add support for parenthesis on LHS (map keys & attribute nam…
Browse files Browse the repository at this point in the history
…es) (#367)

* decoder: Fix crash with missing PathContext in LiteralValue

* schema: Introduce AllowInterpolatedKeys for Map

* schema: Introduce AllowInterpolatedAttrName to Object

* decoder: Enable completion within parenthesis in map keys

* decoder: Enable completion within parenthesis in object attribute names

* decoder: Enable hover within parenthesis in map keys

* decoder: Enable hover within parenthesis in object attribute names

* decoder: Enable semantic tokens within parenthesis in map keys

* decoder: Enable semantic tokens within parenthesis in object attribute names

* decoder: Enable reference origins in map keys

* decoder: Enable reference origins in object attribute names

* Object: Rename AllowInterpolatedAttrName to AllowInterpolatedKeys

* decoder: simplify code
  • Loading branch information
radeksimko authored Jan 22, 2024
1 parent 0298dc8 commit f43c272
Show file tree
Hide file tree
Showing 19 changed files with 848 additions and 85 deletions.
5 changes: 4 additions & 1 deletion decoder/expr_any_completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,9 @@ func (a Any) CompletionAtPos(ctx context.Context, pos hcl.Pos) []lang.Candidate
Elem: schema.AnyExpression{
OfType: typ.ElementType(),
},
AllowInterpolatedKeys: true,
}

return newExpression(a.pathCtx, expr, cons).CompletionAtPos(ctx, pos)
}

Expand All @@ -85,7 +87,8 @@ func (a Any) CompletionAtPos(ctx context.Context, pos hcl.Pos) []lang.Candidate
}

cons := schema.Object{
Attributes: ctyObjectToObjectAttributes(typ),
Attributes: ctyObjectToObjectAttributes(typ),
AllowInterpolatedKeys: true,
}
return newExpression(a.pathCtx, expr, cons).CompletionAtPos(ctx, pos)
}
Expand Down
272 changes: 272 additions & 0 deletions decoder/expr_any_completion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3698,6 +3698,278 @@ func TestCompletionAtPos_exprAny_parentheses(t *testing.T) {
},
}),
},
{
"empty parentheses as map key",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.AnyExpression{
OfType: cty.Map(cty.String),
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
},
Type: cty.String,
},
},
`attr = {
() = "foo"
}
`,
hcl.Pos{Line: 2, Column: 4, Byte: 12},
lang.CompleteCandidates([]lang.Candidate{
{
Label: "var.foo",
Detail: "string",
Kind: lang.ReferenceCandidateKind,
TextEdit: lang.TextEdit{
NewText: "var.foo",
Snippet: "var.foo",
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{Line: 2, Column: 4, Byte: 12},
End: hcl.Pos{Line: 2, Column: 4, Byte: 12},
},
},
},
}),
},
{
"parentheses with prefix as map key",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.AnyExpression{
OfType: cty.Map(cty.String),
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
},
Type: cty.String,
},
},
`attr = {
(var) = "foo"
}
`,
hcl.Pos{Line: 2, Column: 7, Byte: 15},
lang.CompleteCandidates([]lang.Candidate{
{
Label: "var.foo",
Detail: "string",
Kind: lang.ReferenceCandidateKind,
TextEdit: lang.TextEdit{
NewText: "var.foo",
Snippet: "var.foo",
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{Line: 2, Column: 4, Byte: 12},
End: hcl.Pos{Line: 2, Column: 7, Byte: 15},
},
},
},
}),
},
{
"empty parentheses as map key in static map",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.Map{
Elem: schema.LiteralType{Type: cty.String},
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
},
Type: cty.String,
},
},
`attr = {
() = "foo"
}
`,
hcl.Pos{Line: 2, Column: 4, Byte: 12},
lang.CompleteCandidates([]lang.Candidate{}),
},
{
"parentheses with prefix as map key in static map",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.Map{
Elem: schema.LiteralType{Type: cty.String},
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
},
Type: cty.String,
},
},
`attr = {
(var) = "foo"
}
`,
hcl.Pos{Line: 2, Column: 7, Byte: 15},
lang.CompleteCandidates([]lang.Candidate{}),
},
{
"empty parentheses as object attribute name",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.AnyExpression{
OfType: cty.Object(map[string]cty.Type{
"bar": cty.String,
}),
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
},
Type: cty.String,
},
},
`attr = {
() = "foo"
}
`,
hcl.Pos{Line: 2, Column: 4, Byte: 12},
lang.CompleteCandidates([]lang.Candidate{
{
Label: "var.foo",
Detail: "string",
Kind: lang.ReferenceCandidateKind,
TextEdit: lang.TextEdit{
NewText: "var.foo",
Snippet: "var.foo",
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{Line: 2, Column: 4, Byte: 12},
End: hcl.Pos{Line: 2, Column: 4, Byte: 12},
},
},
},
}),
},
{
"parentheses with prefix as object attribute name",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.AnyExpression{
OfType: cty.Object(map[string]cty.Type{
"bar": cty.String,
}),
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
},
Type: cty.String,
},
},
`attr = {
(var) = "foo"
}
`,
hcl.Pos{Line: 2, Column: 7, Byte: 15},
lang.CompleteCandidates([]lang.Candidate{
{
Label: "var.foo",
Detail: "string",
Kind: lang.ReferenceCandidateKind,
TextEdit: lang.TextEdit{
NewText: "var.foo",
Snippet: "var.foo",
Range: hcl.Range{
Filename: "test.tf",
Start: hcl.Pos{Line: 2, Column: 4, Byte: 12},
End: hcl.Pos{Line: 2, Column: 7, Byte: 15},
},
},
},
}),
},
{
"empty parentheses as object attribute name in static object",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.Object{
Attributes: schema.ObjectAttributes{
"foo": &schema.AttributeSchema{
Constraint: schema.LiteralType{Type: cty.String},
},
},
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
},
Type: cty.String,
},
},
`attr = {
() = "foo"
}
`,
hcl.Pos{Line: 2, Column: 4, Byte: 12},
lang.CompleteCandidates([]lang.Candidate{}),
},
{
"parentheses with prefix as map key in static map",
map[string]*schema.AttributeSchema{
"attr": {
Constraint: schema.Object{
Attributes: schema.ObjectAttributes{
"foo": &schema.AttributeSchema{
Constraint: schema.LiteralType{Type: cty.String},
},
},
},
},
},
reference.Targets{
{
Addr: lang.Address{
lang.RootStep{Name: "var"},
lang.AttrStep{Name: "foo"},
},
Type: cty.String,
},
},
`attr = {
(var) = "foo"
}
`,
hcl.Pos{Line: 2, Column: 7, Byte: 15},
lang.CompleteCandidates([]lang.Candidate{}),
},
}

for i, tc := range testCases {
Expand Down
4 changes: 3 additions & 1 deletion decoder/expr_any_hover.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ func (a Any) HoverAtPos(ctx context.Context, pos hcl.Pos) *lang.HoverData {
Elem: schema.AnyExpression{
OfType: typ.ElementType(),
},
AllowInterpolatedKeys: true,
}
return newExpression(a.pathCtx, expr, cons).HoverAtPos(ctx, pos)
}
Expand All @@ -85,7 +86,8 @@ func (a Any) HoverAtPos(ctx context.Context, pos hcl.Pos) *lang.HoverData {
}

cons := schema.Object{
Attributes: ctyObjectToObjectAttributes(typ),
Attributes: ctyObjectToObjectAttributes(typ),
AllowInterpolatedKeys: true,
}
return newExpression(a.pathCtx, expr, cons).HoverAtPos(ctx, pos)
}
Expand Down
Loading

0 comments on commit f43c272

Please sign in to comment.