Skip to content

Commit 97f1dcf

Browse files
committed
Updated Rector to commit f891bb6635642690ec64e4f9d78299ef8ea89af7
rectorphp/rector-src@f891bb6 Introduce FileNode to handle file-level changes (#7728)
1 parent af1f20b commit 97f1dcf

39 files changed

+446
-251
lines changed

UPGRADING.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,110 @@
1+
# Upgrading from Rector 2.2.14 to 2.3
2+
3+
* `FileWithoutNamespace` is deprecated, and replaced by `FileNode` that represents both namespaced and non-namespaced files and allow changes inside
4+
* `beforeTraverse()` is now marked as `@final`, use `getNodeTypes()` with `FileNode::class` instead
5+
6+
**Before**
7+
8+
```php
9+
use Rector\PhpParser\Node\FileWithoutNamespace;
10+
use Rector\Rector\AbstractRector;
11+
12+
final class SomeRector extends AbstractRector
13+
{
14+
public function getNodeTypes(): array
15+
{
16+
return [FileWithoutNamespace::class];
17+
}
18+
19+
public function beforeTraverse(array $nodes): array
20+
{
21+
// some node hacking
22+
}
23+
24+
/**
25+
* @param FileWithoutNamespace $node
26+
*/
27+
public function refactor(Node $node): ?Node
28+
{
29+
// ...
30+
}
31+
32+
}
33+
```
34+
35+
**After**
36+
37+
```php
38+
use Rector\PhpParser\Node\FileNode;
39+
use Rector\Rector\AbstractRector;
40+
41+
final class SomeRector extends AbstractRector
42+
{
43+
public function getNodeTypes(): array
44+
{
45+
return [FileNode::class];
46+
}
47+
48+
/**
49+
* @param FileNode $node
50+
*/
51+
public function refactor(Node $node): ?Node
52+
{
53+
foreach ($node->stmts as $stmt) {
54+
// check if has declare_strict already?
55+
// ...
56+
57+
// create it
58+
$declareStrictTypes = $this->createDeclareStrictTypesNode();
59+
60+
// add it
61+
$node->stmts = array_merge([$declareStrictTypes], $node->stmts);
62+
}
63+
64+
return $node;
65+
}
66+
67+
}
68+
```
69+
70+
<br>
71+
72+
The `FileNode` handles both namespaced and non-namespaced files. To handle the first stmts inside the file, you hook into 2 nodes:
73+
74+
```php
75+
use Rector\PhpParser\Node\FileNode;
76+
use Rector\Rector\AbstractRector;
77+
use PhpParser\Node\Stmt\Namespace_;
78+
79+
final class SomeRector extends AbstractRector
80+
{
81+
public function getNodeTypes(): array
82+
{
83+
return [FileNode::class, Namespace_::class];
84+
}
85+
86+
/**
87+
* @param FileNode|Namespace_ $node
88+
*/
89+
public function refactor(Node $node): ?Node
90+
{
91+
if ($node instanceof FileNode && $node->isNamespaced()) {
92+
// handled in the Namespace_ node
93+
return null;
94+
}
95+
96+
foreach ($node->stmts as $stmt) {
97+
// modify stmts in desired way here
98+
}
99+
100+
return $node;
101+
}
102+
103+
}
104+
```
105+
106+
<br>
107+
1108
# Upgrading from Rector 1.x to 2.0
2109

3110
## PHP version requirements

rules/CodingStyle/Application/UseImportsAdder.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
use Rector\CodingStyle\ClassNameImport\UsedImportsResolver;
1414
use Rector\NodeTypeResolver\Node\AttributeKey;
1515
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
16-
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
16+
use Rector\PhpParser\Node\FileNode;
1717
use Rector\StaticTypeMapper\ValueObject\Type\AliasedObjectType;
1818
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
1919
final class UseImportsAdder
@@ -37,7 +37,7 @@ public function __construct(UsedImportsResolver $usedImportsResolver, TypeFactor
3737
* @param array<FullyQualifiedObjectType|AliasedObjectType> $constantUseImportTypes
3838
* @param array<FullyQualifiedObjectType|AliasedObjectType> $functionUseImportTypes
3939
*/
40-
public function addImportsToStmts(FileWithoutNamespace $fileWithoutNamespace, array $stmts, array $useImportTypes, array $constantUseImportTypes, array $functionUseImportTypes): bool
40+
public function addImportsToStmts(FileNode $fileNode, array $stmts, array $useImportTypes, array $constantUseImportTypes, array $functionUseImportTypes): bool
4141
{
4242
$usedImports = $this->usedImportsResolver->resolveForStmts($stmts);
4343
$existingUseImportTypes = $usedImports->getUseImports();
@@ -73,14 +73,14 @@ public function addImportsToStmts(FileWithoutNamespace $fileWithoutNamespace, ar
7373
$stmts[$key + 1]->setAttribute(AttributeKey::ORIGINAL_NODE, null);
7474
}
7575
array_splice($stmts, $key + 1, 0, $nodesToAdd);
76-
$fileWithoutNamespace->stmts = $stmts;
77-
$fileWithoutNamespace->stmts = array_values($fileWithoutNamespace->stmts);
76+
$fileNode->stmts = $stmts;
77+
$fileNode->stmts = array_values($fileNode->stmts);
7878
return \true;
7979
}
8080
$this->mirrorUseComments($stmts, $newUses);
8181
// make use stmts first
82-
$fileWithoutNamespace->stmts = array_merge($newUses, $this->resolveInsertNop($fileWithoutNamespace), $stmts);
83-
$fileWithoutNamespace->stmts = array_values($fileWithoutNamespace->stmts);
82+
$fileNode->stmts = array_merge($newUses, $this->resolveInsertNop($fileNode), $stmts);
83+
$fileNode->stmts = array_values($fileNode->stmts);
8484
return \true;
8585
}
8686
/**
@@ -110,7 +110,7 @@ public function addImportsToNamespace(Namespace_ $namespace, array $useImportTyp
110110
}
111111
/**
112112
* @return Nop[]
113-
* @param \Rector\PhpParser\Node\CustomNode\FileWithoutNamespace|\PhpParser\Node\Stmt\Namespace_ $namespace
113+
* @param \Rector\PhpParser\Node\FileNode|\PhpParser\Node\Stmt\Namespace_ $namespace
114114
*/
115115
private function resolveInsertNop($namespace): array
116116
{

rules/CodingStyle/Application/UseImportsRemover.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
use PhpParser\Node\Stmt\Namespace_;
77
use PhpParser\Node\Stmt\Use_;
8-
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
8+
use Rector\PhpParser\Node\FileNode;
99
use Rector\Renaming\Collector\RenamedNameCollector;
1010
final class UseImportsRemover
1111
{
@@ -19,7 +19,7 @@ public function __construct(RenamedNameCollector $renamedNameCollector)
1919
}
2020
/**
2121
* @param string[] $removedUses
22-
* @param \Rector\PhpParser\Node\CustomNode\FileWithoutNamespace|\PhpParser\Node\Stmt\Namespace_ $node
22+
* @param \Rector\PhpParser\Node\FileNode|\PhpParser\Node\Stmt\Namespace_ $node
2323
*/
2424
public function removeImportsFromStmts($node, array $removedUses): bool
2525
{

rules/CodingStyle/ClassNameImport/AliasUsesResolver.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use PhpParser\Node\Stmt\Namespace_;
1010
use PhpParser\Node\Stmt\Use_;
1111
use PhpParser\Node\UseItem;
12-
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
12+
use Rector\PhpParser\Node\FileNode;
1313
final class AliasUsesResolver
1414
{
1515
/**
@@ -26,9 +26,9 @@ public function __construct(\Rector\CodingStyle\ClassNameImport\UseImportsTraver
2626
*/
2727
public function resolveFromNode(Node $node, array $stmts): array
2828
{
29-
if (!$node instanceof Namespace_ && !$node instanceof FileWithoutNamespace) {
30-
/** @var Namespace_[]|FileWithoutNamespace[] $namespaces */
31-
$namespaces = array_filter($stmts, static fn(Stmt $stmt): bool => $stmt instanceof Namespace_ || $stmt instanceof FileWithoutNamespace);
29+
if (!$node instanceof Namespace_ && !$node instanceof FileNode) {
30+
/** @var Namespace_[]|FileNode[] $namespaces */
31+
$namespaces = array_filter($stmts, static fn(Stmt $stmt): bool => $stmt instanceof Namespace_ || $stmt instanceof FileNode);
3232
if (count($namespaces) !== 1) {
3333
return [];
3434
}

rules/CodingStyle/ClassNameImport/ShortNameResolver.php

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use PhpParser\Node\Name;
99
use PhpParser\Node\Stmt;
1010
use PhpParser\Node\Stmt\ClassLike;
11-
use PhpParser\Node\Stmt\Namespace_;
1211
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
1312
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
1413
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
@@ -19,7 +18,6 @@
1918
use Rector\PhpDocParser\NodeTraverser\SimpleCallableNodeTraverser;
2019
use Rector\PhpDocParser\PhpDocParser\PhpDocNodeTraverser;
2120
use Rector\PhpParser\Node\BetterNodeFinder;
22-
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
2321
use Rector\ValueObject\Application\File;
2422
/**
2523
* @see \Rector\Tests\CodingStyle\ClassNameImport\ShortNameResolver\ShortNameResolverTest
@@ -77,16 +75,13 @@ public function resolveFromFile(File $file): array
7775
*/
7876
public function resolveShortClassLikeNames(File $file): array
7977
{
80-
$newStmts = $file->getNewStmts();
81-
/** @var Namespace_[]|FileWithoutNamespace[] $namespaces */
82-
$namespaces = array_filter($newStmts, static fn(Stmt $stmt): bool => $stmt instanceof Namespace_ || $stmt instanceof FileWithoutNamespace);
83-
if (count($namespaces) !== 1) {
84-
// only handle single namespace nodes
78+
$rootNode = $file->getUseImportsRootNode();
79+
// nothing to resolve
80+
if (!$rootNode instanceof Node) {
8581
return [];
8682
}
87-
$namespace = current($namespaces);
8883
/** @var ClassLike[] $classLikes */
89-
$classLikes = $this->betterNodeFinder->findInstanceOf($namespace->stmts, ClassLike::class);
84+
$classLikes = $this->betterNodeFinder->findInstanceOf($rootNode->stmts, ClassLike::class);
9085
$shortClassLikeNames = [];
9186
foreach ($classLikes as $classLike) {
9287
$shortClassLikeNames[] = $this->nodeNameResolver->getShortName($classLike);

rules/CodingStyle/ClassNameImport/UseImportsTraverser.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use PhpParser\Node\Stmt\Use_;
1010
use PhpParser\Node\UseItem;
1111
use Rector\NodeNameResolver\NodeNameResolver;
12-
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
12+
use Rector\PhpParser\Node\FileNode;
1313
final class UseImportsTraverser
1414
{
1515
/**
@@ -27,7 +27,7 @@ public function __construct(NodeNameResolver $nodeNameResolver)
2727
public function traverserStmts(array $stmts, callable $callable): void
2828
{
2929
foreach ($stmts as $stmt) {
30-
if ($stmt instanceof Namespace_ || $stmt instanceof FileWithoutNamespace) {
30+
if ($stmt instanceof Namespace_ || $stmt instanceof FileNode) {
3131
$this->traverserStmts($stmt->stmts, $callable);
3232
continue;
3333
}

rules/CodingStyle/Rector/Catch_/CatchExceptionNameMatchingTypeRector.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
use PHPStan\Type\ObjectType;
2121
use Rector\Naming\Naming\PropertyNaming;
2222
use Rector\NodeTypeResolver\Node\AttributeKey;
23-
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
23+
use Rector\PhpParser\Node\FileNode;
2424
use Rector\Rector\AbstractRector;
2525
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
2626
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -65,16 +65,20 @@ public function getRuleDefinition(): RuleDefinition
6565
*/
6666
public function getNodeTypes(): array
6767
{
68-
return [ClassMethod::class, Function_::class, Closure::class, FileWithoutNamespace::class, Namespace_::class];
68+
return [ClassMethod::class, Function_::class, Closure::class, FileNode::class, Namespace_::class];
6969
}
7070
/**
71-
* @param ClassMethod|Function_|Closure|FileWithoutNamespace|Namespace_ $node
71+
* @param ClassMethod|Function_|Closure|FileNode|Namespace_ $node
7272
*/
7373
public function refactor(Node $node): ?Node
7474
{
7575
if ($node->stmts === null) {
7676
return null;
7777
}
78+
if ($node instanceof FileNode && $node->isNamespaced()) {
79+
// handled in Namespace_ node
80+
return null;
81+
}
7882
$hasChanged = \false;
7983
foreach ($node->stmts as $key => $stmt) {
8084
if ($this->shouldSkip($stmt)) {

rules/CodingStyle/Rector/Stmt/RemoveUselessAliasInUseStatementRector.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use PhpParser\Node\Identifier;
99
use PhpParser\Node\Stmt\Namespace_;
1010
use PhpParser\Node\Stmt\Use_;
11-
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
11+
use Rector\PhpParser\Node\FileNode;
1212
use Rector\Rector\AbstractRector;
1313
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
1414
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -32,14 +32,18 @@ public function getRuleDefinition(): RuleDefinition
3232
*/
3333
public function getNodeTypes(): array
3434
{
35-
return [FileWithoutNamespace::class, Namespace_::class];
35+
return [FileNode::class, Namespace_::class];
3636
}
3737
/**
38-
* @param FileWithoutNamespace|Namespace_ $node
39-
* @return null|\Rector\PhpParser\Node\CustomNode\FileWithoutNamespace|\PhpParser\Node\Stmt\Namespace_
38+
* @param Namespace_|FileNode $node
39+
* @return null|\Rector\PhpParser\Node\FileNode|\PhpParser\Node\Stmt\Namespace_
4040
*/
4141
public function refactor(Node $node)
4242
{
43+
if ($node instanceof FileNode && $node->isNamespaced()) {
44+
// handle in Namespace_ node
45+
return null;
46+
}
4347
$hasChanged = \false;
4448
foreach ($node->stmts as $stmt) {
4549
if (!$stmt instanceof Use_) {

rules/CodingStyle/Rector/Use_/SeparateMultiUseImportsRector.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use PhpParser\Node\Stmt\TraitUse;
1111
use PhpParser\Node\Stmt\TraitUseAdaptation\Alias;
1212
use PhpParser\Node\Stmt\Use_;
13-
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
13+
use Rector\PhpParser\Node\FileNode;
1414
use Rector\Rector\AbstractRector;
1515
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
1616
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -46,14 +46,18 @@ class SomeClass
4646
*/
4747
public function getNodeTypes(): array
4848
{
49-
return [FileWithoutNamespace::class, Namespace_::class, Class_::class];
49+
return [FileNode::class, Namespace_::class, Class_::class];
5050
}
5151
/**
52-
* @param FileWithoutNamespace|Namespace_|Class_ $node
53-
* @return \Rector\PhpParser\Node\CustomNode\FileWithoutNamespace|\PhpParser\Node\Stmt\Namespace_|\PhpParser\Node\Stmt\Class_|null
52+
* @param FileNode|Namespace_|Class_ $node
53+
* @return \Rector\PhpParser\Node\FileNode|\PhpParser\Node\Stmt\Namespace_|\PhpParser\Node\Stmt\Class_|null
5454
*/
5555
public function refactor(Node $node)
5656
{
57+
if ($node instanceof FileNode && $node->isNamespaced()) {
58+
// handled in Namespace_
59+
return null;
60+
}
5761
$hasChanged = \false;
5862
foreach ($node->stmts as $key => $stmt) {
5963
if ($stmt instanceof Use_) {

rules/DeadCode/Rector/Stmt/RemoveUnreachableStatementRector.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use PhpParser\Node\Stmt;
88
use Rector\NodeAnalyzer\TerminatedNodeAnalyzer;
99
use Rector\PhpParser\Enum\NodeGroup;
10+
use Rector\PhpParser\Node\FileNode;
1011
use Rector\Rector\AbstractRector;
1112
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
1213
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@@ -59,6 +60,10 @@ public function getNodeTypes(): array
5960
*/
6061
public function refactor(Node $node): ?Node
6162
{
63+
if ($node instanceof FileNode && $node->isNamespaced()) {
64+
// handled in Namespace_ node
65+
return null;
66+
}
6267
if ($node->stmts === null) {
6368
return null;
6469
}

0 commit comments

Comments
 (0)