mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-12 18:36:53 +00:00
added support for macros on "is defined" tests
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
* 2.11.0 (2019-XX-XX)
|
||||
|
||||
* added support for macros on "is defined" tests
|
||||
* fixed macros "import" when using the same name in the parent and child templates
|
||||
* fixed recursive macros
|
||||
* macros imported "globally" in a template are now available in macros without re-importing them
|
||||
|
||||
@@ -679,6 +679,11 @@ class ExpressionParser
|
||||
$arguments = $this->parseArguments(true);
|
||||
}
|
||||
|
||||
if ('defined' === $name && $node instanceof NameExpression && null !== $alias = $this->parser->getImportedSymbol('function', $node->getAttribute('name'))) {
|
||||
$node = new MethodCallExpression($alias['node'], $alias['name'], new ArrayExpression([], $node->getTemplateLine()), $node->getTemplateLine());
|
||||
$node->setAttribute('safe', true);
|
||||
}
|
||||
|
||||
return new $class($node, $name, $arguments, $this->parser->getCurrentToken()->getLine());
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ class MethodCallExpression extends AbstractExpression
|
||||
{
|
||||
public function __construct(AbstractExpression $node, string $method, ArrayExpression $arguments, int $lineno)
|
||||
{
|
||||
parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false], $lineno);
|
||||
parent::__construct(['node' => $node, 'arguments' => $arguments], ['method' => $method, 'safe' => false, 'is_defined_test' => false], $lineno);
|
||||
|
||||
if ($node instanceof NameExpression) {
|
||||
$node->setAttribute('always_defined', true);
|
||||
@@ -26,6 +26,18 @@ class MethodCallExpression extends AbstractExpression
|
||||
|
||||
public function compile(Compiler $compiler)
|
||||
{
|
||||
if ($this->getAttribute('is_defined_test')) {
|
||||
$compiler
|
||||
->raw('method_exists($macros[')
|
||||
->repr($this->getNode('node')->getAttribute('name'))
|
||||
->raw('], ')
|
||||
->repr($this->getAttribute('method'))
|
||||
->raw(')')
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$compiler
|
||||
->raw('$macros[')
|
||||
->repr($this->getNode('node')->getAttribute('name'))
|
||||
|
||||
@@ -18,6 +18,7 @@ use Twig\Node\Expression\BlockReferenceExpression;
|
||||
use Twig\Node\Expression\ConstantExpression;
|
||||
use Twig\Node\Expression\FunctionExpression;
|
||||
use Twig\Node\Expression\GetAttrExpression;
|
||||
use Twig\Node\Expression\MethodCallExpression;
|
||||
use Twig\Node\Expression\NameExpression;
|
||||
use Twig\Node\Expression\TestExpression;
|
||||
use Twig\Node\Node;
|
||||
@@ -47,6 +48,8 @@ class DefinedTest extends TestExpression
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} elseif ($node instanceof ConstantExpression || $node instanceof ArrayExpression) {
|
||||
$node = new ConstantExpression(true, $node->getTemplateLine());
|
||||
} elseif ($node instanceof MethodCallExpression) {
|
||||
$node->setAttribute('is_defined_test', true);
|
||||
} else {
|
||||
throw new SyntaxError('The "defined" test only works with simple variables.', $lineno);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
--TEST--
|
||||
"defined" support for macros
|
||||
--TEMPLATE--
|
||||
{% import _self as macros %}
|
||||
{% from _self import hello, bar %}
|
||||
|
||||
{% if macros.hello is defined -%}
|
||||
OK
|
||||
{% endif %}
|
||||
|
||||
{% if macros.foo is not defined -%}
|
||||
OK
|
||||
{% endif %}
|
||||
|
||||
{% if hello is defined -%}
|
||||
OK
|
||||
{% endif %}
|
||||
|
||||
{% if bar is not defined -%}
|
||||
OK
|
||||
{% endif %}
|
||||
|
||||
{% if foo is not defined -%}
|
||||
OK
|
||||
{% endif %}
|
||||
|
||||
{% macro hello(name) %}
|
||||
Hello {{ name }}
|
||||
{% endmacro %}
|
||||
--DATA--
|
||||
return []
|
||||
--EXPECT--
|
||||
OK
|
||||
|
||||
OK
|
||||
|
||||
OK
|
||||
|
||||
OK
|
||||
|
||||
OK
|
||||
Reference in New Issue
Block a user