diff --git a/internal/php5/php5.go b/internal/php5/php5.go index 498f6b5..7492a95 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 5fb516e..53276ee 100644 --- a/internal/php5/php5.y +++ b/internal/php5/php5.y @@ -241,7 +241,7 @@ import ( %type trait_method_reference_fully_qualified trait_method_reference trait_modifiers member_modifier method %type static_scalar_value static_operation static_var_list global_var_list %type ctor_arguments function_call_parameter_list echo_expr_list -%type trait_adaptations unset_variables +%type trait_adaptations unset_variables declare_list %type switch_case_list %type method_body %type foreach_statement for_statement while_statement @@ -255,7 +255,7 @@ import ( %type top_statement_list namespace_name use_declarations use_function_declarations use_const_declarations %type inner_statement_list encaps_list isset_variables non_empty_array_pair_list %type array_pair_list assignment_list lexical_var_list elseif_list new_elseif_list non_empty_for_expr -%type for_expr case_list declare_list catch_statement additional_catches +%type for_expr case_list catch_statement additional_catches %type non_empty_additional_catches parameter_list non_empty_parameter_list class_statement_list %type class_statement_list variable_modifiers method_modifiers class_variable_declaration %type interface_list non_empty_function_call_parameter_list trait_list trait_adaptation_list non_empty_trait_adaptation_list @@ -722,7 +722,7 @@ constant_declaration: { constList := $1.(*ast.StmtConstList) constList.Node.Position = position.NewNodesPosition($1, $5) - lastNode(constList.Consts).(*ast.StmtConstant).CommaTkn = $2 + constList.SeparatorTkns = append(constList.SeparatorTkns, $2) constList.Consts = append(constList.Consts, &ast.StmtConstant{ Node: ast.Node{ Position: position.NewTokenNodePosition($3, $5), @@ -1130,16 +1130,14 @@ unticked_statement: } | T_DECLARE '(' declare_list ')' declare_statement { + $5.(*ast.StmtDeclare).DeclareTkn = $1 + $5.(*ast.StmtDeclare).OpenParenthesisTkn = $2 + $5.(*ast.StmtDeclare).Consts = $3.(*ast.ParserSeparatedList).Items + $5.(*ast.StmtDeclare).SeparatorTkns = $3.(*ast.ParserSeparatedList).SeparatorTkns + $5.(*ast.StmtDeclare).CloseParenthesisTkn = $4 + $5.(*ast.StmtDeclare).Node.Position = position.NewTokenNodePosition($1, $5) + $$ = $5 - $$.(*ast.StmtDeclare).Consts = $3 - - // save position - $$.GetNode().Position = position.NewTokenNodePosition($1, $5) - - // save comments - yylex.(*Parser).setFreeFloating($$, token.Start, $1.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.Declare, $2.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.ConstList, $4.SkippedTokens) } | ';' { @@ -1646,29 +1644,30 @@ foreach_statement: declare_statement: statement { - $$ = &ast.StmtDeclare{ast.Node{}, false, nil, $1} - - // save position - $$.GetNode().Position = position.NewNodePosition($1) + $$ = &ast.StmtDeclare{ + Node: ast.Node{ + Position: position.NewNodePosition($1), + }, + Stmt: $1, + } } | ':' inner_statement_list T_ENDDECLARE ';' { - stmtList := &ast.StmtStmtList{ + $$ = &ast.StmtDeclare{ Node: ast.Node{ - Position: position.NewNodeListPosition($2), + Position: position.NewTokensPosition($1, $4), }, - Stmts: $2, + Alt: true, + ColonTkn: $1, + Stmt: &ast.StmtStmtList{ + Node: ast.Node{ + Position: position.NewNodeListPosition($2), + }, + Stmts: $2, + }, + EndDeclareTkn: $3, + SemiColonTkn: $4, } - $$ = &ast.StmtDeclare{ast.Node{}, true, nil, stmtList} - - // save position - $$.GetNode().Position = position.NewTokensPosition($1, $4) - - // save comments - yylex.(*Parser).setFreeFloating($$, token.Cond, $1.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.Stmts, $3.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.AltEnd, $4.SkippedTokens) - yylex.(*Parser).setToken($$, token.SemiColon, $4.SkippedTokens) } ; @@ -1676,42 +1675,49 @@ declare_statement: declare_list: T_STRING '=' static_scalar { - $$ = []ast.Vertex{ - &ast.StmtConstant{ - Node: ast.Node{ - Position: position.NewTokenNodePosition($1, $3), - }, - Name: &ast.Identifier{ - Node: ast.Node{ - Position: position.NewTokenPosition($1), + $$ = &ast.ParserSeparatedList{ + Items: []ast.Vertex{ + &ast.StmtConstant{ + Node: ast.Node{ + Position: position.NewTokenNodePosition($1, $3), }, - Value: $1.Value, + Name: &ast.Identifier{ + Node: ast.Node{ + Position: position.NewTokenPosition($1), + }, + Value: $1.Value, + }, + EqualTkn: $2, + Expr: $3, }, - EqualTkn: $2, - Expr: $3, }, } - yylex.(*Parser).setFreeFloating(lastNode($$).(*ast.StmtConstant).Name, token.Start, $1.SkippedTokens) + yylex.(*Parser).setFreeFloating(lastNode($$.(*ast.ParserSeparatedList).Items).(*ast.StmtConstant).Name, token.Start, $1.SkippedTokens) } | declare_list ',' T_STRING '=' static_scalar { - lastNode($1).(*ast.StmtConstant).CommaTkn = $2 - $$ = append($1, &ast.StmtConstant{ - Node: ast.Node{ - Position: position.NewTokenNodePosition($3, $5), - }, - Name: &ast.Identifier{ - Node: ast.Node{ - Position: position.NewTokenPosition($3), + $1.(*ast.ParserSeparatedList).SeparatorTkns = append($1.(*ast.ParserSeparatedList).SeparatorTkns, $2) + $1.(*ast.ParserSeparatedList).Items = append( + $1.(*ast.ParserSeparatedList).Items, + &ast.StmtConstant{ + Node: ast.Node{ + Position: position.NewTokenNodePosition($3, $5), }, - Value: $3.Value, + Name: &ast.Identifier{ + Node: ast.Node{ + Position: position.NewTokenPosition($3), + }, + Value: $3.Value, + }, + EqualTkn: $4, + Expr: $5, }, - EqualTkn: $4, - Expr: $5, - }) + ) - yylex.(*Parser).setFreeFloating(lastNode($$).(*ast.StmtConstant).Name, token.Start, $3.SkippedTokens) + $$ = $1 + + yylex.(*Parser).setFreeFloating(lastNode($$.(*ast.ParserSeparatedList).Items).(*ast.StmtConstant).Name, token.Start, $3.SkippedTokens) } ; diff --git a/internal/php7/php7.go b/internal/php7/php7.go index 4b801a5..6ecb7f7 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 2d9825a..79efe9d 100644 --- a/internal/php7/php7.y +++ b/internal/php7/php7.y @@ -250,7 +250,7 @@ import ( %type variable_class_name dereferencable_scalar constant dereferencable %type callable_expr callable_variable static_member new_variable %type encaps_var encaps_var_offset echo_expr_list -%type if_stmt +%type if_stmt const_list %type alt_if_stmt %type if_stmt_without_else %type class_const_decl @@ -276,7 +276,7 @@ import ( %type encaps_list backticks_expr namespace_name catch_name_list catch_list class_const_list -%type const_list for_exprs non_empty_for_exprs +%type for_exprs non_empty_for_exprs %type unprefixed_use_declarations inline_use_declarations property_list %type case_list trait_adaptation_list %type use_declarations lexical_var_list isset_variables non_empty_array_pair_list @@ -541,9 +541,10 @@ top_statement: Node: ast.Node{ Position: position.NewTokensPosition($1, $3), }, - ConstTkn: $1, - Consts: $2, - SemiColonTkn: $3, + ConstTkn: $1, + Consts: $2.(*ast.ParserSeparatedList).Items, + SeparatorTkns: $2.(*ast.ParserSeparatedList).SeparatorTkns, + SemiColonTkn: $3, } } ; @@ -782,13 +783,16 @@ use_declaration: const_list: const_list ',' const_decl { - lastNode($1).(*ast.StmtConstant).CommaTkn = $2 + $1.(*ast.ParserSeparatedList).SeparatorTkns = append($1.(*ast.ParserSeparatedList).SeparatorTkns, $2) + $1.(*ast.ParserSeparatedList).Items = append($1.(*ast.ParserSeparatedList).Items, $3) - $$ = append($1, $3) + $$ = $1 } | const_decl { - $$ = []ast.Vertex{$1} + $$ = &ast.ParserSeparatedList{ + Items: []ast.Vertex{$1}, + } } ; @@ -1036,16 +1040,14 @@ statement: } | T_DECLARE '(' const_list ')' declare_statement { + $5.(*ast.StmtDeclare).DeclareTkn = $1 + $5.(*ast.StmtDeclare).OpenParenthesisTkn = $2 + $5.(*ast.StmtDeclare).Consts = $3.(*ast.ParserSeparatedList).Items + $5.(*ast.StmtDeclare).SeparatorTkns = $3.(*ast.ParserSeparatedList).SeparatorTkns + $5.(*ast.StmtDeclare).CloseParenthesisTkn = $4 + $5.(*ast.StmtDeclare).Node.Position = position.NewTokenNodePosition($1, $5) + $$ = $5 - $$.(*ast.StmtDeclare).Consts = $3 - - // save position - $$.GetNode().Position = position.NewTokenNodePosition($1, $5) - - // save comments - yylex.(*Parser).setFreeFloating($$, token.Start, $1.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.Declare, $2.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.ConstList, $4.SkippedTokens) } | ';' { @@ -1509,29 +1511,30 @@ foreach_statement: declare_statement: statement { - $$ = &ast.StmtDeclare{ast.Node{}, false, nil, $1} - - // save position - $$.GetNode().Position = position.NewNodePosition($1) + $$ = &ast.StmtDeclare{ + Node: ast.Node{ + Position: position.NewNodePosition($1), + }, + Stmt: $1, + } } | ':' inner_statement_list T_ENDDECLARE ';' { - stmtList := &ast.StmtStmtList{ + $$ = &ast.StmtDeclare{ Node: ast.Node{ - Position: position.NewNodeListPosition($2), + Position: position.NewTokensPosition($1, $4), }, - Stmts: $2, + Alt: true, + ColonTkn: $1, + Stmt: &ast.StmtStmtList{ + Node: ast.Node{ + Position: position.NewNodeListPosition($2), + }, + Stmts: $2, + }, + EndDeclareTkn: $3, + SemiColonTkn: $4, } - $$ = &ast.StmtDeclare{ast.Node{}, true, nil, stmtList} - - // save position - $$.GetNode().Position = position.NewTokensPosition($1, $4) - - // save comments - yylex.(*Parser).setFreeFloating($$, token.Cond, $1.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.Stmts, $3.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.AltEnd, $4.SkippedTokens) - yylex.(*Parser).setToken($$, token.SemiColon, $4.SkippedTokens) } ; diff --git a/pkg/ast/ast.go b/pkg/ast/ast.go index aa2170a..7e02236 100644 --- a/pkg/ast/ast.go +++ b/pkg/ast/ast.go @@ -189,7 +189,6 @@ type NodeVisitor interface { NameRelative(n *NameRelative) NameNamePart(n *NameNamePart) - ParserAs(n *ParserAs) - ParserNsSeparator(n *ParserNsSeparator) ParserBrackets(n *ParserBrackets) + ParserSeparatedList(n *ParserSeparatedList) } diff --git a/pkg/ast/node.go b/pkg/ast/node.go index 516019f..845c124 100644 --- a/pkg/ast/node.go +++ b/pkg/ast/node.go @@ -278,9 +278,10 @@ func (n *StmtClassMethod) Accept(v NodeVisitor) { // StmtConstList node type StmtConstList struct { Node - ConstTkn *token.Token - Consts []Vertex - SemiColonTkn *token.Token + ConstTkn *token.Token + Consts []Vertex + SeparatorTkns []*token.Token + SemiColonTkn *token.Token } func (n *StmtConstList) Accept(v NodeVisitor) { @@ -315,9 +316,16 @@ func (n *StmtContinue) Accept(v NodeVisitor) { // StmtDeclare node type StmtDeclare struct { Node - Alt bool - Consts []Vertex - Stmt Vertex + Alt bool + DeclareTkn *token.Token + OpenParenthesisTkn *token.Token + Consts []Vertex + SeparatorTkns []*token.Token + CloseParenthesisTkn *token.Token + ColonTkn *token.Token + Stmt Vertex + EndDeclareTkn *token.Token + SemiColonTkn *token.Token } func (n *StmtDeclare) Accept(v NodeVisitor) { @@ -1887,24 +1895,6 @@ func (n *NameNamePart) Accept(v NodeVisitor) { v.NameNamePart(n) } -type ParserAs struct { - Node - Child Vertex -} - -func (n *ParserAs) Accept(v NodeVisitor) { - v.ParserAs(n) -} - -type ParserNsSeparator struct { - Node - Child Vertex -} - -func (n *ParserNsSeparator) Accept(v NodeVisitor) { - v.ParserNsSeparator(n) -} - type ParserBrackets struct { Node OpenBracketTkn *token.Token @@ -1915,3 +1905,13 @@ type ParserBrackets struct { func (n *ParserBrackets) Accept(v NodeVisitor) { v.ParserBrackets(n) } + +type ParserSeparatedList struct { + Node + Items []Vertex + SeparatorTkns []*token.Token +} + +func (n *ParserSeparatedList) Accept(v NodeVisitor) { + v.ParserSeparatedList(n) +} diff --git a/pkg/ast/traverser/dfs.go b/pkg/ast/traverser/dfs.go index 615c682..b9189a0 100644 --- a/pkg/ast/traverser/dfs.go +++ b/pkg/ast/traverser/dfs.go @@ -2607,30 +2607,6 @@ func (t *DFS) Traverse(n ast.Vertex) { if !t.visitor.EnterNode(nn) { return } - case *ast.ParserAs: - if nn == nil { - return - } - if !t.visitor.EnterNode(nn) { - return - } - if nn.Child != nil { - t.visitor.Enter("Child", true) - t.Traverse(nn.Child) - t.visitor.Leave("Child", true) - } - case *ast.ParserNsSeparator: - if nn == nil { - return - } - if !t.visitor.EnterNode(nn) { - return - } - if nn.Child != nil { - t.visitor.Enter("Child", true) - t.Traverse(nn.Child) - t.visitor.Leave("Child", true) - } case *ast.ParserBrackets: if nn == nil { return diff --git a/pkg/ast/visitor/dump.go b/pkg/ast/visitor/dump.go index de06927..d8160c1 100644 --- a/pkg/ast/visitor/dump.go +++ b/pkg/ast/visitor/dump.go @@ -1293,20 +1293,12 @@ func (v *Dump) NameNamePart(n *ast.NameNamePart) { v.print(fmt.Sprintf("Value: []byte(%q),\n", n.Value)) } -func (v *Dump) ParserAs(n *ast.ParserAs) { - v.printIndentIfNotSingle(v.indent - 1) - v.print("&ast.ParserAs{\n") - v.printNode(n.GetNode()) -} - -func (v *Dump) ParserNsSeparator(n *ast.ParserNsSeparator) { - v.printIndentIfNotSingle(v.indent - 1) - v.print("&ast.ParserNsSeparator{\n") - v.printNode(n.GetNode()) -} - func (v *Dump) ParserBrackets(n *ast.ParserBrackets) { v.printIndentIfNotSingle(v.indent - 1) v.print("&ast.ParserBrackets{\n") v.printNode(n.GetNode()) } + +func (v *Dump) ParserSeparatedList(n *ast.ParserSeparatedList) { + // do nothing +} diff --git a/pkg/ast/visitor/filter_tokens.go b/pkg/ast/visitor/filter_tokens.go index 6c86b92..63fc40e 100644 --- a/pkg/ast/visitor/filter_tokens.go +++ b/pkg/ast/visitor/filter_tokens.go @@ -70,6 +70,7 @@ func (v *FilterTokens) StmtHaltCompiler(n *ast.StmtHaltCompiler) { func (v *FilterTokens) StmtConstList(n *ast.StmtConstList) { n.ConstTkn = nil + n.SeparatorTkns = nil n.SemiColonTkn = nil } @@ -224,3 +225,13 @@ func (v *FilterTokens) StmtForeach(n *ast.StmtForeach) { n.EndForeachTkn = nil n.SemiColonTkn = nil } + +func (v *FilterTokens) StmtDeclare(n *ast.StmtDeclare) { + n.DeclareTkn = nil + n.OpenParenthesisTkn = nil + n.SeparatorTkns = nil + n.CloseParenthesisTkn = nil + n.ColonTkn = nil + n.EndDeclareTkn = nil + n.SemiColonTkn = nil +} diff --git a/pkg/ast/visitor/null.go b/pkg/ast/visitor/null.go index 582033e..f5e1467 100644 --- a/pkg/ast/visitor/null.go +++ b/pkg/ast/visitor/null.go @@ -674,14 +674,10 @@ func (v *Null) NameNamePart(_ *ast.NameNamePart) { // do nothing } -func (v *Null) ParserAs(_ *ast.ParserAs) { - // do nothing -} - -func (v *Null) ParserNsSeparator(_ *ast.ParserNsSeparator) { - // do nothing -} - func (v *Null) ParserBrackets(_ *ast.ParserBrackets) { // do nothing } + +func (v *Null) ParserSeparatedList(_ *ast.ParserSeparatedList) { + // do nothing +} diff --git a/pkg/printer/printer.go b/pkg/printer/printer.go index b808de1..9195d83 100644 --- a/pkg/printer/printer.go +++ b/pkg/printer/printer.go @@ -484,10 +484,6 @@ func (p *Printer) printNode(n ast.Vertex) { p.printStmtUseDeclaration(n) case *ast.StmtWhile: p.printStmtWhile(n) - case *ast.ParserAs: - p.printParserAs(n) - case *ast.ParserNsSeparator: - p.printParserNsSeparator(n) case *ast.ParserBrackets: p.printParserBrackets(n) } @@ -2158,7 +2154,7 @@ func (p *Printer) printStmtClassConstList(n *ast.StmtClassConstList) { func (p *Printer) printStmtConstList(n *ast.StmtConstList) { p.printToken(n.ConstTkn, "const") p.bufStart = " " - p.joinPrintRefactored(",", n.Consts) + p.printSeparatedList(n.Consts, n.SeparatorTkns, ",") p.printToken(n.SemiColonTkn, ";") } @@ -2180,37 +2176,33 @@ func (p *Printer) printStmtContinue(n *ast.StmtContinue) { p.printToken(n.SemiColonTkn, ";") } -func (p *Printer) printStmtDeclare(n ast.Vertex) { - nn := n.(*ast.StmtDeclare) - p.printFreeFloating(nn, token.Start) +func (p *Printer) printStmtDeclare(n *ast.StmtDeclare) { + if n.Alt { + p.printStmtAltDeclare(n) + return + } + p.printToken(n.DeclareTkn, "declare") + p.printToken(n.OpenParenthesisTkn, "(") + p.printSeparatedList(n.Consts, n.SeparatorTkns, ",") + p.printToken(n.CloseParenthesisTkn, ")") + p.Print(n.Stmt) +} - p.write([]byte("declare")) - p.printFreeFloating(nn, token.Declare) - p.write([]byte("(")) - p.joinPrintRefactored(",", nn.Consts) - p.printFreeFloating(nn, token.ConstList) - p.write([]byte(")")) +func (p *Printer) printStmtAltDeclare(n *ast.StmtDeclare) { + p.printToken(n.DeclareTkn, "declare") + p.printToken(n.OpenParenthesisTkn, "(") + p.printSeparatedList(n.Consts, n.SeparatorTkns, ",") + p.printToken(n.CloseParenthesisTkn, ")") + p.printToken(n.ColonTkn, ":") - if nn.Alt { - p.printFreeFloating(nn, token.Cond) - p.write([]byte(":")) - - s := nn.Stmt.(*ast.StmtStmtList) - p.printNodes(s.Stmts) - p.printFreeFloating(nn, token.Stmts) - - p.write([]byte("enddeclare")) - p.printFreeFloating(nn, token.AltEnd) - - p.printFreeFloating(nn, token.SemiColon) - if nn.GetNode().Tokens.IsEmpty() { - p.write([]byte(";")) - } + if stmtList, ok := n.Stmt.(*ast.StmtStmtList); ok { + p.printNodes(stmtList.Stmts) } else { - p.Print(nn.Stmt) + p.Print(n.Stmt) } - p.printFreeFloating(nn, token.End) + p.printToken(n.EndDeclareTkn, "enddeclare") + p.printToken(n.SemiColonTkn, ";") } func (p *Printer) printStmtDefault(n *ast.StmtDefault) { @@ -2960,26 +2952,6 @@ func (p *Printer) printStmtAltWhile(n *ast.StmtWhile) { p.printToken(n.SemiColonTkn, ";") } -func (p *Printer) printParserAs(n ast.Vertex) { - nn := n.(*ast.ParserAs) - p.printFreeFloating(nn, token.Start) - - p.write([]byte("as")) - p.Print(nn.Child) - - p.printFreeFloating(nn, token.End) -} - -func (p *Printer) printParserNsSeparator(n ast.Vertex) { - nn := n.(*ast.ParserNsSeparator) - p.printFreeFloating(nn, token.Start) - - p.write([]byte("\\")) - p.Print(nn.Child) - - p.printFreeFloating(nn, token.End) -} - func (p *Printer) printParserBrackets(n ast.Vertex) { nn := n.(*ast.ParserBrackets) p.printFreeFloating(nn, token.Start)