From 51b33dff527474662373f7ca009ff6a74a91dc47 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 31 Dec 2023 08:32:03 +0100 Subject: [PATCH] New rector (9.1): ClassConstantToClassConstantRector to rename class constants to a new class. --- config/drupal-9/drupal-9.1-deprecations.php | 24 ++++ .../ClassConstantToClassConstantRector.php | 112 ++++++++++++++++++ ...ssConstantToClassConstantConfiguration.php | 49 ++++++++ .../ConstantToClassConstantRectorTest.php | 35 ++++++ .../config/configured_rule.php | 31 +++++ .../fixture/fixture.php.inc | 19 +++ 6 files changed, 270 insertions(+) create mode 100644 src/Rector/Deprecation/ClassConstantToClassConstantRector.php create mode 100644 src/Rector/ValueObject/ClassConstantToClassConstantConfiguration.php create mode 100644 tests/src/Rector/Deprecation/ClassConstantToClassConstantRector/ConstantToClassConstantRectorTest.php create mode 100644 tests/src/Rector/Deprecation/ClassConstantToClassConstantRector/config/configured_rule.php create mode 100644 tests/src/Rector/Deprecation/ClassConstantToClassConstantRector/fixture/fixture.php.inc diff --git a/config/drupal-9/drupal-9.1-deprecations.php b/config/drupal-9/drupal-9.1-deprecations.php index a2f5125c..536fdb49 100644 --- a/config/drupal-9/drupal-9.1-deprecations.php +++ b/config/drupal-9/drupal-9.1-deprecations.php @@ -15,6 +15,8 @@ use DrupalRector\Drupal9\Rector\Deprecation\UiHelperTraitDrupalPostFormRector; use DrupalRector\Drupal9\Rector\Deprecation\UserPasswordRector; use DrupalRector\Drupal9\Rector\ValueObject\AssertLegacyTraitConfiguration; +use DrupalRector\Rector\Deprecation\ClassConstantToClassConstantRector; +use DrupalRector\Rector\ValueObject\ClassConstantToClassConstantConfiguration; use DrupalRector\Services\AddCommentService; use Rector\Config\RectorConfig; use Rector\PHPUnit\Set\PHPUnitSetList; @@ -107,4 +109,26 @@ 'toNumber' ), ]); + + // Change record: https://www.drupal.org/node/3151009 (only constants are supported) + $rectorConfig->ruleWithConfiguration(ClassConstantToClassConstantRector::class, [ + new ClassConstantToClassConstantConfiguration( + 'Symfony\Cmf\Component\Routing\RouteObjectInterface', + 'ROUTE_NAME', + 'Drupal\Core\Routing\RouteObjectInterface', + 'ROUTE_NAME', + ), + new ClassConstantToClassConstantConfiguration( + 'Symfony\Cmf\Component\Routing\RouteObjectInterface', + 'ROUTE_OBJECT', + 'Drupal\Core\Routing\RouteObjectInterface', + 'ROUTE_OBJECT', + ), + new ClassConstantToClassConstantConfiguration( + 'Symfony\Cmf\Component\Routing\RouteObjectInterface', + 'CONTROLLER_NAME', + 'Drupal\Core\Routing\RouteObjectInterface', + 'CONTROLLER_NAME', + ), + ]); }; diff --git a/src/Rector/Deprecation/ClassConstantToClassConstantRector.php b/src/Rector/Deprecation/ClassConstantToClassConstantRector.php new file mode 100644 index 00000000..75d407d0 --- /dev/null +++ b/src/Rector/Deprecation/ClassConstantToClassConstantRector.php @@ -0,0 +1,112 @@ +constantToClassRenames = $configuration; + } + + /** + * {@inheritdoc} + */ + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition('Fixes deprecated class contant use, used in Drupal 9.1 deprecations', [ + new ConfiguredCodeSample( + <<<'CODE_BEFORE' +$value = Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_NAME; +$value2 = Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT; +$value3 = Symfony\Cmf\Component\Routing\RouteObjectInterface::CONTROLLER_NAME; +CODE_BEFORE + , + <<<'CODE_AFTER' +$value = \Drupal\Core\Routing\RouteObjectInterface::ROUTE_NAME; +$value2 = \Drupal\Core\Routing\RouteObjectInterface::ROUTE_OBJECT; +$value3 = \Drupal\Core\Routing\RouteObjectInterface::CONTROLLER_NAME; +CODE_AFTER + , + [ + new ClassConstantToClassConstantConfiguration( + 'Symfony\Cmf\Component\Routing\RouteObjectInterface', + 'ROUTE_NAME', + 'Drupal\Core\Routing\RouteObjectInterface', + 'ROUTE_NAME', + ), + new ClassConstantToClassConstantConfiguration( + 'Symfony\Cmf\Component\Routing\RouteObjectInterface', + 'ROUTE_OBJECT', + 'Drupal\Core\Routing\RouteObjectInterface', + 'ROUTE_OBJECT', + ), + new ClassConstantToClassConstantConfiguration( + 'Symfony\Cmf\Component\Routing\RouteObjectInterface', + 'CONTROLLER_NAME', + 'Drupal\Core\Routing\RouteObjectInterface', + 'CONTROLLER_NAME', + ), + ] + ), + ]); + } + + /** + * {@inheritdoc} + */ + public function getNodeTypes(): array + { + return [ + Node\Expr\ClassConstFetch::class, + ]; + } + + /** + * {@inheritdoc} + */ + public function refactor(Node $node): ?Node + { + assert($node instanceof Node\Expr\ClassConstFetch); + + foreach ($this->constantToClassRenames as $constantToClassRename) { + if ($this->getName($node->name) === $constantToClassRename->getDeprecated() && $this->getName($node->class) === $constantToClassRename->getDeprecatedClass()) { + // We add a fully qualified class name and the parameters in `rector.php` adds the use statement. + $fully_qualified_class = new Node\Name\FullyQualified($constantToClassRename->getClass()); + + $name = new Node\Identifier($constantToClassRename->getConstant()); + + return new Node\Expr\ClassConstFetch($fully_qualified_class, $name); + } + } + + return null; + } +} diff --git a/src/Rector/ValueObject/ClassConstantToClassConstantConfiguration.php b/src/Rector/ValueObject/ClassConstantToClassConstantConfiguration.php new file mode 100644 index 00000000..9665738d --- /dev/null +++ b/src/Rector/ValueObject/ClassConstantToClassConstantConfiguration.php @@ -0,0 +1,49 @@ +deprecatedClass = $deprecatedClass; + $this->deprecated = $deprecated; + $this->class = $class; + $this->constant = $constant; + + RectorAssert::className($deprecatedClass); + RectorAssert::className($class); + RectorAssert::constantName($deprecated); + RectorAssert::constantName($constant); + } + + public function getDeprecated(): string + { + return $this->deprecated; + } + + public function getClass(): string + { + return $this->class; + } + + public function getConstant(): string + { + return $this->constant; + } + + public function getDeprecatedClass(): string + { + return $this->deprecatedClass; + } +} diff --git a/tests/src/Rector/Deprecation/ClassConstantToClassConstantRector/ConstantToClassConstantRectorTest.php b/tests/src/Rector/Deprecation/ClassConstantToClassConstantRector/ConstantToClassConstantRectorTest.php new file mode 100644 index 00000000..2c7181c7 --- /dev/null +++ b/tests/src/Rector/Deprecation/ClassConstantToClassConstantRector/ConstantToClassConstantRectorTest.php @@ -0,0 +1,35 @@ +doTestFile($filePath); + } + + /** + * @return Iterator<> + */ + public static function provideData(): \Iterator + { + return self::yieldFilesFromDirectory(__DIR__.'/fixture'); + } + + public function provideConfigFilePath(): string + { + // must be implemented + return __DIR__.'/config/configured_rule.php'; + } +} diff --git a/tests/src/Rector/Deprecation/ClassConstantToClassConstantRector/config/configured_rule.php b/tests/src/Rector/Deprecation/ClassConstantToClassConstantRector/config/configured_rule.php new file mode 100644 index 00000000..4d1352cb --- /dev/null +++ b/tests/src/Rector/Deprecation/ClassConstantToClassConstantRector/config/configured_rule.php @@ -0,0 +1,31 @@ + +----- +