Skip to content

Commit

Permalink
minor #4578 Avoid storing expression parser instances in Node attribu…
Browse files Browse the repository at this point in the history
…tes (fabpot)

This PR was merged into the 3.x branch.

Discussion
----------

Avoid storing expression parser instances in Node attributes

That avoids polluting Node instances and exposing a purely internal state.

Commits
-------

d6f539b Avoid storing expression parser instances in Node attributes
  • Loading branch information
fabpot committed Feb 14, 2025
2 parents 20e677b + d6f539b commit 2f31505
Showing 1 changed file with 7 additions and 3 deletions.
10 changes: 7 additions & 3 deletions src/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
class Parser
{
private $stack = [];
private ?\WeakMap $expressionRefs = null;
private $stream;
private $parent;
private $visitors;
Expand Down Expand Up @@ -94,6 +95,7 @@ public function parse(TokenStream $stream, $test = null, bool $dropNeedle = fals
$this->blockStack = [];
$this->importedSymbols = [[]];
$this->embeddedTemplates = [];
$this->expressionRefs = new \WeakMap();

try {
$body = $this->subparse($test, $dropNeedle);
Expand All @@ -111,6 +113,8 @@ public function parse(TokenStream $stream, $test = null, bool $dropNeedle = fals
}

throw $e;
} finally {
$this->expressionRefs = null;
}

$node = new ModuleNode(new BodyNode([$body]), $this->parent, new Nodes($this->blocks), new Nodes($this->macros), new Nodes($this->traits), $this->embeddedTemplates, $stream->getSourceContext());
Expand Down Expand Up @@ -557,7 +561,7 @@ private function filterBodyNodes(Node $node, bool $nested = false): ?Node

private function checkPrecedenceDeprecations(ExpressionParserInterface $expressionParser, AbstractExpression $expr)
{
$expr->setAttribute('expression_parser', $expressionParser);
$this->expressionRefs[$expr] = $expressionParser;
$precedenceChanges = $this->parsers->getPrecedenceChanges();

// Check that the all nodes that are between the 2 precedences have explicit parentheses
Expand All @@ -576,7 +580,7 @@ private function checkPrecedenceDeprecations(ExpressionParserInterface $expressi
if (!\in_array($expressionParser, $changes, true)) {
continue;
}
if ($node->hasAttribute('expression_parser') && $ep === $node->getAttribute('expression_parser')) {
if (isset($this->expressionRefs[$node]) && $ep === $this->expressionRefs[$node]) {
$change = $expressionParser->getPrecedenceChange();
trigger_deprecation($change->getPackage(), $change->getVersion(), \sprintf('As the "%s" %s operator will change its precedence in the next major version, add explicit parentheses to avoid behavior change in "%s" at line %d.', $expressionParser->getName(), ExpressionParserType::getType($expressionParser)->value, $this->getStream()->getSourceContext()->getName(), $node->getTemplateLine()));
}
Expand All @@ -586,7 +590,7 @@ private function checkPrecedenceDeprecations(ExpressionParserInterface $expressi
foreach ($precedenceChanges[$expressionParser] as $ep) {
foreach ($expr as $node) {
/** @var AbstractExpression $node */
if ($node->hasAttribute('expression_parser') && $ep === $node->getAttribute('expression_parser') && !$node->hasExplicitParentheses()) {
if (isset($this->expressionRefs[$node]) && $ep === $this->expressionRefs[$node] && !$node->hasExplicitParentheses()) {
$change = $ep->getPrecedenceChange();
trigger_deprecation($change->getPackage(), $change->getVersion(), \sprintf('As the "%s" %s operator will change its precedence in the next major version, add explicit parentheses to avoid behavior change in "%s" at line %d.', $ep->getName(), ExpressionParserType::getType($ep)->value, $this->getStream()->getSourceContext()->getName(), $node->getTemplateLine()));
}
Expand Down

0 comments on commit 2f31505

Please sign in to comment.