Update Twig to v2.15.4

This commit is contained in:
slawkens
2023-02-02 10:37:45 +01:00
parent e552bcfe82
commit 130f7ba405
309 changed files with 3802 additions and 4005 deletions

View File

@@ -22,7 +22,7 @@ use Twig\Token;
*
* {% apply upper %}
* This text becomes uppercase
* {% endapplys %}
* {% endapply %}
*/
final class ApplyTokenParser extends AbstractTokenParser
{

View File

@@ -18,58 +18,27 @@ use Twig\Token;
/**
* Marks a section of a template to be escaped or not.
*
* {% autoescape true %}
* Everything will be automatically escaped in this block
* {% endautoescape %}
*
* {% autoescape false %}
* Everything will be outputed as is in this block
* {% endautoescape %}
*
* {% autoescape true js %}
* Everything will be automatically escaped in this block
* using the js escaping strategy
* {% endautoescape %}
*
* @final
*/
class AutoEscapeTokenParser extends AbstractTokenParser
final class AutoEscapeTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
if ($stream->test(Token::BLOCK_END_TYPE)) {
if ($stream->test(/* Token::BLOCK_END_TYPE */ 3)) {
$value = 'html';
} else {
$expr = $this->parser->getExpressionParser()->parseExpression();
if (!$expr instanceof ConstantExpression) {
throw new SyntaxError('An escaping strategy must be a string or a bool.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
throw new SyntaxError('An escaping strategy must be a string or false.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
$value = $expr->getAttribute('value');
$compat = true === $value || false === $value;
if (true === $value) {
$value = 'html';
}
if ($compat && $stream->test(Token::NAME_TYPE)) {
@trigger_error('Using the autoescape tag with "true" or "false" before the strategy name is deprecated since version 1.21.', E_USER_DEPRECATED);
if (false === $value) {
throw new SyntaxError('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
$value = $stream->next()->getValue();
}
}
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
return new AutoEscapeNode($value, $body, $lineno, $this->getTag());
}

View File

@@ -26,16 +26,14 @@ use Twig\Token;
* <link rel="stylesheet" href="style.css" />
* <title>{% block title %}{% endblock %} - My Webpage</title>
* {% endblock %}
*
* @final
*/
class BlockTokenParser extends AbstractTokenParser
final class BlockTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$name = $stream->expect(Token::NAME_TYPE)->getValue();
$name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue();
if ($this->parser->hasBlock($name)) {
throw new SyntaxError(sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
@@ -43,9 +41,9 @@ class BlockTokenParser extends AbstractTokenParser
$this->parser->pushLocalScope();
$this->parser->pushBlockStack($name);
if ($stream->nextIf(Token::BLOCK_END_TYPE)) {
if ($stream->nextIf(/* Token::BLOCK_END_TYPE */ 3)) {
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
if ($token = $stream->nextIf(Token::NAME_TYPE)) {
if ($token = $stream->nextIf(/* Token::NAME_TYPE */ 5)) {
$value = $token->getValue();
if ($value != $name) {
@@ -57,7 +55,7 @@ class BlockTokenParser extends AbstractTokenParser
new PrintNode($this->parser->getExpressionParser()->parseExpression(), $lineno),
]);
}
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$block->setNode('body', $body);
$this->parser->popBlockStack();

View File

@@ -16,16 +16,14 @@ use Twig\Token;
/**
* Evaluates an expression, discarding the returned value.
*
* @final
*/
class DoTokenParser extends AbstractTokenParser
final class DoTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$expr = $this->parser->getExpressionParser()->parseExpression();
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
$this->parser->getStream()->expect(/* Token::BLOCK_END_TYPE */ 3);
return new DoNode($expr, $token->getLine(), $this->getTag());
}

View File

@@ -18,10 +18,8 @@ use Twig\Token;
/**
* Embeds a template.
*
* @final
*/
class EmbedTokenParser extends IncludeTokenParser
final class EmbedTokenParser extends IncludeTokenParser
{
public function parse(Token $token)
{
@@ -31,19 +29,19 @@ class EmbedTokenParser extends IncludeTokenParser
list($variables, $only, $ignoreMissing) = $this->parseArguments();
$parentToken = $fakeParentToken = new Token(Token::STRING_TYPE, '__parent__', $token->getLine());
$parentToken = $fakeParentToken = new Token(/* Token::STRING_TYPE */ 7, '__parent__', $token->getLine());
if ($parent instanceof ConstantExpression) {
$parentToken = new Token(Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine());
$parentToken = new Token(/* Token::STRING_TYPE */ 7, $parent->getAttribute('value'), $token->getLine());
} elseif ($parent instanceof NameExpression) {
$parentToken = new Token(Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine());
$parentToken = new Token(/* Token::NAME_TYPE */ 5, $parent->getAttribute('name'), $token->getLine());
}
// inject a fake parent to make the parent() function work
$stream->injectTokens([
new Token(Token::BLOCK_START_TYPE, '', $token->getLine()),
new Token(Token::NAME_TYPE, 'extends', $token->getLine()),
new Token(/* Token::BLOCK_START_TYPE */ 1, '', $token->getLine()),
new Token(/* Token::NAME_TYPE */ 5, 'extends', $token->getLine()),
$parentToken,
new Token(Token::BLOCK_END_TYPE, '', $token->getLine()),
new Token(/* Token::BLOCK_END_TYPE */ 3, '', $token->getLine()),
]);
$module = $this->parser->parse($stream, [$this, 'decideBlockEnd'], true);
@@ -55,7 +53,7 @@ class EmbedTokenParser extends IncludeTokenParser
$this->parser->embedTemplate($module);
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
return new EmbedNode($module->getTemplateName(), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
}

View File

@@ -20,10 +20,8 @@ use Twig\Token;
* Extends a template by another one.
*
* {% extends "base.html" %}
*
* @final
*/
class ExtendsTokenParser extends AbstractTokenParser
final class ExtendsTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{

View File

@@ -24,25 +24,30 @@ use Twig\Token;
* This text becomes uppercase
* {% endfilter %}
*
* @final
* @deprecated since Twig 2.9, to be removed in 3.0 (use the "apply" tag instead)
*/
class FilterTokenParser extends AbstractTokenParser
final class FilterTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$stream = $this->parser->getStream();
$lineno = $token->getLine();
@trigger_error(sprintf('The "filter" tag in "%s" at line %d is deprecated since Twig 2.9, use the "apply" tag instead.', $stream->getSourceContext()->getName(), $lineno), \E_USER_DEPRECATED);
$name = $this->parser->getVarName();
$ref = new BlockReferenceExpression(new ConstantExpression($name, $token->getLine()), null, $token->getLine(), $this->getTag());
$ref = new BlockReferenceExpression(new ConstantExpression($name, $lineno), null, $lineno, $this->getTag());
$filter = $this->parser->getExpressionParser()->parseFilterExpressionRaw($ref, $this->getTag());
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$block = new BlockNode($name, $body, $token->getLine());
$block = new BlockNode($name, $body, $lineno);
$this->parser->setBlock($name, $block);
return new PrintNode($filter, $token->getLine(), $this->getTag());
return new PrintNode($filter, $lineno, $this->getTag());
}
public function decideBlockEnd(Token $token)

View File

@@ -18,14 +18,12 @@ use Twig\Token;
* Flushes the output to the client.
*
* @see flush()
*
* @final
*/
class FlushTokenParser extends AbstractTokenParser
final class FlushTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
$this->parser->getStream()->expect(/* Token::BLOCK_END_TYPE */ 3);
return new FlushNode($token->getLine(), $this->getTag());
}

View File

@@ -18,6 +18,7 @@ use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\ForNode;
use Twig\Node\Node;
use Twig\Token;
use Twig\TokenStream;
@@ -29,33 +30,33 @@ use Twig\TokenStream;
* <li>{{ user.username|e }}</li>
* {% endfor %}
* </ul>
*
* @final
*/
class ForTokenParser extends AbstractTokenParser
final class ForTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$targets = $this->parser->getExpressionParser()->parseAssignmentExpression();
$stream->expect(Token::OPERATOR_TYPE, 'in');
$stream->expect(/* Token::OPERATOR_TYPE */ 8, 'in');
$seq = $this->parser->getExpressionParser()->parseExpression();
$ifexpr = null;
if ($stream->nextIf(Token::NAME_TYPE, 'if')) {
if ($stream->nextIf(/* Token::NAME_TYPE */ 5, 'if')) {
@trigger_error(sprintf('Using an "if" condition on "for" tag in "%s" at line %d is deprecated since Twig 2.10.0, use a "filter" filter or an "if" condition inside the "for" body instead (if your condition depends on a variable updated inside the loop).', $stream->getSourceContext()->getName(), $lineno), \E_USER_DEPRECATED);
$ifexpr = $this->parser->getExpressionParser()->parseExpression();
}
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$body = $this->parser->subparse([$this, 'decideForFork']);
if ('else' == $stream->next()->getValue()) {
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$else = $this->parser->subparse([$this, 'decideForEnd'], true);
} else {
$else = null;
}
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
if (\count($targets) > 1) {
$keyTarget = $targets->getNode(0);
@@ -87,7 +88,7 @@ class ForTokenParser extends AbstractTokenParser
}
// the loop variable cannot be used in the condition
protected function checkLoopUsageCondition(TokenStream $stream, \Twig_NodeInterface $node)
private function checkLoopUsageCondition(TokenStream $stream, Node $node)
{
if ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
throw new SyntaxError('The "loop" variable cannot be used in a looping condition.', $node->getTemplateLine(), $stream->getSourceContext());
@@ -104,7 +105,7 @@ class ForTokenParser extends AbstractTokenParser
// check usage of non-defined loop-items
// it does not catch all problems (for instance when a for is included into another or when the variable is used in an include)
protected function checkLoopUsageBody(TokenStream $stream, \Twig_NodeInterface $node)
private function checkLoopUsageBody(TokenStream $stream, Node $node)
{
if ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression && 'loop' == $node->getNode('node')->getAttribute('name')) {
$attribute = $node->getNode('attribute');

View File

@@ -11,7 +11,6 @@
namespace Twig\TokenParser;
use Twig\Error\SyntaxError;
use Twig\Node\Expression\AssignNameExpression;
use Twig\Node\ImportNode;
use Twig\Token;
@@ -20,44 +19,38 @@ use Twig\Token;
* Imports macros.
*
* {% from 'forms.html' import forms %}
*
* @final
*/
class FromTokenParser extends AbstractTokenParser
final class FromTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$macro = $this->parser->getExpressionParser()->parseExpression();
$stream = $this->parser->getStream();
$stream->expect(Token::NAME_TYPE, 'import');
$stream->expect(/* Token::NAME_TYPE */ 5, 'import');
$targets = [];
do {
$name = $stream->expect(Token::NAME_TYPE)->getValue();
$name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue();
$alias = $name;
if ($stream->nextIf('as')) {
$alias = $stream->expect(Token::NAME_TYPE)->getValue();
$alias = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue();
}
$targets[$name] = $alias;
if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
if (!$stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) {
break;
}
} while (true);
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$var = new AssignNameExpression($this->parser->getVarName(), $token->getLine());
$node = new ImportNode($macro, $var, $token->getLine(), $this->getTag());
$node = new ImportNode($macro, $var, $token->getLine(), $this->getTag(), $this->parser->isMainScope());
foreach ($targets as $name => $alias) {
if ($this->parser->isReservedMacroName($name)) {
throw new SyntaxError(sprintf('"%s" cannot be an imported macro as it is a reserved keyword.', $name), $token->getLine(), $stream->getSourceContext());
}
$this->parser->addImportedSymbol('function', $alias, 'get'.$name, $var);
$this->parser->addImportedSymbol('function', $alias, 'macro_'.$name, $var);
}
return $node;

View File

@@ -27,17 +27,15 @@ use Twig\Token;
* {% endfor %}
* </ul>
* {% endif %}
*
* @final
*/
class IfTokenParser extends AbstractTokenParser
final class IfTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$expr = $this->parser->getExpressionParser()->parseExpression();
$stream = $this->parser->getStream();
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$body = $this->parser->subparse([$this, 'decideIfFork']);
$tests = [$expr, $body];
$else = null;
@@ -46,13 +44,13 @@ class IfTokenParser extends AbstractTokenParser
while (!$end) {
switch ($stream->next()->getValue()) {
case 'else':
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$else = $this->parser->subparse([$this, 'decideIfEnd']);
break;
case 'elseif':
$expr = $this->parser->getExpressionParser()->parseExpression();
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$body = $this->parser->subparse([$this, 'decideIfFork']);
$tests[] = $expr;
$tests[] = $body;
@@ -67,7 +65,7 @@ class IfTokenParser extends AbstractTokenParser
}
}
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
return new IfNode(new Node($tests), $else, $lineno, $this->getTag());
}

View File

@@ -19,21 +19,19 @@ use Twig\Token;
* Imports macros.
*
* {% import 'forms.html' as forms %}
*
* @final
*/
class ImportTokenParser extends AbstractTokenParser
final class ImportTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$macro = $this->parser->getExpressionParser()->parseExpression();
$this->parser->getStream()->expect(Token::NAME_TYPE, 'as');
$var = new AssignNameExpression($this->parser->getStream()->expect(Token::NAME_TYPE)->getValue(), $token->getLine());
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
$this->parser->getStream()->expect(/* Token::NAME_TYPE */ 5, 'as');
$var = new AssignNameExpression($this->parser->getStream()->expect(/* Token::NAME_TYPE */ 5)->getValue(), $token->getLine());
$this->parser->getStream()->expect(/* Token::BLOCK_END_TYPE */ 3);
$this->parser->addImportedSymbol('template', $var->getAttribute('name'));
return new ImportNode($macro, $var, $token->getLine(), $this->getTag());
return new ImportNode($macro, $var, $token->getLine(), $this->getTag(), $this->parser->isMainScope());
}
public function getTag()

View File

@@ -38,23 +38,23 @@ class IncludeTokenParser extends AbstractTokenParser
$stream = $this->parser->getStream();
$ignoreMissing = false;
if ($stream->nextIf(Token::NAME_TYPE, 'ignore')) {
$stream->expect(Token::NAME_TYPE, 'missing');
if ($stream->nextIf(/* Token::NAME_TYPE */ 5, 'ignore')) {
$stream->expect(/* Token::NAME_TYPE */ 5, 'missing');
$ignoreMissing = true;
}
$variables = null;
if ($stream->nextIf(Token::NAME_TYPE, 'with')) {
if ($stream->nextIf(/* Token::NAME_TYPE */ 5, 'with')) {
$variables = $this->parser->getExpressionParser()->parseExpression();
}
$only = false;
if ($stream->nextIf(Token::NAME_TYPE, 'only')) {
if ($stream->nextIf(/* Token::NAME_TYPE */ 5, 'only')) {
$only = true;
}
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
return [$variables, $only, $ignoreMissing];
}

View File

@@ -23,23 +23,21 @@ use Twig\Token;
* {% macro input(name, value, type, size) %}
* <input type="{{ type|default('text') }}" name="{{ name }}" value="{{ value|e }}" size="{{ size|default(20) }}" />
* {% endmacro %}
*
* @final
*/
class MacroTokenParser extends AbstractTokenParser
final class MacroTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$name = $stream->expect(Token::NAME_TYPE)->getValue();
$name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue();
$arguments = $this->parser->getExpressionParser()->parseArguments(true, true);
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$this->parser->pushLocalScope();
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
if ($token = $stream->nextIf(Token::NAME_TYPE)) {
if ($token = $stream->nextIf(/* Token::NAME_TYPE */ 5)) {
$value = $token->getValue();
if ($value != $name) {
@@ -47,7 +45,7 @@ class MacroTokenParser extends AbstractTokenParser
}
}
$this->parser->popLocalScope();
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$this->parser->setMacro($name, new MacroNode($name, new BodyNode([$body]), $arguments, $lineno, $this->getTag()));

View File

@@ -25,17 +25,15 @@ use Twig\Token;
* {% endsandbox %}
*
* @see https://twig.symfony.com/doc/api.html#sandbox-extension for details
*
* @final
*/
class SandboxTokenParser extends AbstractTokenParser
final class SandboxTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$stream = $this->parser->getStream();
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$body = $this->parser->subparse([$this, 'decideBlockEnd'], true);
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
// in a sandbox tag, only include tags are allowed
if (!$body instanceof IncludeNode) {

View File

@@ -24,10 +24,8 @@ use Twig\Token;
* {% set foo = 'foo' ~ 'bar' %}
* {% set foo, bar = 'foo', 'bar' %}
* {% set foo %}Some content{% endset %}
*
* @final
*/
class SetTokenParser extends AbstractTokenParser
final class SetTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
@@ -36,10 +34,10 @@ class SetTokenParser extends AbstractTokenParser
$names = $this->parser->getExpressionParser()->parseAssignmentExpression();
$capture = false;
if ($stream->nextIf(Token::OPERATOR_TYPE, '=')) {
if ($stream->nextIf(/* Token::OPERATOR_TYPE */ 8, '=')) {
$values = $this->parser->getExpressionParser()->parseMultitargetExpression();
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
if (\count($names) !== \count($values)) {
throw new SyntaxError('When using set, you must have the same number of variables and assignments.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
@@ -51,10 +49,10 @@ class SetTokenParser extends AbstractTokenParser
throw new SyntaxError('When using set with a block, you cannot have a multi-target.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$values = $this->parser->subparse([$this, 'decideBlockEnd'], true);
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
}
return new SetNode($capture, $names, $values, $lineno, $this->getTag());

View File

@@ -24,17 +24,20 @@ use Twig\Token;
* {% endspaceless %}
* {# output will be <div><strong>foo</strong></div> #}
*
* @final
* @deprecated since Twig 2.7, to be removed in 3.0 (use the "spaceless" filter with the "apply" tag instead)
*/
class SpacelessTokenParser extends AbstractTokenParser
final class SpacelessTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
$stream = $this->parser->getStream();
$lineno = $token->getLine();
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
@trigger_error(sprintf('The spaceless tag in "%s" at line %d is deprecated since Twig 2.7, use the "spaceless" filter with the "apply" tag instead.', $stream->getSourceContext()->getName(), $lineno), \E_USER_DEPRECATED);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$body = $this->parser->subparse([$this, 'decideSpacelessEnd'], true);
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
return new SpacelessNode($body, $lineno, $this->getTag());
}

View File

@@ -12,6 +12,7 @@
namespace Twig\TokenParser;
use Twig\Error\SyntaxError;
use Twig\Node\Node;
use Twig\Parser;
use Twig\Token;
@@ -30,7 +31,7 @@ interface TokenParserInterface
/**
* Parses a token and returns a node.
*
* @return \Twig_NodeInterface
* @return Node
*
* @throws SyntaxError
*/

View File

@@ -27,10 +27,8 @@ use Twig\Token;
* {% block content %}{% endblock %}
*
* @see https://twig.symfony.com/doc/templates.html#horizontal-reuse for details.
*
* @final
*/
class UseTokenParser extends AbstractTokenParser
final class UseTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
@@ -44,22 +42,22 @@ class UseTokenParser extends AbstractTokenParser
$targets = [];
if ($stream->nextIf('with')) {
do {
$name = $stream->expect(Token::NAME_TYPE)->getValue();
$name = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue();
$alias = $name;
if ($stream->nextIf('as')) {
$alias = $stream->expect(Token::NAME_TYPE)->getValue();
$alias = $stream->expect(/* Token::NAME_TYPE */ 5)->getValue();
}
$targets[$name] = new ConstantExpression($alias, -1);
if (!$stream->nextIf(Token::PUNCTUATION_TYPE, ',')) {
if (!$stream->nextIf(/* Token::PUNCTUATION_TYPE */ 9, ',')) {
break;
}
} while (true);
}
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$this->parser->addTrait(new Node(['template' => $template, 'targets' => new Node($targets)]));

View File

@@ -18,10 +18,8 @@ use Twig\Token;
* Creates a nested scope.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final
*/
class WithTokenParser extends AbstractTokenParser
final class WithTokenParser extends AbstractTokenParser
{
public function parse(Token $token)
{
@@ -29,16 +27,16 @@ class WithTokenParser extends AbstractTokenParser
$variables = null;
$only = false;
if (!$stream->test(Token::BLOCK_END_TYPE)) {
if (!$stream->test(/* Token::BLOCK_END_TYPE */ 3)) {
$variables = $this->parser->getExpressionParser()->parseExpression();
$only = $stream->nextIf(Token::NAME_TYPE, 'only');
$only = (bool) $stream->nextIf(/* Token::NAME_TYPE */ 5, 'only');
}
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
$body = $this->parser->subparse([$this, 'decideWithEnd'], true);
$stream->expect(Token::BLOCK_END_TYPE);
$stream->expect(/* Token::BLOCK_END_TYPE */ 3);
return new WithNode($body, $variables, $only, $token->getLine(), $this->getTag());
}