From 2b2ac80d345f943728828188c48147b405401f78 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Mon, 5 Feb 2024 16:23:59 +0100 Subject: [PATCH] Fxi some errors reported by phpstan --- .../cache-extra/TokenParser/CacheTokenParser.php | 4 ++-- src/Environment.php | 4 ++-- src/ExpressionParser.php | 4 ++-- src/Extension/CoreExtension.php | 16 +++++++--------- src/Extension/EscaperExtension.php | 2 +- src/Node/Expression/Filter/DefaultFilter.php | 2 +- src/Node/Expression/Test/ConstantTest.php | 6 +++--- src/Node/Expression/Test/DivisiblebyTest.php | 2 +- src/Node/Expression/Test/SameasTest.php | 2 +- src/Node/IfNode.php | 6 +++--- src/Node/ModuleNode.php | 4 ++-- src/NodeVisitor/EscaperNodeVisitor.php | 4 ---- src/Parser.php | 3 +++ src/Test/IntegrationTestCase.php | 1 + src/TokenParser/ForTokenParser.php | 6 +++--- src/TokenStream.php | 4 +--- tests/Cache/FilesystemTest.php | 2 +- tests/CompilerTest.php | 4 ++-- tests/ExpressionParserTest.php | 4 ++-- tests/Node/Expression/ArrayTest.php | 2 +- tests/Node/ForTest.php | 2 +- tests/NodeVisitor/OptimizerTest.php | 4 ++-- 22 files changed, 42 insertions(+), 46 deletions(-) diff --git a/extra/cache-extra/TokenParser/CacheTokenParser.php b/extra/cache-extra/TokenParser/CacheTokenParser.php index 5590ab274..323096dd1 100644 --- a/extra/cache-extra/TokenParser/CacheTokenParser.php +++ b/extra/cache-extra/TokenParser/CacheTokenParser.php @@ -40,13 +40,13 @@ class CacheTokenParser extends AbstractTokenParser 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 f9e0086c6..1a575f6c6 100644 --- a/src/Environment.php +++ b/src/Environment.php @@ -437,7 +437,7 @@ class Environment $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 @@ class Environment 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 912d0a930..6839bc932 100644 --- a/src/ExpressionParser.php +++ b/src/ExpressionParser.php @@ -452,14 +452,14 @@ class ExpressionParser 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 c4e0bdab2..598caca45 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -1124,7 +1124,7 @@ final class CoreExtension extends AbstractExtension /** * Removes whitespaces between HTML tags. * - * @param string|null $string + * @param string|null $content * * @return string * @@ -1241,11 +1241,7 @@ final class CoreExtension extends AbstractExtension */ 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 @@ final class CoreExtension extends AbstractExtension if (!$ignoreMissing) { throw $e; } + + return ''; } } @@ -1731,9 +1729,9 @@ final class CoreExtension extends AbstractExtension * {# 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 9a8c66c90..dee0f79fe 100644 --- a/src/Extension/EscaperExtension.php +++ b/src/Extension/EscaperExtension.php @@ -175,7 +175,7 @@ final class EscaperExtension extends AbstractExtension * @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 6a572d488..e8eae20ec 100644 --- a/src/Node/Expression/Filter/DefaultFilter.php +++ b/src/Node/Expression/Filter/DefaultFilter.php @@ -35,7 +35,7 @@ class DefaultFilter extends FilterExpression 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 57e9319d5..867fd0951 100644 --- a/src/Node/Expression/Test/ConstantTest.php +++ b/src/Node/Expression/Test/ConstantTest.php @@ -33,16 +33,16 @@ class ConstantTest extends TestExpression ->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 4cb3ee096..90d58a49a 100644 --- a/src/Node/Expression/Test/DivisiblebyTest.php +++ b/src/Node/Expression/Test/DivisiblebyTest.php @@ -29,7 +29,7 @@ class DivisiblebyTest extends TestExpression ->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 c96d2bc01..f1e24db6f 100644 --- a/src/Node/Expression/Test/SameasTest.php +++ b/src/Node/Expression/Test/SameasTest.php @@ -27,7 +27,7 @@ class SameasTest extends TestExpression ->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 569ab7950..b41ee828d 100644 --- a/src/Node/IfNode.php +++ b/src/Node/IfNode.php @@ -47,13 +47,13 @@ class IfNode extends Node } $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 dce335c63..44186dc5d 100644 --- a/src/Node/ModuleNode.php +++ b/src/Node/ModuleNode.php @@ -381,7 +381,7 @@ final class ModuleNode extends Node $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 @@ final class ModuleNode extends Node ->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 c390d7cc7..91e2ea893 100644 --- a/src/NodeVisitor/EscaperNodeVisitor.php +++ b/src/NodeVisitor/EscaperNodeVisitor.php @@ -131,10 +131,6 @@ final class EscaperNodeVisitor implements NodeVisitorInterface 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 4016a5f39..0c7629b55 100644 --- a/src/Parser.php +++ b/src/Parser.php @@ -101,6 +101,9 @@ class Parser $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 90ff39aad..570c378bb 100644 --- a/src/Test/IntegrationTestCase.php +++ b/src/Test/IntegrationTestCase.php @@ -149,6 +149,7 @@ abstract class IntegrationTestCase extends TestCase } if ($condition) { + $ret = ''; eval('$ret = '.$condition.';'); if (!$ret) { $this->markTestSkipped($condition); diff --git a/src/TokenParser/ForTokenParser.php b/src/TokenParser/ForTokenParser.php index bac8ba2da..1af6da8fd 100644 --- a/src/TokenParser/ForTokenParser.php +++ b/src/TokenParser/ForTokenParser.php @@ -49,12 +49,12 @@ final class ForTokenParser extends AbstractTokenParser $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 1eac11a02..cb578e4fc 100644 --- a/src/TokenStream.php +++ b/src/TokenStream.php @@ -60,9 +60,7 @@ final class TokenStream */ 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/Cache/FilesystemTest.php b/tests/Cache/FilesystemTest.php index 349869c26..63b98a900 100644 --- a/tests/Cache/FilesystemTest.php +++ b/tests/Cache/FilesystemTest.php @@ -23,7 +23,7 @@ class FilesystemTest extends TestCase protected function setUp(): void { - $nonce = hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', uniqid(mt_rand(), true)); + $nonce = hash(\PHP_VERSION_ID < 80100 ? 'sha256' : 'xxh128', uniqid((string) mt_rand(), true)); $this->classname = '__Twig_Tests_Cache_FilesystemTest_Template_'.$nonce; $this->directory = sys_get_temp_dir().'/twig-test'; $this->cache = new FilesystemCache($this->directory); diff --git a/tests/CompilerTest.php b/tests/CompilerTest.php index 35ffad909..a71ee093a 100644 --- a/tests/CompilerTest.php +++ b/tests/CompilerTest.php @@ -22,7 +22,7 @@ class CompilerTest extends TestCase { $compiler = new Compiler(new Environment($this->createMock(LoaderInterface::class))); - $locale = setlocale(\LC_NUMERIC, 0); + $locale = setlocale(\LC_NUMERIC, '0'); if (false === $locale) { $this->markTestSkipped('Your platform does not support locales.'); } @@ -33,7 +33,7 @@ class CompilerTest extends TestCase } $this->assertEquals('1.2', $compiler->repr(1.2)->getSource()); - $this->assertStringContainsString('fr', strtolower(setlocale(\LC_NUMERIC, 0))); + $this->assertStringContainsString('fr', strtolower(setlocale(\LC_NUMERIC, '0'))); setlocale(\LC_NUMERIC, $locale); } diff --git a/tests/ExpressionParserTest.php b/tests/ExpressionParserTest.php index afd1884d8..bb000225a 100644 --- a/tests/ExpressionParserTest.php +++ b/tests/ExpressionParserTest.php @@ -64,7 +64,7 @@ class ExpressionParserTest extends TestCase $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 @@ class ExpressionParserTest extends TestCase $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 cfd9c67f3..f72eeab75 100644 --- a/tests/Node/Expression/ArrayTest.php +++ b/tests/Node/Expression/ArrayTest.php @@ -22,7 +22,7 @@ class ArrayTest extends NodeTestCase $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 dbfac3269..42c34f803 100644 --- a/tests/Node/ForTest.php +++ b/tests/Node/ForTest.php @@ -33,7 +33,7 @@ class ForTest extends NodeTestCase $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 8d02f6c7e..b685f3224 100644 --- a/tests/NodeVisitor/OptimizerTest.php +++ b/tests/NodeVisitor/OptimizerTest.php @@ -28,7 +28,7 @@ class OptimizerTest extends TestCase $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 @@ class OptimizerTest extends TestCase $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'));