diff --git a/grammar/php7.y b/grammar/php7.y index 1f9b4bdd..fc7862c3 100644 --- a/grammar/php7.y +++ b/grammar/php7.y @@ -518,7 +518,8 @@ new_elseif_list: ; new_elseif: - T_ELSEIF '(' expr ')' ':' inner_statement_list { $$ = Stmt\ElseIf_[$3, $6]; } + T_ELSEIF '(' expr ')' ':' inner_statement_list + { $$ = Stmt\ElseIf_[$3, $6]; $this->fixupAlternativeElse($$); } ; else_single: @@ -528,7 +529,8 @@ else_single: new_else_single: /* empty */ { $$ = null; } - | T_ELSE ':' inner_statement_list { $$ = Stmt\Else_[$3]; } + | T_ELSE ':' inner_statement_list + { $$ = Stmt\Else_[$3]; $this->fixupAlternativeElse($$); } ; foreach_variable: diff --git a/lib/PhpParser/Parser/Php7.php b/lib/PhpParser/Parser/Php7.php index 48deff23..c6b9abd0 100644 --- a/lib/PhpParser/Parser/Php7.php +++ b/lib/PhpParser/Parser/Php7.php @@ -1826,7 +1826,7 @@ class Php7 extends \PhpParser\ParserAbstract $this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)]; }, 266 => function ($stackPos) { - $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + $this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); $this->fixupAlternativeElse($this->semValue); }, 267 => function ($stackPos) { $this->semValue = null; @@ -1838,7 +1838,7 @@ class Php7 extends \PhpParser\ParserAbstract $this->semValue = null; }, 270 => function ($stackPos) { - $this->semValue = new Stmt\Else_($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); + $this->semValue = new Stmt\Else_($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->fixupAlternativeElse($this->semValue); }, 271 => function ($stackPos) { $this->semValue = array($this->semStack[$stackPos-(1-1)], false); diff --git a/lib/PhpParser/ParserAbstract.php b/lib/PhpParser/ParserAbstract.php index 301d3c6a..9f9d00c7 100644 --- a/lib/PhpParser/ParserAbstract.php +++ b/lib/PhpParser/ParserAbstract.php @@ -16,9 +16,12 @@ use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassConst; use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Else_; +use PhpParser\Node\Stmt\ElseIf_; use PhpParser\Node\Stmt\Enum_; use PhpParser\Node\Stmt\Interface_; use PhpParser\Node\Stmt\Namespace_; +use PhpParser\Node\Stmt\Nop; use PhpParser\Node\Stmt\Property; use PhpParser\Node\Stmt\TryCatch; use PhpParser\Node\Stmt\UseUse; @@ -876,6 +879,24 @@ abstract class ParserAbstract implements Parser return $attributes; } + /** @param ElseIf_|Else_ $node */ + protected function fixupAlternativeElse($node) { + // Make sure a trailing nop statement carrying comments is part of the node. + $numStmts = \count($node->stmts); + if ($numStmts !== 0 && $node->stmts[$numStmts - 1] instanceof Nop) { + $nopAttrs = $node->stmts[$numStmts - 1]->getAttributes(); + if (isset($nopAttrs['endLine'])) { + $node->setAttribute('endLine', $nopAttrs['endLine']); + } + if (isset($nopAttrs['endFilePos'])) { + $node->setAttribute('endFilePos', $nopAttrs['endFilePos']); + } + if (isset($nopAttrs['endTokenPos'])) { + $node->setAttribute('endTokenPos', $nopAttrs['endTokenPos']); + } + } + } + protected function checkClassModifier($a, $b, $modifierPos) { try { Class_::verifyClassModifier($a, $b); diff --git a/test/code/formatPreservation/comments.test b/test/code/formatPreservation/comments.test index 61f21e2f..1b62ab39 100644 --- a/test/code/formatPreservation/comments.test +++ b/test/code/formatPreservation/comments.test @@ -49,4 +49,4 @@ class Test { public function test() { // some code } -} \ No newline at end of file +} diff --git a/test/code/prettyPrinter/comments.test b/test/code/prettyPrinter/comments.test index 34a9f93d..5163d62e 100644 --- a/test/code/prettyPrinter/comments.test +++ b/test/code/prettyPrinter/comments.test @@ -64,4 +64,28 @@ function test() function test() { // empty -} \ No newline at end of file +} +----- +<?php + +function noDuplicateComment() +{ + if (true): + // TEST 1 + elseif (true): + // TEST 2 + else: + // TEST 3 + endif; +} +----- +function noDuplicateComment() +{ + if (true) { + // TEST 1 + } elseif (true) { + // TEST 2 + } else { + // TEST 3 + } +}