Skip to content

Commit 0e36c35

Browse files
Add PostRectorInterface instance class names to list of applied rectors (#7304)
* [WIP] Add PostRectorInterface instances to list of applied rectors * make RectorWithLineChange allow PostRectorInterface class-string type * Rename getRectorClasses() to getMainRectorClasses() to differentiate use of PostRectorIntercace instance * Fix phpstan * [ci-review] Rector Rectify * grammar fix * grammar fix * part 1: apply line with change on ClassRenamingPostRector * part 2: apply line with change on DocblockNameImportingPostRector * [ci-review] Rector Rectify * Fix phpstan * part 3: apply line with change on UnusedImportRemovingPostRector * part 4: ensure partial remove use detected * part 4: ensure partial remove use detected * part 5: add rector clas with line on NameImportingPostRector * Add OriginalNameImportSkipVoter for auto import * Fix no change handling * Fix cs * Add e2e test * Final touch: add UseAddingPostRector that NameImportingPostRector is rely when NameImportingPostRector exists * Final touch: add UseAddingPostRector that NameImportingPostRector is rely when NameImportingPostRector exists * final touch: fix grammar * Really final touch: ensure UseAddingPostRector correctly added when exactly applied * Really final touch: clean up * Really Really final touch: use call addRectorClassWithLine() itself on UseAddingPostRector when there is add to use * Really final touch: clean up logic --------- Co-authored-by: GitHub Action <actions@github.com>
1 parent c99cce3 commit 0e36c35

File tree

22 files changed

+197
-77
lines changed

22 files changed

+197
-77
lines changed

.github/workflows/e2e.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
matrix:
2525
php_version: ['8.2']
2626
directory:
27+
- 'e2e/applied-auto-import'
2728
- 'e2e/applied-polyfill-php80'
2829
- 'e2e/applied-rule-change-docblock'
2930
- 'e2e/applied-rule-removed-node'

e2e/applied-auto-import/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/vendor
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"require": {
3+
"php": "^8.1"
4+
},
5+
"minimum-stability": "dev",
6+
"prefer-stable": true
7+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
1 file with changes
2+
===================
3+
4+
1) src/RenameDocblock.php:2
5+
6+
---------- begin diff ----------
7+
@@ @@
8+
9+
namespace App;
10+
11+
-use SomeUnusedClass;
12+
+use DateTimeInterface;
13+
14+
/**
15+
- * @param \DateTime $someOldClass
16+
+ * @param DateTimeInterface $someOldClass
17+
*/
18+
-function someFunction(\DateTime $someOldClass)
19+
+function someFunction(DateTimeInterface $someOldClass)
20+
{
21+
}
22+
----------- end diff -----------
23+
24+
Applied rules:
25+
* RenameClassRector
26+
* DocblockNameImportingPostRector
27+
* NameImportingPostRector
28+
* UnusedImportRemovingPostRector
29+
* UseAddingPostRector
30+
31+
32+
[OK] 1 file would have been changed (dry-run) by Rector

e2e/applied-auto-import/rector.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use Rector\Renaming\Rector\Name\RenameClassRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->paths([
10+
__DIR__ . '/src',
11+
]);
12+
13+
$rectorConfig->ruleWithConfiguration(RenameClassRector::class, [
14+
'DateTime' => 'DateTimeInterface'
15+
]);
16+
17+
$rectorConfig->importNames();
18+
$rectorConfig->removeUnusedImports();
19+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace App;
4+
5+
use SomeUnusedClass;
6+
7+
/**
8+
* @param \DateTime $someOldClass
9+
*/
10+
function someFunction(\DateTime $someOldClass)
11+
{
12+
}

phpstan.neon

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ parameters:
238238
paths:
239239
# caching and message of specific child Rector rules
240240
- src/Rector/AbstractRector.php
241+
- src/PostRector/Rector/AbstractPostRector.php
241242
# for cache
242243
- src/Testing/PHPUnit/AbstractRectorTestCase.php
243244

rules/CodingStyle/Application/UseImportsAdder.php

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,14 @@ public function __construct(
3131
* @param array<FullyQualifiedObjectType|AliasedObjectType> $useImportTypes
3232
* @param array<FullyQualifiedObjectType|AliasedObjectType> $constantUseImportTypes
3333
* @param array<FullyQualifiedObjectType|AliasedObjectType> $functionUseImportTypes
34-
* @return Stmt[]
3534
*/
3635
public function addImportsToStmts(
3736
FileWithoutNamespace $fileWithoutNamespace,
3837
array $stmts,
3938
array $useImportTypes,
4039
array $constantUseImportTypes,
4140
array $functionUseImportTypes
42-
): array {
41+
): bool {
4342
$usedImports = $this->usedImportsResolver->resolveForStmts($stmts);
4443
$existingUseImportTypes = $usedImports->getUseImports();
4544
$existingConstantUseImports = $usedImports->getConstantImports();
@@ -57,7 +56,7 @@ public function addImportsToStmts(
5756

5857
$newUses = $this->createUses($useImportTypes, $constantUseImportTypes, $functionUseImportTypes, null);
5958
if ($newUses === []) {
60-
return [$fileWithoutNamespace];
59+
return false;
6160
}
6261

6362
$stmts = array_values(array_filter($stmts, static function (Stmt $stmt): bool {
@@ -94,7 +93,7 @@ public function addImportsToStmts(
9493
$fileWithoutNamespace->stmts = $stmts;
9594
$fileWithoutNamespace->stmts = array_values($fileWithoutNamespace->stmts);
9695

97-
return [$fileWithoutNamespace];
96+
return true;
9897
}
9998

10099
$this->mirrorUseComments($stmts, $newUses);
@@ -103,7 +102,7 @@ public function addImportsToStmts(
103102
$fileWithoutNamespace->stmts = array_merge($newUses, $this->resolveInsertNop($fileWithoutNamespace), $stmts);
104103
$fileWithoutNamespace->stmts = array_values($fileWithoutNamespace->stmts);
105104

106-
return [$fileWithoutNamespace];
105+
return true;
107106
}
108107

109108
/**
@@ -116,7 +115,7 @@ public function addImportsToNamespace(
116115
array $useImportTypes,
117116
array $constantUseImportTypes,
118117
array $functionUseImportTypes
119-
): void {
118+
): bool {
120119
$namespaceName = $this->getNamespaceName($namespace);
121120

122121
$existingUsedImports = $this->usedImportsResolver->resolveForStmts($namespace->stmts);
@@ -141,13 +140,15 @@ public function addImportsToNamespace(
141140
$newUses = $this->createUses($useImportTypes, $constantUseImportTypes, $functionUseImportTypes, $namespaceName);
142141

143142
if ($newUses === []) {
144-
return;
143+
return false;
145144
}
146145

147146
$this->mirrorUseComments($namespace->stmts, $newUses);
148147

149148
$namespace->stmts = array_merge($newUses, $this->resolveInsertNop($namespace), $namespace->stmts);
150149
$namespace->stmts = array_values($namespace->stmts);
150+
151+
return true;
151152
}
152153

153154
/**

rules/CodingStyle/Application/UseImportsRemover.php

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
namespace Rector\CodingStyle\Application;
66

7-
use PhpParser\Node\Stmt;
7+
use PhpParser\Node\Stmt\Namespace_;
88
use PhpParser\Node\Stmt\Use_;
9+
use Rector\PhpParser\Node\CustomNode\FileWithoutNamespace;
910
use Rector\Renaming\Collector\RenamedNameCollector;
1011

1112
final readonly class UseImportsRemover
@@ -16,35 +17,40 @@ public function __construct(
1617
}
1718

1819
/**
19-
* @param Stmt[] $stmts
2020
* @param string[] $removedUses
21-
* @return Stmt[]
2221
*/
23-
public function removeImportsFromStmts(array $stmts, array $removedUses): array
22+
public function removeImportsFromStmts(FileWithoutNamespace|Namespace_ $node, array $removedUses): bool
2423
{
2524
$hasRemoved = false;
26-
foreach ($stmts as $key => $stmt) {
25+
foreach ($node->stmts as $key => $stmt) {
2726
if (! $stmt instanceof Use_) {
2827
continue;
2928
}
3029

31-
$stmt = $this->removeUseFromUse($removedUses, $stmt);
30+
if ($this->removeUseFromUse($removedUses, $stmt)) {
31+
$node->stmts[$key] = $stmt;
32+
$hasRemoved = true;
33+
}
3234

3335
// remove empty uses
3436
if ($stmt->uses === []) {
35-
unset($stmts[$key]);
36-
$hasRemoved = true;
37+
unset($node->stmts[$key]);
3738
}
3839
}
3940

40-
return $hasRemoved ? array_values($stmts) : $stmts;
41+
if ($hasRemoved) {
42+
$node->stmts = array_values($node->stmts);
43+
}
44+
45+
return $hasRemoved;
4146
}
4247

4348
/**
4449
* @param string[] $removedUses
4550
*/
46-
private function removeUseFromUse(array $removedUses, Use_ $use): Use_
51+
private function removeUseFromUse(array $removedUses, Use_ $use): bool
4752
{
53+
$hasChanged = false;
4854
foreach ($use->uses as $usesKey => $useUse) {
4955
$useName = $useUse->name->toString();
5056
if (! in_array($useName, $removedUses, true)) {
@@ -56,8 +62,13 @@ private function removeUseFromUse(array $removedUses, Use_ $use): Use_
5662
}
5763

5864
unset($use->uses[$usesKey]);
65+
$hasChanged = true;
66+
}
67+
68+
if ($hasChanged) {
69+
$use->uses = array_values($use->uses);
5970
}
6071

61-
return $use;
72+
return $hasChanged;
6273
}
6374
}

src/Bridge/SetRectorsResolver.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function resolveFromFilePathIncludingConfiguration(string $configFilePath
4646
{
4747
$rectorConfig = $this->loadRectorConfigFromFilePath($configFilePath);
4848

49-
$rectorClassesWithOptionalConfiguration = $rectorConfig->getRectorClasses();
49+
$rectorClassesWithOptionalConfiguration = $rectorConfig->getMainRectorClasses();
5050

5151
foreach ($rectorConfig->getRuleConfigurations() as $rectorClass => $configuration) {
5252
// remove from non-configurable, if added again with better config

0 commit comments

Comments
 (0)