Deprecate some internal methods from Parser

This commit is contained in:
Fabien Potencier
2024-08-26 09:01:52 +02:00
parent a8c5100e45
commit 9e6c4a6ac1
8 changed files with 46 additions and 11 deletions
+1
View File
@@ -1,5 +1,6 @@
# 3.12.0 (2024-XX-XX)
* Deprecate some internal methods from `Parser`: `getBlockStack()`, `hasBlock()`, `getBlock()`, `hasMacro()`, `hasTraits()`, `getParent()`
* Deprecate passing `null` to `Twig\Parser::setParent()`
* Update `Node::__toString()` to include the node tag if set
* Add support for integers in methods of `Twig\Node\Node` that take a Node name
+4
View File
@@ -160,6 +160,10 @@ Node Visitors
Parser
------
* The following methods from ``Twig\Parser`` are deprecated as of Twig 3.12:
``getBlockStack()``, ``hasBlock()``, ``getBlock()``, ``hasMacro()``,
``hasTraits()``, ``getParent()``.
* The ``Twig\ExpressionParser::parseHashExpression()`` method is deprecated, use
``Twig\ExpressionParser::parseMappingExpression()`` instead.
+5 -5
View File
@@ -1919,15 +1919,15 @@ final class CoreExtension extends AbstractExtension
*/
public static function parseParentFunction(Parser $parser, Node $fakeNode, $args, int $line): AbstractExpression
{
if (!\count($parser->getBlockStack())) {
throw new SyntaxError('Calling "parent" outside a block is forbidden.', $line, $parser->getStream()->getSourceContext());
if (!$blockName = $parser->peekBlockStack()) {
throw new SyntaxError('Calling the "parent" function outside of a block is forbidden.', $line, $parser->getStream()->getSourceContext());
}
if (!$parser->getParent() && !$parser->hasTraits()) {
throw new SyntaxError('Calling "parent" on a template that does not extend nor "use" another template is forbidden.', $line, $parser->getStream()->getSourceContext());
if (!$parser->hasInheritance()) {
throw new SyntaxError('Calling the "parent" function on a template that does not call "extends" or "use" is forbidden.', $line, $parser->getStream()->getSourceContext());
}
return new ParentExpression($parser->peekBlockStack(), $line);
return new ParentExpression($blockName, $line);
}
/**
+22 -1
View File
@@ -92,7 +92,7 @@ class Parser
}
if (!$e->getTemplateLine()) {
$e->setTemplateLine($this->stream->getCurrent()->getLine());
$e->setTemplateLine($this->getCurrentToken()->getLine());
}
throw $e;
@@ -194,6 +194,8 @@ class Parser
public function getBlockStack(): array
{
trigger_deprecation('twig/twig', '3.12', 'Method "%s()" is deprecated.', __METHOD__);
return $this->blockStack;
}
@@ -214,21 +216,31 @@ class Parser
public function hasBlock(string $name): bool
{
trigger_deprecation('twig/twig', '3.12', 'Method "%s()" is deprecated.', __METHOD__);
return isset($this->blocks[$name]);
}
public function getBlock(string $name): Node
{
trigger_deprecation('twig/twig', '3.12', 'Method "%s()" is deprecated.', __METHOD__);
return $this->blocks[$name];
}
public function setBlock(string $name, BlockNode $value): void
{
if (isset($this->blocks[$name])) {
throw new SyntaxError(\sprintf("The block '%s' has already been defined line %d.", $name, $this->blocks[$name]->getTemplateLine()), $this->getCurrentToken()->getLine(), $this->blocks[$name]->getSourceContext());
}
$this->blocks[$name] = new BodyNode([$value], [], $value->getTemplateLine());
}
public function hasMacro(string $name): bool
{
trigger_deprecation('twig/twig', '3.12', 'Method "%s()" is deprecated.', __METHOD__);
return isset($this->macros[$name]);
}
@@ -244,6 +256,8 @@ class Parser
public function hasTraits(): bool
{
trigger_deprecation('twig/twig', '3.12', 'Method "%s()" is deprecated.', __METHOD__);
return \count($this->traits) > 0;
}
@@ -287,9 +301,16 @@ class Parser
public function getParent(): ?Node
{
trigger_deprecation('twig/twig', '3.12', 'Method "%s()" is deprecated.', __METHOD__);
return $this->parent;
}
public function hasInheritance()
{
return $this->parent || 0 < \count($this->traits);
}
public function setParent(?Node $parent): void
{
if (null === $parent) {
-3
View File
@@ -36,9 +36,6 @@ final class BlockTokenParser extends AbstractTokenParser
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$name = $stream->expect(Token::NAME_TYPE)->getValue();
if ($this->parser->hasBlock($name)) {
throw new SyntaxError(\sprintf("The block '%s' has already been defined line %d.", $name, $this->parser->getBlock($name)->getTemplateLine()), $stream->getCurrent()->getLine(), $stream->getSourceContext());
}
$this->parser->setBlock($name, $block = new BlockNode($name, new Node([]), $lineno));
$this->parser->pushLocalScope();
$this->parser->pushBlockStack($name);
@@ -0,0 +1,10 @@
--TEST--
"parent" cannot be called outside of a block
--TEMPLATE--
{% extends "parent.twig" %}
{{ parent() }}
--TEMPLATE(parent.twig)--
--DATA--
return []
--EXCEPTION--
Twig\Error\SyntaxError: Calling the "parent" function outside of a block is forbidden in "index.twig" at line 3.
@@ -5,4 +5,4 @@
{{ parent() }}
{% endblock %}
--EXCEPTION--
Twig\Error\SyntaxError: Calling "parent" on a template that does not extend nor "use" another template is forbidden in "index.twig" at line 3.
Twig\Error\SyntaxError: Calling the "parent" function on a template that does not call "extends" or "use" is forbidden in "index.twig" at line 3.
+3 -1
View File
@@ -151,7 +151,9 @@ class ParserTest extends TestCase
new Token(Token::EOF_TYPE, '', 1),
]));
$this->assertNull($parser->getParent());
$p = new \ReflectionProperty($parser, 'parent');
$p->setAccessible(true);
$this->assertNull($p->getValue($parser));
}
public function testGetVarName()