diff --git a/.github/workflows/fabbot.yml b/.github/workflows/fabbot.yml new file mode 100644 index 000000000..7aa4bc682 --- /dev/null +++ b/.github/workflows/fabbot.yml @@ -0,0 +1,14 @@ +name: CS + +on: + pull_request: + +permissions: + contents: read + +jobs: + call-fabbot: + name: Fabbot + uses: symfony-tools/fabbot/.github/workflows/fabbot.yml@main + with: + package: Twig diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 5c3a731a1..b57df306a 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -13,9 +13,17 @@ return (new PhpCsFixer\Config()) 'heredoc_to_nowdoc' => false, 'ordered_imports' => true, 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], - // TODO: Remove once the "compiler_optimized" set includes "sprintf" - 'native_function_invocation' => ['include' => ['@compiler_optimized', 'sprintf'], 'scope' => 'all'], - ]) + 'header_comment' => [ + 'header' => <<setRiskyAllowed(true) ->setFinder((new PhpCsFixer\Finder())->in(__DIR__)) ; diff --git a/bin/generate_operators_precedence.php b/bin/generate_operators_precedence.php index 72add5ea6..f3d878d3e 100644 --- a/bin/generate_operators_precedence.php +++ b/bin/generate_operators_precedence.php @@ -16,9 +16,9 @@ use Twig\ExpressionParser\InfixAssociativity; use Twig\ExpressionParser\InfixExpressionParserInterface; use Twig\Loader\ArrayLoader; -require_once \dirname(__DIR__).'/vendor/autoload.php'; +require_once dirname(__DIR__).'/vendor/autoload.php'; -$output = fopen(\dirname(__DIR__).'/doc/operators_precedence.rst', 'w'); +$output = fopen(dirname(__DIR__).'/doc/operators_precedence.rst', 'w'); $twig = new Environment(new ArrayLoader([])); $descriptionLength = 11; @@ -29,7 +29,7 @@ foreach ($twig->getExpressionParsers() as $expressionParser) { } fwrite($output, "\n+------------+------------------+---------+---------------+".str_repeat('-', $descriptionLength + 2)."+\n"); -fwrite($output, "| Precedence | Operator | Type | Associativity | Description".str_repeat(' ', $descriptionLength - 11)." |\n"); +fwrite($output, '| Precedence | Operator | Type | Associativity | Description'.str_repeat(' ', $descriptionLength - 11)." |\n"); fwrite($output, '+============+==================+=========+===============+'.str_repeat('=', $descriptionLength + 2).'+'); usort($expressionParsers, fn ($a, $b) => $b->getPrecedence() <=> $a->getPrecedence()); @@ -46,7 +46,7 @@ foreach ($expressionParsers as $expressionParser) { if ($previousPrecedence !== $precedence) { $previous = null; } - fwrite($output, rtrim(\sprintf("\n| %-10s | %-16s | %-7s | %-13s | %-{$descriptionLength}s |\n", + fwrite($output, rtrim(sprintf("\n| %-10s | %-16s | %-7s | %-13s | %-{$descriptionLength}s |\n", (!$previous || $previousPrecedence !== $precedence ? $precedence : '').($expressionParser->getPrecedenceChange() ? ' => '.$expressionParser->getPrecedenceChange()->getNewPrecedence() : ''), '``'.$expressionParser->getName().'``', !$previous || ExpressionParserType::getType($previous) !== ExpressionParserType::getType($expressionParser) ? ExpressionParserType::getType($expressionParser)->value : '', diff --git a/doc/_build/build.php b/doc/_build/build.php index 2b183b186..25950f789 100755 --- a/doc/_build/build.php +++ b/doc/_build/build.php @@ -1,6 +1,15 @@ #!/usr/bin/env php success(\sprintf('The Twig docs were successfully built at %s', realpath($outputDir))); + $io->success(sprintf('The Twig docs were successfully built at %s', realpath($outputDir))); } else { - $io->error(\sprintf("There were some errors while building the docs:\n\n%s\n", $result->getErrorTrace())); + $io->error(sprintf("There were some errors while building the docs:\n\n%s\n", $result->getErrorTrace())); $io->newLine(); $io->comment('Tip: you can add the -v, -vv or -vvv flags to this command to get debug information.'); diff --git a/extra/cssinliner-extra/CssInlinerExtension.php b/extra/cssinliner-extra/CssInlinerExtension.php index 74f144486..8bfd1310c 100644 --- a/extra/cssinliner-extra/CssInlinerExtension.php +++ b/extra/cssinliner-extra/CssInlinerExtension.php @@ -1,9 +1,9 @@ + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/extra/inky-extra/InkyExtension.php b/extra/inky-extra/InkyExtension.php index 80133a319..1493f280d 100644 --- a/extra/inky-extra/InkyExtension.php +++ b/extra/inky-extra/InkyExtension.php @@ -1,9 +1,9 @@ + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/extra/markdown-extra/DefaultMarkdown.php b/extra/markdown-extra/DefaultMarkdown.php index 6650a661a..a20993d45 100644 --- a/extra/markdown-extra/DefaultMarkdown.php +++ b/extra/markdown-extra/DefaultMarkdown.php @@ -13,7 +13,6 @@ namespace Twig\Extra\Markdown; use League\CommonMark\CommonMarkConverter; use Michelf\MarkdownExtra; -use Parsedown; class DefaultMarkdown implements MarkdownInterface { @@ -25,7 +24,7 @@ class DefaultMarkdown implements MarkdownInterface $this->converter = new LeagueMarkdown(); } elseif (class_exists(MarkdownExtra::class)) { $this->converter = new MichelfMarkdown(); - } elseif (class_exists(Parsedown::class)) { + } elseif (class_exists(\Parsedown::class)) { $this->converter = new ErusevMarkdown(); } else { throw new \LogicException('You cannot use the "markdown_to_html" filter as no Markdown library is available; try running "composer require league/commonmark".'); diff --git a/extra/markdown-extra/ErusevMarkdown.php b/extra/markdown-extra/ErusevMarkdown.php index 47b030893..923cf0eeb 100644 --- a/extra/markdown-extra/ErusevMarkdown.php +++ b/extra/markdown-extra/ErusevMarkdown.php @@ -11,15 +11,13 @@ namespace Twig\Extra\Markdown; -use Parsedown; - class ErusevMarkdown implements MarkdownInterface { private $converter; - public function __construct(?Parsedown $converter = null) + public function __construct(?\Parsedown $converter = null) { - $this->converter = $converter ?: new Parsedown(); + $this->converter = $converter ?: new \Parsedown(); } public function convert(string $body): string diff --git a/extra/twig-extra-bundle/DependencyInjection/Compiler/MissingExtensionSuggestorPass.php b/extra/twig-extra-bundle/DependencyInjection/Compiler/MissingExtensionSuggestorPass.php index f57e00c04..38ee03e49 100644 --- a/extra/twig-extra-bundle/DependencyInjection/Compiler/MissingExtensionSuggestorPass.php +++ b/extra/twig-extra-bundle/DependencyInjection/Compiler/MissingExtensionSuggestorPass.php @@ -1,9 +1,9 @@ + * (c) Fabien Potencier * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/extra/twig-extra-bundle/Tests/Fixture/Kernel.php b/extra/twig-extra-bundle/Tests/Fixture/Kernel.php index faad85c18..8986f8ecd 100644 --- a/extra/twig-extra-bundle/Tests/Fixture/Kernel.php +++ b/extra/twig-extra-bundle/Tests/Fixture/Kernel.php @@ -1,5 +1,14 @@ */ + /** + * @var array + */ private array $globals = []; /** * @var array|null diff --git a/src/Error/Error.php b/src/Error/Error.php index b036f488a..6616574d6 100644 --- a/src/Error/Error.php +++ b/src/Error/Error.php @@ -158,7 +158,7 @@ class Error extends \Exception while ($e = array_pop($exceptions)) { $traces = $e->getTrace(); - array_unshift($traces, ['file' => $e instanceof Error ? $e->phpFile : $e->getFile(), 'line' => $e instanceof Error ? $e->phpLine : $e->getLine()]); + array_unshift($traces, ['file' => $e instanceof self ? $e->phpFile : $e->getFile(), 'line' => $e instanceof self ? $e->phpLine : $e->getLine()]); while ($trace = array_shift($traces)) { if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) { continue; diff --git a/src/Extension/AttributeExtension.php b/src/Extension/AttributeExtension.php index 44e4f3f6b..74fcbb857 100644 --- a/src/Extension/AttributeExtension.php +++ b/src/Extension/AttributeExtension.php @@ -104,7 +104,7 @@ final class AttributeExtension extends AbstractExtension ]); if ($callable->getMinimalNumberOfRequiredArguments() > $method->getNumberOfParameters()) { - throw new \LogicException(sprintf('"%s::%s()" needs at least %d arguments to be used AsTwigFilter, but only %d defined.', $reflectionClass->getName(), $method->getName(), $callable->getMinimalNumberOfRequiredArguments(), $method->getNumberOfParameters())); + throw new \LogicException(\sprintf('"%s::%s()" needs at least %d arguments to be used AsTwigFilter, but only %d defined.', $reflectionClass->getName(), $method->getName(), $callable->getMinimalNumberOfRequiredArguments(), $method->getNumberOfParameters())); } $filters[$attribute->name] = $callable; @@ -125,14 +125,13 @@ final class AttributeExtension extends AbstractExtension ]); if ($callable->getMinimalNumberOfRequiredArguments() > $method->getNumberOfParameters()) { - throw new \LogicException(sprintf('"%s::%s()" needs at least %d arguments to be used AsTwigFunction, but only %d defined.', $reflectionClass->getName(), $method->getName(), $callable->getMinimalNumberOfRequiredArguments(), $method->getNumberOfParameters())); + throw new \LogicException(\sprintf('"%s::%s()" needs at least %d arguments to be used AsTwigFunction, but only %d defined.', $reflectionClass->getName(), $method->getName(), $callable->getMinimalNumberOfRequiredArguments(), $method->getNumberOfParameters())); } $functions[$attribute->name] = $callable; } foreach ($method->getAttributes(AsTwigTest::class) as $reflectionAttribute) { - /** @var AsTwigTest $attribute */ $attribute = $reflectionAttribute->newInstance(); @@ -145,7 +144,7 @@ final class AttributeExtension extends AbstractExtension ]); if ($callable->getMinimalNumberOfRequiredArguments() > $method->getNumberOfParameters()) { - throw new \LogicException(sprintf('"%s::%s()" needs at least %d arguments to be used AsTwigTest, but only %d defined.', $reflectionClass->getName(), $method->getName(), $callable->getMinimalNumberOfRequiredArguments(), $method->getNumberOfParameters())); + throw new \LogicException(\sprintf('"%s::%s()" needs at least %d arguments to be used AsTwigTest, but only %d defined.', $reflectionClass->getName(), $method->getName(), $callable->getMinimalNumberOfRequiredArguments(), $method->getNumberOfParameters())); } $tests[$attribute->name] = $callable; diff --git a/src/Markup.php b/src/Markup.php index 35a0a3e9b..5f9eaeb03 100644 --- a/src/Markup.php +++ b/src/Markup.php @@ -42,9 +42,6 @@ class Markup implements \Countable, \JsonSerializable, \Stringable return mb_strlen($this->content, $this->charset); } - /** - * @return mixed - */ public function jsonSerialize(): mixed { return $this->content; diff --git a/src/Node/Expression/Binary/MatchesBinary.php b/src/Node/Expression/Binary/MatchesBinary.php index 32e8d34e4..569dfde05 100644 --- a/src/Node/Expression/Binary/MatchesBinary.php +++ b/src/Node/Expression/Binary/MatchesBinary.php @@ -13,8 +13,8 @@ namespace Twig\Node\Expression\Binary; use Twig\Compiler; use Twig\Error\SyntaxError; -use Twig\Node\Expression\ReturnBoolInterface; use Twig\Node\Expression\ConstantExpression; +use Twig\Node\Expression\ReturnBoolInterface; use Twig\Node\Node; class MatchesBinary extends AbstractBinary implements ReturnBoolInterface diff --git a/src/Node/Expression/FunctionNode/EnumCasesFunction.php b/src/Node/Expression/FunctionNode/EnumCasesFunction.php index 87b56bade..d6417cf7c 100644 --- a/src/Node/Expression/FunctionNode/EnumCasesFunction.php +++ b/src/Node/Expression/FunctionNode/EnumCasesFunction.php @@ -1,5 +1,14 @@ setAttribute('optimizable', false); $node->setAttribute('ignore_strict_check', true); - if ($node->getNode('node') instanceof GetAttrExpression) { + if ($node->getNode('node') instanceof self) { $this->changeIgnoreStrictCheck($node->getNode('node')); } } diff --git a/src/Node/TypesNode.php b/src/Node/TypesNode.php index c4e0f081b..a5dfacb5f 100644 --- a/src/Node/TypesNode.php +++ b/src/Node/TypesNode.php @@ -1,5 +1,14 @@ */ + /** @var array */ private array $escapers = []; /** @internal */ diff --git a/src/Template.php b/src/Template.php index 7e9acaba7..0fc16a0bd 100644 --- a/src/Template.php +++ b/src/Template.php @@ -245,7 +245,7 @@ abstract class Template /** * @param string|TemplateWrapper|array $template */ - protected function load(string|TemplateWrapper|array $template, int $line, int|null $index = null): self + protected function load(string|TemplateWrapper|array $template, int $line, ?int $index = null): self { try { if (\is_array($template)) { diff --git a/tests/Cache/ChainTest.php b/tests/Cache/ChainTest.php index 2396846fd..273ffbea0 100644 --- a/tests/Cache/ChainTest.php +++ b/tests/Cache/ChainTest.php @@ -1,5 +1,14 @@ getCurrent()->getLine(); $stream->expect(Token::BLOCK_END_TYPE); - return new #[YieldReady]class($lineno, $this->addDebugInfo, $this->exceptionWithLineAndContext) extends Node - { + return new #[YieldReady] class($lineno, $this->addDebugInfo, $this->exceptionWithLineAndContext) extends Node { public function __construct(int $lineno, private bool $addDebugInfo, private bool $exceptionWithLineAndContext) { parent::__construct([], [], $lineno); @@ -292,7 +300,7 @@ EOHTML, if ($this->exceptionWithLineAndContext) { $compiler ->write('throw new \Twig\Error\RuntimeError("Runtime error.", ') - ->repr($this->lineno)->raw(", \$this->getSourceContext()") + ->repr($this->lineno)->raw(', $this->getSourceContext()') ->raw(");\n") ; } else { diff --git a/tests/ExpressionParserTest.php b/tests/ExpressionParserTest.php index b1490c224..aacf8b8e7 100644 --- a/tests/ExpressionParserTest.php +++ b/tests/ExpressionParserTest.php @@ -1,5 +1,14 @@ ['{{ 10 + 2|length }}', '{{ 10 + (2|length) }}', eval('return 10 + strlen(2);'), $context]; // - unary stronger than | - yield '- vs |' => ['{{ -1|abs }}', '{{ (-1)|abs }}', eval("return abs(-1);"), $context]; + yield '- vs |' => ['{{ -1|abs }}', '{{ (-1)|abs }}', eval('return abs(-1);'), $context]; // ?? stronger than () - yield '?? vs ()' => ['{{ (1 ?? "a") }}', '{{ ((1 ?? "a")) }}', eval("return 1;")]; + yield '?? vs ()' => ['{{ (1 ?? "a") }}', '{{ ((1 ?? "a")) }}', eval('return 1;')]; } } diff --git a/tests/Extension/AttributeExtensionTest.php b/tests/Extension/AttributeExtensionTest.php index 68e3bfeef..273ac2c24 100644 --- a/tests/Extension/AttributeExtensionTest.php +++ b/tests/Extension/AttributeExtensionTest.php @@ -1,5 +1,14 @@ fail(sprintf('Filter "%s" is not registered.', $name)); + $this->fail(\sprintf('Filter "%s" is not registered.', $name)); } public static function provideFilters() @@ -58,7 +67,7 @@ class AttributeExtensionTest extends TestCase } } - $this->fail(sprintf('Function "%s" is not registered.', $name)); + $this->fail(\sprintf('Function "%s" is not registered.', $name)); } public static function provideFunctions() @@ -86,7 +95,7 @@ class AttributeExtensionTest extends TestCase } } - $this->fail(sprintf('Test "%s" is not registered.', $name)); + $this->fail(\sprintf('Test "%s" is not registered.', $name)); } public static function provideTests() diff --git a/tests/Extension/CoreTest.php b/tests/Extension/CoreTest.php index 59d4b5b4d..34058ee6a 100644 --- a/tests/Extension/CoreTest.php +++ b/tests/Extension/CoreTest.php @@ -1,5 +1,14 @@