diff --git a/internal/php5/php5.go b/internal/php5/php5.go index 392b113..f002d93 100644 Binary files a/internal/php5/php5.go and b/internal/php5/php5.go differ diff --git a/internal/php5/php5.y b/internal/php5/php5.y index a1bb134..6cfbe62 100644 --- a/internal/php5/php5.y +++ b/internal/php5/php5.y @@ -1000,12 +1000,12 @@ unticked_statement: foreach.Var = $6.(*ast.StmtForeach).Var } - if val, ok := foreach.Key.(*ast.ExprReference); ok { + if val, ok := foreach.Key.(*ast.StmtForeach); ok { yylex.(*Parser).errHandlerFunc(errors.NewError("Key element cannot be a reference", val.AmpersandTkn.Position)) foreach.Key = val.Var } - if val, ok := foreach.Var.(*ast.ExprReference); ok { + if val, ok := foreach.Var.(*ast.StmtForeach); ok { foreach.AmpersandTkn = val.AmpersandTkn foreach.Var = val.Var } @@ -1030,12 +1030,12 @@ unticked_statement: foreach.Var = $6.(*ast.StmtForeach).Var } - if val, ok := foreach.Key.(*ast.ExprReference); ok { + if val, ok := foreach.Key.(*ast.StmtForeach); ok { yylex.(*Parser).errHandlerFunc(errors.NewError("Key element cannot be a reference", val.AmpersandTkn.Position)) foreach.Key = val.Var } - if val, ok := foreach.Var.(*ast.ExprReference); ok { + if val, ok := foreach.Var.(*ast.StmtForeach); ok { foreach.AmpersandTkn = val.AmpersandTkn foreach.Var = val.Var } @@ -1462,7 +1462,7 @@ foreach_variable: } | '&' variable { - $$ = &ast.ExprReference{ + $$ = &ast.StmtForeach{ Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), AmpersandTkn: $1, Var: $2, diff --git a/internal/php7/php7.go b/internal/php7/php7.go index 2e0135b..6492224 100644 Binary files a/internal/php7/php7.go and b/internal/php7/php7.go differ diff --git a/internal/php7/php7.y b/internal/php7/php7.y index 3e7e479..9a2cc31 100644 --- a/internal/php7/php7.y +++ b/internal/php7/php7.y @@ -972,7 +972,7 @@ statement: foreach.Var = $5 foreach.CloseParenthesisTkn = $6 - if val, ok := $5.(*ast.ExprReference); ok { + if val, ok := $5.(*ast.StmtForeach); ok { foreach.AmpersandTkn = val.AmpersandTkn foreach.Var = val.Var } @@ -993,7 +993,7 @@ statement: foreach.Var = $7 foreach.CloseParenthesisTkn = $8 - if val, ok := $7.(*ast.ExprReference); ok { + if val, ok := $7.(*ast.StmtForeach); ok { foreach.AmpersandTkn = val.AmpersandTkn foreach.Var = val.Var } @@ -1359,7 +1359,7 @@ foreach_variable: } | '&' variable { - $$ = &ast.ExprReference{ + $$ = &ast.StmtForeach{ Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), AmpersandTkn: $1, Var: $2, diff --git a/pkg/ast/ast.go b/pkg/ast/ast.go index 0cdb4b0..5c5494a 100644 --- a/pkg/ast/ast.go +++ b/pkg/ast/ast.go @@ -107,7 +107,6 @@ type NodeVisitor interface { ExprPreInc(n *ExprPreInc) ExprPrint(n *ExprPrint) ExprPropertyFetch(n *ExprPropertyFetch) - ExprReference(n *ExprReference) ExprRequire(n *ExprRequire) ExprRequireOnce(n *ExprRequireOnce) ExprShellExec(n *ExprShellExec) diff --git a/pkg/ast/node.go b/pkg/ast/node.go index 62d26a5..bdc0b75 100644 --- a/pkg/ast/node.go +++ b/pkg/ast/node.go @@ -1629,21 +1629,6 @@ func (n *ExprPropertyFetch) GetPosition() *position.Position { return n.Position } -// ExprReference node -type ExprReference struct { - Position *position.Position - AmpersandTkn *token.Token - Var Vertex -} - -func (n *ExprReference) Accept(v NodeVisitor) { - v.ExprReference(n) -} - -func (n *ExprReference) GetPosition() *position.Position { - return n.Position -} - // ExprRequire node type ExprRequire struct { Position *position.Position diff --git a/pkg/ast/traverser/dfs.go b/pkg/ast/traverser/dfs.go index 5c8f792..7538f71 100644 --- a/pkg/ast/traverser/dfs.go +++ b/pkg/ast/traverser/dfs.go @@ -1451,18 +1451,6 @@ func (t *DFS) Traverse(n ast.Vertex) { t.Traverse(nn.Property) t.visitor.Leave("Property", true) } - case *ast.ExprReference: - if nn == nil { - return - } - if !t.visitor.EnterNode(nn) { - return - } - if nn.Var != nil { - t.visitor.Enter("Var", true) - t.Traverse(nn.Var) - t.visitor.Leave("Var", true) - } case *ast.ExprRequire: if nn == nil { return diff --git a/pkg/ast/visitor/dumper.go b/pkg/ast/visitor/dumper.go index 598ab1f..bb54652 100644 --- a/pkg/ast/visitor/dumper.go +++ b/pkg/ast/visitor/dumper.go @@ -1425,18 +1425,6 @@ func (v *Dumper) ExprPropertyFetch(n *ast.ExprPropertyFetch) { v.print(v.indent, "},\n") } -func (v *Dumper) ExprReference(n *ast.ExprReference) { - v.print(0, "&ast.ExprReference{\n") - v.indent++ - - v.dumpPosition(n.Position) - v.dumpToken("AmpersandTkn", n.AmpersandTkn) - v.dumpVertex("Var", n.Var) - - v.indent-- - v.print(v.indent, "},\n") -} - func (v *Dumper) ExprRequire(n *ast.ExprRequire) { v.print(0, "&ast.ExprRequire{\n") v.indent++ diff --git a/pkg/ast/visitor/formatter.go b/pkg/ast/visitor/formatter.go index e4b5f97..93c3046 100644 --- a/pkg/ast/visitor/formatter.go +++ b/pkg/ast/visitor/formatter.go @@ -1349,11 +1349,6 @@ func (f *formatter) ExprPropertyFetch(n *ast.ExprPropertyFetch) { n.Property.Accept(f) } -func (f *formatter) ExprReference(n *ast.ExprReference) { - n.AmpersandTkn = f.newToken('&', []byte("&")) - n.Var.Accept(f) -} - func (f *formatter) ExprRequire(n *ast.ExprRequire) { n.RequireTkn = f.newToken(token.T_REQUIRE, []byte("require")) f.addFreeFloating(token.T_WHITESPACE, []byte(" ")) diff --git a/pkg/ast/visitor/formatter_test.go b/pkg/ast/visitor/formatter_test.go index 9723e46..d99fbfa 100644 --- a/pkg/ast/visitor/formatter_test.go +++ b/pkg/ast/visitor/formatter_test.go @@ -4483,31 +4483,6 @@ func TestFormatter_ExprPropertyFetch(t *testing.T) { } } -func TestFormatter_ExprReference(t *testing.T) { - o := bytes.NewBufferString("") - - n := &ast.ExprReference{ - Var: &ast.ExprVariable{ - VarName: &ast.Identifier{ - Value: []byte("$foo"), - }, - }, - } - - f := visitor.NewFormatter().WithState(visitor.FormatterStatePHP).WithIndent(1) - n.Accept(f) - - p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) - n.Accept(p) - - expected := `&$foo` - actual := o.String() - - if expected != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) - } -} - func TestFormatter_ExprRequire(t *testing.T) { o := bytes.NewBufferString("") diff --git a/pkg/ast/visitor/null.go b/pkg/ast/visitor/null.go index cef3d73..6623a75 100644 --- a/pkg/ast/visitor/null.go +++ b/pkg/ast/visitor/null.go @@ -362,10 +362,6 @@ func (v *Null) ExprPropertyFetch(_ *ast.ExprPropertyFetch) { // do nothing } -func (v *Null) ExprReference(_ *ast.ExprReference) { - // do nothing -} - func (v *Null) ExprRequire(_ *ast.ExprRequire) { // do nothing } diff --git a/pkg/ast/visitor/printer.go b/pkg/ast/visitor/printer.go index 479c98c..eb96c0e 100644 --- a/pkg/ast/visitor/printer.go +++ b/pkg/ast/visitor/printer.go @@ -817,11 +817,6 @@ func (p *printer) ExprPropertyFetch(n *ast.ExprPropertyFetch) { p.printNode(n.Property) } -func (p *printer) ExprReference(n *ast.ExprReference) { - p.printToken(n.AmpersandTkn, []byte("&")) - p.printNode(n.Var) -} - func (p *printer) ExprRequire(n *ast.ExprRequire) { p.printToken(n.RequireTkn, []byte("require")) p.printNode(n.Expr) diff --git a/pkg/ast/visitor/printer_test.go b/pkg/ast/visitor/printer_test.go index 187c173..44764bb 100644 --- a/pkg/ast/visitor/printer_test.go +++ b/pkg/ast/visitor/printer_test.go @@ -1634,9 +1634,12 @@ func TestPrinterPrintExprArray(t *testing.T) { }, &ast.ExprArrayItem{ Key: &ast.ScalarLnumber{Value: []byte("2")}, - Val: &ast.ExprReference{Var: &ast.ExprVariable{ + AmpersandTkn: &token.Token{ + Value: []byte("&"), + }, + Val: &ast.ExprVariable{ VarName: &ast.Identifier{Value: []byte("$var")}, - }}, + }, }, &ast.ExprArrayItem{ Val: &ast.ExprVariable{ @@ -2323,25 +2326,6 @@ func TestPrinterPrintPropertyFetch(t *testing.T) { } } -func TestPrinterPrintExprReference(t *testing.T) { - o := bytes.NewBufferString("") - - p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) - n := &ast.ExprReference{ - Var: &ast.ExprVariable{ - VarName: &ast.Identifier{Value: []byte("$foo")}, - }, - } - n.Accept(p) - - expected := `&$foo` - actual := o.String() - - if expected != actual { - t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) - } -} - func TestPrinterPrintRequire(t *testing.T) { o := bytes.NewBufferString("") @@ -2413,9 +2397,12 @@ func TestPrinterPrintExprShortArray(t *testing.T) { }, &ast.ExprArrayItem{ Key: &ast.ScalarLnumber{Value: []byte("2")}, - Val: &ast.ExprReference{Var: &ast.ExprVariable{ + AmpersandTkn: &token.Token{ + Value: []byte("&"), + }, + Val: &ast.ExprVariable{ VarName: &ast.Identifier{Value: []byte("$var")}, - }}, + }, }, &ast.ExprArrayItem{ Val: &ast.ExprVariable{ @@ -2848,11 +2835,47 @@ func TestPrinterPrintAltForeach(t *testing.T) { Key: &ast.ExprVariable{ VarName: &ast.Identifier{Value: []byte("$key")}, }, - Var: &ast.ExprReference{ - Var: &ast.ExprVariable{ - VarName: &ast.Identifier{Value: []byte("$val")}, + Var: &ast.ExprVariable{ + VarName: &ast.Identifier{Value: []byte("$val")}, + }, + ColonTkn: &token.Token{ + Value: []byte(":"), + }, + Stmt: &ast.StmtStmtList{ + Stmts: []ast.Vertex{ + &ast.StmtExpression{Expr: &ast.ExprVariable{ + VarName: &ast.Identifier{Value: []byte("$d")}, + }}, }, }, + } + n.Accept(p) + + expected := `foreach($var as$key=>$val):$d;endforeach;` + actual := o.String() + + if expected != actual { + t.Errorf("\nexpected: %s\ngot: %s\n", expected, actual) + } +} + +func TestPrinterPrintAltForeach_Reference(t *testing.T) { + o := bytes.NewBufferString("") + + p := visitor.NewPrinter(o).WithState(visitor.PrinterStatePHP) + n := &ast.StmtForeach{ + Expr: &ast.ExprVariable{ + VarName: &ast.Identifier{Value: []byte("$var")}, + }, + Key: &ast.ExprVariable{ + VarName: &ast.Identifier{Value: []byte("$key")}, + }, + AmpersandTkn: &token.Token{ + Value: []byte("&"), + }, + Var: &ast.ExprVariable{ + VarName: &ast.Identifier{Value: []byte("$val")}, + }, ColonTkn: &token.Token{ Value: []byte(":"), },