diff --git a/parser/v2/goexpression/parse_test.go b/parser/v2/goexpression/parse_test.go index f330a97fd..f64657a04 100644 --- a/parser/v2/goexpression/parse_test.go +++ b/parser/v2/goexpression/parse_test.go @@ -452,11 +452,27 @@ var templExpressionTests = []testInput{ {Name: "A"}, {Name: "B"}, })`, + }, + { + name: "function call with function arg", + input: `componentA(func(y []int) string { + return "hi" + })`, + }, + { + name: "function call with function called arg", + input: `componentA(func(y []int) string { + return "hi" + }())`, }, { name: "call with braces and brackets", input: `templates.New(test{}, other())`, }, + { + name: "generic call", + input: `templates.New(toString[[]int](data))`, + }, { name: "struct method call", input: `typeName{}.Method()`, diff --git a/parser/v2/goexpression/scanner.go b/parser/v2/goexpression/scanner.go index 1813050b2..73696a668 100644 --- a/parser/v2/goexpression/scanner.go +++ b/parser/v2/goexpression/scanner.go @@ -60,7 +60,6 @@ type ExpressionParser struct { End int Previous token.Token Fns Stack[int] // Stack of function depths. - Slices Stack[int] // Stack of slice depths. } func (ep *ExpressionParser) setEnd(pos token.Pos, tok token.Token, lit string) { @@ -72,10 +71,14 @@ func (ep *ExpressionParser) hasSpaceBeforeCurrentToken(pos token.Pos) bool { } func (ep *ExpressionParser) isTopLevel() bool { - return len(ep.Fns) == 0 && len(ep.Slices) == 0 && len(ep.Stack) == 0 + return len(ep.Fns) == 0 && len(ep.Stack) == 0 } -func (ep *ExpressionParser) Insert(pos token.Pos, tok token.Token, lit string) (stop bool, err error) { +func (ep *ExpressionParser) Insert( + pos token.Pos, + tok token.Token, + lit string, +) (stop bool, err error) { defer func() { ep.Previous = tok }() @@ -87,17 +90,6 @@ func (ep *ExpressionParser) Insert(pos token.Pos, tok token.Token, lit string) ( ep.setEnd(pos, tok, lit) return false, nil } - // Handle slice definitions e.g.: []string{"a", "b"} - // Similarly to functions, we push the current depth onto the stack, - // and prevent stopping until we've closed the slice. - if ep.Previous == token.LBRACK && tok == token.RBRACK { - // Pop a left square bracket from the stack. - ep.Stack.Pop() - // Push the current depth onto the slice stack. - ep.Slices.Push(len(ep.Stack)) - ep.setEnd(pos, tok, lit) - return false, nil - } // If we're opening a pair, we don't stop until we've closed it. if _, isOpener := goTokenOpenToClose[tok]; isOpener { // If we're at an open brace, at the top level, where a space has been used, stop. @@ -134,16 +126,12 @@ func (ep *ExpressionParser) Insert(pos token.Pos, tok token.Token, lit string) ( if len(ep.Stack) == ep.Fns.Peek() { ep.Fns.Pop() } - // If we're closing a slice assignment, pop the slice depth. - if len(ep.Stack) == ep.Slices.Peek() { - ep.Slices.Pop() - } } ep.setEnd(pos, tok, lit) return false, nil } // If we're in a function literal slice, or pair, we allow anything until we close it. - if len(ep.Fns) > 0 || len(ep.Slices) > 0 || len(ep.Stack) > 0 { + if len(ep.Fns) > 0 || len(ep.Stack) > 0 { ep.setEnd(pos, tok, lit) return false, nil }