Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. PrettyPrinterAbstract.php

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.

... See full list

File

vendor/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php, line 600

Class

PrettyPrinterAbstract

Namespace

PhpParser

Code

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;
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal