diff --git a/packages/CodingStyle/src/Application/NameImportingCommander.php b/packages/CodingStyle/src/Application/NameImportingCommander.php index e9d49f5d7b2d..aa8f029a2cce 100644 --- a/packages/CodingStyle/src/Application/NameImportingCommander.php +++ b/packages/CodingStyle/src/Application/NameImportingCommander.php @@ -58,4 +58,9 @@ public function traverseNodes(array $nodes): array return $nodes; } + + public function getPriority(): int + { + return 600; + } } diff --git a/packages/CodingStyle/src/Application/UseAddingCommander.php b/packages/CodingStyle/src/Application/UseAddingCommander.php index ab8fd5f59128..d98035a4a5b8 100644 --- a/packages/CodingStyle/src/Application/UseAddingCommander.php +++ b/packages/CodingStyle/src/Application/UseAddingCommander.php @@ -240,6 +240,11 @@ public function canImportBeAdded(Node $node, FullyQualifiedObjectType $fullyQual return true; } + public function getPriority(): int + { + return 500; + } + /** * @return FullyQualifiedObjectType[] */ diff --git a/src/Commander/CommanderCollector.php b/src/Commander/CommanderCollector.php new file mode 100644 index 000000000000..472900eb610c --- /dev/null +++ b/src/Commander/CommanderCollector.php @@ -0,0 +1,50 @@ +sortAndSetCommanders($commanders); + } + + /** + * @return CommanderInterface[] + */ + public function provide(): array + { + return $this->commanders; + } + + /** + * @param CommanderInterface[] $commanders + */ + private function sortAndSetCommanders(array $commanders): void + { + $commandersByPriority = []; + + foreach ($commanders as $commander) { + if (isset($commandersByPriority[$commander->getPriority()])) { + throw new ShouldNotHappenException(); + } + + $commandersByPriority[$commander->getPriority()] = $commander; + } + + krsort($commandersByPriority); + + $this->commanders = $commandersByPriority; + } +} diff --git a/src/Contract/PhpParser/Node/CommanderInterface.php b/src/Contract/PhpParser/Node/CommanderInterface.php index b7e973deee20..f2524e648df8 100644 --- a/src/Contract/PhpParser/Node/CommanderInterface.php +++ b/src/Contract/PhpParser/Node/CommanderInterface.php @@ -6,6 +6,11 @@ interface CommanderInterface { + /** + * Higher values are executed first + */ + public function getPriority(): int; + public function isActive(): bool; /** diff --git a/src/PhpParser/Node/Commander/NodeAddingCommander.php b/src/PhpParser/Node/Commander/NodeAddingCommander.php index 5ff03df6f183..4bf7a1e13b61 100644 --- a/src/PhpParser/Node/Commander/NodeAddingCommander.php +++ b/src/PhpParser/Node/Commander/NodeAddingCommander.php @@ -82,6 +82,11 @@ public function isActive(): bool return count($this->nodesToAdd) > 0 || count($this->nodesToAddBefore) > 0; } + public function getPriority(): int + { + return 1000; + } + private function resolveNearestExpressionPosition(Node $node): string { if ($node instanceof Expression) { diff --git a/src/PhpParser/Node/Commander/NodeRemovingCommander.php b/src/PhpParser/Node/Commander/NodeRemovingCommander.php index 6ae2864237ae..c7e80175aec4 100644 --- a/src/PhpParser/Node/Commander/NodeRemovingCommander.php +++ b/src/PhpParser/Node/Commander/NodeRemovingCommander.php @@ -81,6 +81,11 @@ public function getNodesToRemove(): array return $this->nodesToRemove; } + public function getPriority(): int + { + return 800; + } + private function ensureIsNotPartOfChainMethodCall(Node $node): void { if (! $node instanceof MethodCall) { diff --git a/src/PhpParser/Node/Commander/PropertyAddingCommander.php b/src/PhpParser/Node/Commander/PropertyAddingCommander.php index 76f5d60a96f9..00f04c2165ce 100644 --- a/src/PhpParser/Node/Commander/PropertyAddingCommander.php +++ b/src/PhpParser/Node/Commander/PropertyAddingCommander.php @@ -56,6 +56,11 @@ public function isActive(): bool return count($this->propertiesByClass) > 0; } + public function getPriority(): int + { + return 900; + } + private function createNodeVisitor(): NodeVisitor { return new class($this->classManipulator, $this->propertiesByClass) extends NodeVisitorAbstract { diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index a4ec811210ac..ded1be40e283 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -9,6 +9,7 @@ use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Expression; use PhpParser\NodeVisitorAbstract; +use Rector\Commander\CommanderCollector; use Rector\Contract\PhpParser\Node\CommanderInterface; use Rector\Contract\Rector\PhpRectorInterface; use Rector\NodeTypeResolver\Node\AttributeKey; @@ -38,9 +39,9 @@ abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorIn private $phpVersionProvider; /** - * @var CommanderInterface[] + * @var CommanderCollector */ - private $commanders = []; + private $commanderCollector; /** * Run once in the every end of one processed file @@ -51,18 +52,17 @@ protected function tearDown(): void /** * @required - * @param CommanderInterface[] $symfonyStyle */ public function autowireAbstractRectorDependencies( SymfonyStyle $symfonyStyle, PhpVersionProvider $phpVersionProvider, - BuilderFactory $builderFactory - // array $commanders = [] + BuilderFactory $builderFactory, + CommanderCollector $commanderCollector ): void { $this->symfonyStyle = $symfonyStyle; $this->phpVersionProvider = $phpVersionProvider; $this->builderFactory = $builderFactory; - // $this->commanders = $commanders; + $this->commanderCollector = $commanderCollector; } /** @@ -123,32 +123,12 @@ final public function enterNode(Node $node) */ public function afterTraverse(array $nodes): array { -// foreach ($this->commanders as $commander) { -// if (! $commander->isActive()) { -// continue; -// } -// -// $nodes = $commander->traverseNodes($nodes); -// } - if ($this->nodeAddingCommander->isActive()) { - $nodes = $this->nodeAddingCommander->traverseNodes($nodes); - } - - if ($this->propertyAddingCommander->isActive()) { - $nodes = $this->propertyAddingCommander->traverseNodes($nodes); - } - - if ($this->nodeRemovingCommander->isActive()) { - $nodes = $this->nodeRemovingCommander->traverseNodes($nodes); - } - - // this must run before use imports, since it adds them - if ($this->nameImportingCommander->isActive()) { - $nodes = $this->nameImportingCommander->traverseNodes($nodes); - } + foreach ($this->commanderCollector->provide() as $commander) { + if (! $commander->isActive()) { + continue; + } - if ($this->useAddingCommander->isActive()) { - $nodes = $this->useAddingCommander->traverseNodes($nodes); + $nodes = $commander->traverseNodes($nodes); } $this->tearDown();