Skip to content

Commit

Permalink
Assemble NodeDumper result in property
Browse files Browse the repository at this point in the history
Append to a property instead of returning strings. This is
significantly faster when dumping large ASTs.

This also fixes an inconsistency where the indentation level for
strings and comments was off-by-one.
  • Loading branch information
nikic committed Sep 23, 2023
1 parent 8f175fe commit 8085116
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 71 deletions.
92 changes: 49 additions & 43 deletions lib/PhpParser/NodeDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class NodeDumper {
private bool $dumpComments;
private bool $dumpPositions;
private ?string $code;
private string $res;
private string $nl;

/**
* Constructs a NodeDumper.
Expand Down Expand Up @@ -39,72 +41,76 @@ public function __construct(array $options = []) {
*/
public function dump($node, ?string $code = null): string {
$this->code = $code;
return $this->dumpRecursive($node);
$this->res = '';
$this->nl = "\n";
$this->dumpRecursive($node, false);
return $this->res;
}

/** @param Node|Comment|array $node */
protected function dumpRecursive($node): string {
/** @param mixed $node */
protected function dumpRecursive($node, bool $indent = true): void {
if ($indent) {
$this->nl .= " ";
}
if ($node instanceof Node) {
$r = $node->getType();
$this->res .= $node->getType();
if ($this->dumpPositions && null !== $p = $this->dumpPosition($node)) {
$r .= $p;
$this->res .= $p;
}
$r .= '(';
$this->res .= '(';

foreach ($node->getSubNodeNames() as $key) {
$r .= "\n " . $key . ': ';
$this->res .= "$this->nl " . $key . ': ';

$value = $node->$key;
if (null === $value) {
$r .= 'null';
} elseif (false === $value) {
$r .= 'false';
} elseif (true === $value) {
$r .= 'true';
} elseif (is_scalar($value)) {
if (\is_int($value)) {
if ('flags' === $key || 'newModifier' === $key) {
$r .= $this->dumpFlags($value);
} elseif ('type' === $key && $node instanceof Include_) {
$r .= $this->dumpIncludeType($value);
} elseif ('type' === $key
$this->res .= $this->dumpFlags($value);
continue;
}
if ('type' === $key && $node instanceof Include_) {
$this->res .= $this->dumpIncludeType($value);
continue;
}
if ('type' === $key
&& ($node instanceof Use_ || $node instanceof UseItem || $node instanceof GroupUse)) {
$r .= $this->dumpUseType($value);
} else {
$r .= $value;
$this->res .= $this->dumpUseType($value);
continue;
}
} else {
$r .= str_replace("\n", "\n ", $this->dumpRecursive($value));
}
$this->dumpRecursive($value);
}

if ($this->dumpComments && $comments = $node->getComments()) {
$r .= "\n comments: " . str_replace("\n", "\n ", $this->dumpRecursive($comments));
$this->res .= "$this->nl comments: ";
$this->dumpRecursive($comments);
}
} elseif (is_array($node)) {
$r = 'array(';

$this->res .= "$this->nl)";
} elseif (\is_array($node)) {
$this->res .= 'array(';
foreach ($node as $key => $value) {
$r .= "\n " . $key . ': ';

if (null === $value) {
$r .= 'null';
} elseif (false === $value) {
$r .= 'false';
} elseif (true === $value) {
$r .= 'true';
} elseif (is_scalar($value)) {
$r .= $value;
} else {
$r .= str_replace("\n", "\n ", $this->dumpRecursive($value));
}
$this->res .= "$this->nl " . $key . ': ';
$this->dumpRecursive($value);
}
$this->res .= "$this->nl)";
} elseif ($node instanceof Comment) {
return $node->getReformattedText();
$this->res .= \str_replace("\n", $this->nl, $node->getReformattedText());
} elseif (\is_string($node)) {
$this->res .= \str_replace("\n", $this->nl, (string)$node);
} elseif (\is_int($node) || \is_float($node)) {
$this->res .= $node;
} elseif (null === $node) {
$this->res .= 'null';
} elseif (false === $node) {
$this->res .= 'false';
} elseif (true === $node) {
$this->res .= 'true';
} else {
throw new \InvalidArgumentException('Can only dump nodes and arrays.');
}

return $r . "\n)";
if ($indent) {
$this->nl = \substr($this->nl, 0, -4);
}
}

protected function dumpFlags(int $flags): string {
Expand Down
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,6 @@ parameters:
count: 1
path: lib/PhpParser/NodeDumper.php

-
message: "#^Method PhpParser\\\\NodeDumper\\:\\:dumpRecursive\\(\\) has parameter \\$node with no value type specified in iterable type array\\.$#"
count: 1
path: lib/PhpParser/NodeDumper.php

-
message: "#^Method PhpParser\\\\NodeTraverser\\:\\:traverseArray\\(\\) has parameter \\$nodes with no value type specified in iterable type array\\.$#"
count: 1
Expand Down
4 changes: 2 additions & 2 deletions test/code/parser/scalar/constantString.test
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ array(
11: Stmt_Expression(
expr: Scalar_String(
value: !"!\!$!
!@@{ "\r" }@@!@@{ "\t" }@@!@@{ "\f" }@@!@@{ "\v" }@@!@@{ chr(27) /* "\e" */ }@@!\a
!@@{ "\r" }@@!@@{ "\t" }@@!@@{ "\f" }@@!@@{ "\v" }@@!@@{ chr(27) /* "\e" */ }@@!\a
)
)
12: Stmt_Expression(
expr: Scalar_String(
value: !@@{ chr(255) }@@!@@{ chr(255) }@@!@@{ chr(0) }@@!@@{ chr(0) }@@!
)
)
)
)
36 changes: 18 additions & 18 deletions test/code/parser/scalar/flexibleDocString.test
Original file line number Diff line number Diff line change
Expand Up @@ -155,45 +155,45 @@ array(
4: Stmt_Expression(
expr: Scalar_String(
value: a
b
b

c
c

d
e
d
e
)
)
5: Stmt_Expression(
expr: Scalar_InterpolatedString(
parts: array(
0: InterpolatedStringPart(
value: a
b
b

)
1: Expr_Variable(
name: test
)
2: InterpolatedStringPart(
value:
d
e
d
e
)
)
)
)
6: Stmt_Expression(
expr: Scalar_String(
value:
a
a

b
b

c
c

d
d

e
e

)
)
Expand All @@ -203,9 +203,9 @@ array(
0: InterpolatedStringPart(
value: a

@@{ "\t" }@@a
@@{ "\t" }@@a

b
b


)
Expand All @@ -215,9 +215,9 @@ array(
2: InterpolatedStringPart(
value:

d
d

e
e

)
)
Expand Down Expand Up @@ -321,7 +321,7 @@ array(
)
1: InterpolatedStringPart(
value:
-
-
)
)
)
Expand All @@ -334,7 +334,7 @@ array(
)
1: InterpolatedStringPart(
value:
-
-
)
)
)
Expand Down
4 changes: 2 additions & 2 deletions test/code/parser/scalar/flexibleDocStringErrors.test
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ array(
exprs: array(
0: Scalar_String(
value: a
b
c
b
c
)
)
)
Expand Down
2 changes: 1 addition & 1 deletion test/code/parser/stmt/haltCompilerOffset.test
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ array(
)
1: Stmt_HaltCompiler(
remaining:
Foo
Foo
)
)

0 comments on commit 8085116

Please sign in to comment.