mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-13 02:46:29 +00:00
Fix unary operator precedence change
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
# 3.18.0 (2024-XX-XX)
|
# 3.18.0 (2024-XX-XX)
|
||||||
|
|
||||||
|
* Fix unary operator precedence change
|
||||||
* Ignore `SyntaxError` exceptions from undefined handlers when using the `guard` tag
|
* Ignore `SyntaxError` exceptions from undefined handlers when using the `guard` tag
|
||||||
* Add a way to stream template rendering (`TemplateWrapper::stream()` and `TemplateWrapper::streamBlock()` )
|
* Add a way to stream template rendering (`TemplateWrapper::stream()` and `TemplateWrapper::streamBlock()`)
|
||||||
|
|
||||||
# 3.17.1 (2024-12-12)
|
# 3.17.1 (2024-12-12)
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,6 @@ class ExpressionParser
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$target = explode('_', $unaryOp)[1];
|
$target = explode('_', $unaryOp)[1];
|
||||||
$change = $this->unaryOperators[$target]['precedence_change'];
|
|
||||||
/** @var AbstractExpression $node */
|
/** @var AbstractExpression $node */
|
||||||
$node = $expr->getNode('node');
|
$node = $expr->getNode('node');
|
||||||
foreach ($this->precedenceChanges as $operatorName => $changes) {
|
foreach ($this->precedenceChanges as $operatorName => $changes) {
|
||||||
@@ -157,6 +156,7 @@ class ExpressionParser
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ($node->hasAttribute('operator') && $operatorName === $node->getAttribute('operator')) {
|
if ($node->hasAttribute('operator') && $operatorName === $node->getAttribute('operator')) {
|
||||||
|
$change = $this->unaryOperators[$target]['precedence_change'];
|
||||||
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()));
|
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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ namespace Twig\Tests;
|
|||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
|
||||||
use Twig\Attribute\FirstClassTwigCallableReady;
|
use Twig\Attribute\FirstClassTwigCallableReady;
|
||||||
|
use Twig\Compiler;
|
||||||
use Twig\Environment;
|
use Twig\Environment;
|
||||||
use Twig\Error\SyntaxError;
|
use Twig\Error\SyntaxError;
|
||||||
use Twig\Extension\AbstractExtension;
|
use Twig\Extension\AbstractExtension;
|
||||||
@@ -24,6 +25,7 @@ use Twig\Node\Expression\ConstantExpression;
|
|||||||
use Twig\Node\Expression\FilterExpression;
|
use Twig\Node\Expression\FilterExpression;
|
||||||
use Twig\Node\Expression\FunctionExpression;
|
use Twig\Node\Expression\FunctionExpression;
|
||||||
use Twig\Node\Expression\TestExpression;
|
use Twig\Node\Expression\TestExpression;
|
||||||
|
use Twig\Node\Expression\Unary\AbstractUnary;
|
||||||
use Twig\Node\Expression\Variable\ContextVariable;
|
use Twig\Node\Expression\Variable\ContextVariable;
|
||||||
use Twig\Node\Node;
|
use Twig\Node\Node;
|
||||||
use Twig\Parser;
|
use Twig\Parser;
|
||||||
@@ -564,6 +566,28 @@ class ExpressionParserTest extends TestCase
|
|||||||
$this->expectNotToPerformAssertions();
|
$this->expectNotToPerformAssertions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testUnaryPrecedenceChange()
|
||||||
|
{
|
||||||
|
$env = new Environment(new ArrayLoader(), ['cache' => false, 'autoescape' => false]);
|
||||||
|
$env->addExtension(new class () extends AbstractExtension {
|
||||||
|
public function getOperators()
|
||||||
|
{
|
||||||
|
$class = new class (new ConstantExpression('foo', 1), 1) extends AbstractUnary {
|
||||||
|
public function operator(Compiler $compiler): Compiler
|
||||||
|
{
|
||||||
|
return $compiler->raw('!');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return [['!' => ['precedence' => 50, 'class' => $class::class]], []];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$parser = new Parser($env);
|
||||||
|
|
||||||
|
$parser->parse($env->tokenize(new Source('{{ !false ? "OK" : "KO" }}', 'index')));
|
||||||
|
$this->expectNotToPerformAssertions();
|
||||||
|
}
|
||||||
|
|
||||||
private static function createContextVariable(string $name, array $attributes): ContextVariable
|
private static function createContextVariable(string $name, array $attributes): ContextVariable
|
||||||
{
|
{
|
||||||
$expression = new ContextVariable($name, 1);
|
$expression = new ContextVariable($name, 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user