Skip to content

Commit cad49f8

Browse files
committed
Fix formatting preservation for alternative elseif/else syntax
Test taken from PR #797. (cherry picked from commit 9b46dff)
1 parent 570e980 commit cad49f8

File tree

5 files changed

+53
-6
lines changed

5 files changed

+53
-6
lines changed

grammar/php7.y

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,8 @@ new_elseif_list:
518518
;
519519

520520
new_elseif:
521-
T_ELSEIF '(' expr ')' ':' inner_statement_list { $$ = Stmt\ElseIf_[$3, $6]; }
521+
T_ELSEIF '(' expr ')' ':' inner_statement_list
522+
{ $$ = Stmt\ElseIf_[$3, $6]; $this->fixupAlternativeElse($$); }
522523
;
523524

524525
else_single:
@@ -528,7 +529,8 @@ else_single:
528529

529530
new_else_single:
530531
/* empty */ { $$ = null; }
531-
| T_ELSE ':' inner_statement_list { $$ = Stmt\Else_[$3]; }
532+
| T_ELSE ':' inner_statement_list
533+
{ $$ = Stmt\Else_[$3]; $this->fixupAlternativeElse($$); }
532534
;
533535

534536
foreach_variable:

lib/PhpParser/Parser/Php7.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1826,7 +1826,7 @@ protected function initReduceCallbacks() {
18261826
$this->semStack[$stackPos-(2-1)][] = $this->semStack[$stackPos-(2-2)]; $this->semValue = $this->semStack[$stackPos-(2-1)];
18271827
},
18281828
266 => function ($stackPos) {
1829-
$this->semValue = new Stmt\ElseIf_($this->semStack[$stackPos-(6-3)], $this->semStack[$stackPos-(6-6)], $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes);
1829+
$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);
18301830
},
18311831
267 => function ($stackPos) {
18321832
$this->semValue = null;
@@ -1838,7 +1838,7 @@ protected function initReduceCallbacks() {
18381838
$this->semValue = null;
18391839
},
18401840
270 => function ($stackPos) {
1841-
$this->semValue = new Stmt\Else_($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes);
1841+
$this->semValue = new Stmt\Else_($this->semStack[$stackPos-(3-3)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); $this->fixupAlternativeElse($this->semValue);
18421842
},
18431843
271 => function ($stackPos) {
18441844
$this->semValue = array($this->semStack[$stackPos-(1-1)], false);

lib/PhpParser/ParserAbstract.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616
use PhpParser\Node\Stmt\Class_;
1717
use PhpParser\Node\Stmt\ClassConst;
1818
use PhpParser\Node\Stmt\ClassMethod;
19+
use PhpParser\Node\Stmt\Else_;
20+
use PhpParser\Node\Stmt\ElseIf_;
1921
use PhpParser\Node\Stmt\Enum_;
2022
use PhpParser\Node\Stmt\Interface_;
2123
use PhpParser\Node\Stmt\Namespace_;
24+
use PhpParser\Node\Stmt\Nop;
2225
use PhpParser\Node\Stmt\Property;
2326
use PhpParser\Node\Stmt\TryCatch;
2427
use PhpParser\Node\Stmt\UseUse;
@@ -876,6 +879,24 @@ protected function createCommentNopAttributes(array $comments) {
876879
return $attributes;
877880
}
878881

882+
/** @param ElseIf_|Else_ $node */
883+
protected function fixupAlternativeElse($node) {
884+
// Make sure a trailing nop statement carrying comments is part of the node.
885+
$numStmts = \count($node->stmts);
886+
if ($numStmts !== 0 && $node->stmts[$numStmts - 1] instanceof Nop) {
887+
$nopAttrs = $node->stmts[$numStmts - 1]->getAttributes();
888+
if (isset($nopAttrs['endLine'])) {
889+
$node->setAttribute('endLine', $nopAttrs['endLine']);
890+
}
891+
if (isset($nopAttrs['endFilePos'])) {
892+
$node->setAttribute('endFilePos', $nopAttrs['endFilePos']);
893+
}
894+
if (isset($nopAttrs['endTokenPos'])) {
895+
$node->setAttribute('endTokenPos', $nopAttrs['endTokenPos']);
896+
}
897+
}
898+
}
899+
879900
protected function checkClassModifier($a, $b, $modifierPos) {
880901
try {
881902
Class_::verifyClassModifier($a, $b);

test/code/formatPreservation/comments.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,4 @@ class Test {
4949
public function test() {
5050
// some code
5151
}
52-
}
52+
}

test/code/prettyPrinter/comments.test

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,28 @@ function test()
6464
function test()
6565
{
6666
// empty
67-
}
67+
}
68+
-----
69+
<?php
70+
71+
function noDuplicateComment()
72+
{
73+
if (true):
74+
// TEST 1
75+
elseif (true):
76+
// TEST 2
77+
else:
78+
// TEST 3
79+
endif;
80+
}
81+
-----
82+
function noDuplicateComment()
83+
{
84+
if (true) {
85+
// TEST 1
86+
} elseif (true) {
87+
// TEST 2
88+
} else {
89+
// TEST 3
90+
}
91+
}

0 commit comments

Comments
 (0)