diff --git a/extra/cache-extra/TokenParser/CacheTokenParser.php b/extra/cache-extra/TokenParser/CacheTokenParser.php index 5590ab27441..323096dd1ae 100644 --- a/extra/cache-extra/TokenParser/CacheTokenParser.php +++ b/extra/cache-extra/TokenParser/CacheTokenParser.php @@ -40,13 +40,13 @@ public function parse(Token $token): Node if (1 !== \count($args)) { throw new SyntaxError(sprintf('The "ttl" modifier takes exactly one argument (%d given).', \count($args)), $stream->getCurrent()->getLine(), $stream->getSourceContext()); } - $ttl = $args->getNode(0); + $ttl = $args->getNode('0'); break; case 'tags': if (1 !== \count($args)) { throw new SyntaxError(sprintf('The "tags" modifier takes exactly one argument (%d given).', \count($args)), $stream->getCurrent()->getLine(), $stream->getSourceContext()); } - $tags = $args->getNode(0); + $tags = $args->getNode('0'); break; default: throw new SyntaxError(sprintf('Unknown "%s" configuration.', $k), $stream->getCurrent()->getLine(), $stream->getSourceContext()); diff --git a/src/Environment.php b/src/Environment.php index f9e0086c60a..1a575f6c68a 100644 --- a/src/Environment.php +++ b/src/Environment.php @@ -437,7 +437,7 @@ public function resolveTemplate($names): TemplateWrapper $count = \count($names); foreach ($names as $name) { if ($name instanceof Template) { - return $name; + return new TemplateWrapper($this, $name); } if ($name instanceof TemplateWrapper) { return $name; @@ -535,7 +535,7 @@ public function getLoader(): LoaderInterface public function setCharset(string $charset) { - if ('UTF8' === $charset = null === $charset ? null : strtoupper($charset)) { + if ('UTF8' === $charset = strtoupper($charset ?: '')) { // iconv on Windows requires "UTF-8" instead of "UTF8" $charset = 'UTF-8'; } diff --git a/src/ExpressionParser.php b/src/ExpressionParser.php index 912d0a930a5..6839bc93204 100644 --- a/src/ExpressionParser.php +++ b/src/ExpressionParser.php @@ -452,14 +452,14 @@ public function getFunctionNode($name, $line) throw new SyntaxError('The "block" function takes one argument (the block name).', $line, $this->parser->getStream()->getSourceContext()); } - return new BlockReferenceExpression($args->getNode(0), \count($args) > 1 ? $args->getNode(1) : null, $line); + return new BlockReferenceExpression($args->getNode('0'), \count($args) > 1 ? $args->getNode('1') : null, $line); case 'attribute': $args = $this->parseArguments(); if (\count($args) < 2) { throw new SyntaxError('The "attribute" function takes at least two arguments (the variable and the attributes).', $line, $this->parser->getStream()->getSourceContext()); } - return new GetAttrExpression($args->getNode(0), $args->getNode(1), \count($args) > 2 ? $args->getNode(2) : null, Template::ANY_CALL, $line); + return new GetAttrExpression($args->getNode('0'), $args->getNode('1'), \count($args) > 2 ? $args->getNode('2') : null, Template::ANY_CALL, $line); default: if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) { $arguments = new ArrayExpression([], $line); diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index c4e0bdab228..598caca4536 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -1124,7 +1124,7 @@ public static function nl2br($string) /** * Removes whitespaces between HTML tags. * - * @param string|null $string + * @param string|null $content * * @return string * @@ -1241,11 +1241,7 @@ public static function striptags($string, $allowable_tags = null) */ public static function titleStringFilter(Environment $env, $string) { - if (null !== $charset = $env->getCharset()) { - return mb_convert_case($string ?? '', \MB_CASE_TITLE, $charset); - } - - return ucwords(strtolower($string ?? '')); + return mb_convert_case($string ?? '', \MB_CASE_TITLE, $env->getCharset()); } /** @@ -1436,6 +1432,8 @@ public static function source(Environment $env, $name, $ignoreMissing = false) if (!$ignoreMissing) { throw $e; } + + return ''; } } @@ -1731,9 +1729,9 @@ public static function getAttribute(Environment $env, Source $source, $object, $ * {# fruits now contains ['apple', 'orange'] #} * * - * @param array|Traversable $array An array - * @param mixed $name The column name - * @param mixed $index The column to use as the index/keys for the returned array + * @param array|\Traversable $array An array + * @param mixed $name The column name + * @param mixed $index The column to use as the index/keys for the returned array * * @return array The array of values * diff --git a/src/Extension/EscaperExtension.php b/src/Extension/EscaperExtension.php index 9a8c66c9047..dee0f79fe8c 100644 --- a/src/Extension/EscaperExtension.php +++ b/src/Extension/EscaperExtension.php @@ -175,7 +175,7 @@ public static function escapeFilterIsSafe(Node $filterArgs) * @param string $charset The charset * @param bool $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false) * - * @return string + * @return string|Markup * * @internal */ diff --git a/src/Node/Expression/Filter/DefaultFilter.php b/src/Node/Expression/Filter/DefaultFilter.php index 6a572d48848..e8eae20ecd3 100644 --- a/src/Node/Expression/Filter/DefaultFilter.php +++ b/src/Node/Expression/Filter/DefaultFilter.php @@ -35,7 +35,7 @@ public function __construct(Node $node, ConstantExpression $filterName, Node $ar if ('default' === $filterName->getAttribute('value') && ($node instanceof NameExpression || $node instanceof GetAttrExpression)) { $test = new DefinedTest(clone $node, 'defined', new Node(), $node->getTemplateLine()); - $false = \count($arguments) ? $arguments->getNode(0) : new ConstantExpression('', $node->getTemplateLine()); + $false = \count($arguments) ? $arguments->getNode('0') : new ConstantExpression('', $node->getTemplateLine()); $node = new ConditionalExpression($test, $default, $false, $node->getTemplateLine()); } else { diff --git a/src/Node/Expression/Test/ConstantTest.php b/src/Node/Expression/Test/ConstantTest.php index 57e9319d574..867fd09517c 100644 --- a/src/Node/Expression/Test/ConstantTest.php +++ b/src/Node/Expression/Test/ConstantTest.php @@ -33,16 +33,16 @@ public function compile(Compiler $compiler): void ->raw(' === constant(') ; - if ($this->getNode('arguments')->hasNode(1)) { + if ($this->getNode('arguments')->hasNode('1')) { $compiler ->raw('get_class(') - ->subcompile($this->getNode('arguments')->getNode(1)) + ->subcompile($this->getNode('arguments')->getNode('1')) ->raw(')."::".') ; } $compiler - ->subcompile($this->getNode('arguments')->getNode(0)) + ->subcompile($this->getNode('arguments')->getNode('0')) ->raw('))') ; } diff --git a/src/Node/Expression/Test/DivisiblebyTest.php b/src/Node/Expression/Test/DivisiblebyTest.php index 4cb3ee09692..90d58a49a16 100644 --- a/src/Node/Expression/Test/DivisiblebyTest.php +++ b/src/Node/Expression/Test/DivisiblebyTest.php @@ -29,7 +29,7 @@ public function compile(Compiler $compiler): void ->raw('(0 == ') ->subcompile($this->getNode('node')) ->raw(' % ') - ->subcompile($this->getNode('arguments')->getNode(0)) + ->subcompile($this->getNode('arguments')->getNode('0')) ->raw(')') ; } diff --git a/src/Node/Expression/Test/SameasTest.php b/src/Node/Expression/Test/SameasTest.php index c96d2bc01a3..f1e24db6f7e 100644 --- a/src/Node/Expression/Test/SameasTest.php +++ b/src/Node/Expression/Test/SameasTest.php @@ -27,7 +27,7 @@ public function compile(Compiler $compiler): void ->raw('(') ->subcompile($this->getNode('node')) ->raw(' === ') - ->subcompile($this->getNode('arguments')->getNode(0)) + ->subcompile($this->getNode('arguments')->getNode('0')) ->raw(')') ; } diff --git a/src/Node/IfNode.php b/src/Node/IfNode.php index 569ab7950e0..b41ee828d43 100644 --- a/src/Node/IfNode.php +++ b/src/Node/IfNode.php @@ -47,13 +47,13 @@ public function compile(Compiler $compiler): void } $compiler - ->subcompile($this->getNode('tests')->getNode($i)) + ->subcompile($this->getNode('tests')->getNode((string) $i)) ->raw(") {\n") ->indent() ; // The node might not exists if the content is empty - if ($this->getNode('tests')->hasNode($i + 1)) { - $compiler->subcompile($this->getNode('tests')->getNode($i + 1)); + if ($this->getNode('tests')->hasNode((string) ($i + 1))) { + $compiler->subcompile($this->getNode('tests')->getNode((string) ($i + 1))); } } diff --git a/src/Node/ModuleNode.php b/src/Node/ModuleNode.php index dce335c63f5..44186dc5d00 100644 --- a/src/Node/ModuleNode.php +++ b/src/Node/ModuleNode.php @@ -381,7 +381,7 @@ protected function compileIsTraitable(Compiler $compiler) $traitable = !$this->hasNode('parent') && 0 === \count($this->getNode('macros')); if ($traitable) { if ($this->getNode('body') instanceof BodyNode) { - $nodes = $this->getNode('body')->getNode(0); + $nodes = $this->getNode('body')->getNode('0'); } else { $nodes = $this->getNode('body'); } @@ -418,7 +418,7 @@ protected function compileIsTraitable(Compiler $compiler) ->write(" */\n") ->write("public function isTraitable()\n", "{\n") ->indent() - ->write(sprintf("return %s;\n", $traitable ? 'true' : 'false')) + ->write("return false;\n") ->outdent() ->write("}\n\n") ; diff --git a/src/NodeVisitor/EscaperNodeVisitor.php b/src/NodeVisitor/EscaperNodeVisitor.php index c390d7cc71b..91e2ea89392 100644 --- a/src/NodeVisitor/EscaperNodeVisitor.php +++ b/src/NodeVisitor/EscaperNodeVisitor.php @@ -131,10 +131,6 @@ private function escapeInlinePrintNode(InlinePrint $node, Environment $env, stri private function escapePrintNode(PrintNode $node, Environment $env, string $type): Node { - if (false === $type) { - return $node; - } - $expression = $node->getNode('expr'); if ($this->isSafeFor($type, $expression, $env)) { diff --git a/src/Parser.php b/src/Parser.php index 4016a5f39ab..0c7629b5572 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -101,6 +101,9 @@ public function parse(TokenStream $stream, $test = null, bool $dropNeedle = fals $traverser = new NodeTraverser($this->env, $this->visitors); + /** + * @var ModuleNode $node + */ $node = $traverser->traverse($node); // restore previous stack so previous parse() call can resume working diff --git a/src/Test/IntegrationTestCase.php b/src/Test/IntegrationTestCase.php index 90ff39aadaf..570c378bbe0 100644 --- a/src/Test/IntegrationTestCase.php +++ b/src/Test/IntegrationTestCase.php @@ -149,6 +149,7 @@ protected function doIntegrationTest($file, $message, $condition, $templates, $e } if ($condition) { + $ret = ''; eval('$ret = '.$condition.';'); if (!$ret) { $this->markTestSkipped($condition); diff --git a/src/TokenParser/ForTokenParser.php b/src/TokenParser/ForTokenParser.php index bac8ba2dae8..1af6da8fde5 100644 --- a/src/TokenParser/ForTokenParser.php +++ b/src/TokenParser/ForTokenParser.php @@ -49,12 +49,12 @@ public function parse(Token $token): Node $stream->expect(/* Token::BLOCK_END_TYPE */ 3); if (\count($targets) > 1) { - $keyTarget = $targets->getNode(0); + $keyTarget = $targets->getNode('0'); $keyTarget = new AssignNameExpression($keyTarget->getAttribute('name'), $keyTarget->getTemplateLine()); - $valueTarget = $targets->getNode(1); + $valueTarget = $targets->getNode('1'); } else { $keyTarget = new AssignNameExpression('_key', $lineno); - $valueTarget = $targets->getNode(0); + $valueTarget = $targets->getNode('0'); } $valueTarget = new AssignNameExpression($valueTarget->getAttribute('name'), $valueTarget->getTemplateLine()); diff --git a/src/TokenStream.php b/src/TokenStream.php index 1eac11a02d6..cb578e4fcb9 100644 --- a/src/TokenStream.php +++ b/src/TokenStream.php @@ -60,9 +60,7 @@ public function next(): Token */ public function nextIf($primary, $secondary = null) { - if ($this->tokens[$this->current]->test($primary, $secondary)) { - return $this->next(); - } + return $this->tokens[$this->current]->test($primary, $secondary) ? $this->next() : null; } /** diff --git a/tests/ExpressionParserTest.php b/tests/ExpressionParserTest.php index afd1884d8ee..bb000225ae5 100644 --- a/tests/ExpressionParserTest.php +++ b/tests/ExpressionParserTest.php @@ -64,7 +64,7 @@ public function testArrayExpression($template, $expected) $parser = new Parser($env); $expected->setSourceContext($source); - $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr')); + $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode('0')->getNode('expr')); } /** @@ -217,7 +217,7 @@ public function testStringExpression($template, $expected) $parser = new Parser($env); $expected->setSourceContext($source); - $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr')); + $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode('0')->getNode('expr')); } public function getTestsForString() diff --git a/tests/Node/Expression/ArrayTest.php b/tests/Node/Expression/ArrayTest.php index cfd9c67f3cb..f72eeab757b 100644 --- a/tests/Node/Expression/ArrayTest.php +++ b/tests/Node/Expression/ArrayTest.php @@ -22,7 +22,7 @@ public function testConstructor() $elements = [new ConstantExpression('foo', 1), $foo = new ConstantExpression('bar', 1)]; $node = new ArrayExpression($elements, 1); - $this->assertEquals($foo, $node->getNode(1)); + $this->assertEquals($foo, $node->getNode('1')); } public function getTests() diff --git a/tests/Node/ForTest.php b/tests/Node/ForTest.php index dbfac3269b2..42c34f8031c 100644 --- a/tests/Node/ForTest.php +++ b/tests/Node/ForTest.php @@ -33,7 +33,7 @@ public function testConstructor() $this->assertEquals($keyTarget, $node->getNode('key_target')); $this->assertEquals($valueTarget, $node->getNode('value_target')); $this->assertEquals($seq, $node->getNode('seq')); - $this->assertEquals($body, $node->getNode('body')->getNode(0)); + $this->assertEquals($body, $node->getNode('body')->getNode('0')); $this->assertFalse($node->hasNode('else')); $else = new PrintNode(new NameExpression('foo', 1), 1); diff --git a/tests/NodeVisitor/OptimizerTest.php b/tests/NodeVisitor/OptimizerTest.php index 8d02f6c7e2a..b685f32248a 100644 --- a/tests/NodeVisitor/OptimizerTest.php +++ b/tests/NodeVisitor/OptimizerTest.php @@ -28,7 +28,7 @@ public function testRenderBlockOptimizer() $stream = $env->parse($env->tokenize(new Source('{{ block("foo") }}', 'index'))); - $node = $stream->getNode('body')->getNode(0); + $node = $stream->getNode('body')->getNode('0'); $this->assertInstanceOf(BlockReferenceExpression::class, $node); $this->assertTrue($node->getAttribute('output')); @@ -40,7 +40,7 @@ public function testRenderParentBlockOptimizer() $stream = $env->parse($env->tokenize(new Source('{% extends "foo" %}{% block content %}{{ parent() }}{% endblock %}', 'index'))); - $node = $stream->getNode('blocks')->getNode('content')->getNode(0)->getNode('body'); + $node = $stream->getNode('blocks')->getNode('content')->getNode('0')->getNode('body'); $this->assertInstanceOf(ParentExpression::class, $node); $this->assertTrue($node->getAttribute('output'));