diff --git a/internal/php5/php5.go b/internal/php5/php5.go index d6165d2..a5870d0 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 b760bdc..c5e03a3 100644 --- a/internal/php5/php5.y +++ b/internal/php5/php5.y @@ -911,16 +911,18 @@ unticked_statement: } | T_DO statement T_WHILE parenthesis_expr ';' { - $$ = &ast.StmtDo{ast.Node{}, $2, $4} - - // save position - $$.GetNode().Position = position.NewTokensPosition($1, $5) - - // save comments - yylex.(*Parser).setFreeFloating($$, token.Start, $1.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.Stmts, $3.SkippedTokens) - yylex.(*Parser).setFreeFloating($4, token.End, $5.SkippedTokens) - yylex.(*Parser).setToken($$, token.SemiColon, $5.SkippedTokens) + $$ = &ast.StmtDo{ + Node: ast.Node{ + Position: position.NewTokensPosition($1, $5), + }, + DoTkn: $1, + Stmt: $2, + WhileTkn: $3, + OpenParenthesisTkn: $4.(*ast.ParserBrackets).OpenBracketTkn, + Cond: $4.(*ast.ParserBrackets).Child, + CloseParenthesisTkn: $4.(*ast.ParserBrackets).CloseBracketTkn, + SemiColonTkn: $5, + } } | T_FOR '(' for_expr ';' for_expr ';' for_expr ')' for_statement { diff --git a/internal/php7/php7.go b/internal/php7/php7.go index 323095b..2862d9e 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 bc12e9f..e1914fe 100644 --- a/internal/php7/php7.y +++ b/internal/php7/php7.y @@ -880,25 +880,18 @@ statement: } | T_DO statement T_WHILE '(' expr ')' ';' { - exprBrackets := &ast.ParserBrackets{ + $$ = &ast.StmtDo{ Node: ast.Node{ - Position: position.NewTokensPosition($4, $6), + Position: position.NewTokensPosition($1, $7), }, - OpenBracketTkn: $4, - Child: $5, - CloseBracketTkn: $6, + DoTkn: $1, + Stmt: $2, + WhileTkn: $3, + OpenParenthesisTkn: $4, + Cond: $5, + CloseParenthesisTkn: $6, + SemiColonTkn: $7, } - $$ = &ast.StmtDo{ast.Node{}, $2, exprBrackets} - - // save position - $$.GetNode().Position = position.NewTokensPosition($1, $7) - - // save comments - yylex.(*Parser).setFreeFloating($$, token.Start, $1.SkippedTokens) - yylex.(*Parser).setFreeFloating($$, token.Stmts, $3.SkippedTokens) - yylex.(*Parser).setFreeFloatingTokens(exprBrackets, token.Start, $4.SkippedTokens) - yylex.(*Parser).setFreeFloating(exprBrackets, token.End, append($6.SkippedTokens, $7.SkippedTokens...)) - yylex.(*Parser).setToken($$, token.SemiColon, $7.SkippedTokens) } | T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement { diff --git a/pkg/ast/node.go b/pkg/ast/node.go index 80ca23e..017d979 100644 --- a/pkg/ast/node.go +++ b/pkg/ast/node.go @@ -378,8 +378,13 @@ func (n *StmtDefault) Accept(v NodeVisitor) { // StmtDo node type StmtDo struct { Node - Stmt Vertex - Cond Vertex + DoTkn *token.Token + Stmt Vertex + WhileTkn *token.Token + OpenParenthesisTkn *token.Token + Cond Vertex + CloseParenthesisTkn *token.Token + SemiColonTkn *token.Token } func (n *StmtDo) Accept(v NodeVisitor) { diff --git a/pkg/ast/visitor/filter_parser_nodes.go b/pkg/ast/visitor/filter_parser_nodes.go index 20ed98d..83f9cb2 100644 --- a/pkg/ast/visitor/filter_parser_nodes.go +++ b/pkg/ast/visitor/filter_parser_nodes.go @@ -13,16 +13,6 @@ func (v *FilterParserNodes) EnterNode(n ast.Vertex) bool { return true } -func (v *FilterParserNodes) StmtDo(n *ast.StmtDo) { - for { - if nn, ok := n.Cond.(*ast.ParserBrackets); ok { - n.Cond = nn.Child - } else { - break - } - } -} - func (v *FilterParserNodes) StmtSwitch(n *ast.StmtSwitch) { for { if nn, ok := n.Cond.(*ast.ParserBrackets); ok { diff --git a/pkg/ast/visitor/filter_tokens.go b/pkg/ast/visitor/filter_tokens.go index 620b703..3d60dd5 100644 --- a/pkg/ast/visitor/filter_tokens.go +++ b/pkg/ast/visitor/filter_tokens.go @@ -122,3 +122,11 @@ func (v *FilterTokens) StmtWhile(n *ast.StmtWhile) { n.EndWhileTkn = nil n.SemiColonTkn = nil } + +func (v *FilterTokens) StmtDo(n *ast.StmtDo) { + n.DoTkn = nil + n.WhileTkn = nil + n.OpenParenthesisTkn = nil + n.CloseParenthesisTkn = nil + n.SemiColonTkn = nil +} diff --git a/pkg/printer/pretty_printer_test.go b/pkg/printer/pretty_printer_test.go index 6bb07ea..a193202 100644 --- a/pkg/printer/pretty_printer_test.go +++ b/pkg/printer/pretty_printer_test.go @@ -2343,7 +2343,7 @@ func TestPrintAltWhile(t *testing.T) { p.Print(&ast.StmtNamespace{ Stmts: []ast.Vertex{ &ast.StmtWhile{ - Alt: true, + Alt: true, Cond: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("a")}}, Stmt: &ast.StmtStmtList{ Stmts: []ast.Vertex{ diff --git a/pkg/printer/printer.go b/pkg/printer/printer.go index 8275817..e678ae6 100644 --- a/pkg/printer/printer.go +++ b/pkg/printer/printer.go @@ -2361,42 +2361,17 @@ func (p *Printer) printStmtDefault(n ast.Vertex) { p.printFreeFloating(nn, token.End) } -func (p *Printer) printStmtDo(n ast.Vertex) { - nn := n.(*ast.StmtDo) - p.printFreeFloating(nn, token.Start) +func (p *Printer) printStmtDo(n *ast.StmtDo) { + p.printToken(n.DoTkn, "do") + p.bufStart = " " - io.WriteString(p.w, "do") + p.Print(n.Stmt) - if _, ok := nn.Stmt.(*ast.StmtStmtList); !ok { - if nn.Stmt.GetNode().Tokens.IsEmpty() { - io.WriteString(p.w, " ") - } - } - - p.Print(nn.Stmt) - - p.printFreeFloating(nn, token.Stmts) - - io.WriteString(p.w, "while") - - if _, ok := nn.Cond.(*ast.ParserBrackets); !ok { - io.WriteString(p.w, "(") - } - - p.Print(nn.Cond) - - if _, ok := nn.Cond.(*ast.ParserBrackets); !ok { - io.WriteString(p.w, ")") - } - - p.printFreeFloating(nn, token.Cond) - - p.printFreeFloating(nn, token.SemiColon) - if nn.GetNode().Tokens.IsEmpty() { - io.WriteString(p.w, ";") - } - - p.printFreeFloating(nn, token.End) + p.printToken(n.WhileTkn, "while") + p.printToken(n.OpenParenthesisTkn, "(") + p.Print(n.Cond) + p.printToken(n.CloseParenthesisTkn, ")") + p.printToken(n.SemiColonTkn, ";") } func (p *Printer) printStmtEcho(n ast.Vertex) { diff --git a/pkg/printer/printer_parsed_php5_test.go b/pkg/printer/printer_parsed_php5_test.go index 1af1e60..ce35495 100644 --- a/pkg/printer/printer_parsed_php5_test.go +++ b/pkg/printer/printer_parsed_php5_test.go @@ -945,7 +945,8 @@ func TestParseAndPrintPhp5Declare(t *testing.T) { } func TestParseAndPrintPhp5DoWhile(t *testing.T) { - src := `