Skip to content

Commit dc3ace5

Browse files
committed
FPPP: Support insert at start of list node (#446)
1 parent e5453f0 commit dc3ace5

File tree

4 files changed

+161
-22
lines changed

4 files changed

+161
-22
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ Version 4.0.0-dev
55

66
* Fixed comment indentation in formatting-preserving pretty printer.
77

8+
### Added
9+
10+
* Added support for inserting at the start of list nodes in formatting-preserving pretty printer.
11+
812
Version 4.0.0-alpha2 (2017-11-10)
913
---------------------------------
1014

lib/PhpParser/PrettyPrinterAbstract.php

Lines changed: 47 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,10 @@ protected function pArray(
688688
) {
689689
$diff = $this->nodeListDiffer->diffWithReplacements($origNodes, $nodes);
690690

691+
/** @var Node|null $delayedAddNode Used for insertions at the start of the list */
692+
$delayedAddNode = null;
693+
$delayedAddInsertStr = '';
694+
691695
$result = '';
692696
foreach ($diff as $i => $diffElem) {
693697
$diffType = $diffElem->type;
@@ -726,23 +730,46 @@ protected function pArray(
726730

727731
$comments = $arrItem->getComments();
728732
$origComments = $origArrItem->getComments();
729-
if ($comments !== $origComments) {
730-
if ($origComments) {
731-
$commentStartPos = $origComments[0]->getTokenPos();
732-
\assert($commentStartPos >= 0);
733+
$commentStartPos = $origComments ? $origComments[0]->getTokenPos() : $itemStartPos;
734+
\assert($commentStartPos >= 0);
735+
736+
$commentsChanged = $comments !== $origComments;
737+
if ($commentsChanged) {
738+
// Remove old comments
739+
$itemStartPos = $commentStartPos;
740+
}
741+
742+
if (null !== $delayedAddNode) {
743+
$result .= $this->origTokens->getTokenCode(
744+
$pos, $commentStartPos, $indentAdjustment);
733745

734-
// Remove old comments
735-
$itemStartPos = $commentStartPos;
746+
if ($delayedAddInsertStr === "\n") {
747+
$delayedAddComments = $delayedAddNode->getComments();
748+
if ($delayedAddComments) {
749+
$result .= $this->pComments($delayedAddComments) . $this->nl;
750+
}
736751
}
737752

738-
$result .= $this->origTokens->getTokenCode($pos, $itemStartPos, $indentAdjustment);
753+
$this->safeAppend($result, $this->p($delayedAddNode));
739754

740-
if ($comments) {
741-
// Add new comments
742-
$result .= $this->pComments($comments) . $this->nl;
755+
if ($delayedAddInsertStr === "\n") {
756+
$result .= $this->nl;
757+
} else {
758+
$result .= $delayedAddInsertStr;
743759
}
760+
761+
$result .= $this->origTokens->getTokenCode(
762+
$commentStartPos, $itemStartPos, $indentAdjustment);
763+
764+
$delayedAddNode = null;
744765
} else {
745-
$result .= $this->origTokens->getTokenCode($pos, $itemStartPos, $indentAdjustment);
766+
$result .= $this->origTokens->getTokenCode(
767+
$pos, $itemStartPos, $indentAdjustment);
768+
}
769+
770+
if ($commentsChanged && $comments) {
771+
// Add new comments
772+
$result .= $this->pComments($comments) . $this->nl;
746773
}
747774
} else if ($diffType === DiffElem::TYPE_ADD) {
748775
if (null === $insertStr) {
@@ -751,8 +778,15 @@ protected function pArray(
751778
}
752779

753780
if ($i === 0) {
754-
// TODO Handle insertion at the start
755-
return null;
781+
if (count($diff) === 1) {
782+
// TODO Handle insertion into empty list
783+
return null;
784+
}
785+
786+
// These will be inserted at the next "replace" or "keep" element
787+
$delayedAddNode = $arrItem;
788+
$delayedAddInsertStr = $insertStr;
789+
continue;
756790
}
757791

758792
$itemStartPos = $pos;

test/code/formatPreservation/abc1.test

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ call1(
8989
);
9090
-----
9191
<?php
92+
x;
9293
function test() {
9394
call1(
9495
$bar
@@ -98,15 +99,14 @@ call2(
9899
$foo
99100
);
100101
-----
101-
$tmp = $stmts[0]->stmts[0];
102-
$stmts[0]->stmts[0] = $stmts[1];
103-
$stmts[1] = $tmp;
104-
// Same test, but also prepending to $stmts, triggering fallback
105-
array_unshift($stmts, new Stmt\Echo_([new Scalar\LNumber(42)]));
102+
$tmp = $stmts[1]->stmts[0];
103+
$stmts[1]->stmts[0] = $stmts[2];
104+
$stmts[2] = $tmp;
105+
// Same test, but also removing first statement, triggering fallback
106+
array_splice($stmts, 0, 1, []);
106107
-----
107108
<?php
108109

109-
echo 42;
110110
function test() {
111111
call2(
112112
$foo

test/code/formatPreservation/listInsertion.test

Lines changed: 104 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,21 @@ try {
6363
function test(Foo $param1) {}
6464
-----
6565
array_unshift($stmts[0]->params, new Node\Param(new Expr\Variable('param0')));
66-
/* Insertion at the start not handled yet */
6766
-----
6867
<?php
6968

70-
function test($param0, Foo $param1)
69+
function test($param0, Foo $param1) {}
70+
-----
71+
<?php
72+
73+
function test() {}
74+
-----
75+
$stmts[0]->params[] = new Node\Param(new Expr\Variable('param0'));
76+
/* Insertion into empty list not handled yet */
77+
-----
78+
<?php
79+
80+
function test($param0)
7181
{
7282
}
7383
-----
@@ -138,4 +148,95 @@ $stmts[0]->name->parts[0] = 'Xyz';
138148
-----
139149
<?php
140150
namespace
141-
Xyz;
151+
Xyz;
152+
-----
153+
<?php
154+
function test() {
155+
$foo; $bar;
156+
}
157+
-----
158+
$node = new Stmt\Expression(new Expr\Variable('baz'));
159+
array_unshift($stmts[0]->stmts, $node);
160+
-----
161+
<?php
162+
function test() {
163+
$baz;
164+
$foo; $bar;
165+
}
166+
-----
167+
<?php
168+
function test() {
169+
$foo; $bar;
170+
}
171+
-----
172+
$node = new Stmt\Expression(new Expr\Variable('baz'));
173+
$node->setAttribute('comments', [new Comment('// Test')]);
174+
array_unshift($stmts[0]->stmts, $node);
175+
-----
176+
<?php
177+
function test() {
178+
// Test
179+
$baz;
180+
$foo; $bar;
181+
}
182+
-----
183+
<?php
184+
function test() {
185+
186+
// Foo bar
187+
$foo; $bar;
188+
}
189+
-----
190+
$node = new Stmt\Expression(new Expr\Variable('baz'));
191+
$node->setAttribute('comments', [new Comment('// Test')]);
192+
array_unshift($stmts[0]->stmts, $node);
193+
-----
194+
<?php
195+
function test() {
196+
197+
// Test
198+
$baz;
199+
// Foo bar
200+
$foo; $bar;
201+
}
202+
-----
203+
<?php
204+
function test() {
205+
206+
// Foo bar
207+
$foo; $bar;
208+
}
209+
-----
210+
$node = new Stmt\Expression(new Expr\Variable('baz'));
211+
$node->setAttribute('comments', [new Comment('// Test')]);
212+
array_unshift($stmts[0]->stmts, $node);
213+
$stmts[0]->stmts[1]->setAttribute('comments', [new Comment('// Bar foo')]);
214+
-----
215+
<?php
216+
function test() {
217+
218+
// Test
219+
$baz;
220+
// Bar foo
221+
$foo; $bar;
222+
}
223+
-----
224+
<?php
225+
function test() {
226+
227+
// Foo bar
228+
$foo; $bar;
229+
}
230+
-----
231+
$node = new Stmt\Expression(new Expr\Variable('baz'));
232+
$node->setAttribute('comments', [new Comment('// Test')]);
233+
array_unshift($stmts[0]->stmts, $node);
234+
$stmts[0]->stmts[1]->setAttribute('comments', []);
235+
-----
236+
<?php
237+
function test() {
238+
239+
// Test
240+
$baz;
241+
$foo; $bar;
242+
}

0 commit comments

Comments
 (0)