mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-30 03:57:21 +00:00
Move extends validation into correctness visitor
This commit is contained in:
@@ -42,6 +42,7 @@ final class CorrectnessNodeVisitor implements NodeVisitorInterface
|
||||
private bool $hasParent = false;
|
||||
private int $blockDepth = 0;
|
||||
private int $macroDepth = 0;
|
||||
private ?ConfigNode $extendsNode = null;
|
||||
|
||||
public function enterNode(Node $node, Environment $env): Node
|
||||
{
|
||||
@@ -52,6 +53,7 @@ final class CorrectnessNodeVisitor implements NodeVisitorInterface
|
||||
$this->tagStack = [];
|
||||
$this->blockDepth = 0;
|
||||
$this->macroDepth = 0;
|
||||
$this->extendsNode = null;
|
||||
|
||||
$body = $node->getNode('body')->getNode('0');
|
||||
// Parser::subparse() does not wrap the parsed nodes when there is only one,
|
||||
@@ -77,15 +79,21 @@ final class CorrectnessNodeVisitor implements NodeVisitorInterface
|
||||
$this->tagStack[] = $node;
|
||||
}
|
||||
|
||||
if ($node instanceof ConfigNode && !isset($this->rootNodes[$node])) {
|
||||
if ($node instanceof ConfigNode && 'extends' === $node->getNodeTag()) {
|
||||
// "extends" inside a "block" or a "macro" has always been a hard error; keep it
|
||||
if ('extends' === $node->getNodeTag() && $this->blockDepth) {
|
||||
if ($this->blockDepth) {
|
||||
throw new SyntaxError('Cannot use "extend" in a block.', $node->getTemplateLine(), $node->getSourceContext());
|
||||
}
|
||||
if ('extends' === $node->getNodeTag() && $this->macroDepth) {
|
||||
if ($this->macroDepth) {
|
||||
throw new SyntaxError('Cannot use "extend" in a macro.', $node->getTemplateLine(), $node->getSourceContext());
|
||||
}
|
||||
if ($this->extendsNode) {
|
||||
throw new SyntaxError('Multiple extends tags are forbidden.', $node->getTemplateLine(), $node->getSourceContext());
|
||||
}
|
||||
$this->extendsNode = $node;
|
||||
}
|
||||
|
||||
if ($node instanceof ConfigNode && !isset($this->rootNodes[$node])) {
|
||||
trigger_deprecation('twig/twig', '3.27', 'Using the "%s" tag outside the root of a template is deprecated in %s at line %d.', $node->getNodeTag(), $node->getSourceContext()->getName(), $node->getTemplateLine());
|
||||
}
|
||||
|
||||
@@ -112,6 +120,7 @@ final class CorrectnessNodeVisitor implements NodeVisitorInterface
|
||||
if ($node instanceof ModuleNode) {
|
||||
$this->rootNodes = null;
|
||||
$this->hasParent = false;
|
||||
$this->extendsNode = null;
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
+5
-1
@@ -414,7 +414,7 @@ class Parser
|
||||
return $this->parent || 0 < \count($this->traits);
|
||||
}
|
||||
|
||||
public function setParent(?Node $parent): void
|
||||
public function setParent(?Node $parent, bool $throwOnMultiple = true): void
|
||||
{
|
||||
if (null === $parent) {
|
||||
trigger_deprecation('twig/twig', '3.12', 'Passing "null" to "%s()" is deprecated.', __METHOD__);
|
||||
@@ -425,6 +425,10 @@ class Parser
|
||||
}
|
||||
|
||||
if (null !== $this->parent) {
|
||||
if (!$throwOnMultiple) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new SyntaxError('Multiple extends tags are forbidden.', $parent->getTemplateLine(), $parent->getSourceContext());
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
namespace Twig\TokenParser;
|
||||
|
||||
use Twig\Error\SyntaxError;
|
||||
use Twig\Node\ConfigNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Token;
|
||||
@@ -29,14 +28,7 @@ final class ExtendsTokenParser extends AbstractTokenParser
|
||||
public function parse(Token $token): Node
|
||||
{
|
||||
$stream = $this->parser->getStream();
|
||||
|
||||
if ($this->parser->peekBlockStack()) {
|
||||
throw new SyntaxError('Cannot use "extend" in a block.', $token->getLine(), $stream->getSourceContext());
|
||||
} elseif (!$this->parser->isMainScope()) {
|
||||
throw new SyntaxError('Cannot use "extend" in a macro.', $token->getLine(), $stream->getSourceContext());
|
||||
}
|
||||
|
||||
$this->parser->setParent($this->parser->parseExpression());
|
||||
$this->parser->setParent($this->parser->parseExpression(), false);
|
||||
$stream->expect(Token::BLOCK_END_TYPE);
|
||||
|
||||
return new ConfigNode($token->getLine());
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
Multiple "extends" tags are forbidden
|
||||
--TEMPLATE--
|
||||
{% extends "base.twig" %}
|
||||
{% extends "other.twig" %}
|
||||
--TEMPLATE(base.twig)--
|
||||
--TEMPLATE(other.twig)--
|
||||
--DATA--
|
||||
return []
|
||||
--EXCEPTION--
|
||||
Twig\Error\SyntaxError: Multiple extends tags are forbidden in "index.twig" at line 3.
|
||||
Reference in New Issue
Block a user