From 127bffb6c9a14d1bd7126777f3ee14f3b3600e37 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 1 Feb 2025 18:50:23 +0100 Subject: [PATCH] Pass the current token instead of just the line of the token on Operator::parse() --- src/ExpressionParser.php | 10 +++++----- src/Operator/Binary/AbstractBinaryOperator.php | 7 +++---- src/Operator/Binary/ArrowBinaryOperator.php | 5 +++-- src/Operator/Binary/BinaryOperatorInterface.php | 3 ++- src/Operator/Binary/DotBinaryOperator.php | 2 +- src/Operator/Binary/FilterBinaryOperator.php | 7 ++++--- src/Operator/Binary/FunctionBinaryOperator.php | 4 +++- src/Operator/Binary/IsBinaryOperator.php | 4 ++-- src/Operator/Binary/IsNotBinaryOperator.php | 5 +++-- src/Operator/Binary/SquareBracketBinaryOperator.php | 3 +-- src/Operator/Ternary/ConditionalTernaryOperator.php | 6 +++--- src/Operator/Ternary/TernaryOperatorInterface.php | 3 ++- src/Operator/Unary/AbstractUnaryOperator.php | 7 +++---- src/Operator/Unary/ParenthesisUnaryOperator.php | 6 +++--- src/Operator/Unary/UnaryOperatorInterface.php | 3 ++- src/TokenParser/ApplyTokenParser.php | 2 +- 16 files changed, 41 insertions(+), 36 deletions(-) diff --git a/src/ExpressionParser.php b/src/ExpressionParser.php index 182f020eb2..4ea78681d0 100644 --- a/src/ExpressionParser.php +++ b/src/ExpressionParser.php @@ -101,7 +101,7 @@ public function parseExpression($precedence = 0) $this->parser->getStream()->next(); $previous = $this->setDeprecationCheck(true); try { - $expr = $op->parse($this, $expr, $token->getLine()); + $expr = $op->parse($this, $expr, $token); } finally { $this->setDeprecationCheck($previous); } @@ -160,7 +160,7 @@ public function parsePrimary(): AbstractExpression $this->parser->getStream()->next(); $previous = $this->setDeprecationCheck(false); try { - $expr = $operator->parse($this, $token->getLine()); + $expr = $operator->parse($this, $token); } finally { $this->setDeprecationCheck($previous); } @@ -415,10 +415,10 @@ public function parseSubscriptExpression($node) trigger_deprecation('twig/twig', '3.20', 'The "%s()" method is deprecated.', __METHOD__); if ('.' === $this->parser->getStream()->next()->getValue()) { - return $this->operators->getBinary('.')->parse($this, $node, $this->parser->getCurrentToken()->getLine()); + return $this->operators->getBinary('.')->parse($this, $node, $this->parser->getCurrentToken()); } - return $this->operators->getBinary('[')->parse($this, $node, $this->parser->getCurrentToken()->getLine()); + return $this->operators->getBinary('[')->parse($this, $node, $this->parser->getCurrentToken()); } /** @@ -442,7 +442,7 @@ public function parseFilterExpressionRaw($node) $op = $this->operators->getBinary('|'); while (true) { - $node = $op->parse($this, $node, $this->parser->getCurrentToken()->getLine()); + $node = $op->parse($this, $node, $this->parser->getCurrentToken()); if (!$this->parser->getStream()->test(Token::OPERATOR_TYPE, '|')) { break; } diff --git a/src/Operator/Binary/AbstractBinaryOperator.php b/src/Operator/Binary/AbstractBinaryOperator.php index e61d136888..64fc903399 100644 --- a/src/Operator/Binary/AbstractBinaryOperator.php +++ b/src/Operator/Binary/AbstractBinaryOperator.php @@ -16,16 +16,15 @@ use Twig\Operator\AbstractOperator; use Twig\Operator\OperatorArity; use Twig\Operator\OperatorAssociativity; +use Twig\Token; abstract class AbstractBinaryOperator extends AbstractOperator implements BinaryOperatorInterface { - public function parse(ExpressionParser $parser, AbstractExpression $left, int $line): AbstractExpression + public function parse(ExpressionParser $parser, AbstractExpression $left, Token $token): AbstractExpression { - $class = $this->getNodeClass(); - $right = $parser->parseExpression(OperatorAssociativity::Left === $this->getAssociativity() ? $this->getPrecedence() + 1 : $this->getPrecedence()); - return new $class($left, $right, $line); + return new ($this->getNodeClass())($left, $right, $token->getLine()); } public function getArity(): OperatorArity diff --git a/src/Operator/Binary/ArrowBinaryOperator.php b/src/Operator/Binary/ArrowBinaryOperator.php index 8ce33e0a71..253b00fc78 100644 --- a/src/Operator/Binary/ArrowBinaryOperator.php +++ b/src/Operator/Binary/ArrowBinaryOperator.php @@ -17,13 +17,14 @@ use Twig\Operator\AbstractOperator; use Twig\Operator\OperatorArity; use Twig\Operator\OperatorAssociativity; +use Twig\Token; class ArrowBinaryOperator extends AbstractOperator implements BinaryOperatorInterface { - public function parse(ExpressionParser $parser, AbstractExpression $expr, int $line): AbstractExpression + public function parse(ExpressionParser $parser, AbstractExpression $expr, Token $token): AbstractExpression { // As the expression of the arrow function is independent from the current precedence, we want a precedence of 0 - return new ArrowFunctionExpression($parser->parseExpression(), $expr, $line); + return new ArrowFunctionExpression($parser->parseExpression(), $expr, $token->getLine()); } public function getOperator(): string diff --git a/src/Operator/Binary/BinaryOperatorInterface.php b/src/Operator/Binary/BinaryOperatorInterface.php index c401272aff..5ff2c4b9a7 100644 --- a/src/Operator/Binary/BinaryOperatorInterface.php +++ b/src/Operator/Binary/BinaryOperatorInterface.php @@ -15,10 +15,11 @@ use Twig\Node\Expression\AbstractExpression; use Twig\Operator\OperatorAssociativity; use Twig\Operator\OperatorInterface; +use Twig\Token; interface BinaryOperatorInterface extends OperatorInterface { - public function parse(ExpressionParser $parser, AbstractExpression $left, int $line): AbstractExpression; + public function parse(ExpressionParser $parser, AbstractExpression $left, Token $token): AbstractExpression; public function getAssociativity(): OperatorAssociativity; } diff --git a/src/Operator/Binary/DotBinaryOperator.php b/src/Operator/Binary/DotBinaryOperator.php index 1c02f807dc..2aecf0b10c 100644 --- a/src/Operator/Binary/DotBinaryOperator.php +++ b/src/Operator/Binary/DotBinaryOperator.php @@ -29,7 +29,7 @@ class DotBinaryOperator extends AbstractOperator implements BinaryOperatorInterface { - public function parse(ExpressionParser $parser, AbstractExpression $expr, int $line): AbstractExpression + public function parse(ExpressionParser $parser, AbstractExpression $expr, Token $token): AbstractExpression { $stream = $parser->getStream(); $token = $stream->getCurrent(); diff --git a/src/Operator/Binary/FilterBinaryOperator.php b/src/Operator/Binary/FilterBinaryOperator.php index 1402963dc8..9dc6333898 100644 --- a/src/Operator/Binary/FilterBinaryOperator.php +++ b/src/Operator/Binary/FilterBinaryOperator.php @@ -25,10 +25,11 @@ class FilterBinaryOperator extends AbstractOperator implements BinaryOperatorInt { private $readyNodes = []; - public function parse(ExpressionParser $parser, AbstractExpression $expr, int $line): AbstractExpression + public function parse(ExpressionParser $parser, AbstractExpression $expr, Token $token): AbstractExpression { $stream = $parser->getStream(); $token = $stream->expect(Token::NAME_TYPE); + $line = $token->getLine(); if (!$stream->test(Token::OPERATOR_TYPE, '(')) { $arguments = new EmptyNode(); @@ -36,7 +37,7 @@ public function parse(ExpressionParser $parser, AbstractExpression $expr, int $l $arguments = $parser->parseNamedArguments(); } - $filter = $parser->getFilter($token->getValue(), $token->getLine()); + $filter = $parser->getFilter($token->getValue(), $line); $ready = true; if (!isset($this->readyNodes[$class = $filter->getNodeClass()])) { @@ -47,7 +48,7 @@ public function parse(ExpressionParser $parser, AbstractExpression $expr, int $l trigger_deprecation('twig/twig', '3.12', 'Twig node "%s" is not marked as ready for passing a "TwigFilter" in the constructor instead of its name; please update your code and then add #[FirstClassTwigCallableReady] attribute to the constructor.', $class); } - return new $class($expr, $ready ? $filter : new ConstantExpression($filter->getName(), $token->getLine()), $arguments, $token->getLine()); + return new $class($expr, $ready ? $filter : new ConstantExpression($filter->getName(), $line), $arguments, $line); } public function getOperator(): string diff --git a/src/Operator/Binary/FunctionBinaryOperator.php b/src/Operator/Binary/FunctionBinaryOperator.php index 58dd13d33d..740c1ce594 100644 --- a/src/Operator/Binary/FunctionBinaryOperator.php +++ b/src/Operator/Binary/FunctionBinaryOperator.php @@ -21,13 +21,15 @@ use Twig\Operator\AbstractOperator; use Twig\Operator\OperatorArity; use Twig\Operator\OperatorAssociativity; +use Twig\Token; class FunctionBinaryOperator extends AbstractOperator implements BinaryOperatorInterface { private $readyNodes = []; - public function parse(ExpressionParser $parser, AbstractExpression $expr, int $line): AbstractExpression + public function parse(ExpressionParser $parser, AbstractExpression $expr, Token $token): AbstractExpression { + $line = $token->getLine(); if (!$expr instanceof NameExpression) { throw new SyntaxError('Function name must be an identifier.', $line, $parser->getStream()->getSourceContext()); } diff --git a/src/Operator/Binary/IsBinaryOperator.php b/src/Operator/Binary/IsBinaryOperator.php index 0fca6d6c7a..4236b769a4 100644 --- a/src/Operator/Binary/IsBinaryOperator.php +++ b/src/Operator/Binary/IsBinaryOperator.php @@ -28,10 +28,10 @@ class IsBinaryOperator extends AbstractOperator implements BinaryOperatorInterfa { private $readyNodes = []; - public function parse(ExpressionParser $parser, AbstractExpression $expr, int $line): AbstractExpression + public function parse(ExpressionParser $parser, AbstractExpression $expr, Token $token): AbstractExpression { $stream = $parser->getStream(); - $test = $parser->getTest($line); + $test = $parser->getTest($token->getLine()); $arguments = null; if ($stream->test(Token::OPERATOR_TYPE, '(')) { diff --git a/src/Operator/Binary/IsNotBinaryOperator.php b/src/Operator/Binary/IsNotBinaryOperator.php index 80bba50618..2455f73871 100644 --- a/src/Operator/Binary/IsNotBinaryOperator.php +++ b/src/Operator/Binary/IsNotBinaryOperator.php @@ -14,12 +14,13 @@ use Twig\ExpressionParser; use Twig\Node\Expression\AbstractExpression; use Twig\Node\Expression\Unary\NotUnary; +use Twig\Token; class IsNotBinaryOperator extends IsBinaryOperator { - public function parse(ExpressionParser $parser, AbstractExpression $expr, int $line): AbstractExpression + public function parse(ExpressionParser $parser, AbstractExpression $expr, Token $token): AbstractExpression { - return new NotUnary(parent::parse($parser, $expr, $line), $line); + return new NotUnary(parent::parse($parser, $expr, $token), $token->getLine()); } public function getOperator(): string diff --git a/src/Operator/Binary/SquareBracketBinaryOperator.php b/src/Operator/Binary/SquareBracketBinaryOperator.php index b4313cfa32..c2e8b50065 100644 --- a/src/Operator/Binary/SquareBracketBinaryOperator.php +++ b/src/Operator/Binary/SquareBracketBinaryOperator.php @@ -25,10 +25,9 @@ class SquareBracketBinaryOperator extends AbstractOperator implements BinaryOperatorInterface { - public function parse(ExpressionParser $parser, AbstractExpression $expr, int $line): AbstractExpression + public function parse(ExpressionParser $parser, AbstractExpression $expr, Token $token): AbstractExpression { $stream = $parser->getStream(); - $token = $stream->getCurrent(); $lineno = $token->getLine(); $arguments = new ArrayExpression([], $lineno); diff --git a/src/Operator/Ternary/ConditionalTernaryOperator.php b/src/Operator/Ternary/ConditionalTernaryOperator.php index 606a349e0f..7c20963db5 100644 --- a/src/Operator/Ternary/ConditionalTernaryOperator.php +++ b/src/Operator/Ternary/ConditionalTernaryOperator.php @@ -19,7 +19,7 @@ class ConditionalTernaryOperator extends AbstractTernaryOperator { - public function parse(ExpressionParser $parser, AbstractExpression $left, int $line): AbstractExpression + public function parse(ExpressionParser $parser, AbstractExpression $left, Token $token): AbstractExpression { $then = $parser->parseExpression($this->getPrecedence()); if ($parser->getStream()->nextIf(Token::PUNCTUATION_TYPE, $this->getElseOperator())) { @@ -27,10 +27,10 @@ public function parse(ExpressionParser $parser, AbstractExpression $left, int $l $else = $parser->parseExpression($this->getPrecedence()); } else { // Ternary without else (expr ? expr2) - $else = new ConstantExpression('', $line); + $else = new ConstantExpression('', $token->getLine()); } - return new ConditionalTernary($left, $then, $else, $line); + return new ConditionalTernary($left, $then, $else, $token->getLine()); } public function getOperator(): string diff --git a/src/Operator/Ternary/TernaryOperatorInterface.php b/src/Operator/Ternary/TernaryOperatorInterface.php index e98c08cce0..86628203e0 100644 --- a/src/Operator/Ternary/TernaryOperatorInterface.php +++ b/src/Operator/Ternary/TernaryOperatorInterface.php @@ -15,10 +15,11 @@ use Twig\Node\Expression\AbstractExpression; use Twig\Operator\OperatorAssociativity; use Twig\Operator\OperatorInterface; +use Twig\Token; interface TernaryOperatorInterface extends OperatorInterface { - public function parse(ExpressionParser $parser, AbstractExpression $left, int $line): AbstractExpression; + public function parse(ExpressionParser $parser, AbstractExpression $left, Token $token): AbstractExpression; public function getAssociativity(): OperatorAssociativity; } diff --git a/src/Operator/Unary/AbstractUnaryOperator.php b/src/Operator/Unary/AbstractUnaryOperator.php index 6a58c060b1..d8b7210f80 100644 --- a/src/Operator/Unary/AbstractUnaryOperator.php +++ b/src/Operator/Unary/AbstractUnaryOperator.php @@ -15,14 +15,13 @@ use Twig\Node\Expression\AbstractExpression; use Twig\Operator\AbstractOperator; use Twig\Operator\OperatorArity; +use Twig\Token; abstract class AbstractUnaryOperator extends AbstractOperator implements UnaryOperatorInterface { - public function parse(ExpressionParser $parser, int $line): AbstractExpression + public function parse(ExpressionParser $parser, Token $token): AbstractExpression { - $class = $this->getNodeClass(); - - return new $class($parser->parseExpression($this->getPrecedence()), $line); + return new ($this->getNodeClass())($parser->parseExpression($this->getPrecedence()), $token->getLine()); } public function getArity(): OperatorArity diff --git a/src/Operator/Unary/ParenthesisUnaryOperator.php b/src/Operator/Unary/ParenthesisUnaryOperator.php index 0e236676fc..8191cb8204 100644 --- a/src/Operator/Unary/ParenthesisUnaryOperator.php +++ b/src/Operator/Unary/ParenthesisUnaryOperator.php @@ -22,7 +22,7 @@ class ParenthesisUnaryOperator extends AbstractOperator implements UnaryOperatorInterface { - public function parse(ExpressionParser $parser, int $line): AbstractExpression + public function parse(ExpressionParser $parser, Token $token): AbstractExpression { $stream = $parser->getStream(); $expr = $parser->parseExpression($this->getPrecedence()); @@ -32,7 +32,7 @@ public function parse(ExpressionParser $parser, int $line): AbstractExpression return $expr->setExplicitParentheses(); } - return new ListExpression([$expr], $line); + return new ListExpression([$expr], $token->getLine()); } // determine if we are parsing an arrow function arguments @@ -54,7 +54,7 @@ public function parse(ExpressionParser $parser, int $line): AbstractExpression throw new SyntaxError('A list of variables must be followed by an arrow.', $stream->getCurrent()->getLine(), $stream->getSourceContext()); } - return new ListExpression($names, $line); + return new ListExpression($names, $token->getLine()); } public function getOperator(): string diff --git a/src/Operator/Unary/UnaryOperatorInterface.php b/src/Operator/Unary/UnaryOperatorInterface.php index f609407515..71c599acf6 100644 --- a/src/Operator/Unary/UnaryOperatorInterface.php +++ b/src/Operator/Unary/UnaryOperatorInterface.php @@ -14,8 +14,9 @@ use Twig\ExpressionParser; use Twig\Node\Expression\AbstractExpression; use Twig\Operator\OperatorInterface; +use Twig\Token; interface UnaryOperatorInterface extends OperatorInterface { - public function parse(ExpressionParser $parser, int $line): AbstractExpression; + public function parse(ExpressionParser $parser, Token $token): AbstractExpression; } diff --git a/src/TokenParser/ApplyTokenParser.php b/src/TokenParser/ApplyTokenParser.php index af897df763..68ef7c17e6 100644 --- a/src/TokenParser/ApplyTokenParser.php +++ b/src/TokenParser/ApplyTokenParser.php @@ -36,7 +36,7 @@ public function parse(Token $token): Node $filter = $ref; $op = $this->parser->getEnvironment()->getOperators()->getBinary('|'); while (true) { - $filter = $op->parse($this->parser->getExpressionParser(), $filter, $this->parser->getCurrentToken()->getLine()); + $filter = $op->parse($this->parser->getExpressionParser(), $filter, $this->parser->getCurrentToken()); if (!$this->parser->getStream()->test(Token::OPERATOR_TYPE, '|')) { break; }