function Printer::printArrayFormatPreserving
*
Parameters
Node[] $nodes: * @param Node[] $originalNodes
2 calls to Printer::printArrayFormatPreserving()
- Printer::printFormatPreserving in vendor/
phpstan/ phpdoc-parser/ src/ Printer/ Printer.php - Printer::printNodeFormatPreserving in vendor/
phpstan/ phpdoc-parser/ src/ Printer/ Printer.php
File
-
vendor/
phpstan/ phpdoc-parser/ src/ Printer/ Printer.php, line 544
Class
Namespace
PHPStan\PhpDocParser\PrinterCode
private function printArrayFormatPreserving(array $nodes, array $originalNodes, TokenIterator $originalTokens, int &$tokenIndex, string $parentNodeClass, string $subNodeName) : ?string {
$diff = $this->differ
->diffWithReplacements($originalNodes, $nodes);
$mapKey = $parentNodeClass . '->' . $subNodeName;
$insertStr = $this->listInsertionMap[$mapKey] ?? null;
$result = '';
$beforeFirstKeepOrReplace = true;
$delayedAdd = [];
$insertNewline = false;
[
$isMultiline,
$beforeAsteriskIndent,
$afterAsteriskIndent,
] = $this->isMultiline($tokenIndex, $originalNodes, $originalTokens);
if ($insertStr === "\n * ") {
$insertStr = sprintf('%s%s*%s', $originalTokens->getDetectedNewline() ?? "\n", $beforeAsteriskIndent, $afterAsteriskIndent);
}
foreach ($diff as $i => $diffElem) {
$diffType = $diffElem->type;
$newNode = $diffElem->new;
$originalNode = $diffElem->old;
if ($diffType === DiffElem::TYPE_KEEP || $diffType === DiffElem::TYPE_REPLACE) {
$beforeFirstKeepOrReplace = false;
if (!$newNode instanceof Node || !$originalNode instanceof Node) {
return null;
}
$itemStartPos = $originalNode->getAttribute(Attribute::START_INDEX);
$itemEndPos = $originalNode->getAttribute(Attribute::END_INDEX);
if ($itemStartPos < 0 || $itemEndPos < 0 || $itemStartPos < $tokenIndex) {
throw new LogicException();
}
$result .= $originalTokens->getContentBetween($tokenIndex, $itemStartPos);
if (count($delayedAdd) > 0) {
foreach ($delayedAdd as $delayedAddNode) {
$parenthesesNeeded = isset($this->parenthesesListMap[$mapKey]) && in_array(get_class($delayedAddNode), $this->parenthesesListMap[$mapKey], true);
if ($parenthesesNeeded) {
$result .= '(';
}
$result .= $this->printNodeFormatPreserving($delayedAddNode, $originalTokens);
if ($parenthesesNeeded) {
$result .= ')';
}
if ($insertNewline) {
$result .= $insertStr . sprintf('%s%s*%s', $originalTokens->getDetectedNewline() ?? "\n", $beforeAsteriskIndent, $afterAsteriskIndent);
}
else {
$result .= $insertStr;
}
}
$delayedAdd = [];
}
$parenthesesNeeded = isset($this->parenthesesListMap[$mapKey]) && in_array(get_class($newNode), $this->parenthesesListMap[$mapKey], true) && !in_array(get_class($originalNode), $this->parenthesesListMap[$mapKey], true);
$addParentheses = $parenthesesNeeded && !$originalTokens->hasParentheses($itemStartPos, $itemEndPos);
if ($addParentheses) {
$result .= '(';
}
$result .= $this->printNodeFormatPreserving($newNode, $originalTokens);
if ($addParentheses) {
$result .= ')';
}
$tokenIndex = $itemEndPos + 1;
}
elseif ($diffType === DiffElem::TYPE_ADD) {
if ($insertStr === null) {
return null;
}
if (!$newNode instanceof Node) {
return null;
}
if ($insertStr === ', ' && $isMultiline) {
$insertStr = ',';
$insertNewline = true;
}
if ($beforeFirstKeepOrReplace) {
// Will be inserted at the next "replace" or "keep" element
$delayedAdd[] = $newNode;
continue;
}
$itemEndPos = $tokenIndex - 1;
if ($insertNewline) {
$result .= $insertStr . sprintf('%s%s*%s', $originalTokens->getDetectedNewline() ?? "\n", $beforeAsteriskIndent, $afterAsteriskIndent);
}
else {
$result .= $insertStr;
}
$parenthesesNeeded = isset($this->parenthesesListMap[$mapKey]) && in_array(get_class($newNode), $this->parenthesesListMap[$mapKey], true);
if ($parenthesesNeeded) {
$result .= '(';
}
$result .= $this->printNodeFormatPreserving($newNode, $originalTokens);
if ($parenthesesNeeded) {
$result .= ')';
}
$tokenIndex = $itemEndPos + 1;
}
elseif ($diffType === DiffElem::TYPE_REMOVE) {
if (!$originalNode instanceof Node) {
return null;
}
$itemStartPos = $originalNode->getAttribute(Attribute::START_INDEX);
$itemEndPos = $originalNode->getAttribute(Attribute::END_INDEX);
if ($itemStartPos < 0 || $itemEndPos < 0) {
throw new LogicException();
}
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.
$originalTokensArray = $originalTokens->getTokens();
for ($j = $tokenIndex; $j < $itemStartPos; $j++) {
if ($originalTokensArray[$j][Lexer::TYPE_OFFSET] === Lexer::TOKEN_PHPDOC_EOL) {
break;
}
$result .= $originalTokensArray[$j][Lexer::VALUE_OFFSET];
}
}
$tokenIndex = $itemEndPos + 1;
}
}
if (count($delayedAdd) > 0) {
if (!isset($this->emptyListInsertionMap[$mapKey])) {
return null;
}
[
$findToken,
$extraLeft,
$extraRight,
] = $this->emptyListInsertionMap[$mapKey];
if ($findToken !== null) {
$originalTokensArray = $originalTokens->getTokens();
for (; $tokenIndex < count($originalTokensArray); $tokenIndex++) {
$result .= $originalTokensArray[$tokenIndex][Lexer::VALUE_OFFSET];
if ($originalTokensArray[$tokenIndex][Lexer::VALUE_OFFSET] !== $findToken) {
continue;
}
$tokenIndex++;
break;
}
}
$first = true;
$result .= $extraLeft;
foreach ($delayedAdd as $delayedAddNode) {
if (!$first) {
$result .= $insertStr;
if ($insertNewline) {
$result .= sprintf('%s%s*%s', $originalTokens->getDetectedNewline() ?? "\n", $beforeAsteriskIndent, $afterAsteriskIndent);
}
}
$result .= $this->printNodeFormatPreserving($delayedAddNode, $originalTokens);
$first = false;
}
$result .= $extraRight;
}
return $result;
}