diff --git a/hclsyntax/parser.go b/hclsyntax/parser.go index 20fa1481..cd9d63d2 100644 --- a/hclsyntax/parser.go +++ b/hclsyntax/parser.go @@ -1157,6 +1157,7 @@ func (p *parser) finishParsingFunctionCall(name Token) (Expression, hcl.Diagnost } nameStr := string(name.Bytes) + nameEndPos := name.Range.End for openTok.Type == TokenDoubleColon { nextName := p.Read() if nextName.Type != TokenIdent { @@ -1179,10 +1180,17 @@ func (p *parser) finishParsingFunctionCall(name Token) (Expression, hcl.Diagnost // doesn't exist in EvalContext, to return better error messages // when namespaces are used incorrectly. nameStr = nameStr + "::" + string(nextName.Bytes) + nameEndPos = nextName.Range.End openTok = p.Read() } + nameRange := hcl.Range{ + Filename: name.Range.Filename, + Start: name.Range.Start, + End: nameEndPos, + } + if openTok.Type != TokenOParen { diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, @@ -1259,7 +1267,7 @@ Token: diags = append(diags, &hcl.Diagnostic{ Severity: hcl.DiagError, Summary: "Unterminated function call", - Detail: "There is no closing parenthesis for this function call before the end of the file. This may be caused by incorrect parethesis nesting elsewhere in this file.", + Detail: "There is no closing parenthesis for this function call before the end of the file. This may be caused by incorrect parenthesis nesting elsewhere in this file.", Subject: hcl.RangeBetween(name.Range, openTok.Range).Ptr(), }) default: @@ -1291,7 +1299,7 @@ Token: ExpandFinal: expandFinal, - NameRange: name.Range, + NameRange: nameRange, OpenParenRange: openTok.Range, CloseParenRange: closeTok.Range, }, diags diff --git a/hclsyntax/parser_test.go b/hclsyntax/parser_test.go index 69636c9f..236daa0d 100644 --- a/hclsyntax/parser_test.go +++ b/hclsyntax/parser_test.go @@ -2462,6 +2462,103 @@ block "valid" {} }, }, }, + { + "a = a::namespaced::func(data.first.ref.attr)\n", + 0, + &Body{ + Attributes: Attributes{ + "a": { + Name: "a", + Expr: &FunctionCallExpr{ + Name: "a::namespaced::func", + Args: []Expression{ + &ScopeTraversalExpr{ + Traversal: hcl.Traversal{ + hcl.TraverseRoot{ + Name: "data", + SrcRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 25, Byte: 24}, + End: hcl.Pos{Line: 1, Column: 29, Byte: 28}, + }, + }, + hcl.TraverseAttr{ + Name: "first", + SrcRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 29, Byte: 28}, + End: hcl.Pos{Line: 1, Column: 35, Byte: 34}, + }, + }, + hcl.TraverseAttr{ + Name: "ref", + SrcRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 35, Byte: 34}, + End: hcl.Pos{Line: 1, Column: 39, Byte: 38}, + }, + }, + hcl.TraverseAttr{ + Name: "attr", + SrcRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 39, Byte: 38}, + End: hcl.Pos{Line: 1, Column: 44, Byte: 43}, + }, + }, + }, + SrcRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 25, Byte: 24}, + End: hcl.Pos{Line: 1, Column: 44, Byte: 43}, + }, + }, + }, + ExpandFinal: false, + NameRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 5, Byte: 4}, + End: hcl.Pos{Line: 1, Column: 24, Byte: 23}, + }, + OpenParenRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 24, Byte: 23}, + End: hcl.Pos{Line: 1, Column: 25, Byte: 24}, + }, + CloseParenRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 44, Byte: 43}, + End: hcl.Pos{Line: 1, Column: 45, Byte: 44}, + }, + }, + SrcRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, + End: hcl.Pos{Line: 1, Column: 45, Byte: 44}, + }, + NameRange: hcl.Range{ + Filename: "", + Start: hcl.Pos{Line: 1, Column: 1, Byte: 0}, + End: hcl.Pos{Line: 1, Column: 2, Byte: 1}, + }, + EqualsRange: hcl.Range{ + Filename: "", + 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: 2, Column: 1, Byte: 45}, + }, + EndRange: hcl.Range{ + Start: hcl.Pos{Line: 2, Column: 1, Byte: 45}, + End: hcl.Pos{Line: 2, Column: 1, Byte: 45}, + }, + }, + }, } for _, test := range tests {