From 8b278986b8645512dd013807404cc6be903de652 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 24 Sep 2024 17:36:20 +0200 Subject: [PATCH] Deprecate using Node directly, introduce EmptyNode and Nodes --- CHANGELOG | 1 + doc/deprecated.rst | 7 ++++ src/ExpressionParser.php | 20 ++++++----- src/Node/EmptyNode.php | 28 +++++++++++++++ src/Node/Expression/Filter/DefaultFilter.php | 3 +- src/Node/Expression/Filter/RawFilter.php | 3 +- .../Expression/NullCoalesceExpression.php | 5 +-- src/Node/ForNode.php | 2 +- src/Node/ModuleNode.php | 12 +++---- src/Node/Node.php | 4 +++ src/Node/Nodes.php | 28 +++++++++++++++ src/Node/SetNode.php | 3 +- src/NodeVisitor/EscaperNodeVisitor.php | 3 +- src/NodeVisitor/SandboxNodeVisitor.php | 5 +-- src/Parser.php | 13 ++++--- .../NodeVisitor/ProfilerNodeVisitor.php | 5 +-- src/TokenParser/ApplyTokenParser.php | 5 +-- src/TokenParser/BlockTokenParser.php | 6 ++-- src/TokenParser/ExtendsTokenParser.php | 3 +- src/TokenParser/IfTokenParser.php | 3 +- src/TokenParser/MacroTokenParser.php | 3 +- src/TokenParser/UseTokenParser.php | 6 ++-- tests/Node/AutoEscapeTest.php | 6 ++-- tests/Node/DeprecatedTest.php | 9 ++--- tests/Node/Expression/CallTest.php | 4 +-- tests/Node/Expression/FilterTest.php | 7 ++-- tests/Node/Expression/FunctionTest.php | 7 ++-- tests/Node/Expression/TestTest.php | 9 ++--- tests/Node/ForTest.php | 12 +++---- tests/Node/IfTest.php | 18 +++++----- tests/Node/MacroTest.php | 8 ++--- tests/Node/ModuleTest.php | 25 ++++++------- tests/Node/NodeTest.php | 36 ++++++++++--------- tests/Node/SetTest.php | 24 ++++++------- tests/NodeVisitor/SandboxTest.php | 4 +-- tests/ParserTest.php | 16 +++++---- tests/Util/CallableArgumentsExtractorTest.php | 7 ++-- 37 files changed, 230 insertions(+), 130 deletions(-) create mode 100644 src/Node/EmptyNode.php create mode 100644 src/Node/Nodes.php diff --git a/CHANGELOG b/CHANGELOG index 8fcd964030f..e1d01be3c41 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -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()` diff --git a/doc/deprecated.rst b/doc/deprecated.rst index 3a80f632249..2488e761dd5 100644 --- a/doc/deprecated.rst +++ b/doc/deprecated.rst @@ -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. diff --git a/src/ExpressionParser.php b/src/ExpressionParser.php index d45860840a8..cd1b1993eb6 100644 --- a/src/ExpressionParser.php +++ b/src/ExpressionParser.php @@ -14,6 +14,7 @@ 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\PosUnary; use Twig\Node\Expression\Unary\SpreadUnary; use Twig\Node\Node; +use Twig\Node\Nodes; /** * Parses expressions. @@ -110,7 +112,7 @@ private function parseArrow() $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 @@ private function parseArrow() $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 @@ public function getFunctionNode($name, $line) $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 @@ public function parseSubscriptExpression($node) } $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 @@ public function parseFilterExpressionRaw($node) $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 @@ public function parseArguments($namedArguments = false, $definition = false, $al } $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 @@ public function parseAssignmentExpression() } } - return new Node($targets); + return new Nodes($targets); } public function parseMultitargetExpression() @@ -730,7 +732,7 @@ public function parseMultitargetExpression() } } - return new Node($targets); + return new Nodes($targets); } private function parseNotTestExpression(Node $node): NotUnary @@ -747,7 +749,7 @@ private function parseTestExpression(Node $node): TestExpression 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'))) { diff --git a/src/Node/EmptyNode.php b/src/Node/EmptyNode.php new file mode 100644 index 00000000000..95ee5408e4b --- /dev/null +++ b/src/Node/EmptyNode.php @@ -0,0 +1,28 @@ + + */ +#[YieldReady] +final class EmptyNode extends Node +{ + public function __construct(int $lineno = 0) + { + parent::__construct([], [], $lineno); + } +} diff --git a/src/Node/Expression/Filter/DefaultFilter.php b/src/Node/Expression/Filter/DefaultFilter.php index 75b6d18c287..fa93e227ca4 100644 --- a/src/Node/Expression/Filter/DefaultFilter.php +++ b/src/Node/Expression/Filter/DefaultFilter.php @@ -14,6 +14,7 @@ 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 @@ public function __construct(Node $node, TwigFilter|ConstantExpression $filter, N } 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()); diff --git a/src/Node/Expression/Filter/RawFilter.php b/src/Node/Expression/Filter/RawFilter.php index e115ab19410..adb6de7895f 100644 --- a/src/Node/Expression/Filter/RawFilter.php +++ b/src/Node/Expression/Filter/RawFilter.php @@ -13,6 +13,7 @@ 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 diff --git a/src/Node/Expression/NullCoalesceExpression.php b/src/Node/Expression/NullCoalesceExpression.php index 98630f7f068..dd2384f9562 100644 --- a/src/Node/Expression/NullCoalesceExpression.php +++ b/src/Node/Expression/NullCoalesceExpression.php @@ -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() ); } diff --git a/src/Node/ForNode.php b/src/Node/ForNode.php index 2fc014792ab..53a950a90ca 100644 --- a/src/Node/ForNode.php +++ b/src/Node/ForNode.php @@ -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) { diff --git a/src/Node/ModuleNode.php b/src/Node/ModuleNode.php index f67c3b0e76c..ddb3f734622 100644 --- a/src/Node/ModuleNode.php +++ b/src/Node/ModuleNode.php @@ -44,11 +44,11 @@ public function __construct(Node $body, ?AbstractExpression $parent, Node $block '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 @@ protected function compileIsTraitable(Compiler $compiler) } if (!\count($nodes)) { - $nodes = new Node([$nodes]); + $nodes = new Nodes([$nodes]); } foreach ($nodes as $node) { diff --git a/src/Node/Node.php b/src/Node/Node.php index 275e61e2d68..d2fcb30ce37 100644 --- a/src/Node/Node.php +++ b/src/Node/Node.php @@ -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)); diff --git a/src/Node/Nodes.php b/src/Node/Nodes.php new file mode 100644 index 00000000000..bd67053abe1 --- /dev/null +++ b/src/Node/Nodes.php @@ -0,0 +1,28 @@ + + */ +#[YieldReady] +final class Nodes extends Node +{ + public function __construct(array $nodes = [], int $lineno = 0) + { + parent::__construct($nodes, [], $lineno); + } +} diff --git a/src/Node/SetNode.php b/src/Node/SetNode.php index 288911a5c22..6e0661edb51 100644 --- a/src/Node/SetNode.php +++ b/src/Node/SetNode.php @@ -33,7 +33,8 @@ public function __construct(bool $capture, Node $names, Node $values, int $linen $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) { diff --git a/src/NodeVisitor/EscaperNodeVisitor.php b/src/NodeVisitor/EscaperNodeVisitor.php index 32f49ab1e8e..a4a415c9a39 100644 --- a/src/NodeVisitor/EscaperNodeVisitor.php +++ b/src/NodeVisitor/EscaperNodeVisitor.php @@ -24,6 +24,7 @@ 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 @@ private function getEscaperFilter(Environment $env, string $type, Node $node): F { $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); } diff --git a/src/NodeVisitor/SandboxNodeVisitor.php b/src/NodeVisitor/SandboxNodeVisitor.php index 37e184a3edc..ab51d33d4a0 100644 --- a/src/NodeVisitor/SandboxNodeVisitor.php +++ b/src/NodeVisitor/SandboxNodeVisitor.php @@ -23,6 +23,7 @@ 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 @@ public function leaveNode(Node $node, Environment $env): ?Node 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; diff --git a/src/Parser.php b/src/Parser.php index 40370bb1bf2..d30868a069a 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -16,12 +16,14 @@ 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 @@ public function parse(TokenStream $stream, $test = null, bool $dropNeedle = fals $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 @@ public function parse(TokenStream $stream, $test = null, bool $dropNeedle = fals 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 @@ public function subparse($test, bool $dropNeedle = false): Node return $rv[0]; } - return new Node($rv, [], $lineno); + return new Nodes($rv, $lineno); } if (!$subparser = $this->env->getTokenParser($token->getValue())) { @@ -189,7 +191,7 @@ public function subparse($test, bool $dropNeedle = false): Node return $rv[0]; } - return new Node($rv, [], $lineno); + return new Nodes($rv, $lineno); } public function getBlockStack(): array @@ -371,7 +373,8 @@ private function filterBodyNodes(Node $node, bool $nested = false): ?Node // 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); diff --git a/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php b/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php index 1458bc5fcc8..4c5c2005d21 100644 --- a/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php +++ b/src/Profiler/NodeVisitor/ProfilerNodeVisitor.php @@ -17,6 +17,7 @@ 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 @@ public function enterNode(Node $node, Environment $env): Node 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), diff --git a/src/TokenParser/ApplyTokenParser.php b/src/TokenParser/ApplyTokenParser.php index 0a6c1afb513..58c2a3ee4e2 100644 --- a/src/TokenParser/ApplyTokenParser.php +++ b/src/TokenParser/ApplyTokenParser.php @@ -13,6 +13,7 @@ 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 @@ public function parse(Token $token): Node $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 diff --git a/src/TokenParser/BlockTokenParser.php b/src/TokenParser/BlockTokenParser.php index 81d675db0d9..3561b99cdd7 100644 --- a/src/TokenParser/BlockTokenParser.php +++ b/src/TokenParser/BlockTokenParser.php @@ -15,7 +15,9 @@ 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 @@ public function parse(Token $token): Node $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 @@ public function parse(Token $token): Node } } } else { - $body = new Node([ + $body = new Nodes([ new PrintNode($this->parser->getExpressionParser()->parseExpression(), $lineno), ]); } diff --git a/src/TokenParser/ExtendsTokenParser.php b/src/TokenParser/ExtendsTokenParser.php index 86ddfdfba34..a93afe8cd59 100644 --- a/src/TokenParser/ExtendsTokenParser.php +++ b/src/TokenParser/ExtendsTokenParser.php @@ -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 @@ public function parse(Token $token): Node $stream->expect(Token::BLOCK_END_TYPE); - return new Node([], [], $token->getLine()); + return new EmptyNode($token->getLine()); } public function getTag(): string diff --git a/src/TokenParser/IfTokenParser.php b/src/TokenParser/IfTokenParser.php index 4ea6f3df9c3..6b90105633b 100644 --- a/src/TokenParser/IfTokenParser.php +++ b/src/TokenParser/IfTokenParser.php @@ -15,6 +15,7 @@ use Twig\Error\SyntaxError; use Twig\Node\IfNode; use Twig\Node\Node; +use Twig\Node\Nodes; use Twig\Token; /** @@ -69,7 +70,7 @@ public function parse(Token $token): Node $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 diff --git a/src/TokenParser/MacroTokenParser.php b/src/TokenParser/MacroTokenParser.php index c7762075c56..8dab480f9d2 100644 --- a/src/TokenParser/MacroTokenParser.php +++ b/src/TokenParser/MacroTokenParser.php @@ -13,6 +13,7 @@ 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 @@ public function parse(Token $token): Node $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 diff --git a/src/TokenParser/UseTokenParser.php b/src/TokenParser/UseTokenParser.php index 1b96b40478e..ebd95aa317f 100644 --- a/src/TokenParser/UseTokenParser.php +++ b/src/TokenParser/UseTokenParser.php @@ -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 @@ public function parse(Token $token): Node $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 diff --git a/tests/Node/AutoEscapeTest.php b/tests/Node/AutoEscapeTest.php index 546d4345546..29dbf83a538 100644 --- a/tests/Node/AutoEscapeTest.php +++ b/tests/Node/AutoEscapeTest.php @@ -12,7 +12,7 @@ */ 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 @@ public function testConstructor() 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 [ diff --git a/tests/Node/DeprecatedTest.php b/tests/Node/DeprecatedTest.php index 9738b2ff4cf..fe646a0355a 100644 --- a/tests/Node/DeprecatedTest.php +++ b/tests/Node/DeprecatedTest.php @@ -15,10 +15,11 @@ 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 @@ public static function provideTests(): iterable 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 @@ public static function provideTests(): iterable $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)); diff --git a/tests/Node/Expression/CallTest.php b/tests/Node/Expression/CallTest.php index 75cac054734..a77834ced56 100644 --- a/tests/Node/Expression/CallTest.php +++ b/tests/Node/Expression/CallTest.php @@ -13,8 +13,8 @@ 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 @@ private function getArguments($call, $args) 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); } } diff --git a/tests/Node/Expression/FilterTest.php b/tests/Node/Expression/FilterTest.php index 78bf5066426..ff4484d4efd 100644 --- a/tests/Node/Expression/FilterTest.php +++ b/tests/Node/Expression/FilterTest.php @@ -15,9 +15,10 @@ 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 @@ public function testConstructor() { $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 @@ public function testCompileWithMissingNamedArgument() 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 diff --git a/tests/Node/Expression/FunctionTest.php b/tests/Node/Expression/FunctionTest.php index a6e562c06ce..97c215c398e 100644 --- a/tests/Node/Expression/FunctionTest.php +++ b/tests/Node/Expression/FunctionTest.php @@ -13,9 +13,10 @@ 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 @@ public static function provideTests(): iterable 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 diff --git a/tests/Node/Expression/TestTest.php b/tests/Node/Expression/TestTest.php index ddda8a486b4..0e9459c3bd9 100644 --- a/tests/Node/Expression/TestTest.php +++ b/tests/Node/Expression/TestTest.php @@ -13,10 +13,11 @@ 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 @@ public function testConstructor() { $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 @@ public static function provideTests(): iterable $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 @@ public static function provideTests(): iterable 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 diff --git a/tests/Node/ForTest.php b/tests/Node/ForTest.php index 047c2a1092d..4f96e94c4f8 100644 --- a/tests/Node/ForTest.php +++ b/tests/Node/ForTest.php @@ -14,7 +14,7 @@ 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 @@ public function testConstructor() $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 @@ public static function provideTests(): iterable $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 @@ public static function provideTests(): iterable $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 @@ public static function provideTests(): iterable $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 @@ public static function provideTests(): iterable $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); diff --git a/tests/Node/IfTest.php b/tests/Node/IfTest.php index 4736def3ffa..c3939f1e000 100644 --- a/tests/Node/IfTest.php +++ b/tests/Node/IfTest.php @@ -14,7 +14,7 @@ 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 @@ public static function provideTests(): iterable { $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 @@ public static function provideTests(): iterable 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 @@ public static function provideTests(): iterable 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); diff --git a/tests/Node/MacroTest.php b/tests/Node/MacroTest.php index 6fb6062cbd3..7321c780197 100644 --- a/tests/Node/MacroTest.php +++ b/tests/Node/MacroTest.php @@ -17,7 +17,7 @@ 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 @@ public function testConstructor() 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); diff --git a/tests/Node/ModuleTest.php b/tests/Node/ModuleTest.php index 21f59c8b0cf..bee23c28066 100644 --- a/tests/Node/ModuleTest.php +++ b/tests/Node/ModuleTest.php @@ -14,12 +14,13 @@ 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 @@ public function testConstructor() { $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 @@ public static function provideTests(): iterable $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, << '{{ 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, << function () { return '1'; }], 1); + $node = new NodeForTest([], ['value' => function () { return '1'; }], 1); $this->assertEquals(<< new TwigFunction('a_function'), 'filter' => new TwigFilter('a_filter'), 'test' => new TwigTest('a_test'), ], 1); $this->assertEquals(<<setNodeTag('tag'); $this->assertEquals(<< 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 @@ public function testAttributeDeprecationIgnore() */ 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 @@ public function testAttributeDeprecationWithoutAlternative() */ 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 @@ public function testNodeDeprecationIgnore() */ 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 @@ public function testNodeDeprecationWithoutAlternative() */ 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 +{ +} \ No newline at end of file diff --git a/tests/Node/SetTest.php b/tests/Node/SetTest.php index 06f0407dd2b..6283884afe8 100644 --- a/tests/Node/SetTest.php +++ b/tests/Node/SetTest.php @@ -16,7 +16,7 @@ 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 @@ public static function provideTests(): iterable { $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, << 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, <<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); diff --git a/tests/ParserTest.php b/tests/ParserTest.php index dc45fd66d30..0602d8d0f77 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -16,7 +16,9 @@ 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 @@ public static function getFilterBodyNodesData() { 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 @@ public static function getFilterBodyNodesDataThrowsException() { 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 @@ public function testImplicitMacroArgumentDefaultValues() 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 @@ public function parse(Token $token): Node $this->parser->getStream()->expect(Token::BLOCK_END_TYPE); - return new Node([], [], 1); + return new EmptyNode(1); } public function getTag(): string diff --git a/tests/Util/CallableArgumentsExtractorTest.php b/tests/Util/CallableArgumentsExtractorTest.php index 182283183ad..a06e19aa9a1 100644 --- a/tests/Util/CallableArgumentsExtractorTest.php +++ b/tests/Util/CallableArgumentsExtractorTest.php @@ -14,10 +14,11 @@ 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 @@ public function customFunctionWithArbitraryArguments() 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'); }