Skip to content

Commit efcd52f

Browse files
committed
add standalone RectorRegistry to filter active rectors per file path
1 parent f6741cc commit efcd52f

4 files changed

Lines changed: 127 additions & 0 deletions

File tree

‎src/Application/RectorRegistry.php‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Application;
6+
7+
use Rector\Contract\Rector\RectorInterface;
8+
use Rector\Skipper\Skipper\Skipper;
9+
10+
final class RectorRegistry
11+
{
12+
/**
13+
* @param RectorInterface[] $rectors
14+
*/
15+
public function __construct(
16+
private array $rectors,
17+
private readonly Skipper $skipper
18+
) {
19+
}
20+
21+
/**
22+
* @param RectorInterface[] $rectors
23+
* @api used in tests to update the active rules
24+
*
25+
* @internal Used only in Rector core, not supported outside. Might change any time.
26+
*/
27+
public function refreshRectors(array $rectors): void
28+
{
29+
$this->rectors = $rectors;
30+
}
31+
32+
/**
33+
* @return RectorInterface[]
34+
*
35+
* @api used in tests
36+
*/
37+
public function forPath(string $filePath): array
38+
{
39+
$rectorsForPath = [];
40+
foreach ($this->rectors as $rector) {
41+
if ($this->skipper->shouldSkipRectorAndFile($rector, $filePath)) {
42+
continue;
43+
}
44+
45+
$rectorsForPath[] = $rector;
46+
}
47+
48+
return $rectorsForPath;
49+
}
50+
}

‎src/DependencyInjection/LazyContainerFactory.php‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PHPStan\Reflection\ReflectionProvider;
1717
use Rector\Application\FileProcessor;
1818
use Rector\Application\Provider\CurrentFileProvider;
19+
use Rector\Application\RectorRegistry;
1920
use Rector\BetterPhpDocParser\Comment\CommentsMerger;
2021
use Rector\BetterPhpDocParser\Contract\BasePhpDocNodeVisitorInterface;
2122
use Rector\BetterPhpDocParser\PhpDocNodeVisitor\ArrayTypePhpDocNodeVisitor;
@@ -168,6 +169,7 @@ private function registerFileProcessing(RectorConfig $rectorConfig): void
168169
{
169170
$rectorConfig->singleton(FileProcessor::class);
170171
$rectorConfig->singleton(PostFileProcessor::class);
172+
$rectorConfig->singleton(RectorRegistry::class);
171173

172174
// shared state: collects used skips across the skipper, the path skipper and the file processor
173175
$rectorConfig->singleton(UsedSkipCollector::class);
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\Application;
6+
7+
use Rector\Application\RectorRegistry;
8+
use Rector\Configuration\Option;
9+
use Rector\Configuration\Parameter\SimpleParameterProvider;
10+
use Rector\Testing\PHPUnit\AbstractLazyTestCase;
11+
use Rector\Tests\Application\Source\SkippableRector;
12+
13+
final class RectorRegistryTest extends AbstractLazyTestCase
14+
{
15+
private RectorRegistry $rectorRegistry;
16+
17+
protected function setUp(): void
18+
{
19+
parent::setUp();
20+
21+
SimpleParameterProvider::setParameter(Option::SKIP, [
22+
SkippableRector::class => ['*/skipped_directory/*'],
23+
]);
24+
25+
$this->rectorRegistry = $this->make(RectorRegistry::class);
26+
$this->rectorRegistry->refreshRectors([new SkippableRector()]);
27+
}
28+
29+
protected function tearDown(): void
30+
{
31+
SimpleParameterProvider::setParameter(Option::SKIP, []);
32+
}
33+
34+
public function testForPathSkipsRectorForSkippedPath(): void
35+
{
36+
$rectorsForPath = $this->rectorRegistry->forPath(__DIR__ . '/skipped_directory/some_file.php');
37+
38+
$this->assertSame([], $rectorsForPath);
39+
}
40+
41+
public function testForPathKeepsRectorForOtherPath(): void
42+
{
43+
$rectorsForPath = $this->rectorRegistry->forPath(__DIR__ . '/some_file.php');
44+
45+
$this->assertCount(1, $rectorsForPath);
46+
$this->assertInstanceOf(SkippableRector::class, $rectorsForPath[0]);
47+
}
48+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\Application\Source;
6+
7+
use PhpParser\Node;
8+
use Rector\Contract\Rector\RectorInterface;
9+
use Rector\RuleDoc\RuleDefinition;
10+
11+
final class SkippableRector implements RectorInterface
12+
{
13+
public function getRuleDefinition(): RuleDefinition
14+
{
15+
return new RuleDefinition('Fixture rule used to assert registry path skipping', []);
16+
}
17+
18+
public function getNodeTypes(): array
19+
{
20+
return [];
21+
}
22+
23+
public function refactor(Node $node)
24+
{
25+
return null;
26+
}
27+
}

0 commit comments

Comments
 (0)