function PrettyPrinterAbstract::p
Pretty prints a node.
This method also handles formatting preservation for nodes.
Parameters
Node $node Node to be pretty printed:
int $precedence Precedence of parent operator:
int $lhsPrecedence Precedence for unary operator on LHS of binary operator:
bool $parentFormatPreserved Whether parent node has preserved formatting:
Return value
string Pretty printed node
86 calls to PrettyPrinterAbstract::p()
- PrettyPrinterAbstract::pArray in vendor/
nikic/ php-parser/ lib/ PhpParser/ PrettyPrinterAbstract.php - Perform a format-preserving pretty print of an array.
- PrettyPrinterAbstract::pCommaSeparatedMultiline in vendor/
nikic/ php-parser/ lib/ PhpParser/ PrettyPrinterAbstract.php - Pretty prints a comma-separated list of nodes in multiline style, including comments.
- PrettyPrinterAbstract::pFixup in vendor/
nikic/ php-parser/ lib/ PhpParser/ PrettyPrinterAbstract.php - Print node with fixups.
- PrettyPrinterAbstract::pImplode in vendor/
nikic/ php-parser/ lib/ PhpParser/ PrettyPrinterAbstract.php - Pretty prints an array of nodes and implodes the printed values.
- PrettyPrinterAbstract::pInfixOp in vendor/
nikic/ php-parser/ lib/ PhpParser/ PrettyPrinterAbstract.php - Pretty-print an infix operation while taking precedence into account.
File
-
vendor/
nikic/ php-parser/ lib/ PhpParser/ PrettyPrinterAbstract.php, line 600
Class
Namespace
PhpParserCode
protected function p(Node $node, int $precedence = self::MAX_PRECEDENCE, int $lhsPrecedence = self::MAX_PRECEDENCE, bool $parentFormatPreserved = false) : string {
// No orig tokens means this is a normal pretty print without preservation of formatting
if (!$this->origTokens) {
return $this->{'p' . $node->getType()}($node, $precedence, $lhsPrecedence);
}
/** @var Node|null $origNode */
$origNode = $node->getAttribute('origNode');
if (null === $origNode) {
return $this->pFallback($node, $precedence, $lhsPrecedence);
}
$class = \get_class($node);
\assert($class === \get_class($origNode));
$startPos = $origNode->getStartTokenPos();
$endPos = $origNode->getEndTokenPos();
\assert($startPos >= 0 && $endPos >= 0);
$fallbackNode = $node;
if ($node instanceof Expr\New_ && $node->class instanceof Stmt\Class_) {
// Normalize node structure of anonymous classes
assert($origNode instanceof Expr\New_);
$node = PrintableNewAnonClassNode::fromNewNode($node);
$origNode = PrintableNewAnonClassNode::fromNewNode($origNode);
$class = PrintableNewAnonClassNode::class;
}
// InlineHTML node does not contain closing and opening PHP tags. If the parent formatting
// is not preserved, then we need to use the fallback code to make sure the tags are
// printed.
if ($node instanceof Stmt\InlineHTML && !$parentFormatPreserved) {
return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
}
$indentAdjustment = $this->indentLevel - $this->origTokens
->getIndentationBefore($startPos);
$type = $node->getType();
$fixupInfo = $this->fixupMap[$class] ?? null;
$result = '';
$pos = $startPos;
foreach ($node->getSubNodeNames() as $subNodeName) {
$subNode = $node->{$subNodeName};
$origSubNode = $origNode->{$subNodeName};
if (!$subNode instanceof Node && $subNode !== null || !$origSubNode instanceof Node && $origSubNode !== null) {
if ($subNode === $origSubNode) {
// Unchanged, can reuse old code
continue;
}
if (is_array($subNode) && is_array($origSubNode)) {
// Array subnode changed, we might be able to reconstruct it
$listResult = $this->pArray($subNode, $origSubNode, $pos, $indentAdjustment, $class, $subNodeName, $fixupInfo[$subNodeName] ?? null);
if (null === $listResult) {
return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
}
$result .= $listResult;
continue;
}
// Check if this is a modifier change
$key = $class . '->' . $subNodeName;
if (!isset($this->modifierChangeMap[$key])) {
return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
}
[
$printFn,
$findToken,
] = $this->modifierChangeMap[$key];
$result .= $this->{$printFn}($subNode);
$pos = $this->origTokens
->findRight($pos, $findToken);
continue;
}
$extraLeft = '';
$extraRight = '';
if ($origSubNode !== null) {
$subStartPos = $origSubNode->getStartTokenPos();
$subEndPos = $origSubNode->getEndTokenPos();
\assert($subStartPos >= 0 && $subEndPos >= 0);
}
else {
if ($subNode === null) {
// Both null, nothing to do
continue;
}
// A node has been inserted, check if we have insertion information for it
$key = $type . '->' . $subNodeName;
if (!isset($this->insertionMap[$key])) {
return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
}
list($findToken, $beforeToken, $extraLeft, $extraRight) = $this->insertionMap[$key];
if (null !== $findToken) {
$subStartPos = $this->origTokens
->findRight($pos, $findToken) + (int) (!$beforeToken);
}
else {
$subStartPos = $pos;
}
if (null === $extraLeft && null !== $extraRight) {
// If inserting on the right only, skipping whitespace looks better
$subStartPos = $this->origTokens
->skipRightWhitespace($subStartPos);
}
$subEndPos = $subStartPos - 1;
}
if (null === $subNode) {
// A node has been removed, check if we have removal information for it
$key = $type . '->' . $subNodeName;
if (!isset($this->removalMap[$key])) {
return $this->pFallback($fallbackNode, $precedence, $lhsPrecedence);
}
// Adjust positions to account for additional tokens that must be skipped
$removalInfo = $this->removalMap[$key];
if (isset($removalInfo['left'])) {
$subStartPos = $this->origTokens
->skipLeft($subStartPos - 1, $removalInfo['left']) + 1;
}
if (isset($removalInfo['right'])) {
$subEndPos = $this->origTokens
->skipRight($subEndPos + 1, $removalInfo['right']) - 1;
}
}
$result .= $this->origTokens
->getTokenCode($pos, $subStartPos, $indentAdjustment);
if (null !== $subNode) {
$result .= $extraLeft;
$origIndentLevel = $this->indentLevel;
$this->setIndentLevel(max($this->origTokens
->getIndentationBefore($subStartPos) + $indentAdjustment, 0));
// If it's the same node that was previously in this position, it certainly doesn't
// need fixup. It's important to check this here, because our fixup checks are more
// conservative than strictly necessary.
if (isset($fixupInfo[$subNodeName]) && $subNode->getAttribute('origNode') !== $origSubNode) {
$fixup = $fixupInfo[$subNodeName];
$res = $this->pFixup($fixup, $subNode, $class, $subStartPos, $subEndPos);
}
else {
$res = $this->p($subNode, self::MAX_PRECEDENCE, self::MAX_PRECEDENCE, true);
}
$this->safeAppend($result, $res);
$this->setIndentLevel($origIndentLevel);
$result .= $extraRight;
}
$pos = $subEndPos + 1;
}
$result .= $this->origTokens
->getTokenCode($pos, $endPos + 1, $indentAdjustment);
return $result;
}