mirror of
https://github.com/nikic/PHP-Parser.git
synced 2025-04-21 06:22:12 +02:00
FPPP: Support removing nodes from start of list
This commit is contained in:
parent
56356e4aec
commit
bd722809f7
@ -33,7 +33,7 @@ class TokenStream
|
||||
* @return bool
|
||||
*/
|
||||
public function haveParens(int $startPos, int $endPos) : bool {
|
||||
return $this->haveTokenImmediativelyBefore($startPos, '(')
|
||||
return $this->haveTokenImmediatelyBefore($startPos, '(')
|
||||
&& $this->haveTokenImmediatelyAfter($endPos, ')');
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ class TokenStream
|
||||
* @return bool
|
||||
*/
|
||||
public function haveBraces(int $startPos, int $endPos) : bool {
|
||||
return $this->haveTokenImmediativelyBefore($startPos, '{')
|
||||
return $this->haveTokenImmediatelyBefore($startPos, '{')
|
||||
&& $this->haveTokenImmediatelyAfter($endPos, '}');
|
||||
}
|
||||
|
||||
@ -60,7 +60,7 @@ class TokenStream
|
||||
*
|
||||
* @return bool Whether the expected token was found
|
||||
*/
|
||||
public function haveTokenImmediativelyBefore(int $pos, $expectedTokenType) : bool {
|
||||
public function haveTokenImmediatelyBefore(int $pos, $expectedTokenType) : bool {
|
||||
$tokens = $this->tokens;
|
||||
$pos--;
|
||||
for (; $pos >= 0; $pos--) {
|
||||
|
@ -706,6 +706,7 @@ abstract class PrettyPrinterAbstract
|
||||
$insertStr = $this->listInsertionMap[$mapKey] ?? null;
|
||||
|
||||
$beforeFirstKeepOrReplace = true;
|
||||
$skipRemovedNode = false;
|
||||
$delayedAdd = [];
|
||||
$lastElemIndentLevel = $this->indentLevel;
|
||||
|
||||
@ -797,7 +798,7 @@ abstract class PrettyPrinterAbstract
|
||||
$commentStartPos, $itemStartPos, $indentAdjustment);
|
||||
|
||||
$delayedAdd = [];
|
||||
} else {
|
||||
} else if (!$skipRemovedNode) {
|
||||
$result .= $this->origTokens->getTokenCode(
|
||||
$pos, $itemStartPos, $indentAdjustment);
|
||||
}
|
||||
@ -806,6 +807,9 @@ abstract class PrettyPrinterAbstract
|
||||
// Add new comments
|
||||
$result .= $this->pComments($comments) . $this->nl;
|
||||
}
|
||||
|
||||
// If we had to remove anything, we have done so now.
|
||||
$skipRemovedNode = false;
|
||||
} elseif ($diffType === DiffElem::TYPE_ADD) {
|
||||
if (null === $insertStr) {
|
||||
// We don't have insertion information for this list type
|
||||
@ -839,18 +843,42 @@ abstract class PrettyPrinterAbstract
|
||||
$result .= $insertStr;
|
||||
}
|
||||
} elseif ($diffType === DiffElem::TYPE_REMOVE) {
|
||||
if ($i === 0) {
|
||||
// TODO Handle removal at the start
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$origArrItem instanceof Node) {
|
||||
// We only support removal for nodes
|
||||
return null;
|
||||
}
|
||||
|
||||
$itemStartPos = $origArrItem->getStartTokenPos();
|
||||
$itemEndPos = $origArrItem->getEndTokenPos();
|
||||
\assert($itemEndPos >= 0);
|
||||
\assert($itemStartPos >= 0 && $itemEndPos >= 0);
|
||||
|
||||
// Consider comments part of the node.
|
||||
$origComments = $origArrItem->getComments();
|
||||
if ($origComments) {
|
||||
$itemStartPos = $origComments[0]->getStartTokenPos();
|
||||
}
|
||||
|
||||
if ($i === 0) {
|
||||
// If we're removing from the start, keep the tokens before the node and drop those after it,
|
||||
// instead of the other way around.
|
||||
$result .= $this->origTokens->getTokenCode(
|
||||
$pos, $itemStartPos, $indentAdjustment);
|
||||
$skipRemovedNode = true;
|
||||
|
||||
if ($this->origTokens->haveTokenImmediatelyAfter($itemEndPos, '{')
|
||||
|| $this->origTokens->haveTokenImmediatelyAfter($itemEndPos, '}')) {
|
||||
// We'd remove the brace of a code block.
|
||||
// TODO: Preserve formatting.
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
if ($this->origTokens->haveTokenImmediatelyBefore($itemStartPos, '{')
|
||||
|| $this->origTokens->haveTokenImmediatelyBefore($itemStartPos, '}')) {
|
||||
// We'd remove the brace of a code block.
|
||||
// TODO: Preserve formatting.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
$pos = $itemEndPos + 1;
|
||||
continue;
|
||||
@ -869,6 +897,11 @@ abstract class PrettyPrinterAbstract
|
||||
$pos = $itemEndPos + 1;
|
||||
}
|
||||
|
||||
if ($skipRemovedNode) {
|
||||
// TODO: Support removing single node.
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!empty($delayedAdd)) {
|
||||
if (!isset($this->emptyListInsertionMap[$mapKey])) {
|
||||
return null;
|
||||
|
@ -106,7 +106,6 @@ $stmts[2] = $tmp;
|
||||
array_splice($stmts, 0, 1, []);
|
||||
-----
|
||||
<?php
|
||||
|
||||
function test() {
|
||||
call2(
|
||||
$foo
|
||||
|
@ -49,4 +49,66 @@ array_pop($stmts[0]->returnType->types);
|
||||
-----
|
||||
<?php
|
||||
function test(): A
|
||||
|B {}
|
||||
|B {}
|
||||
-----
|
||||
<?php $a; $b; $c;
|
||||
-----
|
||||
array_splice($stmts, 0, 1, []);
|
||||
-----
|
||||
<?php $b; $c;
|
||||
-----
|
||||
<?php $a; $b; $c;
|
||||
-----
|
||||
array_splice($stmts, 0, 2, []);
|
||||
-----
|
||||
<?php $c;
|
||||
-----
|
||||
<?php
|
||||
{ $x; }
|
||||
$y;
|
||||
-----
|
||||
array_splice($stmts, 0, 1, []);
|
||||
-----
|
||||
<?php
|
||||
|
||||
$y;
|
||||
-----
|
||||
<?php
|
||||
$x;
|
||||
{ $y; }
|
||||
-----
|
||||
array_splice($stmts, 0, 1, []);
|
||||
-----
|
||||
<?php
|
||||
|
||||
$y;
|
||||
-----
|
||||
<?php
|
||||
$x;
|
||||
{ $y; }
|
||||
-----
|
||||
array_pop($stmts);
|
||||
-----
|
||||
<?php
|
||||
|
||||
$x;
|
||||
-----
|
||||
<?php
|
||||
{ $x; }
|
||||
$y;
|
||||
-----
|
||||
array_pop($stmts);
|
||||
-----
|
||||
<?php
|
||||
|
||||
$x;
|
||||
-----
|
||||
<?php
|
||||
// Foo
|
||||
$x;
|
||||
$y;
|
||||
-----
|
||||
array_splice($stmts, 0, 1, []);
|
||||
-----
|
||||
<?php
|
||||
$y;
|
Loading…
x
Reference in New Issue
Block a user