hcl-lang
hcl-lang copied to clipboard
Provide completion near unterminated `FunctionCallExpr`
Context
While implementing support for operators in https://github.com/hashicorp/hcl-lang/pull/320 a few edge cases concerning completion near an unterminated function call were discovered.
attr = !lower(attr = 42 + sum(attr = lower(
In these cases we do not provide relevant completion because we do not consider the completion "trigger position" to be inside of the attribute or any expression.
At least in two of the 3 examples above though the upstream HCL parser will still provide helpful relevant AST, as shown below in Implementation Notes.
Similar to https://github.com/hashicorp/hcl-lang/issues/321 the root cause is most likely here https://github.com/hashicorp/hcl-lang/blob/436a15d944d87a2a4abeaec8e2d7b399f54eab6f/decoder/candidates.go#L175-L187
Implementation Notes
package main
import (
"log"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hclsyntax"
)
func main() {
cfg := `attr = !lower(`
f, diags := hclsyntax.ParseConfig([]byte(cfg), "", hcl.InitialPos)
if len(diags) > 0 {
log.Printf("diagnostics: %s", diags)
}
attrs, _ := f.Body.JustAttributes()
log.Printf("attribute range: %#v\n", attrs["attr"].Range)
log.Printf("%T range: %#v", attrs["attr"].Expr, attrs["attr"].Expr.Range())
log.Printf("val expr: %#v", attrs["attr"].Expr.(*hclsyntax.UnaryOpExpr).Val)
}
2023/09/29 08:10:50 diagnostics: :1,15-15: Missing expression; Expected the start of an expression, but found the end of the file.
2023/09/29 08:10:50 attribute range: hcl.Range{Filename:"", Start:hcl.Pos{Line:1, Column:1, Byte:0}, End:hcl.Pos{Line:1, Column:15, Byte:14}}
2023/09/29 08:10:50 *hclsyntax.UnaryOpExpr range: hcl.Range{Filename:"", Start:hcl.Pos{Line:1, Column:8, Byte:7}, End:hcl.Pos{Line:0, Column:0, Byte:0}}
2023/09/29 08:10:50 val expr: &hclsyntax.FunctionCallExpr{Name:"lower", Args:[]hclsyntax.Expression{(*hclsyntax.LiteralValueExpr)(0x1400011c360)}, ExpandFinal:false, NameRange:hcl.Range{Filename:"", Start:hcl.Pos{Line:1, Column:9, Byte:8}, End:hcl.Pos{Line:1, Column:14, Byte:13}}, OpenParenRange:hcl.Range{Filename:"", Start:hcl.Pos{Line:1, Column:14, Byte:13}, End:hcl.Pos{Line:1, Column:15, Byte:14}}, CloseParenRange:hcl.Range{Filename:"", Start:hcl.Pos{Line:0, Column:0, Byte:0}, End:hcl.Pos{Line:0, Column:0, Byte:0}}}
the incomplete expressions have End positions zero-ed out, which is the main reason we are unable to provide completion at the moment.