diff --git a/internal/php5/parser_test.go b/internal/php5/parser_test.go index a60a8fb..6ff6707 100644 --- a/internal/php5/parser_test.go +++ b/internal/php5/parser_test.go @@ -31770,7 +31770,7 @@ func TestExprClosure_Use(t *testing.T) { EndPos: 36, }, FunctionTkn: &token.Token{ - ID: token.T_FUNCTION, + ID: token.T_FUNCTION, Value: []byte("function"), Position: &position.Position{ StartLine: 1, @@ -31780,7 +31780,7 @@ func TestExprClosure_Use(t *testing.T) { }, FreeFloating: []*token.Token{ { - ID: token.T_OPEN_TAG, + ID: token.T_OPEN_TAG, Value: []byte(" 0 { f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) - n.ClosureUse.Accept(f) + n.UseTkn = f.newToken(token.T_USE, []byte("use")) + n.OpenParenthesisTkn = f.newToken('(', []byte("(")) + n.SeparatorTkns = f.formatList(n.Use, ',') + n.CloseParenthesisTkn = f.newToken(')', []byte(")")) } n.ColonTkn = nil @@ -1189,10 +1196,11 @@ func (f *formatter) ExprClosure(n *ast.ExprClosure) { } func (f *formatter) ExprClosureUse(n *ast.ExprClosureUse) { - n.UseTkn = f.newToken(token.T_USE, []byte("use")) - n.OpenParenthesisTkn = f.newToken('(', []byte("(")) - n.SeparatorTkns = f.formatList(n.Uses, ',') - n.CloseParenthesisTkn = f.newToken(')', []byte(")")) + if n.AmpersandTkn != nil { + n.AmpersandTkn = f.newToken('&', []byte("&")) + } + + n.Var.Accept(f) } func (f *formatter) ExprConstFetch(n *ast.ExprConstFetch) { diff --git a/pkg/ast/visitor/formatter_test.go b/pkg/ast/visitor/formatter_test.go index ee8637b..b917aea 100644 --- a/pkg/ast/visitor/formatter_test.go +++ b/pkg/ast/visitor/formatter_test.go @@ -3714,9 +3714,9 @@ func TestFormatter_ExprClosure_Use(t *testing.T) { o := bytes.NewBufferString("") n := &ast.ExprClosure{ - ClosureUse: &ast.ExprClosureUse{ - Uses: []ast.Vertex{ - &ast.ExprVariable{ + Use: []ast.Vertex{ + &ast.ExprClosureUse{ + Var: &ast.ExprVariable{ VarName: &ast.Identifier{ Value: []byte("$foo"), }, @@ -3748,16 +3748,9 @@ func TestFormatter_ExprClosureUse(t *testing.T) { o := bytes.NewBufferString("") n := &ast.ExprClosureUse{ - Uses: []ast.Vertex{ - &ast.ExprVariable{ - VarName: &ast.Identifier{ - Value: []byte("$a"), - }, - }, - &ast.ExprVariable{ - VarName: &ast.Identifier{ - Value: []byte("$b"), - }, + Var: &ast.ExprVariable{ + VarName: &ast.Identifier{ + Value: []byte("$a"), }, }, } @@ -3768,7 +3761,33 @@ func TestFormatter_ExprClosureUse(t *testing.T) { p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) n.Accept(p) - expected := `use($a, $b)` + expected := `$a` + actual := o.String() + + if expected != actual { + t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) + } +} + +func TestFormatter_ExprClosureUse_Reference(t *testing.T) { + o := bytes.NewBufferString("") + + n := &ast.ExprClosureUse{ + AmpersandTkn: &token.Token{}, + Var: &ast.ExprVariable{ + VarName: &ast.Identifier{ + Value: []byte("$a"), + }, + }, + } + + f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1) + n.Accept(f) + + p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) + n.Accept(p) + + expected := `&$a` actual := o.String() if expected != actual { diff --git a/pkg/ast/visitor/namespace_resolver_test.go b/pkg/ast/visitor/namespace_resolver_test.go index f42f11e..8a8bb14 100644 --- a/pkg/ast/visitor/namespace_resolver_test.go +++ b/pkg/ast/visitor/namespace_resolver_test.go @@ -562,7 +562,6 @@ func TestResolveClosureName(t *testing.T) { Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("foo")}}, }, }, - ClosureUse: nil, ReturnType: &ast.Nullable{Expr: nameBC}, Stmts: []ast.Vertex{}, } diff --git a/pkg/ast/visitor/printer.go b/pkg/ast/visitor/printer.go index 255ffe9..8802a43 100644 --- a/pkg/ast/visitor/printer.go +++ b/pkg/ast/visitor/printer.go @@ -684,7 +684,10 @@ func (p *printer) ExprClosure(n *ast.ExprClosure) { p.printToken(n.OpenParenthesisTkn, []byte("(")) p.printSeparatedList(n.Params, n.SeparatorTkns, []byte(",")) p.printToken(n.CloseParenthesisTkn, []byte(")")) - p.printNode(n.ClosureUse) + p.printToken(n.UseTkn, p.ifNodeList(n.Use, []byte("use"))) + p.printToken(n.UseOpenParenthesisTkn, p.ifNodeList(n.Use, []byte("("))) + p.printSeparatedList(n.Use, n.UseSeparatorTkns, []byte(",")) + p.printToken(n.UseCloseParenthesisTkn, p.ifNodeList(n.Use, []byte(")"))) p.printToken(n.ColonTkn, p.ifNode(n.ReturnType, []byte(":"))) p.printNode(n.ReturnType) p.printToken(n.OpenCurlyBracketTkn, []byte("{")) @@ -693,10 +696,8 @@ func (p *printer) ExprClosure(n *ast.ExprClosure) { } func (p *printer) ExprClosureUse(n *ast.ExprClosureUse) { - p.printToken(n.UseTkn, []byte("use")) - p.printToken(n.OpenParenthesisTkn, []byte("(")) - p.printSeparatedList(n.Uses, n.SeparatorTkns, []byte(",")) - p.printToken(n.CloseParenthesisTkn, []byte(")")) + p.printToken(n.AmpersandTkn, nil) + p.printNode(n.Var) } func (p *printer) ExprConstFetch(n *ast.ExprConstFetch) { diff --git a/pkg/ast/visitor/printer_test.go b/pkg/ast/visitor/printer_test.go index d918f0a..571f51e 100644 --- a/pkg/ast/visitor/printer_test.go +++ b/pkg/ast/visitor/printer_test.go @@ -1717,18 +1717,35 @@ func TestPrinterPrintExprClosureUse(t *testing.T) { p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) n := &ast.ExprClosureUse{ - Uses: []ast.Vertex{ - &ast.ExprReference{Var: &ast.ExprVariable{ - VarName: &ast.Identifier{Value: []byte("$foo")}, - }}, - &ast.ExprVariable{ - VarName: &ast.Identifier{Value: []byte("$bar")}, - }, + Var: &ast.ExprVariable{ + VarName: &ast.Identifier{Value: []byte("$foo")}, }, } n.Accept(p) - expected := `use(&$foo,$bar)` + expected := `$foo` + actual := o.String() + + if expected != actual { + t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) + } +} + +func TestPrinterPrintExprClosureUse_Reference(t *testing.T) { + o := bytes.NewBufferString("") + + p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) + n := &ast.ExprClosureUse{ + AmpersandTkn: &token.Token{ + Value: []byte("&"), + }, + Var: &ast.ExprVariable{ + VarName: &ast.Identifier{Value: []byte("$foo")}, + }, + } + n.Accept(p) + + expected := `&$foo` actual := o.String() if expected != actual { @@ -1754,12 +1771,17 @@ func TestPrinterPrintExprClosure(t *testing.T) { }, }, }, - ClosureUse: &ast.ExprClosureUse{ - Uses: []ast.Vertex{ - &ast.ExprReference{Var: &ast.ExprVariable{ + Use: []ast.Vertex{ + &ast.ExprClosureUse{ + AmpersandTkn: &token.Token{ + Value: []byte("&"), + }, + Var: &ast.ExprVariable{ VarName: &ast.Identifier{Value: []byte("$a")}, - }}, - &ast.ExprVariable{ + }, + }, + &ast.ExprClosureUse{ + Var: &ast.ExprVariable{ VarName: &ast.Identifier{Value: []byte("$b")}, }, },