Skip to content

Commit 447abec

Browse files
Update to PHPStan 2.0
1 parent f123356 commit 447abec

File tree

96 files changed

+4013
-77
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+4013
-77
lines changed

.github/workflows/all_tests.yml

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ jobs:
1414
fail-fast: false
1515
matrix:
1616
php-version:
17-
- "8.0"
1817
- "8.1"
1918
- "8.2"
2019
- "8.3"
20+
- "8.4"
2121

2222
steps:
2323
- name: "Checkout"
@@ -44,4 +44,8 @@ jobs:
4444
run: "composer install --no-interaction --no-progress"
4545

4646
- name: "Run tests"
47-
run: "composer tests"
47+
run: "composer tests-without-psalm"
48+
49+
- name: "Run Psalm"
50+
if: matrix.php-version != '8.4' # Psalm does not fully support PHP 8.4 yet
51+
run: "composer psalm"

README.md

+28-2
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ To replace all the annotations that this package covers, use the set provided by
8080

8181
```php
8282
use Rector\Config\RectorConfig;
83-
use PhpStaticAnalysis\RectorRule\Set\PhpStaticAnalysisSetList;
83+
use PhpStaticAnalysis\RectorRule\Set\PhpStaticAnalysisAnnotationsToAttributesSetList;
8484

8585
return RectorConfig::configure()
8686
->withSets([
87-
PhpStaticAnalysisSetList::ANNOTATIONS_TO_ATTRIBUTES
87+
PhpStaticAnalysisAnnotationsToAttributesSetList::ANNOTATIONS_TO_ATTRIBUTES
8888
])
8989
->withImportNames();
9090
```
@@ -255,6 +255,32 @@ return RectorConfig::configure()
255255
]
256256
);
257257
```
258+
## Using these rules with Rector
259+
260+
Once you have converted your static analysis annotations to attributes, you may want to use them with Rector, so that Rector can
261+
understand them and use them to apply its rules. To do this, when running rector we first need to temporarily convert these attributes
262+
back to annotations, then run your Rector rules and finally convert the annotations back to attributes. To do this, use this in your
263+
configuration:
264+
265+
```php
266+
use PhpStaticAnalysis\RectorRule\Set\PhpStaticAnalysisAnnotationsToAttributesSetList;
267+
use PhpStaticAnalysis\RectorRule\Set\PhpStaticAnalysisAttributesToAnnotationsSetList;
268+
use Rector\Config\RectorConfig;
269+
...
270+
271+
return RectorConfig::configure()
272+
->withSets([
273+
PhpStaticAnalysisAttributesToAnnotationsSetList::ATTRIBUTES_TO_ANNOTATIONS
274+
])
275+
...
276+
//any other Rector rules or sets
277+
...
278+
->withSets([
279+
PhpStaticAnalysisAnnotationsToAttributesSetList::ANNOTATIONS_TO_ATTRIBUTES
280+
]);
281+
```
282+
If you use any special configuration for the Annotations to Attributes process, for example only converting some of the annotations
283+
or setting some flags, use it in this last part of the block of code instead of the sample.
258284

259285
## Sponsor this project
260286

composer.json

+19-9
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,20 @@
2626
"minimum-stability": "dev",
2727
"prefer-stable": true,
2828
"require": {
29-
"php": ">=8.0",
30-
"php-static-analysis/attributes": "^0.3.1 || dev-main",
31-
"php-static-analysis/node-visitor": "^0.3.1 || dev-main",
32-
"rector/rector": "^0.19 || ^1.0"
29+
"php": ">=8.1",
30+
"php-static-analysis/attributes": "^0.4.0 || dev-main",
31+
"php-static-analysis/node-visitor": "^0.4.0 || dev-main",
32+
"rector/rector": "^2.0"
3333
},
3434
"require-dev": {
35-
"php-static-analysis/phpstan-extension": "dev-main",
36-
"php-static-analysis/psalm-plugin": "dev-main",
35+
"composer/composer": "^2.8",
36+
"php-static-analysis/phpstan-extension": "^0.4.0 || dev-main",
37+
"php-static-analysis/psalm-plugin": "^0.4.0 || dev-main",
3738
"phpstan/extension-installer": "^1.3",
38-
"phpstan/phpstan": "^1.8",
39+
"phpstan/phpstan": "^2.0",
3940
"phpunit/phpunit": "^9.0",
4041
"symplify/easy-coding-standard": "^12.1",
41-
"vimeo/psalm": "^5",
42+
"vimeo/psalm": "dev-master",
4243
"webmozart/assert": "^1.11"
4344
},
4445
"scripts": {
@@ -49,17 +50,26 @@
4950
"@phpstan",
5051
"@rector"
5152
],
53+
"tests-without-psalm": [
54+
"@ecs",
55+
"@phpunit",
56+
"@phpstan",
57+
"@rector"
58+
],
5259
"psalm": "psalm",
5360
"ecs": "ecs",
5461
"ecs-fix": "ecs --fix",
5562
"phpunit": "phpunit",
5663
"phpstan": "phpstan analyse",
5764
"rector": "rector --dry-run",
5865
"rector-fix": "rector",
59-
"rector-debug": "rector --clear-cache --xdebug --dry-run"
66+
"rector-debug": "rector --clear-cache --xdebug --dry-run",
67+
"post-install-cmd": "PhpStaticAnalysis\\RectorRule\\Composer\\Plugin::onPostInstall",
68+
"post-update-cmd": "PhpStaticAnalysis\\RectorRule\\Composer\\Plugin::onPostUpdate"
6069
},
6170
"config": {
6271
"allow-plugins": {
72+
"php-static-analysis/psalm-plugin": true,
6373
"phpstan/extension-installer": true
6474
},
6575
"sort-packages": true

config/sets/php-static-analysis-annotations-to-attributes.php

+8-9
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,30 @@
1111
use PhpStaticAnalysis\Attributes\ImportType;
1212
use PhpStaticAnalysis\Attributes\Impure;
1313
use PhpStaticAnalysis\Attributes\Internal;
14+
use PhpStaticAnalysis\Attributes\IsReadOnly;
1415
use PhpStaticAnalysis\Attributes\Method;
1516
use PhpStaticAnalysis\Attributes\Mixin;
17+
use PhpStaticAnalysis\Attributes\Param;
1618
use PhpStaticAnalysis\Attributes\ParamOut;
19+
use PhpStaticAnalysis\Attributes\Property;
1720
use PhpStaticAnalysis\Attributes\PropertyRead;
1821
use PhpStaticAnalysis\Attributes\PropertyWrite;
1922
use PhpStaticAnalysis\Attributes\Pure;
2023
use PhpStaticAnalysis\Attributes\RequireExtends;
2124
use PhpStaticAnalysis\Attributes\RequireImplements;
25+
use PhpStaticAnalysis\Attributes\Returns;
2226
use PhpStaticAnalysis\Attributes\SelfOut;
27+
use PhpStaticAnalysis\Attributes\Template;
2328
use PhpStaticAnalysis\Attributes\TemplateContravariant;
2429
use PhpStaticAnalysis\Attributes\TemplateCovariant;
2530
use PhpStaticAnalysis\Attributes\TemplateExtends;
2631
use PhpStaticAnalysis\Attributes\TemplateImplements;
2732
use PhpStaticAnalysis\Attributes\TemplateUse;
2833
use PhpStaticAnalysis\Attributes\Throws;
29-
use Rector\Config\RectorConfig;
30-
use Rector\Php80\ValueObject\AnnotationToAttribute;
31-
use PhpStaticAnalysis\Attributes\IsReadOnly;
32-
use PhpStaticAnalysis\Attributes\Param;
33-
use PhpStaticAnalysis\Attributes\Property;
34-
use PhpStaticAnalysis\Attributes\Returns;
35-
use PhpStaticAnalysis\Attributes\Template;
3634
use PhpStaticAnalysis\Attributes\Type;
3735
use PhpStaticAnalysis\RectorRule\AnnotationsToAttributesRector;
36+
use Rector\Config\RectorConfig;
37+
use Rector\Php80\ValueObject\AnnotationToAttribute;
3838

3939
return RectorConfig::configure()
4040
->withConfiguredRule(
@@ -81,5 +81,4 @@
8181
'excludeAnnotations' => [],
8282
'useTypeAttributeForTypeClassAnnotation' => false,
8383
]
84-
)
85-
->withImportNames();
84+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use PhpStaticAnalysis\RectorRule\AttributesToAnnotationsRector;
6+
use Rector\Config\RectorConfig;
7+
8+
return RectorConfig::configure()
9+
->withRules([
10+
AttributesToAnnotationsRector::class
11+
]);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--- /dev/null
2+
+++ ../src/Application/FileProcessor.php
3+
@@ -3,6 +3,7 @@
4+
declare (strict_types=1);
5+
namespace Rector\Application;
6+
7+
+use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
8+
use RectorPrefix202412\Nette\Utils\FileSystem;
9+
use PHPStan\AnalysedCodeException;
10+
use PHPStan\Parser\ParserErrorsException;
11+
@@ -66,7 +67,9 @@
12+
* @readonly
13+
*/
14+
private NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator;
15+
- public function __construct(BetterStandardPrinter $betterStandardPrinter, RectorNodeTraverser $rectorNodeTraverser, SymfonyStyle $symfonyStyle, FileDiffFactory $fileDiffFactory, ChangedFilesDetector $changedFilesDetector, ErrorFactory $errorFactory, FilePathHelper $filePathHelper, PostFileProcessor $postFileProcessor, RectorParser $rectorParser, NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator)
16+
+ public function __construct(BetterStandardPrinter $betterStandardPrinter, RectorNodeTraverser $rectorNodeTraverser, SymfonyStyle $symfonyStyle, FileDiffFactory $fileDiffFactory, ChangedFilesDetector $changedFilesDetector, ErrorFactory $errorFactory, FilePathHelper $filePathHelper, PostFileProcessor $postFileProcessor, RectorParser $rectorParser, NodeScopeAndMetadataDecorator $nodeScopeAndMetadataDecorator,
17+
+ private PhpDocInfoFactory $phpDocInfoFactory
18+
+ )
19+
{
20+
$this->betterStandardPrinter = $betterStandardPrinter;
21+
$this->rectorNodeTraverser = $rectorNodeTraverser;
22+
@@ -90,6 +93,7 @@
23+
$fileHasChanged = \false;
24+
$filePath = $file->getFilePath();
25+
do {
26+
+ $this->phpDocInfoFactory->clearCache();
27+
$file->changeHasChanged(\false);
28+
// 1. change nodes with Rector Rules
29+
$newStmts = $this->rectorNodeTraverser->traverse($file->getNewStmts());
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
--- /dev/null
2+
+++ ../src/BetterPhpDocParser/PhpDocInfo/PhpDocInfoFactory.php
3+
@@ -55,6 +55,10 @@
4+
$this->annotationNaming = $annotationNaming;
5+
$this->phpDocNodeByTypeFinder = $phpDocNodeByTypeFinder;
6+
}
7+
+ public function clearCache(): void
8+
+ {
9+
+ $this->phpDocInfosByObjectId = [];
10+
+ }
11+
public function createFromNodeOrEmpty(Node $node) : \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo
12+
{
13+
// already added

patches/rector-rector-src-nodetyperesolver-node-attributekey-php.patch

-11
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
--- /dev/null
2+
+++ ../src/PhpParser/NodeTraverser/RectorNodeTraverser.php
3+
@@ -7,6 +7,8 @@
4+
use PhpParser\Node\Stmt;
5+
use PhpParser\NodeTraverser;
6+
use PhpParser\NodeVisitor;
7+
+use PhpStaticAnalysis\RectorRule\AnnotationsToAttributesRector;
8+
+use PhpStaticAnalysis\RectorRule\AttributesToAnnotationsRector;
9+
use Rector\Configuration\ConfigurationRuleFilter;
10+
use Rector\Contract\Rector\RectorInterface;
11+
use Rector\VersionBonding\PhpVersionedFilter;
12+
@@ -97,6 +99,23 @@
13+
$this->visitors = $this->phpVersionedFilter->filter($this->rectors);
14+
// filter by configuration
15+
$this->visitors = $this->configurationRuleFilter->filter($this->visitors);
16+
+
17+
+ $first = [];
18+
+ $middle = [];
19+
+ $last = [];
20+
+
21+
+ foreach ($this->visitors as $visitor) {
22+
+ if ($visitor instanceof AttributesToAnnotationsRector) {
23+
+ $first[] = $visitor;
24+
+ } elseif ($visitor instanceof AnnotationsToAttributesRector) {
25+
+ $last[] = $visitor;
26+
+ } else {
27+
+ $middle[] = $visitor;
28+
+ }
29+
+ }
30+
+
31+
+ $this->visitors = array_merge($first, $middle, $last);
32+
+
33+
$this->areNodeVisitorsPrepared = \true;
34+
}
35+
}

patches/rector-rector-src-phpparser-printer-betterstandardprinter-php.patch

-18
This file was deleted.

rector.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
declare(strict_types=1);
44

5+
use PhpStaticAnalysis\RectorRule\Set\PhpStaticAnalysisAnnotationsToAttributesSetList;
56
use Rector\Config\RectorConfig;
6-
use PhpStaticAnalysis\RectorRule\Set\PhpStaticAnalysisSetList;
77

88
return RectorConfig::configure()
99
->withPaths([
@@ -15,5 +15,5 @@
1515
__DIR__ . '/tests/SpecialFixture',
1616
])
1717
->withSets([
18-
PhpStaticAnalysisSetList::ANNOTATIONS_TO_ATTRIBUTES
18+
PhpStaticAnalysisAnnotationsToAttributesSetList::ANNOTATIONS_TO_ATTRIBUTES
1919
]);

src/AnnotationsToAttributesRector.php

+11-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use PhpParser\Node\Expr\Variable;
1212
use PhpParser\Node\Identifier;
1313
use PhpParser\Node\Name\FullyQualified;
14-
use PhpParser\Node\Scalar;
1514
use PhpParser\Node\Scalar\String_;
1615
use PhpParser\Node\Stmt;
1716
use PhpParser\Node\Stmt\Class_;
@@ -53,6 +52,7 @@
5352
use PhpStaticAnalysis\Attributes\Property;
5453
use PhpStaticAnalysis\Attributes\Returns;
5554
use PhpStaticAnalysis\Attributes\Type;
55+
use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode;
5656
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
5757
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
5858
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover;
@@ -62,6 +62,7 @@
6262
use Rector\Php80\NodeManipulator\AttributeGroupNamedArgumentManipulator;
6363
use Rector\Php80\ValueObject\AnnotationToAttribute;
6464
use Rector\Rector\AbstractRector;
65+
use Rector\ValueObject\PhpVersion;
6566
use Rector\ValueObject\PhpVersionFeature;
6667
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
6768
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@@ -207,6 +208,8 @@ public function getNodeTypes(): array
207208
#[Param(node: 'Stmt\Class_|Stmt\ClassConst|Stmt\ClassMethod|Stmt\Function_|Stmt\Interface_|Stmt\Property|Stmt\Trait_')]
208209
public function refactor(Node $node): ?Node
209210
{
211+
$nodeModified = false;
212+
210213
$phpDocInfo = $this->phpDocInfoFactory->createFromNode($node);
211214

212215
$attributeGroups = [];
@@ -215,6 +218,8 @@ public function refactor(Node $node): ?Node
215218
}
216219

217220
if ($attributeGroups !== []) {
221+
$nodeModified = true;
222+
218223
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node);
219224

220225
$this->attributeGroupNamedArgumentManipulator->decorate($attributeGroups);
@@ -262,6 +267,8 @@ public function refactor(Node $node): ?Node
262267
$useAttributeGroups = $this->processAnnotations($phpDocInfo);
263268

264269
if ($useAttributeGroups !== []) {
270+
$nodeModified = true;
271+
265272
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($stmt);
266273

267274
$this->attributeGroupNamedArgumentManipulator->decorate($useAttributeGroups);
@@ -276,7 +283,7 @@ public function refactor(Node $node): ?Node
276283
$node->attrGroups = array_merge($node->attrGroups, $attributeGroups);
277284
}
278285

279-
return $node;
286+
return $nodeModified ? $node : null;
280287
}
281288

282289
#[Returns('AttributeGroup[]')]
@@ -350,6 +357,7 @@ private function processAnnotations(PhpDocInfo $phpDocInfo): array
350357
}
351358
$attributeComment = $tagValueNode->description;
352359
break;
360+
case $tagValueNode instanceof DoctrineAnnotationTagValueNode:
353361
case $tagValueNode instanceof DeprecatedTagValueNode:
354362
case $tagValueNode instanceof GenericTagValueNode:
355363
$args = [];
@@ -442,6 +450,7 @@ private function processAnnotations(PhpDocInfo $phpDocInfo): array
442450
return $attributeGroups;
443451
}
444452

453+
#[Returns('PhpVersion::PHP_80')]
445454
public function provideMinPhpVersion(): int
446455
{
447456
return PhpVersionFeature::ATTRIBUTES;

0 commit comments

Comments
 (0)