Deprecate using Node directly, introduce EmptyNode and Nodes

This commit is contained in:
Fabien Potencier
2024-09-24 17:36:20 +02:00
parent a1daf1e551
commit 8b278986b8
37 changed files with 230 additions and 130 deletions
+1
View File
@@ -1,5 +1,6 @@
# 3.15.0 (2024-XX-XX)
* Deprecate instantiating `Node` directly. Use `EmptyNode` or `Nodes` instead.
* Add support for inline comments
* Add support for accessing class constants with the dot operator
* Add `Profile::getStartTime()` and `Profile::getEndTime()`
+7
View File
@@ -289,3 +289,10 @@ Functions/Filters/Tests
* For variadic arguments, use snake-case for the argument name to ease the
transition to 4.0.
Node
----
* Instantiating ``Twig\Node\Node`` directly is deprecated as of Twig 3.15. Use
``EmptyNode`` or ``Nodes`` instead depending on the use case. The
``Twig\Node\Node`` class will be abstract in Twig 4.0.
+11 -9
View File
@@ -14,6 +14,7 @@ namespace Twig;
use Twig\Attribute\FirstClassTwigCallableReady;
use Twig\Error\SyntaxError;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\ArrayExpression;
use Twig\Node\Expression\ArrowFunctionExpression;
@@ -32,6 +33,7 @@ use Twig\Node\Expression\Unary\NotUnary;
use Twig\Node\Expression\Unary\PosUnary;
use Twig\Node\Expression\Unary\SpreadUnary;
use Twig\Node\Node;
use Twig\Node\Nodes;
/**
* Parses expressions.
@@ -110,7 +112,7 @@ class ExpressionParser
$names = [new AssignNameExpression($token->getValue(), $token->getLine())];
$stream->expect(Token::ARROW_TYPE);
return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
return new ArrowFunctionExpression($this->parseExpression(0), new Nodes($names), $line);
}
// first, determine if we are parsing an arrow function by finding => (long form)
@@ -151,7 +153,7 @@ class ExpressionParser
$stream->expect(Token::PUNCTUATION_TYPE, ')');
$stream->expect(Token::ARROW_TYPE);
return new ArrowFunctionExpression($this->parseExpression(0), new Node($names), $line);
return new ArrowFunctionExpression($this->parseExpression(0), new Nodes($names), $line);
}
private function getPrimary(): AbstractExpression
@@ -467,7 +469,7 @@ class ExpressionParser
$function = $this->getFunction($name, $line);
if ($function->getParserCallable()) {
$fakeNode = new Node(lineno: $line);
$fakeNode = new EmptyNode($line);
$fakeNode->setSourceContext($this->parser->getStream()->getSourceContext());
return ($function->getParserCallable())($this->parser, $fakeNode, $args, $line);
@@ -556,7 +558,7 @@ class ExpressionParser
}
$filter = $this->getFilter('slice', $token->getLine());
$arguments = new Node([$arg, $length]);
$arguments = new Nodes([$arg, $length]);
$filter = new ($filter->getNodeClass())($node, $filter, $arguments, $token->getLine());
$stream->expect(Token::PUNCTUATION_TYPE, ']');
@@ -587,7 +589,7 @@ class ExpressionParser
$token = $this->parser->getStream()->expect(Token::NAME_TYPE);
if (!$this->parser->getStream()->test(Token::PUNCTUATION_TYPE, '(')) {
$arguments = new Node();
$arguments = new EmptyNode();
} else {
$arguments = $this->parseArguments(true, false, true);
}
@@ -691,7 +693,7 @@ class ExpressionParser
}
$stream->expect(Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis');
return new Node($args);
return new Nodes($args);
}
public function parseAssignmentExpression()
@@ -717,7 +719,7 @@ class ExpressionParser
}
}
return new Node($targets);
return new Nodes($targets);
}
public function parseMultitargetExpression()
@@ -730,7 +732,7 @@ class ExpressionParser
}
}
return new Node($targets);
return new Nodes($targets);
}
private function parseNotTestExpression(Node $node): NotUnary
@@ -747,7 +749,7 @@ class ExpressionParser
if ($stream->test(Token::PUNCTUATION_TYPE, '(')) {
$arguments = $this->parseArguments(true);
} elseif ($test->hasOneMandatoryArgument()) {
$arguments = new Node([0 => $this->parsePrimaryExpression()]);
$arguments = new Nodes([0 => $this->parsePrimaryExpression()]);
}
if ('defined' === $test->getName() && $node instanceof NameExpression && null !== $alias = $this->parser->getImportedSymbol('function', $node->getAttribute('name'))) {
+28
View File
@@ -0,0 +1,28 @@
<?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;
use Twig\Attribute\YieldReady;
/**
* Represents an empty node.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
final class EmptyNode extends Node
{
public function __construct(int $lineno = 0)
{
parent::__construct([], [], $lineno);
}
}
+2 -1
View File
@@ -14,6 +14,7 @@ namespace Twig\Node\Expression\Filter;
use Twig\Attribute\FirstClassTwigCallableReady;
use Twig\Compiler;
use Twig\Extension\CoreExtension;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\ConditionalExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FilterExpression;
@@ -45,7 +46,7 @@ class DefaultFilter extends FilterExpression
}
if ('default' === $name && ($node instanceof NameExpression || $node instanceof GetAttrExpression)) {
$test = new DefinedTest(clone $node, new TwigTest('defined'), new Node(), $node->getTemplateLine());
$test = new DefinedTest(clone $node, new TwigTest('defined'), new EmptyNode(), $node->getTemplateLine());
$false = \count($arguments) ? $arguments->getNode('0') : new ConstantExpression('', $node->getTemplateLine());
$node = new ConditionalExpression($test, $default, $false, $node->getTemplateLine());
+2 -1
View File
@@ -13,6 +13,7 @@ namespace Twig\Node\Expression\Filter;
use Twig\Attribute\FirstClassTwigCallableReady;
use Twig\Compiler;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FilterExpression;
use Twig\Node\Node;
@@ -26,7 +27,7 @@ class RawFilter extends FilterExpression
#[FirstClassTwigCallableReady]
public function __construct(Node $node, TwigFilter|ConstantExpression|null $filter = null, ?Node $arguments = null, int $lineno = 0)
{
parent::__construct($node, $filter ?: new TwigFilter('raw', null, ['is_safe' => ['all']]), $arguments ?: new Node(), $lineno ?: $node->getTemplateLine());
parent::__construct($node, $filter ?: new TwigFilter('raw', null, ['is_safe' => ['all']]), $arguments ?: new EmptyNode(), $lineno ?: $node->getTemplateLine());
}
public function compile(Compiler $compiler): void
@@ -12,6 +12,7 @@
namespace Twig\Node\Expression;
use Twig\Compiler;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\Binary\AndBinary;
use Twig\Node\Expression\Test\DefinedTest;
use Twig\Node\Expression\Test\NullTest;
@@ -23,12 +24,12 @@ class NullCoalesceExpression extends ConditionalExpression
{
public function __construct(Node $left, Node $right, int $lineno)
{
$test = new DefinedTest(clone $left, new TwigTest('defined'), new Node(), $left->getTemplateLine());
$test = new DefinedTest(clone $left, new TwigTest('defined'), new EmptyNode(), $left->getTemplateLine());
// for "block()", we don't need the null test as the return value is always a string
if (!$left instanceof BlockReferenceExpression) {
$test = new AndBinary(
$test,
new NotUnary(new NullTest($left, new TwigTest('null'), new Node(), $left->getTemplateLine()), $left->getTemplateLine()),
new NotUnary(new NullTest($left, new TwigTest('null'), new EmptyNode(), $left->getTemplateLine()), $left->getTemplateLine()),
$left->getTemplateLine()
);
}
+1 -1
View File
@@ -29,7 +29,7 @@ class ForNode extends Node
public function __construct(AssignNameExpression $keyTarget, AssignNameExpression $valueTarget, AbstractExpression $seq, ?Node $ifexpr, Node $body, ?Node $else, int $lineno)
{
$body = new Node([$body, $this->loop = new ForLoopNode($lineno)]);
$body = new Nodes([$body, $this->loop = new ForLoopNode($lineno)]);
$nodes = ['key_target' => $keyTarget, 'value_target' => $valueTarget, 'seq' => $seq, 'body' => $body];
if (null !== $else) {
+6 -6
View File
@@ -44,11 +44,11 @@ final class ModuleNode extends Node
'blocks' => $blocks,
'macros' => $macros,
'traits' => $traits,
'display_start' => new Node(),
'display_end' => new Node(),
'constructor_start' => new Node(),
'constructor_end' => new Node(),
'class_end' => new Node(),
'display_start' => new EmptyNode(),
'display_end' => new EmptyNode(),
'constructor_start' => new EmptyNode(),
'constructor_end' => new EmptyNode(),
'class_end' => new EmptyNode(),
];
if (null !== $parent) {
$nodes['parent'] = $parent;
@@ -414,7 +414,7 @@ final class ModuleNode extends Node
}
if (!\count($nodes)) {
$nodes = new Node([$nodes]);
$nodes = new Nodes([$nodes]);
}
foreach ($nodes as $node) {
+4
View File
@@ -47,6 +47,10 @@ class Node implements \Countable, \IteratorAggregate
*/
public function __construct(array $nodes = [], array $attributes = [], int $lineno = 0)
{
if (self::class === static::class) {
trigger_deprecation('twig/twig', '3.15', \sprintf('Instantiating "%s" directly is deprecated; the class will become abstract in 4.0.', self::class));
}
foreach ($nodes as $name => $node) {
if (!$node instanceof self) {
throw new \InvalidArgumentException(\sprintf('Using "%s" for the value of node "%s" of "%s" is not supported. You must pass a \Twig\Node\Node instance.', \is_object($node) ? $node::class : (null === $node ? 'null' : \gettype($node)), $name, static::class));
+28
View File
@@ -0,0 +1,28 @@
<?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;
use Twig\Attribute\YieldReady;
/**
* Represents a list of nodes.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
#[YieldReady]
final class Nodes extends Node
{
public function __construct(array $nodes = [], int $lineno = 0)
{
parent::__construct($nodes, [], $lineno);
}
}
+2 -1
View File
@@ -33,7 +33,8 @@ class SetNode extends Node implements NodeCaptureInterface
$safe = false;
if ($capture) {
$safe = true;
if (Node::class === get_class($values) && !count($values)) {
// Node::class === get_class($values) should be removed in Twig 4.0
if (($values instanceof Nodes || Node::class === get_class($values)) && !count($values)) {
$values = new ConstantExpression('', $values->getTemplateLine());
$capture = false;
} elseif ($values instanceof TextNode) {
+2 -1
View File
@@ -24,6 +24,7 @@ use Twig\Node\Expression\InlinePrint;
use Twig\Node\ImportNode;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\PrintNode;
use Twig\NodeTraverser;
@@ -197,7 +198,7 @@ final class EscaperNodeVisitor implements NodeVisitorInterface
{
$line = $node->getTemplateLine();
$filter = $env->getFilter('escape');
$args = new Node([new ConstantExpression($type, $line), new ConstantExpression(null, $line), new ConstantExpression(true, $line)]);
$args = new Nodes([new ConstantExpression($type, $line), new ConstantExpression(null, $line), new ConstantExpression(true, $line)]);
return new FilterExpression($node, $filter, $args, $line);
}
+3 -2
View File
@@ -23,6 +23,7 @@ use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\PrintNode;
use Twig\Node\SetNode;
@@ -105,8 +106,8 @@ final class SandboxNodeVisitor implements NodeVisitorInterface
if ($node instanceof ModuleNode) {
$this->inAModule = false;
$node->setNode('constructor_end', new Node([new CheckSecurityCallNode(), $node->getNode('constructor_end')]));
$node->setNode('class_end', new Node([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('class_end')]));
$node->setNode('constructor_end', new Nodes([new CheckSecurityCallNode(), $node->getNode('constructor_end')]));
$node->setNode('class_end', new Nodes([new CheckSecurityNode($this->filters, $this->tags, $this->functions), $node->getNode('class_end')]));
} elseif ($this->inAModule) {
if ($node instanceof PrintNode || $node instanceof SetNode) {
$this->needsToStringWrap = false;
+8 -5
View File
@@ -16,12 +16,14 @@ use Twig\Error\SyntaxError;
use Twig\Node\BlockNode;
use Twig\Node\BlockReferenceNode;
use Twig\Node\BodyNode;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\MacroNode;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\NodeCaptureInterface;
use Twig\Node\NodeOutputInterface;
use Twig\Node\Nodes;
use Twig\Node\PrintNode;
use Twig\Node\TextNode;
use Twig\TokenParser\TokenParserInterface;
@@ -83,7 +85,7 @@ class Parser
$body = $this->subparse($test, $dropNeedle);
if (null !== $this->parent && null === $body = $this->filterBodyNodes($body)) {
$body = new Node();
$body = new EmptyNode();
}
} catch (SyntaxError $e) {
if (!$e->getSourceContext()) {
@@ -97,7 +99,7 @@ class Parser
throw $e;
}
$node = new ModuleNode(new BodyNode([$body]), $this->parent, new Node($this->blocks), new Node($this->macros), new Node($this->traits), $this->embeddedTemplates, $stream->getSourceContext());
$node = new ModuleNode(new BodyNode([$body]), $this->parent, new Nodes($this->blocks), new Nodes($this->macros), new Nodes($this->traits), $this->embeddedTemplates, $stream->getSourceContext());
$traverser = new NodeTraverser($this->env, $this->visitors);
@@ -149,7 +151,7 @@ class Parser
return $rv[0];
}
return new Node($rv, [], $lineno);
return new Nodes($rv, $lineno);
}
if (!$subparser = $this->env->getTokenParser($token->getValue())) {
@@ -189,7 +191,7 @@ class Parser
return $rv[0];
}
return new Node($rv, [], $lineno);
return new Nodes($rv, $lineno);
}
public function getBlockStack(): array
@@ -371,7 +373,8 @@ class Parser
// here, $nested means "being at the root level of a child template"
// we need to discard the wrapping "Node" for the "body" node
$nested = $nested || Node::class !== \get_class($node);
// Node::class !== \get_class($node) should be removed in Twig 4.0
$nested = $nested || (Node::class !== \get_class($node) && !$node instanceof Nodes);
foreach ($node as $k => $n) {
if (null !== $n && null === $this->filterBodyNodes($n, $nested)) {
$node->removeNode($k);
@@ -17,6 +17,7 @@ use Twig\Node\BodyNode;
use Twig\Node\MacroNode;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\NodeVisitor\NodeVisitorInterface;
use Twig\Profiler\Node\EnterProfileNode;
use Twig\Profiler\Node\LeaveProfileNode;
@@ -43,8 +44,8 @@ final class ProfilerNodeVisitor implements NodeVisitorInterface
public function leaveNode(Node $node, Environment $env): ?Node
{
if ($node instanceof ModuleNode) {
$node->setNode('display_start', new Node([new EnterProfileNode($this->extensionName, Profile::TEMPLATE, $node->getTemplateName(), $this->varName), $node->getNode('display_start')]));
$node->setNode('display_end', new Node([new LeaveProfileNode($this->varName), $node->getNode('display_end')]));
$node->setNode('display_start', new Nodes([new EnterProfileNode($this->extensionName, Profile::TEMPLATE, $node->getTemplateName(), $this->varName), $node->getNode('display_start')]));
$node->setNode('display_end', new Nodes([new LeaveProfileNode($this->varName), $node->getNode('display_end')]));
} elseif ($node instanceof BlockNode) {
$node->setNode('body', new BodyNode([
new EnterProfileNode($this->extensionName, Profile::BLOCK, $node->getAttribute('name'), $this->varName),
+3 -2
View File
@@ -13,6 +13,7 @@ namespace Twig\TokenParser;
use Twig\Node\Expression\TempNameExpression;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\PrintNode;
use Twig\Node\SetNode;
use Twig\Token;
@@ -42,10 +43,10 @@ final class ApplyTokenParser extends AbstractTokenParser
$body = $this->parser->subparse([$this, 'decideApplyEnd'], true);
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
return new Node([
return new Nodes([
new SetNode(true, $ref, $body, $lineno),
new PrintNode($filter, $lineno),
], [], $lineno);
], $lineno);
}
public function decideApplyEnd(Token $token): bool
+4 -2
View File
@@ -15,7 +15,9 @@ namespace Twig\TokenParser;
use Twig\Error\SyntaxError;
use Twig\Node\BlockNode;
use Twig\Node\BlockReferenceNode;
use Twig\Node\EmptyNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\PrintNode;
use Twig\Token;
@@ -36,7 +38,7 @@ final class BlockTokenParser extends AbstractTokenParser
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$name = $stream->expect(Token::NAME_TYPE)->getValue();
$this->parser->setBlock($name, $block = new BlockNode($name, new Node([]), $lineno));
$this->parser->setBlock($name, $block = new BlockNode($name, new EmptyNode(), $lineno));
$this->parser->pushLocalScope();
$this->parser->pushBlockStack($name);
@@ -50,7 +52,7 @@ final class BlockTokenParser extends AbstractTokenParser
}
}
} else {
$body = new Node([
$body = new Nodes([
new PrintNode($this->parser->getExpressionParser()->parseExpression(), $lineno),
]);
}
+2 -1
View File
@@ -13,6 +13,7 @@
namespace Twig\TokenParser;
use Twig\Error\SyntaxError;
use Twig\Node\EmptyNode;
use Twig\Node\Node;
use Twig\Token;
@@ -39,7 +40,7 @@ final class ExtendsTokenParser extends AbstractTokenParser
$stream->expect(Token::BLOCK_END_TYPE);
return new Node([], [], $token->getLine());
return new EmptyNode($token->getLine());
}
public function getTag(): string
+2 -1
View File
@@ -15,6 +15,7 @@ namespace Twig\TokenParser;
use Twig\Error\SyntaxError;
use Twig\Node\IfNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Token;
/**
@@ -69,7 +70,7 @@ final class IfTokenParser extends AbstractTokenParser
$stream->expect(Token::BLOCK_END_TYPE);
return new IfNode(new Node($tests), $else, $lineno);
return new IfNode(new Nodes($tests), $else, $lineno);
}
public function decideIfFork(Token $token): bool
+2 -1
View File
@@ -13,6 +13,7 @@ namespace Twig\TokenParser;
use Twig\Error\SyntaxError;
use Twig\Node\BodyNode;
use Twig\Node\EmptyNode;
use Twig\Node\MacroNode;
use Twig\Node\Node;
use Twig\Token;
@@ -51,7 +52,7 @@ final class MacroTokenParser extends AbstractTokenParser
$this->parser->setMacro($name, new MacroNode($name, new BodyNode([$body]), $arguments, $lineno));
return new Node([], [], $lineno);
return new EmptyNode($lineno);
}
public function decideBlockEnd(Token $token): bool
+4 -2
View File
@@ -12,8 +12,10 @@
namespace Twig\TokenParser;
use Twig\Error\SyntaxError;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Token;
/**
@@ -61,9 +63,9 @@ final class UseTokenParser extends AbstractTokenParser
$stream->expect(Token::BLOCK_END_TYPE);
$this->parser->addTrait(new Node(['template' => $template, 'targets' => new Node($targets)]));
$this->parser->addTrait(new Nodes(['template' => $template, 'targets' => new Nodes($targets)]));
return new Node([], [], $token->getLine());
return new EmptyNode($token->getLine());
}
public function getTag(): string
+3 -3
View File
@@ -12,7 +12,7 @@ namespace Twig\Tests\Node;
*/
use Twig\Node\AutoEscapeNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\TextNode;
use Twig\Test\NodeTestCase;
@@ -20,7 +20,7 @@ class AutoEscapeTest extends NodeTestCase
{
public function testConstructor()
{
$body = new Node([new TextNode('foo', 1)]);
$body = new Nodes([new TextNode('foo', 1)]);
$node = new AutoEscapeNode(true, $body, 1);
$this->assertEquals($body, $node->getNode('body'));
@@ -29,7 +29,7 @@ class AutoEscapeTest extends NodeTestCase
public static function provideTests(): iterable
{
$body = new Node([new TextNode('foo', 1)]);
$body = new Nodes([new TextNode('foo', 1)]);
$node = new AutoEscapeNode(true, $body, 1);
return [
+5 -4
View File
@@ -15,10 +15,11 @@ use Twig\Compiler;
use Twig\Environment;
use Twig\Loader\ArrayLoader;
use Twig\Node\DeprecatedNode;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FunctionExpression;
use Twig\Node\IfNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Source;
use Twig\Test\NodeTestCase;
use Twig\TwigFunction;
@@ -49,10 +50,10 @@ trigger_deprecation("twig/twig", "1.1", "This section is deprecated"." in \"foo.
EOF
];
$t = new Node([
$t = new Nodes([
new ConstantExpression(true, 1),
$dep = new DeprecatedNode($expr, 2),
], [], 1);
], 1);
$node = new IfNode($t, null, 1);
$node->setSourceContext(new Source('', 'foo.twig'));
$dep->setNode('package', new ConstantExpression('twig/twig', 1));
@@ -70,7 +71,7 @@ EOF
$environment = new Environment(new ArrayLoader());
$environment->addFunction($function = new TwigFunction('foo', 'Twig\Tests\Node\foo', []));
$expr = new FunctionExpression($function, new Node(), 1);
$expr = new FunctionExpression($function, new EmptyNode(), 1);
$node = new DeprecatedNode($expr, 1);
$node->setSourceContext(new Source('', 'foo.twig'));
$node->setNode('package', new ConstantExpression('twig/twig', 1));
+2 -2
View File
@@ -13,8 +13,8 @@ namespace Twig\Tests\Node\Expression;
use PHPUnit\Framework\TestCase;
use Twig\Error\SyntaxError;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\FunctionExpression;
use Twig\Node\Node;
use Twig\TwigFunction;
/**
@@ -156,7 +156,7 @@ class CallTest extends TestCase
private function createFunctionExpression($name, $callable, $isVariadic = false): Node_Expression_Call
{
return new Node_Expression_Call(new TwigFunction($name, $callable, ['is_variadic' => $isVariadic]), new Node([]), 0);
return new Node_Expression_Call(new TwigFunction($name, $callable, ['is_variadic' => $isVariadic]), new EmptyNode(), 0);
}
}
+4 -3
View File
@@ -15,9 +15,10 @@ use Twig\Environment;
use Twig\Error\SyntaxError;
use Twig\Extension\AbstractExtension;
use Twig\Loader\ArrayLoader;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FilterExpression;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Test\NodeTestCase;
use Twig\TwigFilter;
@@ -27,7 +28,7 @@ class FilterTest extends NodeTestCase
{
$expr = new ConstantExpression('foo', 1);
$filter = new TwigFilter($name = 'upper');
$args = new Node();
$args = new EmptyNode();
$node = new FilterExpression($expr, $filter, $args, 1);
$this->assertEquals($expr, $node->getNode('node'));
@@ -158,7 +159,7 @@ class FilterTest extends NodeTestCase
private static function createFilter(Environment $env, $node, $name, array $arguments = []): FilterExpression
{
return new FilterExpression($node, $env->getFilter($name), new Node($arguments), 1);
return new FilterExpression($node, $env->getFilter($name), new Nodes($arguments), 1);
}
protected static function createEnvironment(): Environment
+4 -3
View File
@@ -13,9 +13,10 @@ namespace Twig\Tests\Node\Expression;
use Twig\Environment;
use Twig\Loader\ArrayLoader;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FunctionExpression;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Test\NodeTestCase;
use Twig\TwigFunction;
@@ -24,7 +25,7 @@ class FunctionTest extends NodeTestCase
public function testConstructor()
{
$name = 'function';
$args = new Node();
$args = new EmptyNode();
$node = new FunctionExpression(new TwigFunction($name), $args, 1);
$this->assertEquals($name, $node->getAttribute('name'));
@@ -98,7 +99,7 @@ class FunctionTest extends NodeTestCase
private static function createFunction(Environment $env, $name, array $arguments = []): FunctionExpression
{
return new FunctionExpression($env->getFunction($name), new Node($arguments), 1);
return new FunctionExpression($env->getFunction($name), new Nodes($arguments), 1);
}
protected static function createEnvironment(): Environment
+5 -4
View File
@@ -13,10 +13,11 @@ namespace Twig\Tests\Node\Expression;
use Twig\Environment;
use Twig\Loader\ArrayLoader;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\Test\NullTest;
use Twig\Node\Expression\TestExpression;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Test\NodeTestCase;
use Twig\TwigTest;
@@ -26,7 +27,7 @@ class TestTest extends NodeTestCase
{
$expr = new ConstantExpression('foo', 1);
$name = 'test_name';
$args = new Node();
$args = new EmptyNode();
$node = new TestExpression($expr, new TwigTest($name), $args, 1);
$this->assertEquals($expr, $node->getNode('node'));
@@ -41,7 +42,7 @@ class TestTest extends NodeTestCase
$tests = [];
$expr = new ConstantExpression('foo', 1);
$node = new NullTest($expr, $environment->getTest('null'), new Node([]), 1);
$node = new NullTest($expr, $environment->getTest('null'), new EmptyNode(), 1);
$tests[] = [$node, '(null === "foo")'];
// test as an anonymous function
@@ -72,7 +73,7 @@ class TestTest extends NodeTestCase
private static function createTest(Environment $env, $node, $name, array $arguments = []): TestExpression
{
return new TestExpression($node, $env->getTest($name), new Node($arguments), 1);
return new TestExpression($node, $env->getTest($name), new Nodes($arguments), 1);
}
protected static function createEnvironment(): Environment
+6 -6
View File
@@ -14,7 +14,7 @@ namespace Twig\Tests\Node;
use Twig\Node\Expression\AssignNameExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\ForNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\PrintNode;
use Twig\Test\NodeTestCase;
@@ -25,7 +25,7 @@ class ForTest extends NodeTestCase
$keyTarget = new AssignNameExpression('key', 1);
$valueTarget = new AssignNameExpression('item', 1);
$seq = new NameExpression('items', 1);
$body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
$body = new Nodes([new PrintNode(new NameExpression('foo', 1), 1)], 1);
$else = null;
$node = new ForNode($keyTarget, $valueTarget, $seq, null, $body, $else, 1);
$node->setAttribute('with_loop', false);
@@ -49,7 +49,7 @@ class ForTest extends NodeTestCase
$keyTarget = new AssignNameExpression('key', 1);
$valueTarget = new AssignNameExpression('item', 1);
$seq = new NameExpression('items', 1);
$body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
$body = new Nodes([new PrintNode(new NameExpression('foo', 1), 1)], 1);
$else = null;
$node = new ForNode($keyTarget, $valueTarget, $seq, null, $body, $else, 1);
$node->setAttribute('with_loop', false);
@@ -74,7 +74,7 @@ EOF
$keyTarget = new AssignNameExpression('k', 1);
$valueTarget = new AssignNameExpression('v', 1);
$seq = new NameExpression('values', 1);
$body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
$body = new Nodes([new PrintNode(new NameExpression('foo', 1), 1)], 1);
$else = null;
$node = new ForNode($keyTarget, $valueTarget, $seq, null, $body, $else, 1);
$node->setAttribute('with_loop', true);
@@ -116,7 +116,7 @@ EOF
$keyTarget = new AssignNameExpression('k', 1);
$valueTarget = new AssignNameExpression('v', 1);
$seq = new NameExpression('values', 1);
$body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
$body = new Nodes([new PrintNode(new NameExpression('foo', 1), 1)], 1);
$else = null;
$node = new ForNode($keyTarget, $valueTarget, $seq, null, $body, $else, 1);
$node->setAttribute('with_loop', true);
@@ -158,7 +158,7 @@ EOF
$keyTarget = new AssignNameExpression('k', 1);
$valueTarget = new AssignNameExpression('v', 1);
$seq = new NameExpression('values', 1);
$body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
$body = new Nodes([new PrintNode(new NameExpression('foo', 1), 1)], 1);
$else = new PrintNode(new NameExpression('foo', 1), 1);
$node = new ForNode($keyTarget, $valueTarget, $seq, null, $body, $else, 1);
$node->setAttribute('with_loop', true);
+9 -9
View File
@@ -14,7 +14,7 @@ namespace Twig\Tests\Node;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\IfNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\PrintNode;
use Twig\Test\NodeTestCase;
@@ -22,10 +22,10 @@ class IfTest extends NodeTestCase
{
public function testConstructor()
{
$t = new Node([
$t = new Nodes([
new ConstantExpression(true, 1),
new PrintNode(new NameExpression('foo', 1), 1),
], [], 1);
], 1);
$else = null;
$node = new IfNode($t, $else, 1);
@@ -41,10 +41,10 @@ class IfTest extends NodeTestCase
{
$tests = [];
$t = new Node([
$t = new Nodes([
new ConstantExpression(true, 1),
new PrintNode(new NameExpression('foo', 1), 1),
], [], 1);
], 1);
$else = null;
$node = new IfNode($t, $else, 1);
@@ -59,12 +59,12 @@ if (true) {
EOF
];
$t = new Node([
$t = new Nodes([
new ConstantExpression(true, 1),
new PrintNode(new NameExpression('foo', 1), 1),
new ConstantExpression(false, 1),
new PrintNode(new NameExpression('bar', 1), 1),
], [], 1);
], 1);
$else = null;
$node = new IfNode($t, $else, 1);
@@ -78,10 +78,10 @@ if (true) {
EOF
];
$t = new Node([
$t = new Nodes([
new ConstantExpression(true, 1),
new PrintNode(new NameExpression('foo', 1), 1),
], [], 1);
], 1);
$else = new PrintNode(new NameExpression('bar', 1), 1);
$node = new IfNode($t, $else, 1);
+4 -4
View File
@@ -17,7 +17,7 @@ use Twig\Node\BodyNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\MacroNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\TextNode;
use Twig\Test\NodeTestCase;
@@ -26,7 +26,7 @@ class MacroTest extends NodeTestCase
public function testConstructor()
{
$body = new BodyNode([new TextNode('foo', 1)]);
$arguments = new Node([new NameExpression('foo', 1)], [], 1);
$arguments = new Nodes([new NameExpression('foo', 1)], 1);
$node = new MacroNode('foo', $body, $arguments, 1);
$this->assertEquals($body, $node->getNode('body'));
@@ -36,10 +36,10 @@ class MacroTest extends NodeTestCase
public static function provideTests(): iterable
{
$arguments = new Node([
$arguments = new Nodes([
'foo' => new ConstantExpression(null, 1),
'bar' => new ConstantExpression('Foo', 1),
], [], 1);
], 1);
$body = new BodyNode([new TextNode('foo', 1)]);
$node = new MacroNode('foo', $body, $arguments, 1);
+13 -12
View File
@@ -14,12 +14,13 @@ namespace Twig\Tests\Node;
use Twig\Environment;
use Twig\Loader\ArrayLoader;
use Twig\Node\BodyNode;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\AssignNameExpression;
use Twig\Node\Expression\ConditionalExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\ImportNode;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\SetNode;
use Twig\Node\TextNode;
use Twig\Source;
@@ -31,11 +32,11 @@ class ModuleTest extends NodeTestCase
{
$body = new BodyNode([new TextNode('foo', 1)]);
$parent = new ConstantExpression('layout.twig', 1);
$blocks = new Node();
$macros = new Node();
$traits = new Node();
$blocks = new EmptyNode();
$macros = new EmptyNode();
$traits = new EmptyNode();
$source = new Source('{{ foo }}', 'foo.twig');
$node = new ModuleNode($body, $parent, $blocks, $macros, $traits, new Node([]), $source);
$node = new ModuleNode($body, $parent, $blocks, $macros, $traits, new EmptyNode(), $source);
$this->assertEquals($body, $node->getNode('body'));
$this->assertEquals($blocks, $node->getNode('blocks'));
@@ -52,12 +53,12 @@ class ModuleTest extends NodeTestCase
$body = new BodyNode([new TextNode('foo', 1)]);
$extends = null;
$blocks = new Node();
$macros = new Node();
$traits = new Node();
$blocks = new EmptyNode();
$macros = new EmptyNode();
$traits = new EmptyNode();
$source = new Source('{{ foo }}', 'foo.twig');
$node = new ModuleNode($body, $extends, $blocks, $macros, $traits, new Node([]), $source);
$node = new ModuleNode($body, $extends, $blocks, $macros, $traits, new EmptyNode(), $source);
$tests[] = [$node, <<<EOF
<?php
@@ -133,7 +134,7 @@ EOF
$body = new BodyNode([$import]);
$extends = new ConstantExpression('layout.twig', 1);
$node = new ModuleNode($body, $extends, $blocks, $macros, $traits, new Node([]), $source);
$node = new ModuleNode($body, $extends, $blocks, $macros, $traits, new EmptyNode(), $source);
$tests[] = [$node, <<<EOF
<?php
@@ -218,7 +219,7 @@ class __TwigTemplate_%x extends Template
EOF
, $twig, true];
$set = new SetNode(false, new Node([new AssignNameExpression('foo', 4)]), new Node([new ConstantExpression('foo', 4)]), 4);
$set = new SetNode(false, new Nodes([new AssignNameExpression('foo', 4)]), new Nodes([new ConstantExpression('foo', 4)]), 4);
$body = new BodyNode([$set]);
$extends = new ConditionalExpression(
new ConstantExpression(true, 2),
@@ -228,7 +229,7 @@ EOF
);
$twig = new Environment(new ArrayLoader(['foo.twig' => '{{ foo }}']), ['debug' => true]);
$node = new ModuleNode($body, $extends, $blocks, $macros, $traits, new Node([]), $source);
$node = new ModuleNode($body, $extends, $blocks, $macros, $traits, new EmptyNode(), $source);
$tests[] = [$node, <<<EOF
<?php
+20 -16
View File
@@ -26,10 +26,10 @@ class NodeTest extends TestCase
public function testToString()
{
// callable is not a supported type for a Node attribute, but Drupal uses some apparently
$node = new Node([], ['value' => function () { return '1'; }], 1);
$node = new NodeForTest([], ['value' => function () { return '1'; }], 1);
$this->assertEquals(<<<EOF
Twig\Node\Node
Twig\Tests\Node\NodeForTest
attributes:
value: \Closure
EOF
@@ -39,14 +39,14 @@ EOF
public function testToStringWithTwigCallables()
{
$node = new Node([], [
$node = new NodeForTest([], [
'function' => new TwigFunction('a_function'),
'filter' => new TwigFilter('a_filter'),
'test' => new TwigTest('a_test'),
], 1);
$this->assertEquals(<<<EOF
Twig\Node\Node
Twig\Tests\Node\NodeForTest
attributes:
function: Twig\TwigFunction(a_function)
filter: Twig\TwigFilter(a_filter)
@@ -57,11 +57,11 @@ EOF
public function testToStringWithTag()
{
$node = new Node([], [], 1);
$node = new NodeForTest();
$node->setNodeTag('tag');
$this->assertEquals(<<<EOF
Twig\Node\Node
Twig\Tests\Node\NodeForTest
tag: tag
EOF
, (string) $node);
@@ -69,7 +69,7 @@ EOF
public function testAttributeDeprecationIgnore()
{
$node = new Node([], ['foo' => false]);
$node = new NodeForTest([], ['foo' => false]);
$node->deprecateAttribute('foo', new NameDeprecation('foo/bar', '2.0', 'bar'));
$this->assertFalse($node->getAttribute('foo', false));
@@ -80,10 +80,10 @@ EOF
*/
public function testAttributeDeprecationWithoutAlternative()
{
$node = new Node([], ['foo' => false]);
$node = new NodeForTest([], ['foo' => false]);
$node->deprecateAttribute('foo', new NameDeprecation('foo/bar', '2.0'));
$this->expectDeprecation('Since foo/bar 2.0: Getting attribute "foo" on a "Twig\Node\Node" class is deprecated.');
$this->expectDeprecation('Since foo/bar 2.0: Getting attribute "foo" on a "Twig\Tests\Node\NodeForTest" class is deprecated.');
$this->assertFalse($node->getAttribute('foo'));
}
@@ -92,16 +92,16 @@ EOF
*/
public function testAttributeDeprecationWithAlternative()
{
$node = new Node([], ['foo' => false]);
$node = new NodeForTest([], ['foo' => false]);
$node->deprecateAttribute('foo', new NameDeprecation('foo/bar', '2.0', 'bar'));
$this->expectDeprecation('Since foo/bar 2.0: Getting attribute "foo" on a "Twig\Node\Node" class is deprecated, get the "bar" attribute instead.');
$this->expectDeprecation('Since foo/bar 2.0: Getting attribute "foo" on a "Twig\Tests\Node\NodeForTest" class is deprecated, get the "bar" attribute instead.');
$this->assertFalse($node->getAttribute('foo'));
}
public function testNodeDeprecationIgnore()
{
$node = new Node(['foo' => $foo = new Node()], []);
$node = new NodeForTest(['foo' => $foo = new NodeForTest()]);
$node->deprecateNode('foo', new NameDeprecation('foo/bar', '2.0'));
$this->assertSame($foo, $node->getNode('foo', false));
@@ -112,10 +112,10 @@ EOF
*/
public function testNodeDeprecationWithoutAlternative()
{
$node = new Node(['foo' => $foo = new Node()], []);
$node = new NodeForTest(['foo' => $foo = new NodeForTest()]);
$node->deprecateNode('foo', new NameDeprecation('foo/bar', '2.0'));
$this->expectDeprecation('Since foo/bar 2.0: Getting node "foo" on a "Twig\Node\Node" class is deprecated.');
$this->expectDeprecation('Since foo/bar 2.0: Getting node "foo" on a "Twig\Tests\Node\NodeForTest" class is deprecated.');
$this->assertSame($foo, $node->getNode('foo'));
}
@@ -124,10 +124,14 @@ EOF
*/
public function testNodeAttributeDeprecationWithAlternative()
{
$node = new Node(['foo' => $foo = new Node()], []);
$node = new NodeForTest(['foo' => $foo = new NodeForTest()]);
$node->deprecateNode('foo', new NameDeprecation('foo/bar', '2.0', 'bar'));
$this->expectDeprecation('Since foo/bar 2.0: Getting node "foo" on a "Twig\Node\Node" class is deprecated, get the "bar" node instead.');
$this->expectDeprecation('Since foo/bar 2.0: Getting node "foo" on a "Twig\Tests\Node\NodeForTest" class is deprecated, get the "bar" node instead.');
$this->assertSame($foo, $node->getNode('foo'));
}
}
class NodeForTest extends Node
{
}
+12 -12
View File
@@ -16,7 +16,7 @@ use Twig\Loader\ArrayLoader;
use Twig\Node\Expression\AssignNameExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\PrintNode;
use Twig\Node\SetNode;
use Twig\Node\TextNode;
@@ -26,8 +26,8 @@ class SetTest extends NodeTestCase
{
public function testConstructor()
{
$names = new Node([new AssignNameExpression('foo', 1)], [], 1);
$values = new Node([new ConstantExpression('foo', 1)], [], 1);
$names = new Nodes([new AssignNameExpression('foo', 1)], 1);
$values = new Nodes([new ConstantExpression('foo', 1)], 1);
$node = new SetNode(false, $names, $values, 1);
$this->assertEquals($names, $node->getNode('names'));
@@ -39,8 +39,8 @@ class SetTest extends NodeTestCase
{
$tests = [];
$names = new Node([new AssignNameExpression('foo', 1)], [], 1);
$values = new Node([new ConstantExpression('foo', 1)], [], 1);
$names = new Nodes([new AssignNameExpression('foo', 1)], 1);
$values = new Nodes([new ConstantExpression('foo', 1)], 1);
$node = new SetNode(false, $names, $values, 1);
$tests[] = [$node, <<<EOF
// line 1
@@ -48,8 +48,8 @@ class SetTest extends NodeTestCase
EOF
];
$names = new Node([new AssignNameExpression('foo', 1)], [], 1);
$values = new Node([new PrintNode(new ConstantExpression('foo', 1), 1)], [], 1);
$names = new Nodes([new AssignNameExpression('foo', 1)], 1);
$values = new Nodes([new PrintNode(new ConstantExpression('foo', 1), 1)], 1);
$node = new SetNode(true, $names, $values, 1);
$tests[] = [$node, <<<EOF
@@ -72,7 +72,7 @@ EOF
, new Environment(new ArrayLoader(), ['use_yield' => false]),
];
$names = new Node([new AssignNameExpression('foo', 1)], [], 1);
$names = new Nodes([new AssignNameExpression('foo', 1)], 1);
$values = new TextNode('foo', 1);
$node = new SetNode(true, $names, $values, 1);
$tests[] = [$node, <<<EOF
@@ -81,7 +81,7 @@ EOF
EOF
];
$names = new Node([new AssignNameExpression('foo', 1)], [], 1);
$names = new Nodes([new AssignNameExpression('foo', 1)], 1);
$values = new TextNode('', 1);
$node = new SetNode(true, $names, $values, 1);
$tests[] = [$node, <<<EOF
@@ -90,7 +90,7 @@ EOF
EOF
];
$names = new Node([new AssignNameExpression('foo', 1)], [], 1);
$names = new Nodes([new AssignNameExpression('foo', 1)], 1);
$values = new PrintNode(new ConstantExpression('foo', 1), 1);
$node = new SetNode(true, $names, $values, 1);
$tests[] = [$node, <<<EOF
@@ -99,8 +99,8 @@ EOF
EOF
];
$names = new Node([new AssignNameExpression('foo', 1), new AssignNameExpression('bar', 1)], [], 1);
$values = new Node([new ConstantExpression('foo', 1), new NameExpression('bar', 1)], [], 1);
$names = new Nodes([new AssignNameExpression('foo', 1), new AssignNameExpression('bar', 1)], 1);
$values = new Nodes([new ConstantExpression('foo', 1), new NameExpression('bar', 1)], 1);
$node = new SetNode(false, $names, $values, 1);
$tests[] = [$node, <<<'EOF'
// line 1
+2 -2
View File
@@ -16,9 +16,9 @@ use Twig\Environment;
use Twig\Loader\ArrayLoader;
use Twig\Node\BodyNode;
use Twig\Node\CheckToStringNode;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\NameExpression;
use Twig\Node\ModuleNode;
use Twig\Node\Node;
use Twig\Node\PrintNode;
use Twig\NodeTraverser;
use Twig\NodeVisitor\SandboxNodeVisitor;
@@ -31,7 +31,7 @@ class SandboxTest extends TestCase
$env = new Environment(new ArrayLoader());
$expr = new NameExpression('foo', 1);
$expr->setAttribute('is_generator', true);
$node = new ModuleNode(new BodyNode([new PrintNode($expr, 1)]), null, new Node(), new Node(), new Node(), new Node([]), new Source('foo', 'foo'));
$node = new ModuleNode(new BodyNode([new PrintNode($expr, 1)]), null, new EmptyNode(), new EmptyNode(), new EmptyNode(), new EmptyNode(), new Source('foo', 'foo'));
$traverser = new NodeTraverser($env, [new SandboxNodeVisitor($env)]);
$node = $traverser->traverse($node);
+9 -7
View File
@@ -16,7 +16,9 @@ use Twig\Environment;
use Twig\Error\SyntaxError;
use Twig\Lexer;
use Twig\Loader\ArrayLoader;
use Twig\Node\EmptyNode;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Node\SetNode;
use Twig\Node\TextNode;
use Twig\Parser;
@@ -75,15 +77,15 @@ class ParserTest extends TestCase
{
return [
[
new Node([new TextNode(' ', 1)]),
new Node([]),
new Nodes([new TextNode(' ', 1)]),
new Nodes([]),
],
[
$input = new Node([new SetNode(false, new Node(), new Node(), 1)]),
$input = new Nodes([new SetNode(false, new EmptyNode(), new EmptyNode(), 1)]),
$input,
],
[
$input = new Node([new SetNode(true, new Node(), new Node([new Node([new TextNode('foo', 1)])]), 1)]),
$input = new Nodes([new SetNode(true, new EmptyNode(), new Nodes([new Nodes([new TextNode('foo', 1)])]), 1)]),
$input,
],
];
@@ -107,7 +109,7 @@ class ParserTest extends TestCase
{
return [
[new TextNode('foo', 1)],
[new Node([new Node([new TextNode('foo', 1)])])],
[new Nodes([new Nodes([new TextNode('foo', 1)])])],
];
}
@@ -203,7 +205,7 @@ EOF
protected function getParser()
{
$parser = new Parser(new Environment(new ArrayLoader()));
$parser->setParent(new Node());
$parser->setParent(new EmptyNode());
$p = new \ReflectionProperty($parser, 'stream');
$p->setAccessible(true);
@@ -228,7 +230,7 @@ class TestTokenParser extends AbstractTokenParser
$this->parser->getStream()->expect(Token::BLOCK_END_TYPE);
return new Node([], [], 1);
return new EmptyNode(1);
}
public function getTag(): string
@@ -14,10 +14,11 @@ namespace Twig\Tests\Util;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Twig\Error\SyntaxError;
use Twig\Node\EmptyNode;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FunctionExpression;
use Twig\Node\Expression\VariadicExpression;
use Twig\Node\Node;
use Twig\Node\Nodes;
use Twig\Source;
use Twig\TwigFunction;
use Twig\Util\CallableArgumentsExtractor;
@@ -183,13 +184,13 @@ class CallableArgumentsExtractorTest extends TestCase
private function getArguments(string $name, $callable, array $args, bool $isVariadic = false): array
{
$function = new TwigFunction($name, $callable, ['is_variadic' => $isVariadic]);
$node = new ExpressionCall($function, new Node([]), 2);
$node = new ExpressionCall($function, new EmptyNode(), 2);
$node->setSourceContext(new Source('', 'test.twig'));
foreach ($args as $name => $arg) {
$args[$name] = new ConstantExpression($arg, 0);
}
$arguments = (new CallableArgumentsExtractor($node, $function))->extractArguments(new Node($args));
$arguments = (new CallableArgumentsExtractor($node, $function))->extractArguments(new Nodes($args));
foreach ($arguments as $name => $argument) {
$arguments[$name] = $isVariadic ? $argument : $argument->getAttribute('value');
}