Skip to content

Commit 75d48db

Browse files
VincentLangletfabpot
authored andcommitted
Add phpstan analysis
1 parent 8c91bd7 commit 75d48db

11 files changed

Lines changed: 79 additions & 16 deletions

.github/workflows/ci.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,29 @@ jobs:
154154

155155
- run: bash ./tests/drupal_test.sh
156156
shell: "bash"
157+
158+
phpstan:
159+
name: "PHPStan"
160+
161+
runs-on: 'ubuntu-latest'
162+
163+
strategy:
164+
matrix:
165+
php-version:
166+
- '8.4'
167+
168+
steps:
169+
- name: "Checkout code"
170+
uses: actions/checkout@v4
171+
172+
- name: "Install PHP with extensions"
173+
uses: shivammathur/setup-php@v2
174+
with:
175+
coverage: "none"
176+
php-version: ${{ matrix.php-version }}
177+
ini-values: memory_limit=-1
178+
179+
- run: composer install
180+
181+
- name: "Run tests"
182+
run: vendor/bin/phpstan

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232
},
3333
"require-dev": {
3434
"symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0",
35-
"psr/container": "^1.0|^2.0"
35+
"psr/container": "^1.0|^2.0",
36+
"phpstan/phpstan": "^2.0"
3637
},
3738
"autoload": {
3839
"files": [

phpstan-baseline.neon

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
parameters:
2+
ignoreErrors:
3+
- # The method is dynamically generated by the CheckSecurityNode
4+
message: '#^Call to an undefined method Twig\\Template\:\:checkSecurity\(\)\.$#'
5+
identifier: method.notFound
6+
count: 1
7+
path: src/Extension/CoreExtension.php
8+
9+
- # Avoid BC-break
10+
message: '#^Constructor of class Twig\\Node\\ForNode has an unused parameter \$ifexpr\.$#'
11+
identifier: constructor.unusedParameter
12+
count: 1
13+
path: src/Node/ForNode.php
14+
15+
- # 2 parameters will be required
16+
message: '#^Method Twig\\Node\\IncludeNode\:\:addGetTemplate\(\) invoked with 2 parameters, 1 required\.$#'
17+
identifier: arguments.count
18+
count: 1
19+
path: src/Node/IncludeNode.php
20+
21+
- # int|string will be supported in 4.x
22+
message: '#^PHPDoc tag @param for parameter $name with type int|string is not subtype of native type string\.$#'
23+
identifier: parameter.phpDocType
24+
count: 5
25+
path: src/Node/Node.php

phpstan.neon.dist

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
includes:
2+
- phpstan-baseline.neon
3+
4+
parameters:
5+
level: 3
6+
paths:
7+
- src
8+
excludePaths:
9+
- src/Test

src/ExpressionParser.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ class ExpressionParser
5353
public const OPERATOR_LEFT = 1;
5454
public const OPERATOR_RIGHT = 2;
5555

56-
/** @var array<string, array{precedence: int, class: class-string<AbstractUnary>}> */
56+
/** @var array<string, array{precedence: int, precedence_change?: OperatorPrecedenceChange, class: class-string<AbstractUnary>}> */
5757
private $unaryOperators;
58-
/** @var array<string, array{precedence: int, class: class-string<AbstractBinary>, associativity: self::OPERATOR_*}> */
58+
/** @var array<string, array{precedence: int, precedence_change?: OperatorPrecedenceChange, class: class-string<AbstractBinary>, associativity: self::OPERATOR_*}> */
5959
private $binaryOperators;
6060
private $readyNodes = [];
6161
private array $precedenceChanges = [];
@@ -125,7 +125,7 @@ public function parseExpression($precedence = 0)
125125

126126
$expr->setAttribute('operator', 'binary_'.$token->getValue());
127127

128-
$this->triggerPrecedenceDeprecations($expr, $token);
128+
$this->triggerPrecedenceDeprecations($expr);
129129

130130
$token = $this->parser->getCurrentToken();
131131
}
@@ -246,7 +246,7 @@ private function getPrimary(): AbstractExpression
246246
$expr->setAttribute('operator', 'unary_'.$token->getValue());
247247

248248
if ($this->deprecationCheck) {
249-
$this->triggerPrecedenceDeprecations($expr, $token);
249+
$this->triggerPrecedenceDeprecations($expr);
250250
}
251251

252252
return $this->parsePostfixExpression($expr);

src/ExtensionSet.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ final class ExtensionSet
4848
private $unaryOperators;
4949
/** @var array<string, array{precedence: int, class?: class-string<AbstractExpression>, associativity: ExpressionParser::OPERATOR_*}> */
5050
private $binaryOperators;
51-
/** @var array<string, mixed> */
51+
/** @var array<string, mixed>|null */
5252
private $globals;
5353
private $functionCallbacks = [];
5454
private $filterCallbacks = [];

src/Node/Expression/BlockReferenceExpression.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class BlockReferenceExpression extends AbstractExpression
2828
public function __construct(Node $name, ?Node $template, int $lineno)
2929
{
3030
if (!$name instanceof AbstractExpression) {
31-
trigger_deprecation('twig/twig', '3.15', 'Not passing a "%s" instance to the "node" argument of "%s" is deprecated ("%s" given).', AbstractExpression::class, static::class, get_class($node));
31+
trigger_deprecation('twig/twig', '3.15', 'Not passing a "%s" instance to the "node" argument of "%s" is deprecated ("%s" given).', AbstractExpression::class, static::class, get_class($name));
3232
}
3333

3434
$nodes = ['name' => $name];

src/Node/Expression/Variable/AssignTemplateVariable.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,20 @@ public function __construct(TemplateVariable $var, bool $global = true)
2323

2424
public function compile(Compiler $compiler): void
2525
{
26+
/** @var TemplateVariable $var */
27+
$var = $this->nodes['var'];
28+
2629
$compiler
2730
->addDebugInfo($this)
2831
->write('$macros[')
29-
->string($this->nodes['var']->getName($compiler))
32+
->string($var->getName($compiler))
3033
->raw('] = ')
3134
;
3235

3336
if ($this->getAttribute('global')) {
3437
$compiler
3538
->raw('$this->macros[')
36-
->string($this->nodes['var']->getName($compiler))
39+
->string($var->getName($compiler))
3740
->raw('] = ')
3841
;
3942
}

src/Node/ImportNode.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,9 @@
2525
#[YieldReady]
2626
class ImportNode extends Node
2727
{
28-
/**
29-
* @param bool $global
30-
*/
3128
public function __construct(AbstractExpression $expr, AbstractExpression|AssignTemplateVariable $var, int $lineno)
3229
{
33-
if (!\is_bool(\func_num_args() > 3)) {
30+
if (\func_num_args() > 3) {
3431
trigger_deprecation('twig/twig', '3.15', \sprintf('Passing more than 3 arguments to "%s()" is deprecated.', __METHOD__));
3532
}
3633

src/Node/MacroNode.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ public function compile(Compiler $compiler): void
6464
->write(\sprintf('public function macro_%s(', $this->getAttribute('name')))
6565
;
6666

67-
foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) {
67+
/** @var ArrayExpression $arguments */
68+
$arguments = $this->getNode('arguments');
69+
foreach ($arguments->getKeyValuePairs() as $pair) {
6870
$name = $pair['key'];
6971
$default = $pair['value'];
7072
$compiler
@@ -85,7 +87,7 @@ public function compile(Compiler $compiler): void
8587
->indent()
8688
;
8789

88-
foreach ($this->getNode('arguments')->getKeyValuePairs() as $pair) {
90+
foreach ($arguments->getKeyValuePairs() as $pair) {
8991
$name = $pair['key'];
9092
$compiler
9193
->write('')

0 commit comments

Comments
 (0)