From dc5b67ea1d9445f6bebec9982598a99e9978b9dd Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Mon, 12 Feb 2024 13:46:26 +0100 Subject: [PATCH 1/5] decoder: Fix crash on prefix comletion for funcs --- decoder/expr_any_completion_test.go | 30 +++++++++++++++++++++++++++++ decoder/expr_function.go | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/decoder/expr_any_completion_test.go b/decoder/expr_any_completion_test.go index 25b7a9aa..e4bee7dd 100644 --- a/decoder/expr_any_completion_test.go +++ b/decoder/expr_any_completion_test.go @@ -878,6 +878,36 @@ func TestCompletionAtPos_exprAny_functions(t *testing.T) { }, }), }, + { + "in front of prefix (with space)", + map[string]*schema.AttributeSchema{ + "attr": { + Constraint: schema.AnyExpression{ + OfType: cty.String, + }, + }, + }, + reference.Targets{}, + `attr = t +`, + hcl.Pos{Line: 1, Column: 7, Byte: 6}, + lang.CompleteCandidates([]lang.Candidate{}), + }, + { + "in front of non-empty [ ]", + map[string]*schema.AttributeSchema{ + "attr": { + Constraint: schema.AnyExpression{ + OfType: cty.String, + }, + }, + }, + reference.Targets{}, + `attr = t [x] +`, + hcl.Pos{Line: 1, Column: 9, Byte: 8}, + lang.CompleteCandidates([]lang.Candidate{}), + }, } for i, tc := range testCases { diff --git a/decoder/expr_function.go b/decoder/expr_function.go index 5acf49be..0399e564 100644 --- a/decoder/expr_function.go +++ b/decoder/expr_function.go @@ -49,7 +49,7 @@ func (fe functionExpr) CompletionAtPos(ctx context.Context, pos hcl.Pos) []lang. // There can be a single segment with trailing dot which cannot // be a function anymore as functions cannot contain dots. - if prefixLen > len(rootName) { + if prefixLen < 0 || prefixLen > len(rootName) { return []lang.Candidate{} } From 22945c0a09389d58af01bced271e0666cf0d48e5 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Mon, 12 Feb 2024 13:47:09 +0100 Subject: [PATCH 2/5] decoder: Fix crash on prefix comletion for keyword --- decoder/expr_keyword_completion.go | 2 +- decoder/expr_keyword_completion_test.go | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/decoder/expr_keyword_completion.go b/decoder/expr_keyword_completion.go index 8e5ea4e6..a0cb7e3b 100644 --- a/decoder/expr_keyword_completion.go +++ b/decoder/expr_keyword_completion.go @@ -43,7 +43,7 @@ func (kw Keyword) CompletionAtPos(ctx context.Context, pos hcl.Pos) []lang.Candi } prefixLen := pos.Byte - eType.Traversal.SourceRange().Start.Byte - if prefixLen > len(eType.Traversal.RootName()) { + if prefixLen < 0 || prefixLen > len(eType.Traversal.RootName()) { // The user has probably typed an extra character, such as a // period, that is not (yet) part of the expression. This prefix // won't match anything, so we'll return early. diff --git a/decoder/expr_keyword_completion_test.go b/decoder/expr_keyword_completion_test.go index 28d96a00..ba8784ea 100644 --- a/decoder/expr_keyword_completion_test.go +++ b/decoder/expr_keyword_completion_test.go @@ -123,7 +123,19 @@ func TestCompletionAtPos_exprKeyword(t *testing.T) { hcl.Pos{Line: 1, Column: 9, Byte: 8}, lang.CompleteCandidates([]lang.Candidate{}), }, + { + "in front of prefix (with space)", + map[string]*schema.AttributeSchema{ + "attr": { + Constraint: schema.Keyword{Keyword: "foobar"}, + }, + }, + `attr = f`, + hcl.Pos{Line: 1, Column: 7, Byte: 6}, + lang.CompleteCandidates([]lang.Candidate{}), + }, } + for i, tc := range testCases { t.Run(fmt.Sprintf("%d-%s", i, tc.testName), func(t *testing.T) { bodySchema := &schema.BodySchema{ From 9f57d3ad80e45a7c47b4195d4e23496c38790f07 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Mon, 12 Feb 2024 13:47:25 +0100 Subject: [PATCH 3/5] decoder: Fix crash on prefix comletion for literal type --- decoder/expr_literal_type_completion.go | 2 +- decoder/expr_literal_type_completion_test.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/decoder/expr_literal_type_completion.go b/decoder/expr_literal_type_completion.go index d54fd949..2124e8b8 100644 --- a/decoder/expr_literal_type_completion.go +++ b/decoder/expr_literal_type_completion.go @@ -140,7 +140,7 @@ func (lt LiteralType) completeBoolAtPos(ctx context.Context, pos hcl.Pos) []lang case *hclsyntax.ScopeTraversalExpr: prefixLen := pos.Byte - eType.Range().Start.Byte - if prefixLen > len(eType.Traversal.RootName()) { + if prefixLen < 0 || prefixLen > len(eType.Traversal.RootName()) { // The user has probably typed an extra character, such as a // period, that is not (yet) part of the expression. This prefix // won't match anything, so we'll return early. diff --git a/decoder/expr_literal_type_completion_test.go b/decoder/expr_literal_type_completion_test.go index 473a843c..69ff1719 100644 --- a/decoder/expr_literal_type_completion_test.go +++ b/decoder/expr_literal_type_completion_test.go @@ -1190,6 +1190,20 @@ func TestCompletionAtPos_exprLiteralType(t *testing.T) { }, }), }, + { + "in front of prefix (with space)", + map[string]*schema.AttributeSchema{ + "attr": { + Constraint: schema.LiteralType{ + Type: cty.Bool, + }, + }, + }, + `attr = f +`, + hcl.Pos{Line: 1, Column: 7, Byte: 6}, + lang.CompleteCandidates([]lang.Candidate{}), + }, } for i, tc := range testCases { From 38db710dddff5dfedc0a79f099f257535c3faae4 Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Mon, 12 Feb 2024 13:47:38 +0100 Subject: [PATCH 4/5] decoder: Fix crash on prefix comletion for literal value --- decoder/expr_literal_value_completion.go | 2 +- decoder/expr_literal_value_completion_test.go | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/decoder/expr_literal_value_completion.go b/decoder/expr_literal_value_completion.go index 94141af8..b69eb828 100644 --- a/decoder/expr_literal_value_completion.go +++ b/decoder/expr_literal_value_completion.go @@ -87,7 +87,7 @@ func (lv LiteralValue) completeBoolAtPos(ctx context.Context, pos hcl.Pos) []lan case *hclsyntax.ScopeTraversalExpr: prefixLen := pos.Byte - eType.Range().Start.Byte - if prefixLen > len(eType.Traversal.RootName()) { + if prefixLen < 0 || prefixLen > len(eType.Traversal.RootName()) { // The user has probably typed an extra character, such as a // period, that is not (yet) part of the expression. This prefix // won't match anything, so we'll return early. diff --git a/decoder/expr_literal_value_completion_test.go b/decoder/expr_literal_value_completion_test.go index 6bd4066e..bd2f0b70 100644 --- a/decoder/expr_literal_value_completion_test.go +++ b/decoder/expr_literal_value_completion_test.go @@ -621,6 +621,20 @@ func TestCompletionAtPos_exprLiteralValue(t *testing.T) { }, }), }, + { + "in front of prefix (with space)", + map[string]*schema.AttributeSchema{ + "attr": { + Constraint: schema.LiteralValue{ + Value: cty.BoolVal(true), + }, + }, + }, + `attr = t +`, + hcl.Pos{Line: 1, Column: 7, Byte: 6}, + lang.CompleteCandidates([]lang.Candidate{}), + }, } for i, tc := range testCases { From de23d389c547833c6d1a84fcbe2a9c73fde5695e Mon Sep 17 00:00:00 2001 From: Daniel Banck Date: Mon, 12 Feb 2024 13:47:49 +0100 Subject: [PATCH 5/5] decoder: Fix crash on prefix comletion for type decl --- decoder/expr_type_declaration_completion.go | 2 +- decoder/expr_type_declaration_completion_test.go | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/decoder/expr_type_declaration_completion.go b/decoder/expr_type_declaration_completion.go index c9f3fc07..4676ba49 100644 --- a/decoder/expr_type_declaration_completion.go +++ b/decoder/expr_type_declaration_completion.go @@ -32,7 +32,7 @@ func (td TypeDeclaration) CompletionAtPos(ctx context.Context, pos hcl.Pos) []la } prefixLen := pos.Byte - eType.Range().Start.Byte - if prefixLen > len(eType.Traversal.RootName()) { + if prefixLen < 0 || prefixLen > len(eType.Traversal.RootName()) { // The user has probably typed an extra character, such as a // period, that is not (yet) part of the expression. This prefix // won't match anything, so we'll return early. diff --git a/decoder/expr_type_declaration_completion_test.go b/decoder/expr_type_declaration_completion_test.go index 47f17f32..d64af250 100644 --- a/decoder/expr_type_declaration_completion_test.go +++ b/decoder/expr_type_declaration_completion_test.go @@ -125,7 +125,7 @@ func TestCompletionAtPos_exprTypeDeclaration(t *testing.T) { }), }, { - "partial name with dot", + "partial name with dot", map[string]*schema.AttributeSchema{ "attr": { Constraint: schema.TypeDeclaration{}, @@ -1014,6 +1014,18 @@ func TestCompletionAtPos_exprTypeDeclaration(t *testing.T) { hcl.Pos{Line: 2, Column: 4, Byte: 19}, lang.CompleteCandidates([]lang.Candidate{}), }, + { + "in front of prefix (with space)", + map[string]*schema.AttributeSchema{ + "attr": { + Constraint: schema.TypeDeclaration{}, + }, + }, + `attr = st +`, + hcl.Pos{Line: 1, Column: 7, Byte: 6}, + lang.CompleteCandidates([]lang.Candidate{}), + }, } for i, tc := range testCases {