diff --git a/packages/DeprecationExtractor/src/Console/Command/ExtractDeprecationsCommand.php b/packages/DeprecationExtractor/src/Console/Command/ExtractDeprecationsCommand.php index c39b9882ed3..63409d03786 100644 --- a/packages/DeprecationExtractor/src/Console/Command/ExtractDeprecationsCommand.php +++ b/packages/DeprecationExtractor/src/Console/Command/ExtractDeprecationsCommand.php @@ -81,16 +81,7 @@ final class ExtractDeprecationsCommand extends Command count($this->deprecationCollector->getDeprecations()) )); - /** @var RectorGuess[] $guessedRectors */ - $guessedRectors = []; - $deprecations = $this->deprecationCollector->getDeprecations(); - - foreach ($deprecations as $deprecation) { - $guessedRectors[] = $this->rectorGuesser->guessFromMessageAndNode( - $deprecation['message'], - $deprecation['node'] - ); - } + $guessedRectors = $this->rectorGuesser->guessForDeprecations($this->deprecationCollector->getDeprecations()); foreach ($guessedRectors as $guessedRector) { if ($this->shouldSkipGuessedRector($guessedRector)) { @@ -122,7 +113,7 @@ final class ExtractDeprecationsCommand extends Command return true; } - $typesToHide = [RectorGuess::YAML_CONFIGURATION, RectorGuess::SERVICE]; + $typesToHide = [RectorGuess::TYPE_YAML_CONFIGURATION, RectorGuess::TYPE_SERVICE]; if (in_array($guessedRector->getGuessedRectorClass(), $typesToHide, true)) { return true; } diff --git a/packages/DeprecationExtractor/src/Deprecation/Deprecation.php b/packages/DeprecationExtractor/src/Deprecation/Deprecation.php new file mode 100644 index 00000000000..d09fbe91be6 --- /dev/null +++ b/packages/DeprecationExtractor/src/Deprecation/Deprecation.php @@ -0,0 +1,39 @@ +message = $message; + $this->node = $node; + } + + public static function createFromMessageAndNode(string $message, Node $node): self + { + return new self($message, $node); + } + + public function getMessage(): string + { + return $this->message; + } + + public function getNode(): Node + { + return $this->node; + } +} diff --git a/packages/DeprecationExtractor/src/Deprecation/DeprecationCollector.php b/packages/DeprecationExtractor/src/Deprecation/DeprecationCollector.php index b150a709d7d..c1764ad4b1b 100644 --- a/packages/DeprecationExtractor/src/Deprecation/DeprecationCollector.php +++ b/packages/DeprecationExtractor/src/Deprecation/DeprecationCollector.php @@ -11,20 +11,17 @@ use PhpParser\Node; final class DeprecationCollector { /** - * @var string[]|Node[] + * @var Deprecation[] */ private $deprecations = []; public function addDeprecation(string $message, Node $node): void { - $this->deprecations[] = [ - 'message' => $message, - 'node' => $node, - ]; + $this->deprecations[] = Deprecation::createFromMessageAndNode($message, $node); } /** - * @return mixed[] + * @return Deprecation[] */ public function getDeprecations(): array { diff --git a/packages/DeprecationExtractor/src/Rector/RectorGuesser.php b/packages/DeprecationExtractor/src/Rector/RectorGuesser.php index bba009401e1..cf2e0d614df 100644 --- a/packages/DeprecationExtractor/src/Rector/RectorGuesser.php +++ b/packages/DeprecationExtractor/src/Rector/RectorGuesser.php @@ -5,6 +5,7 @@ namespace Rector\DeprecationExtractor\Rector; use Nette\Utils\Strings; use PhpParser\Builder\Class_; use PhpParser\Node; +use Rector\DeprecationExtractor\Deprecation\Deprecation; use Rector\DeprecationExtractor\RectorGuess\RectorGuess; use Rector\DeprecationExtractor\RectorGuess\RectorGuessFactory; use Rector\Exception\NotImplementedException; @@ -54,48 +55,49 @@ final class RectorGuesser 'Relying on its factory\'s return-type to define the class of service', ]; + /** + * @var UnsupportedDeprecationFilter + */ + private $unsupportedDeprecationFilter; + public function __construct( NodeValueResolver $nodeValueResolver, ClassPrepender $classPrepender, - RectorGuessFactory $rectorGuessFactory + RectorGuessFactory $rectorGuessFactory, + UnsupportedDeprecationFilter $unsupportedDeprecationFilter ) { $this->nodeValueResolver = $nodeValueResolver; $this->classPrepender = $classPrepender; $this->rectorGuessFactory = $rectorGuessFactory; + $this->unsupportedDeprecationFilter = $unsupportedDeprecationFilter; } - public function guessFromMessageAndNode(string $message, Node $node): ?RectorGuess + public function guessForDeprecation(Deprecation $deprecation): ?RectorGuess { - // @todo: group to early filter method - foreach ($this->yamlDeprecationMessages as $yamlDeprecationMessage) { - if (Strings::contains($message, $yamlDeprecationMessage)) { - return $this->rectorGuessFactory->createYamlConfiguration($message, $node); - } + if ($this->unsupportedDeprecationFilter->matches($deprecation)) { + return $this->rectorGuessFactory-> } - foreach ($this->serviceDeprecationMessages as $serviceDeprecationMessage) { - if (Strings::contains($message, $serviceDeprecationMessage)) { - return $this->rectorGuessFactory->createService($message, $node); - } + $rectorGuess = $this->processWithEarlyFilter($deprecation); + if ($rectorGuess !== null) { + return $rectorGuess; } - $message = $this->classPrepender->completeClassToLocalMethods( - $message, - (string) $node->getAttribute(Attribute::CLASS_NAME) + $deprecation->getMessage(), + (string) $deprecation->getNode()->getAttribute(Attribute::CLASS_NAME) ); if ($message === '') { throw new NotImplementedException(sprintf( 'Not implemented yet. Go to "%s()" and add check for "%s" node.', __METHOD__, - get_class($node) + get_class($deprecation->getNode()) )); } - if (Strings::contains($message, 'It will be made mandatory in') || Strings::contains($message, 'Not defining it is deprecated since')) { - return $this->rectorGuessFactory->createNewArgument($message, $node); + return $this->rectorGuessFactory->createNewArgument($message, $deprecation->getNode()); } $result = Strings::split($message, '#use |Use#'); @@ -105,69 +107,101 @@ final class RectorGuesser return $this->rectorGuessFactory->createClassReplacer( '...', $message, - $node + $deprecation->getNode() ); } return $this->rectorGuessFactory->createMethodNameReplacerGuess( $message, - $node + $deprecation->getNode() ); } - return $this->rectorGuessFactory->createRemoval($message, $node); + return $this->rectorGuessFactory->createRemoval($message, $deprecation->getNode()); } - public function guess(string $message, Node $node): ?RectorGuess + /** + * @param Deprecation[] $deprecations + * @return RectorGuess[] + */ + public function guessForDeprecations(array $deprecations): array { - // @todo: per node resolver... - if ($node instanceof Class_) { - return $this->rectorGuessFactory->createClassReplacer( - $node->namespacedName->toString(), - $message, - $node - ); + $guessedRectors = []; + + foreach ($deprecations as $deprecation) { + $guessedRectors[] = $this->guessForDeprecation($deprecation); } - if ($node instanceof Node\Stmt\ClassMethod) { - $classWithMethod = $this->classAndMethodMatcher->matchClassWithMethod($message); - $localMethod = $this->classAndMethodMatcher->matchLocalMethod($message); - - $className = $node->getAttribute(Attribute::CLASS_NODE)->namespacedName->toString(); - $methodName = (string) $node->name . '()'; - $fqnMethodName = $className . '::' . $methodName; - - if ($classWithMethod === '' && $localMethod === '') { - return $this->rectorGuessFactory->createRemoval($message, $node); - } - - if ($localMethod) { - return $this->rectorGuessFactory->createRemoval( - $fqnMethodName . ' => ' . $className . '::' . $localMethod . '()' . $message, - $node - ); - } - - $namespacedClassWithMethod = $this->classAndMethodMatcher->matchNamespacedClassWithMethod($message); - - /** @var string[] $useStatements */ - $useStatements = $node->getAttribute(Attribute::USE_STATEMENTS); - $fqnClassWithMethod = $this->completeNamespace($useStatements, $namespacedClassWithMethod); - - return $this->rectorGuessFactory->createRemoval( - $fqnMethodName . '=> ' . $fqnClassWithMethod, - $node - ); - } - - throw new NotImplementedException(sprintf( - '%s() was unable to create a Deprecation based on "%s" string and "%s" Node. Create a new method there.', - __METHOD__, - $message, - get_class($node) - )); + return $guessedRectors; } + private function processWithEarlyFilter(Deprecation $deprecation): ?RectorGuess + { + foreach ($this->yamlDeprecationMessages as $yamlDeprecationMessage) { + if (Strings::contains($deprecation->getMessage(), $yamlDeprecationMessage)) { + return $this->rectorGuessFactory->createYamlConfiguration($deprecation->getMessage(), $deprecation->getNode()); + } + } + + foreach ($this->serviceDeprecationMessages as $serviceDeprecationMessage) { + if (Strings::contains($deprecation->getMessage(), $serviceDeprecationMessage)) { + return $this->rectorGuessFactory->createService($deprecation->getMessage(), $deprecation->getNode()); + } + } + + return null; + } + +// private function guess(string $message, Node $node): ?RectorGuess +// { +// // @todo: per node resolver... +// if ($node instanceof Class_) { +// return $this->rectorGuessFactory->createClassReplacer( +// $node->namespacedName->toString(), +// $message, +// $node +// ); +// } +// +// if ($node instanceof Node\Stmt\ClassMethod) { +// $classWithMethod = $this->classAndMethodMatcher->matchClassWithMethod($message); +// $localMethod = $this->classAndMethodMatcher->matchLocalMethod($message); +// +// $className = $node->getAttribute(Attribute::CLASS_NODE)->namespacedName->toString(); +// $methodName = (string) $node->name . '()'; +// $fqnMethodName = $className . '::' . $methodName; +// +// if ($classWithMethod === '' && $localMethod === '') { +// return $this->rectorGuessFactory->createRemoval($message, $node); +// } +// +// if ($localMethod) { +// return $this->rectorGuessFactory->createRemoval( +// $fqnMethodName . ' => ' . $className . '::' . $localMethod . '()' . $message, +// $node +// ); +// } +// +// $namespacedClassWithMethod = $this->classAndMethodMatcher->matchNamespacedClassWithMethod($message); +// +// /** @var string[] $useStatements */ +// $useStatements = $node->getAttribute(Attribute::USE_STATEMENTS); +// $fqnClassWithMethod = $this->completeNamespace($useStatements, $namespacedClassWithMethod); +// +// return $this->rectorGuessFactory->createRemoval( +// $fqnMethodName . '=> ' . $fqnClassWithMethod, +// $node +// ); +// } +// +// throw new NotImplementedException(sprintf( +// '%s() was unable to create a Deprecation based on "%s" string and "%s" Node. Create a new method there.', +// __METHOD__, +// $message, +// get_class($node) +// )); +// } + /** * @param string[] $useStatements */ diff --git a/packages/DeprecationExtractor/src/Rector/UnsupportedDeprecationFilter.php b/packages/DeprecationExtractor/src/Rector/UnsupportedDeprecationFilter.php new file mode 100644 index 00000000000..aab0ea2dff6 --- /dev/null +++ b/packages/DeprecationExtractor/src/Rector/UnsupportedDeprecationFilter.php @@ -0,0 +1,52 @@ +yamlDeprecationMessages as $yamlDeprecationMessage) { + if (Strings::contains($deprecation->getMessage(), $yamlDeprecationMessage)) { + return true; + } + } + + foreach ($this->serviceDeprecationMessages as $serviceDeprecationMessage) { + if (Strings::contains($deprecation->getMessage(), $serviceDeprecationMessage)) { + return true; + } + } + + return false; + } +} diff --git a/packages/DeprecationExtractor/src/RectorGuess/RectorGuess.php b/packages/DeprecationExtractor/src/RectorGuess/RectorGuess.php index e9dcb8a167e..ec43fbbf80e 100644 --- a/packages/DeprecationExtractor/src/RectorGuess/RectorGuess.php +++ b/packages/DeprecationExtractor/src/RectorGuess/RectorGuess.php @@ -15,12 +15,12 @@ final class RectorGuess /** * @var string */ - public const YAML_CONFIGURATION = 'YAML_CONFIGURATION'; + public const TYPE_YAML_CONFIGURATION = 'YAML_CONFIGURATION'; /** * @var string */ - public const SERVICE = 'SERVICE'; + public const TYPE_SERVICE = 'SERVICE'; /** * @var string diff --git a/packages/DeprecationExtractor/src/RectorGuess/RectorGuessFactory.php b/packages/DeprecationExtractor/src/RectorGuess/RectorGuessFactory.php index 8a72da57d73..959a96f255f 100644 --- a/packages/DeprecationExtractor/src/RectorGuess/RectorGuessFactory.php +++ b/packages/DeprecationExtractor/src/RectorGuess/RectorGuessFactory.php @@ -39,7 +39,7 @@ final class RectorGuessFactory public function createYamlConfiguration(string $message, Node $node): RectorGuess { return new RectorGuess( - RectorGuess::YAML_CONFIGURATION, + RectorGuess::TYPE_YAML_CONFIGURATION, $node, $message ); @@ -48,7 +48,7 @@ final class RectorGuessFactory public function createService(string $message, Node $node): RectorGuess { return new RectorGuess( - RectorGuess::SERVICE, + RectorGuess::TYPE_SERVICE, $node, $message );