diff --git a/src/ExpressionParser.php b/src/ExpressionParser.php index 6839bc932..f33bd1135 100644 --- a/src/ExpressionParser.php +++ b/src/ExpressionParser.php @@ -591,7 +591,7 @@ public function parseFilterExpressionRaw($node, $tag = null) * Parses arguments. * * @param bool $namedArguments Whether to allow named arguments or not - * @param bool $definition Whether we are parsing arguments for a function definition + * @param bool $definition Whether we are parsing arguments for a function (or macro) definition * * @return Node * @@ -642,6 +642,7 @@ public function parseArguments($namedArguments = false, $definition = false, $al if (null === $name) { $name = $value->getAttribute('name'); $value = new ConstantExpression(null, $this->parser->getCurrentToken()->getLine()); + $value->setAttribute('isImplicit', true); } $args[$name] = $value; } else { diff --git a/tests/ParserTest.php b/tests/ParserTest.php index cdd8e8757..4774bf5ee 100644 --- a/tests/ParserTest.php +++ b/tests/ParserTest.php @@ -14,6 +14,7 @@ use PHPUnit\Framework\TestCase; use Twig\Environment; use Twig\Error\SyntaxError; +use Twig\Lexer; use Twig\Loader\LoaderInterface; use Twig\Node\Node; use Twig\Node\SetNode; @@ -175,6 +176,37 @@ public function testGetVarName() $this->addToAssertionCount(1); } + public function testImplicitMacroArgumentDefaultValues() + { + $template = '{% macro marco (po, lo = null) %}{% endmacro %}'; + $lexer = new Lexer(new Environment($this->createMock(LoaderInterface::class))); + $stream = $lexer->tokenize(new Source($template, 'index')); + + $argumentNodes = $this->getParser() + ->parse($stream) + ->getNode('macros') + ->getNode('marco') + ->getNode('arguments') + ; + + self::assertTrue( + $argumentNodes->getNode('po')->hasAttribute('isImplicit') + ); + self::assertTrue( + $argumentNodes->getNode('po')->getAttribute('isImplicit') + ); + self::assertNull( + $argumentNodes->getNode('po')->getAttribute('value') + ); + + self::assertFalse( + $argumentNodes->getNode('lo')->hasAttribute('isImplicit') + ); + self::assertNull( + $argumentNodes->getNode('lo')->getAttribute('value') + ); + } + protected function getParser() { $parser = new Parser(new Environment($this->createMock(LoaderInterface::class)));