Skip to content

Commit 2cbf023

Browse files
committed
Trigger the macro parentheses deprecation only once, at parse time
1 parent eee2326 commit 2cbf023

9 files changed

Lines changed: 11 additions & 34 deletions

CHANGELOG

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
* Fix duplicated macro argument names triggering a PHP fatal error instead of a `SyntaxError`
88
* Deprecate defining a macro more than once in the same template
99
* Deprecate `TemplateVariable` and `AssignTemplateVariable`; use `MacroVariable` and `AssignMacroVariable` instead
10-
* Deprecate omitting parentheses when calling a macro; it will throw a `SyntaxError` in 4.0
1110
* Deprecate calling or testing a macro with a name whose case differs from its definition; macro names will be case-sensitive in 4.0
1211
* Deprecate omitting parentheses when calling or testing a macro; it will throw a `SyntaxError` in 4.0
1312
* Deprecate calling a macro without a value for an argument that has no default value; the argument will be required in 4.0

doc/deprecated.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -324,12 +324,6 @@ Macros
324324
3.29 and will throw a ``SyntaxError`` in Twig 4.0. Give each macro a unique
325325
name.
326326

327-
* Omitting parentheses when calling a macro (e.g. ``macros.input`` or
328-
``macros.(name)``) is deprecated as of Twig 3.29 and will throw a
329-
``SyntaxError`` in Twig 4.0. Add parentheses after the macro name (e.g.
330-
``macros.input()`` or ``macros.(name)()``). Parentheses remain optional when
331-
testing whether a macro is defined.
332-
333327
* Passing more arguments to a macro than it declares is deprecated as of Twig
334328
3.29 and will throw in Twig 4.0. Declare an explicit variadic argument
335329
(``{% macro foo(a, ...rest) %}``) to accept extra positional and named

src/ExpressionParser/Infix/DotExpressionParser.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,12 @@ public function parse(Parser $parser, AbstractExpression $expr, Token $token): A
7373

7474
if ($isMacroTarget) {
7575
if (Template::METHOD_CALL !== $type) {
76-
trigger_deprecation('twig/twig', '3.29', 'Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name.');
76+
trigger_deprecation('twig/twig', '3.29', 'Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name in "%s" at line %d.', $stream->getSourceContext()->getName(), $expr->getTemplateLine());
7777
}
7878

7979
$name = $attribute instanceof ConstantExpression ? (string) $attribute->getAttribute('value') : $attribute;
80-
$node = new MacroReferenceExpression(new MacroVariable($expr->getAttribute('name'), $expr->getTemplateLine()), $name, $arguments, $expr->getTemplateLine());
81-
$node->setHasParentheses(Template::METHOD_CALL === $type);
8280

83-
return $node;
81+
return new MacroReferenceExpression(new MacroVariable($expr->getAttribute('name'), $expr->getTemplateLine()), $name, $arguments, $expr->getTemplateLine());
8482
}
8583

8684
return new GetAttrExpression($expr, $attribute, $arguments, $type, $lineno, $nullSafe);

src/Node/Expression/MacroReferenceExpression.php

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ class MacroReferenceExpression extends AbstractExpression implements SupportDefi
2525
use SupportDefinedTestDeprecationTrait;
2626
use SupportDefinedTestTrait;
2727

28-
private bool $hasParentheses = true;
29-
3028
/**
3129
* @param string|AbstractExpression $name The bare macro name (a static identifier) or, for a dynamic
3230
* call, an expression resolving to the macro name
@@ -45,14 +43,6 @@ public function __construct(MacroVariable $template, string|AbstractExpression $
4543
parent::__construct($nodes, $attributes, $lineno);
4644
}
4745

48-
/**
49-
* @internal
50-
*/
51-
public function setHasParentheses(bool $hasParentheses): void
52-
{
53-
$this->hasParentheses = $hasParentheses;
54-
}
55-
5646
public function __clone()
5747
{
5848
// The template node must not be deep-cloned because its name is
@@ -65,10 +55,6 @@ public function __clone()
6555

6656
public function compile(Compiler $compiler): void
6757
{
68-
if (!$this->hasParentheses && !$this->definedTest) {
69-
trigger_deprecation('twig/twig', '3.29', 'Omitting parentheses when calling a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name in "%s" at line %d.', $this->getTemplateName(), $this->getTemplateLine());
70-
}
71-
7258
$compiler->subcompile($this->getNode('template'));
7359

7460
if ($this->definedTest) {

tests/Extension/SandboxTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,7 +1250,7 @@ public function testMacrosInASandbox(): void
12501250

12511251
public function testSelfMacroReferenceWithStringLiteralDoesNotInjectPhp(): void
12521252
{
1253-
$twig = $this->getEnvironment(true, [], ['index' => '{{ _self.(\'foo + 1; trigger_error("BAD-MACRO-REF") //\') }}']);
1253+
$twig = $this->getEnvironment(true, [], ['index' => '{{ _self.(\'foo + 1; trigger_error("BAD-MACRO-REF") //\')() }}']);
12541254

12551255
$compiled = $twig->compileSource($twig->getLoader()->getSourceContext('index'));
12561256
$this->assertStringNotContainsString('trigger_error("BAD-MACRO-REF")', $compiled, 'Attacker-controlled string must not appear raw in compiled PHP source.');
@@ -1278,7 +1278,7 @@ public function testSelfMacroReferenceWithStringLiteralDoesNotInjectPhp(): void
12781278

12791279
public function testImportedTemplateMacroReferenceWithBadIdentifierDoesNotInjectPhp(): void
12801280
{
1281-
$payload = '{% import "m" as m %}{{ m.(\'foo + 1; trigger_error("BAD-IMPORT-REF") //\') }}';
1281+
$payload = '{% import "m" as m %}{{ m.(\'foo + 1; trigger_error("BAD-IMPORT-REF") //\')() }}';
12821282
$twig = $this->getEnvironment(true, [], [
12831283
'index' => $payload,
12841284
'm' => '{% macro greet() %}hi{% endmacro %}',

tests/Fixtures/macros/call_without_parentheses.legacy.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
--TEST--
22
Omitting parentheses when calling macros is deprecated
33
--DEPRECATION--
4-
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name.
5-
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name.
4+
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name in "index.twig" at line 4.
5+
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name in "index.twig" at line 5.
66
--TEMPLATE--
77
{% import _self as macros %}
88
{% set name = 'hello' %}

tests/Fixtures/tests/defined_for_macros_dynamic_name_without_parentheses.legacy.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
--TEST--
22
Omitting parentheses when testing dynamic macro names is deprecated
33
--DEPRECATION--
4-
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name.
5-
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name.
4+
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name in "index.twig" at line 5.
5+
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name in "index.twig" at line 6.
66
--TEMPLATE--
77
{% import _self as macros %}
88
{% set known = 'hello' %}

tests/Fixtures/tests/defined_for_macros_without_parentheses.legacy.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
--TEST--
22
Omitting parentheses when testing static macro names is deprecated
33
--DEPRECATION--
4-
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name.
5-
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name.
4+
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name in "index.twig" at line 3.
5+
Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name in "index.twig" at line 4.
66
--TEMPLATE--
77
{% import _self as macros %}
88
{{ macros.hello is defined ? 'OK' : 'KO' }}

tests/ParserTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ public function testMacroTargetsWithoutParenthesesAreDeprecated(string $expressi
157157
{
158158
$twig = new Environment(new ArrayLoader());
159159

160-
$this->expectDeprecation('Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name.');
160+
$this->expectDeprecation('Since twig/twig 3.29: Omitting parentheses when calling or testing a macro is deprecated and will throw a SyntaxError in Twig 4.0; add parentheses after the macro name in "index" at line 1.');
161161

162162
$module = $twig->parse($twig->tokenize(new Source("{% import _self as macros %}{{ $expression }}", 'index')));
163163
$macroReferences = [];

0 commit comments

Comments
 (0)