mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-30 03:57:21 +00:00
Fix inheritance logic to be able to use instanceof ContextVariable instead of NameExpression
This commit is contained in:
@@ -655,7 +655,7 @@ class ExpressionParser
|
||||
|
||||
$name = null;
|
||||
if ($namedArguments && (($token = $stream->nextIf(Token::OPERATOR_TYPE, '=')) || (!$definition && $token = $stream->nextIf(Token::PUNCTUATION_TYPE, ':')))) {
|
||||
if (!$value instanceof NameExpression) {
|
||||
if (!$value instanceof ContextVariable) {
|
||||
throw new SyntaxError(\sprintf('A parameter name must be a string, "%s" given.', \get_class($value)), $token->getLine(), $stream->getSourceContext());
|
||||
}
|
||||
$name = $value->getAttribute('name');
|
||||
@@ -743,7 +743,7 @@ class ExpressionParser
|
||||
$arguments = new Nodes([0 => $this->getPrimary()]);
|
||||
}
|
||||
|
||||
if ('defined' === $test->getName() && $node instanceof NameExpression && null !== $alias = $this->parser->getImportedSymbol('function', $node->getAttribute('name'))) {
|
||||
if ('defined' === $test->getName() && $node instanceof ContextVariable && null !== $alias = $this->parser->getImportedSymbol('function', $node->getAttribute('name'))) {
|
||||
$node = new MacroReferenceExpression($alias['node']->getNode('var'), $alias['name'], new ArrayExpression([], $node->getTemplateLine()), $node->getTemplateLine());
|
||||
}
|
||||
|
||||
@@ -898,7 +898,7 @@ class ExpressionParser
|
||||
|
||||
$name = null;
|
||||
if (($token = $stream->nextIf(Token::OPERATOR_TYPE, '=')) || ($token = $stream->nextIf(Token::PUNCTUATION_TYPE, ':'))) {
|
||||
if (!$value instanceof NameExpression) {
|
||||
if (!$value instanceof ContextVariable) {
|
||||
throw new SyntaxError(\sprintf('A parameter name must be a string, "%s" given.', \get_class($value)), $token->getLine(), $stream->getSourceContext());
|
||||
}
|
||||
$name = $value->getAttribute('name');
|
||||
@@ -946,7 +946,7 @@ class ExpressionParser
|
||||
}
|
||||
|
||||
if (
|
||||
$node instanceof NameExpression
|
||||
$node instanceof ContextVariable
|
||||
&& (
|
||||
null !== $this->parser->getImportedSymbol('template', $node->getAttribute('name'))
|
||||
|| '_self' === $node->getAttribute('name') && $attribute instanceof ConstantExpression
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Node\Expression\Unary\StringCastUnary;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
|
||||
class ArrayExpression extends AbstractExpression
|
||||
{
|
||||
@@ -99,7 +100,7 @@ class ArrayExpression extends AbstractExpression
|
||||
++$nextIndex;
|
||||
} else {
|
||||
$key = null;
|
||||
if ($pair['key'] instanceof NameExpression) {
|
||||
if ($pair['key'] instanceof ContextVariable) {
|
||||
$pair['key'] = new StringCastUnary($pair['key'], $pair['key']->getTemplateLine());
|
||||
}
|
||||
if ($pair['key'] instanceof TempNameExpression) {
|
||||
|
||||
@@ -15,8 +15,9 @@ namespace Twig\Node\Expression;
|
||||
use Twig\Compiler;
|
||||
use Twig\Error\SyntaxError;
|
||||
use Twig\Node\Expression\Variable\AssignContextVariable;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
|
||||
class AssignNameExpression extends NameExpression
|
||||
class AssignNameExpression extends ContextVariable
|
||||
{
|
||||
public function __construct(string $name, int $lineno)
|
||||
{
|
||||
|
||||
@@ -15,11 +15,11 @@ use Twig\Compiler;
|
||||
use Twig\Node\EmptyNode;
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Expression\BlockReferenceExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\OperatorEscapeInterface;
|
||||
use Twig\Node\Expression\Test\DefinedTest;
|
||||
use Twig\Node\Expression\Test\NullTest;
|
||||
use Twig\Node\Expression\Unary\NotUnary;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\TwigTest;
|
||||
|
||||
final class NullCoalesceBinary extends AbstractBinary implements OperatorEscapeInterface
|
||||
@@ -28,7 +28,7 @@ final class NullCoalesceBinary extends AbstractBinary implements OperatorEscapeI
|
||||
{
|
||||
parent::__construct($left, $right, $lineno);
|
||||
|
||||
if (!$left instanceof NameExpression) {
|
||||
if (!$left instanceof ContextVariable) {
|
||||
$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) {
|
||||
|
||||
@@ -19,9 +19,9 @@ use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Expression\ConstantExpression;
|
||||
use Twig\Node\Expression\FilterExpression;
|
||||
use Twig\Node\Expression\GetAttrExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\Ternary\ConditionalTernary;
|
||||
use Twig\Node\Expression\Test\DefinedTest;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\Node\Node;
|
||||
use Twig\TwigFilter;
|
||||
use Twig\TwigTest;
|
||||
@@ -53,7 +53,7 @@ class DefaultFilter extends FilterExpression
|
||||
$default = new FilterExpression($node, new TwigFilter('default', [CoreExtension::class, 'default']), $arguments, $node->getTemplateLine());
|
||||
}
|
||||
|
||||
if ('default' === $name && ($node instanceof NameExpression || $node instanceof GetAttrExpression)) {
|
||||
if ('default' === $name && ($node instanceof ContextVariable || $node instanceof GetAttrExpression)) {
|
||||
$test = new DefinedTest(clone $node, new TwigTest('defined'), new EmptyNode(), $node->getTemplateLine());
|
||||
$false = \count($arguments) ? $arguments->getNode('0') : new ConstantExpression('', $node->getTemplateLine());
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Extension\SandboxExtension;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\Template;
|
||||
|
||||
class GetAttrExpression extends AbstractExpression
|
||||
@@ -28,7 +29,7 @@ class GetAttrExpression extends AbstractExpression
|
||||
$nodes['arguments'] = $arguments;
|
||||
}
|
||||
|
||||
if ($arguments && !$arguments instanceof ArrayExpression && !$arguments instanceof NameExpression) {
|
||||
if ($arguments && !$arguments instanceof ArrayExpression && !$arguments instanceof ContextVariable) {
|
||||
trigger_deprecation('twig/twig', '3.15', \sprintf('Not passing a "%s" instance as the "arguments" argument of the "%s" constructor is deprecated ("%s" given).', ArrayExpression::class, static::class, $arguments::class));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace Twig\Node\Expression;
|
||||
|
||||
use Twig\Compiler;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
|
||||
class MethodCallExpression extends AbstractExpression
|
||||
{
|
||||
@@ -21,7 +22,7 @@ class MethodCallExpression extends AbstractExpression
|
||||
|
||||
parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false, 'is_defined_test' => false], $lineno);
|
||||
|
||||
if ($node instanceof NameExpression) {
|
||||
if ($node instanceof ContextVariable) {
|
||||
$node->setAttribute('always_defined', true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ use Twig\Node\Expression\Binary\NullCoalesceBinary;
|
||||
use Twig\Node\Expression\Test\DefinedTest;
|
||||
use Twig\Node\Expression\Test\NullTest;
|
||||
use Twig\Node\Expression\Unary\NotUnary;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\Node\Node;
|
||||
use Twig\TwigTest;
|
||||
|
||||
@@ -60,7 +61,7 @@ class NullCoalesceExpression extends ConditionalExpression
|
||||
* cases might be implemented as an optimizer node visitor, but has not been done
|
||||
* as benefits are probably not worth the added complexity.
|
||||
*/
|
||||
if ($this->getNode('expr2') instanceof NameExpression) {
|
||||
if ($this->getNode('expr2') instanceof ContextVariable) {
|
||||
$this->getNode('expr2')->setAttribute('always_defined', true);
|
||||
$compiler
|
||||
->raw('((')
|
||||
|
||||
@@ -24,6 +24,7 @@ use Twig\Node\Expression\MacroReferenceExpression;
|
||||
use Twig\Node\Expression\MethodCallExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\TestExpression;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\Node\Node;
|
||||
use Twig\TwigTest;
|
||||
|
||||
@@ -49,7 +50,7 @@ class DefinedTest extends TestExpression
|
||||
trigger_deprecation('twig/twig', '3.15', 'Not passing a "%s" instance to the "node" argument of "%s" is deprecated ("%s" given).', AbstractExpression::class, static::class, \get_class($node));
|
||||
}
|
||||
|
||||
if ($node instanceof NameExpression) {
|
||||
if ($node instanceof ContextVariable) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} elseif ($node instanceof GetAttrExpression) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
|
||||
@@ -13,6 +13,6 @@ namespace Twig\Node\Expression\Variable;
|
||||
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
|
||||
final class ContextVariable extends NameExpression
|
||||
class ContextVariable extends NameExpression
|
||||
{
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use Twig\Compiler;
|
||||
use Twig\Node\Expression\AbstractExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\Variable\AssignTemplateVariable;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
|
||||
/**
|
||||
* Represents an import node.
|
||||
@@ -44,7 +45,7 @@ class ImportNode extends Node
|
||||
{
|
||||
$compiler->subcompile($this->getNode('var'));
|
||||
|
||||
if ($this->getNode('expr') instanceof NameExpression && '_self' === $this->getNode('expr')->getAttribute('name')) {
|
||||
if ($this->getNode('expr') instanceof ContextVariable && '_self' === $this->getNode('expr')->getAttribute('name')) {
|
||||
$compiler->raw('$this');
|
||||
} else {
|
||||
$compiler
|
||||
|
||||
@@ -19,6 +19,7 @@ use Twig\Node\Expression\FunctionExpression;
|
||||
use Twig\Node\Expression\GetAttrExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\ParentExpression;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\Node\ForNode;
|
||||
use Twig\Node\IncludeNode;
|
||||
use Twig\Node\Node;
|
||||
@@ -137,13 +138,13 @@ final class OptimizerNodeVisitor implements NodeVisitorInterface
|
||||
// when do we need to add the loop variable back?
|
||||
|
||||
// the loop variable is referenced for the current loop
|
||||
elseif ($node instanceof NameExpression && 'loop' === $node->getAttribute('name')) {
|
||||
elseif ($node instanceof ContextVariable && 'loop' === $node->getAttribute('name')) {
|
||||
$node->setAttribute('always_defined', true);
|
||||
$this->addLoopToCurrent();
|
||||
}
|
||||
|
||||
// optimize access to loop targets
|
||||
elseif ($node instanceof NameExpression && \in_array($node->getAttribute('name'), $this->loopsTargets)) {
|
||||
elseif ($node instanceof ContextVariable && \in_array($node->getAttribute('name'), $this->loopsTargets)) {
|
||||
$node->setAttribute('always_defined', true);
|
||||
}
|
||||
|
||||
@@ -173,7 +174,7 @@ final class OptimizerNodeVisitor implements NodeVisitorInterface
|
||||
|| 'parent' === $node->getNode('attribute')->getAttribute('value')
|
||||
)
|
||||
&& (true === $this->loops[0]->getAttribute('with_loop')
|
||||
|| ($node->getNode('node') instanceof NameExpression
|
||||
|| ($node->getNode('node') instanceof ContextVariable
|
||||
&& 'loop' === $node->getNode('node')->getAttribute('name')
|
||||
)
|
||||
)
|
||||
|
||||
@@ -22,6 +22,7 @@ use Twig\Node\Expression\MethodCallExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\OperatorEscapeInterface;
|
||||
use Twig\Node\Expression\ParentExpression;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\Node\Node;
|
||||
|
||||
/**
|
||||
@@ -146,7 +147,7 @@ final class SafeAnalysisNodeVisitor implements NodeVisitorInterface
|
||||
} elseif ($node instanceof MethodCallExpression || $node instanceof MacroReferenceExpression) {
|
||||
// all macro calls are safe
|
||||
$this->setSafe($node, ['all']);
|
||||
} elseif ($node instanceof GetAttrExpression && $node->getNode('node') instanceof NameExpression) {
|
||||
} elseif ($node instanceof GetAttrExpression && $node->getNode('node') instanceof ContextVariable) {
|
||||
$name = $node->getNode('node')->getAttribute('name');
|
||||
if (\in_array($name, $this->safeVars)) {
|
||||
$this->setSafe($node, ['all']);
|
||||
|
||||
@@ -23,6 +23,7 @@ use Twig\Node\Expression\FunctionExpression;
|
||||
use Twig\Node\Expression\GetAttrExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\Unary\SpreadUnary;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\Node\ModuleNode;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Node\Nodes;
|
||||
@@ -122,7 +123,7 @@ final class SandboxNodeVisitor implements NodeVisitorInterface
|
||||
private function wrapNode(Node $node, string $name): void
|
||||
{
|
||||
$expr = $node->getNode($name);
|
||||
if (($expr instanceof NameExpression || $expr instanceof GetAttrExpression) && !$expr->isGenerator()) {
|
||||
if (($expr instanceof ContextVariable || $expr instanceof GetAttrExpression) && !$expr->isGenerator()) {
|
||||
// Simplify in 4.0 as the spread attribute has been removed there
|
||||
$new = new CheckToStringNode($expr);
|
||||
if ($expr->hasAttribute('spread')) {
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Twig\TokenParser;
|
||||
use Twig\Node\EmbedNode;
|
||||
use Twig\Node\Expression\ConstantExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\Variable\ContextVariable;
|
||||
use Twig\Node\Node;
|
||||
use Twig\Token;
|
||||
|
||||
@@ -35,7 +36,7 @@ final class EmbedTokenParser extends IncludeTokenParser
|
||||
$parentToken = $fakeParentToken = new Token(Token::STRING_TYPE, '__parent__', $token->getLine());
|
||||
if ($parent instanceof ConstantExpression) {
|
||||
$parentToken = new Token(Token::STRING_TYPE, $parent->getAttribute('value'), $token->getLine());
|
||||
} elseif ($parent instanceof NameExpression) {
|
||||
} elseif ($parent instanceof ContextVariable) {
|
||||
$parentToken = new Token(Token::NAME_TYPE, $parent->getAttribute('name'), $token->getLine());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user