Skip to content

Commit

Permalink
FPPP: Support insert at start of list node (#446)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikic committed Dec 1, 2017
1 parent e5453f0 commit dc3ace5
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Version 4.0.0-dev

* Fixed comment indentation in formatting-preserving pretty printer.

### Added

* Added support for inserting at the start of list nodes in formatting-preserving pretty printer.

Version 4.0.0-alpha2 (2017-11-10)
---------------------------------

Expand Down
60 changes: 47 additions & 13 deletions lib/PhpParser/PrettyPrinterAbstract.php
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,10 @@ protected function pArray(
) {
$diff = $this->nodeListDiffer->diffWithReplacements($origNodes, $nodes);

/** @var Node|null $delayedAddNode Used for insertions at the start of the list */
$delayedAddNode = null;
$delayedAddInsertStr = '';

$result = '';
foreach ($diff as $i => $diffElem) {
$diffType = $diffElem->type;
Expand Down Expand Up @@ -726,23 +730,46 @@ protected function pArray(

$comments = $arrItem->getComments();
$origComments = $origArrItem->getComments();
if ($comments !== $origComments) {
if ($origComments) {
$commentStartPos = $origComments[0]->getTokenPos();
\assert($commentStartPos >= 0);
$commentStartPos = $origComments ? $origComments[0]->getTokenPos() : $itemStartPos;
\assert($commentStartPos >= 0);

$commentsChanged = $comments !== $origComments;
if ($commentsChanged) {
// Remove old comments
$itemStartPos = $commentStartPos;
}

if (null !== $delayedAddNode) {
$result .= $this->origTokens->getTokenCode(
$pos, $commentStartPos, $indentAdjustment);

// Remove old comments
$itemStartPos = $commentStartPos;
if ($delayedAddInsertStr === "\n") {
$delayedAddComments = $delayedAddNode->getComments();
if ($delayedAddComments) {
$result .= $this->pComments($delayedAddComments) . $this->nl;
}
}

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

if ($comments) {
// Add new comments
$result .= $this->pComments($comments) . $this->nl;
if ($delayedAddInsertStr === "\n") {
$result .= $this->nl;
} else {
$result .= $delayedAddInsertStr;
}

$result .= $this->origTokens->getTokenCode(
$commentStartPos, $itemStartPos, $indentAdjustment);

$delayedAddNode = null;
} else {
$result .= $this->origTokens->getTokenCode($pos, $itemStartPos, $indentAdjustment);
$result .= $this->origTokens->getTokenCode(
$pos, $itemStartPos, $indentAdjustment);
}

if ($commentsChanged && $comments) {
// Add new comments
$result .= $this->pComments($comments) . $this->nl;
}
} else if ($diffType === DiffElem::TYPE_ADD) {
if (null === $insertStr) {
Expand All @@ -751,8 +778,15 @@ protected function pArray(
}

if ($i === 0) {
// TODO Handle insertion at the start
return null;
if (count($diff) === 1) {
// TODO Handle insertion into empty list
return null;
}

// These will be inserted at the next "replace" or "keep" element
$delayedAddNode = $arrItem;
$delayedAddInsertStr = $insertStr;
continue;
}

$itemStartPos = $pos;
Expand Down
12 changes: 6 additions & 6 deletions test/code/formatPreservation/abc1.test
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ call1(
);
-----
<?php
x;
function test() {
call1(
$bar
Expand All @@ -98,15 +99,14 @@ call2(
$foo
);
-----
$tmp = $stmts[0]->stmts[0];
$stmts[0]->stmts[0] = $stmts[1];
$stmts[1] = $tmp;
// Same test, but also prepending to $stmts, triggering fallback
array_unshift($stmts, new Stmt\Echo_([new Scalar\LNumber(42)]));
$tmp = $stmts[1]->stmts[0];
$stmts[1]->stmts[0] = $stmts[2];
$stmts[2] = $tmp;
// Same test, but also removing first statement, triggering fallback
array_splice($stmts, 0, 1, []);
-----
<?php

echo 42;
function test() {
call2(
$foo
Expand Down
107 changes: 104 additions & 3 deletions test/code/formatPreservation/listInsertion.test
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,21 @@ try {
function test(Foo $param1) {}
-----
array_unshift($stmts[0]->params, new Node\Param(new Expr\Variable('param0')));
/* Insertion at the start not handled yet */
-----
<?php

function test($param0, Foo $param1)
function test($param0, Foo $param1) {}
-----
<?php

function test() {}
-----
$stmts[0]->params[] = new Node\Param(new Expr\Variable('param0'));
/* Insertion into empty list not handled yet */
-----
<?php

function test($param0)
{
}
-----
Expand Down Expand Up @@ -138,4 +148,95 @@ $stmts[0]->name->parts[0] = 'Xyz';
-----
<?php
namespace
Xyz;
Xyz;
-----
<?php
function test() {
$foo; $bar;
}
-----
$node = new Stmt\Expression(new Expr\Variable('baz'));
array_unshift($stmts[0]->stmts, $node);
-----
<?php
function test() {
$baz;
$foo; $bar;
}
-----
<?php
function test() {
$foo; $bar;
}
-----
$node = new Stmt\Expression(new Expr\Variable('baz'));
$node->setAttribute('comments', [new Comment('// Test')]);
array_unshift($stmts[0]->stmts, $node);
-----
<?php
function test() {
// Test
$baz;
$foo; $bar;
}
-----
<?php
function test() {

// Foo bar
$foo; $bar;
}
-----
$node = new Stmt\Expression(new Expr\Variable('baz'));
$node->setAttribute('comments', [new Comment('// Test')]);
array_unshift($stmts[0]->stmts, $node);
-----
<?php
function test() {

// Test
$baz;
// Foo bar
$foo; $bar;
}
-----
<?php
function test() {

// Foo bar
$foo; $bar;
}
-----
$node = new Stmt\Expression(new Expr\Variable('baz'));
$node->setAttribute('comments', [new Comment('// Test')]);
array_unshift($stmts[0]->stmts, $node);
$stmts[0]->stmts[1]->setAttribute('comments', [new Comment('// Bar foo')]);
-----
<?php
function test() {

// Test
$baz;
// Bar foo
$foo; $bar;
}
-----
<?php
function test() {

// Foo bar
$foo; $bar;
}
-----
$node = new Stmt\Expression(new Expr\Variable('baz'));
$node->setAttribute('comments', [new Comment('// Test')]);
array_unshift($stmts[0]->stmts, $node);
$stmts[0]->stmts[1]->setAttribute('comments', []);
-----
<?php
function test() {

// Test
$baz;
$foo; $bar;
}

0 comments on commit dc3ace5

Please sign in to comment.