Merge branch '3.x' into 4.x

* 3.x:
  Fix typos in CHANGELOG
  Fix typo
  Fix some minor issues
  Add support for named arguments on special functions
This commit is contained in:
Fabien Potencier
2024-08-17 18:03:35 +02:00
10 changed files with 52 additions and 18 deletions
+13 -11
View File
@@ -34,6 +34,7 @@ use Twig\Node\Expression\Unary\NegUnary;
use Twig\Node\Expression\Unary\NotUnary;
use Twig\Node\Expression\Unary\PosUnary;
use Twig\Node\Node;
use Twig\Util\CallableArgumentsExtractor;
/**
* Parses expressions.
@@ -439,7 +440,6 @@ class ExpressionParser
{
switch ($name) {
case 'parent':
$this->parseArguments();
if (!\count($this->parser->getBlockStack())) {
throw new SyntaxError('Calling "parent" outside a block is forbidden.', $line, $this->parser->getStream()->getSourceContext());
}
@@ -448,21 +448,23 @@ class ExpressionParser
throw new SyntaxError('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $this->parser->getStream()->getSourceContext());
}
$this->parseArguments(true);
return new ParentExpression($this->parser->peekBlockStack(), $line);
case 'block':
$args = $this->parseArguments();
if (\count($args) < 1) {
throw new SyntaxError('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext());
}
$fakeNode = new Node(lineno: $line);
$fakeNode->setSourceContext($this->parser->getStream()->getSourceContext());
$fakeFunction = new TwigFunction('block', fn ($name, $template = null) => null);
$args = (new CallableArgumentsExtractor($fakeNode, $fakeFunction))->extractArguments($this->parseArguments(true));
return new BlockReferenceExpression($args->getNode('0'), \count($args) > 1 ? $args->getNode('1') : null, $line);
return new BlockReferenceExpression($args[0], $args[1] ?? null, $line);
case 'attribute':
$args = $this->parseArguments();
if (\count($args) < 2) {
throw new SyntaxError('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext());
}
$fakeNode = new Node(lineno: $line);
$fakeNode->setSourceContext($this->parser->getStream()->getSourceContext());
$fakeFunction = new TwigFunction('attribute', fn ($variable, $attribute, $arguments = null) => null);
$args = (new CallableArgumentsExtractor($fakeNode, $fakeFunction))->extractArguments($this->parseArguments(true));
return new GetAttrExpression($args->getNode('0'), $args->getNode('1'), \count($args) > 2 ? $args->getNode('2') : null, Template::ANY_CALL, $line);
return new GetAttrExpression($args[0], $args[1], $args[2] ?? null, Template::ANY_CALL, $line);
case 'loop':
$args = $this->parseArguments();
if (\count($args) < 1) {