mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-01 21:17:21 +00:00
Add support for argument unpacking
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
# 3.15.0 (2024-XX-XX)
|
# 3.15.0 (2024-XX-XX)
|
||||||
|
|
||||||
|
* Add support for argument unpackaging
|
||||||
* Add JSON support for the file extension escaping strategy
|
* Add JSON support for the file extension escaping strategy
|
||||||
* Support Markup instances (and any other \Stringable) as dynamic mapping keys
|
* Support Markup instances (and any other \Stringable) as dynamic mapping keys
|
||||||
* Deprecate the `sandbox` tag
|
* Deprecate the `sandbox` tag
|
||||||
|
|||||||
+9
-2
@@ -815,14 +815,21 @@ The following operators don't fit into any of the other categories:
|
|||||||
{# returns the value of foo if it is defined and not null, 'no' otherwise #}
|
{# returns the value of foo if it is defined and not null, 'no' otherwise #}
|
||||||
{{ foo ?? 'no' }}
|
{{ foo ?? 'no' }}
|
||||||
|
|
||||||
* ``...``: The spread operator can be used to expand sequences or mappings (it
|
* ``...``: The spread operator can be used to expand sequences or mappings or
|
||||||
cannot be used to expand the arguments of a function call):
|
to expand the arguments of a function call:
|
||||||
|
|
||||||
.. code-block:: twig
|
.. code-block:: twig
|
||||||
|
|
||||||
{% set numbers = [1, 2, ...moreNumbers] %}
|
{% set numbers = [1, 2, ...moreNumbers] %}
|
||||||
{% set ratings = {'foo': 10, 'bar': 5, ...moreRatings} %}
|
{% set ratings = {'foo': 10, 'bar': 5, ...moreRatings} %}
|
||||||
|
|
||||||
|
{{ 'Hello %s %s!'|format(...['Fabien', 'Potencier']) }}
|
||||||
|
|
||||||
|
.. versionadded:: 3.15
|
||||||
|
|
||||||
|
Support for expanding the arguments of a function call was introduced in
|
||||||
|
Twig 3.15.
|
||||||
|
|
||||||
Operators
|
Operators
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ use Twig\Node\Expression\Unary\AbstractUnary;
|
|||||||
use Twig\Node\Expression\Unary\NegUnary;
|
use Twig\Node\Expression\Unary\NegUnary;
|
||||||
use Twig\Node\Expression\Unary\NotUnary;
|
use Twig\Node\Expression\Unary\NotUnary;
|
||||||
use Twig\Node\Expression\Unary\PosUnary;
|
use Twig\Node\Expression\Unary\PosUnary;
|
||||||
|
use Twig\Node\Expression\Unary\SpreadUnary;
|
||||||
use Twig\Node\Node;
|
use Twig\Node\Node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -618,6 +619,7 @@ class ExpressionParser
|
|||||||
$stream = $this->parser->getStream();
|
$stream = $this->parser->getStream();
|
||||||
|
|
||||||
$stream->expect(Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
|
$stream->expect(Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis');
|
||||||
|
$hasSpread = false;
|
||||||
while (!$stream->test(Token::PUNCTUATION_TYPE, ')')) {
|
while (!$stream->test(Token::PUNCTUATION_TYPE, ')')) {
|
||||||
if ($args) {
|
if ($args) {
|
||||||
$stream->expect(Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
|
$stream->expect(Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma');
|
||||||
@@ -632,7 +634,14 @@ class ExpressionParser
|
|||||||
$token = $stream->expect(Token::NAME_TYPE, null, 'An argument must be a name');
|
$token = $stream->expect(Token::NAME_TYPE, null, 'An argument must be a name');
|
||||||
$value = new NameExpression($token->getValue(), $this->parser->getCurrentToken()->getLine());
|
$value = new NameExpression($token->getValue(), $this->parser->getCurrentToken()->getLine());
|
||||||
} else {
|
} else {
|
||||||
$value = $this->parseExpression(0, $allowArrow);
|
if ($stream->nextIf(Token::SPREAD_TYPE)) {
|
||||||
|
$hasSpread = true;
|
||||||
|
$value = new SpreadUnary($this->parseExpression(0, $allowArrow), $stream->getCurrent()->getLine());
|
||||||
|
} elseif ($hasSpread) {
|
||||||
|
throw new SyntaxError('Normal arguments must be placed before argument unpacking.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
|
||||||
|
} else {
|
||||||
|
$value = $this->parseExpression(0, $allowArrow);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$name = null;
|
$name = null;
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of Twig.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Twig\Node\Expression\Unary;
|
||||||
|
|
||||||
|
use Twig\Compiler;
|
||||||
|
|
||||||
|
final class SpreadUnary extends AbstractUnary
|
||||||
|
{
|
||||||
|
public function operator(Compiler $compiler): Compiler
|
||||||
|
{
|
||||||
|
return $compiler->raw('...');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
--TEST--
|
||||||
|
Twig supports array unpacking for function calls
|
||||||
|
--TEMPLATE--
|
||||||
|
{{ '%s %s %s'|format(...[1, 2, 3]) }}
|
||||||
|
{{ '%s %s %s'|format(...[1], ...[2, 3]) }}
|
||||||
|
{{ '%s %s %s'|format(1, ...[2, 3]) }}
|
||||||
|
{{ '%s %s %s'|format(1, ...[2], ...[3]) }}
|
||||||
|
{{ '%s %s %s'|format(...it) }}
|
||||||
|
--DATA--
|
||||||
|
return ['it' => new \ArrayIterator([1, 2, 3])]
|
||||||
|
--EXPECT--
|
||||||
|
1 2 3
|
||||||
|
1 2 3
|
||||||
|
1 2 3
|
||||||
|
1 2 3
|
||||||
|
1 2 3
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
--TEST--
|
||||||
|
Twig supports array unpacking for function calls (but not before normal args)
|
||||||
|
--TEMPLATE--
|
||||||
|
{{ '%s %s %s'|format(...[1, 2], 3) }}
|
||||||
|
--DATA--
|
||||||
|
return []
|
||||||
|
--EXCEPTION--
|
||||||
|
Twig\Error\SyntaxError: Normal arguments must be placed before argument unpacking in "index.twig" at line 2.
|
||||||
Reference in New Issue
Block a user