summaryrefslogtreecommitdiff
path: root/hclsyntax/parser_test.go
diff options
context:
space:
mode:
authorAnsgar Mertens <ansgar@hashicorp.com>2024-08-21 15:32:07 +0200
committerAnsgar Mertens <ansgar@hashicorp.com>2024-08-21 15:39:23 +0200
commit117baa8bf53bc2050fe5e0f2ab85c4ef9341d20e (patch)
treef8a334690cb164297ce4e759531f14b44aa461e9 /hclsyntax/parser_test.go
parent360ae579460fab69e9939599af85c8f255a59007 (diff)
feat: return an ExprSyntaxError for invalid references that end in a dot (commonly occurs in editors for completions)
Detect value expressions of the ExprSyntaxError type when parsing object constructor expressions and use them to add an item to the result even though we skip parsing the object due to recovery after the invalid expression. This allows the Terraform language server to support completions for object attributes after a dot was typed.
Diffstat (limited to 'hclsyntax/parser_test.go')
-rw-r--r--hclsyntax/parser_test.go81
1 files changed, 81 insertions, 0 deletions
diff --git a/hclsyntax/parser_test.go b/hclsyntax/parser_test.go
index 10825f1..66f1308 100644
--- a/hclsyntax/parser_test.go
+++ b/hclsyntax/parser_test.go
@@ -2672,6 +2672,87 @@ block "valid" {}
},
},
},
+ {
+ "a = { b = c. }",
+ 1,
+ &Body{
+ Attributes: Attributes{
+ "a": {
+ Name: "a",
+ Expr: &ObjectConsExpr{
+ Items: []ObjectConsItem{
+ {
+ KeyExpr: &ObjectConsKeyExpr{
+ Wrapped: &ScopeTraversalExpr{
+ Traversal: hcl.Traversal{
+ hcl.TraverseRoot{
+ Name: "b",
+ SrcRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
+ End: hcl.Pos{Line: 1, Column: 8, Byte: 7},
+ },
+ },
+ },
+ SrcRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 7, Byte: 6},
+ End: hcl.Pos{Line: 1, Column: 8, Byte: 7},
+ },
+ },
+ },
+ ValueExpr: &ExprSyntaxError{
+ Placeholder: cty.DynamicVal,
+ SrcRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 11, Byte: 10},
+ End: hcl.Pos{Line: 1, Column: 13, Byte: 12},
+ },
+ ParseDiags: hcl.Diagnostics{
+ {
+ Severity: hcl.DiagError,
+ Summary: "Invalid attribute name",
+ Detail: "An attribute name is required after a dot.",
+ Subject: &hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 14, Byte: 13},
+ End: hcl.Pos{Line: 1, Column: 15, Byte: 14},
+ },
+ },
+ },
+ },
+ },
+ },
+ SrcRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
+ End: hcl.Pos{Line: 1, Column: 15, Byte: 14},
+ },
+ OpenRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 5, Byte: 4},
+ End: hcl.Pos{Line: 1, Column: 6, Byte: 5},
+ },
+ },
+ SrcRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
+ End: hcl.Pos{Line: 1, Column: 15, Byte: 14},
+ },
+ NameRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
+ End: hcl.Pos{Line: 1, Column: 2, Byte: 1},
+ },
+ EqualsRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 3, Byte: 2},
+ End: hcl.Pos{Line: 1, Column: 4, Byte: 3},
+ },
+ },
+ },
+ Blocks: Blocks{},
+ SrcRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 1, Byte: 0},
+ End: hcl.Pos{Line: 1, Column: 15, Byte: 14},
+ },
+ EndRange: hcl.Range{
+ Start: hcl.Pos{Line: 1, Column: 15, Byte: 14},
+ End: hcl.Pos{Line: 1, Column: 15, Byte: 14},
+ },
+ },
+ },
}
for _, test := range tests {