mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-31 04:27:00 +00:00
Fix deprecation dep feature
This commit is contained in:
+33
-13
@@ -56,6 +56,7 @@ class ExpressionParser
|
||||
private $binaryOperators;
|
||||
private $readyNodes = [];
|
||||
private array $precedenceChanges = [];
|
||||
private bool $deprecationCheck = true;
|
||||
|
||||
public function __construct(
|
||||
private Parser $parser,
|
||||
@@ -86,14 +87,14 @@ class ExpressionParser
|
||||
}
|
||||
}
|
||||
|
||||
public function parseExpression($precedence = 0, $allowArrow = false, bool $deprecationCheck = true)
|
||||
public function parseExpression($precedence = 0, $allowArrow = false)
|
||||
{
|
||||
if ($allowArrow && $arrow = $this->parseArrow()) {
|
||||
return $arrow;
|
||||
}
|
||||
|
||||
$expr = $this->getPrimary();
|
||||
$previousToken = $token = $this->parser->getCurrentToken();
|
||||
$token = $this->parser->getCurrentToken();
|
||||
while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) {
|
||||
$op = $this->binaryOperators[$token->getValue()];
|
||||
$this->parser->getStream()->next();
|
||||
@@ -105,19 +106,21 @@ class ExpressionParser
|
||||
} elseif (isset($op['callable'])) {
|
||||
$expr = $op['callable']($this->parser, $expr);
|
||||
} else {
|
||||
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence'], true);
|
||||
$previous = $this->setDeprecationCheck(true);
|
||||
try {
|
||||
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence'], true);
|
||||
} finally {
|
||||
$this->setDeprecationCheck($previous);
|
||||
}
|
||||
$class = $op['class'];
|
||||
$expr = new $class($expr, $expr1, $token->getLine());
|
||||
}
|
||||
|
||||
$expr->setAttribute('operator', 'binary_'.$token->getValue());
|
||||
|
||||
$previousToken = $token;
|
||||
$token = $this->parser->getCurrentToken();
|
||||
}
|
||||
$this->triggerPrecedenceDeprecations($expr, $token);
|
||||
|
||||
if ($deprecationCheck) {
|
||||
$this->triggerPrecedenceDeprecations($expr, $previousToken);
|
||||
$token = $this->parser->getCurrentToken();
|
||||
}
|
||||
|
||||
if (0 === $precedence) {
|
||||
@@ -147,7 +150,7 @@ class ExpressionParser
|
||||
continue;
|
||||
}
|
||||
if ($node->hasAttribute('operator') && $operatorName === $node->getAttribute('operator')) {
|
||||
trigger_deprecation($change->getPackage(), $change->getVersion(), \sprintf('Add explicit parentheses around the "%s" unary operator to avoid behavior change in the next major version as its precedence will change in "%s" at line %d.', $target, $this->parser->getStream()->getSourceContext()->getName(), $token->getLine()));
|
||||
trigger_deprecation($change->getPackage(), $change->getVersion(), \sprintf('Add explicit parentheses around the "%s" unary operator to avoid behavior change in the next major version as its precedence will change in "%s" at line %d.', $target, $this->parser->getStream()->getSourceContext()->getName(), $node->getTemplateLine()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -157,7 +160,7 @@ class ExpressionParser
|
||||
if ($node->hasAttribute('operator') && $operatorName === $node->getAttribute('operator') && !$node->hasExplicitParentheses()) {
|
||||
$op = explode('_', $operatorName)[1];
|
||||
$change = $this->binaryOperators[$op]['precedence_change'];
|
||||
trigger_deprecation($change->getPackage(), $change->getVersion(), \sprintf('Add explicit parentheses around the "%s" binary operator to avoid behavior change in the next major version as its precedence will change in "%s" at line %d.', $op, $this->parser->getStream()->getSourceContext()->getName(), $token->getLine()));
|
||||
trigger_deprecation($change->getPackage(), $change->getVersion(), \sprintf('Add explicit parentheses around the "%s" binary operator to avoid behavior change in the next major version as its precedence will change in "%s" at line %d.', $op, $this->parser->getStream()->getSourceContext()->getName(), $node->getTemplateLine()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -178,7 +181,7 @@ class ExpressionParser
|
||||
$names = [new AssignNameExpression($token->getValue(), $token->getLine())];
|
||||
$stream->expect(Token::ARROW_TYPE);
|
||||
|
||||
return new ArrowFunctionExpression($this->parseExpression(0), new Nodes($names), $line);
|
||||
return new ArrowFunctionExpression($this->parseExpression(), new Nodes($names), $line);
|
||||
}
|
||||
|
||||
// first, determine if we are parsing an arrow function by finding => (long form)
|
||||
@@ -219,7 +222,7 @@ class ExpressionParser
|
||||
$stream->expect(Token::PUNCTUATION_TYPE, ')');
|
||||
$stream->expect(Token::ARROW_TYPE);
|
||||
|
||||
return new ArrowFunctionExpression($this->parseExpression(0), new Nodes($names), $line);
|
||||
return new ArrowFunctionExpression($this->parseExpression(), new Nodes($names), $line);
|
||||
}
|
||||
|
||||
private function getPrimary(): AbstractExpression
|
||||
@@ -235,10 +238,19 @@ class ExpressionParser
|
||||
$expr = new $class($expr, $token->getLine());
|
||||
$expr->setAttribute('operator', 'unary_'.$token->getValue());
|
||||
|
||||
if ($this->deprecationCheck) {
|
||||
$this->triggerPrecedenceDeprecations($expr, $token);
|
||||
}
|
||||
|
||||
return $this->parsePostfixExpression($expr);
|
||||
} elseif ($token->test(Token::PUNCTUATION_TYPE, '(')) {
|
||||
$this->parser->getStream()->next();
|
||||
$expr = $this->parseExpression(deprecationCheck: false)->setExplicitParentheses();
|
||||
$previous = $this->setDeprecationCheck(false);
|
||||
try {
|
||||
$expr = $this->parseExpression()->setExplicitParentheses();
|
||||
} finally {
|
||||
$this->setDeprecationCheck($previous);
|
||||
}
|
||||
$this->parser->getStream()->expect(Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
|
||||
|
||||
return $this->parsePostfixExpression($expr);
|
||||
@@ -921,4 +933,12 @@ class ExpressionParser
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private function setDeprecationCheck(bool $deprecationCheck): bool
|
||||
{
|
||||
$current = $this->deprecationCheck;
|
||||
$this->deprecationCheck = $deprecationCheck;
|
||||
|
||||
return $current;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,40 @@ Twig supports the ?? operator
|
||||
--DEPRECATION--
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "??" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 4.
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "??" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 5.
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "??" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 6.
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "??" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 7.
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "??" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 10.
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "~" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 9.
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "~" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 11.
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "??" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 16.
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "~" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 15.
|
||||
Since twig/twig 3.15: Add explicit parentheses around the "~" binary operator to avoid behavior change in the next major version as its precedence will change in "index.twig" at line 17.
|
||||
--TEMPLATE--
|
||||
{{ nope ?? nada ?? 'OK' -}} {# no deprecation as the operators have the same precedence #}
|
||||
|
||||
{{ 1 + nope ?? nada ?? 2 }}
|
||||
{{ 1 + nope ?? 3 + nada ?? 2 }}
|
||||
{{ 1 + nope ??
|
||||
3 + nada ?? 2 }}
|
||||
{{ 1 ~ 'notnull' ?? 'foo' ~ '_bar' }}
|
||||
{{
|
||||
1 ~ 2 + 3
|
||||
??
|
||||
1 ~
|
||||
2 + 4
|
||||
}}
|
||||
{{ (
|
||||
1 ~ 2 + 3
|
||||
??
|
||||
1 ~
|
||||
2 + 4
|
||||
)
|
||||
}}
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
OK
|
||||
3
|
||||
6
|
||||
1notnull_bar
|
||||
48
|
||||
48
|
||||
|
||||
Reference in New Issue
Block a user