From 95c95e697b1e92d9e51d6067bc5c45a203697893 Mon Sep 17 00:00:00 2001 From: Timo Huisman Date: Thu, 25 Jan 2024 09:08:33 +0100 Subject: [PATCH 01/46] refactor: replace deprecated LevelSetLists for PHPUnit, Symfony and Twig See https://github.com/rectorphp/rector-src/pull/5477 --- config/drupal-10/drupal-10.0-deprecations.php | 12 ++++++------ config/drupal-10/drupal-10.1-deprecations.php | 4 ++-- config/drupal-9/drupal-9-all-deprecations.php | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config/drupal-10/drupal-10.0-deprecations.php b/config/drupal-10/drupal-10.0-deprecations.php index db48e70e..5d97596c 100644 --- a/config/drupal-10/drupal-10.0-deprecations.php +++ b/config/drupal-10/drupal-10.0-deprecations.php @@ -4,15 +4,15 @@ use DrupalRector\Rector\PHPUnit\ShouldCallParentMethodsRector; use Rector\Config\RectorConfig; -use Rector\PHPUnit\Set\PHPUnitLevelSetList; -use Rector\Symfony\Set\SymfonyLevelSetList; -use Rector\Symfony\Set\TwigLevelSetList; +use Rector\PHPUnit\Set\PHPUnitSetList; +use Rector\Symfony\Set\SymfonySetList; +use Rector\Symfony\Set\TwigSetList; return static function (RectorConfig $rectorConfig): void { $rectorConfig->sets([ - PHPUnitLevelSetList::UP_TO_PHPUNIT_90, - SymfonyLevelSetList::UP_TO_SYMFONY_62, - TwigLevelSetList::UP_TO_TWIG_240, + PHPUnitSetList::PHPUNIT_90, + SymfonySetList::SYMFONY_62, + TwigSetList::TWIG_240, ]); $rectorConfig->rule(ShouldCallParentMethodsRector::class); diff --git a/config/drupal-10/drupal-10.1-deprecations.php b/config/drupal-10/drupal-10.1-deprecations.php index 0cbe4940..54393725 100644 --- a/config/drupal-10/drupal-10.1-deprecations.php +++ b/config/drupal-10/drupal-10.1-deprecations.php @@ -8,11 +8,11 @@ use DrupalRector\Rector\ValueObject\DrupalIntroducedVersionConfiguration; use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration; use Rector\Config\RectorConfig; -use Rector\Symfony\Set\SymfonyLevelSetList; +use Rector\Symfony\Set\SymfonySetList; return static function (RectorConfig $rectorConfig): void { $rectorConfig->sets([ - SymfonyLevelSetList::UP_TO_SYMFONY_63, + SymfonySetList::SYMFONY_63, ]); // https://www.drupal.org/node/3244583 diff --git a/config/drupal-9/drupal-9-all-deprecations.php b/config/drupal-9/drupal-9-all-deprecations.php index d76cc289..8c524574 100644 --- a/config/drupal-9/drupal-9-all-deprecations.php +++ b/config/drupal-9/drupal-9-all-deprecations.php @@ -5,7 +5,7 @@ use DrupalRector\Services\AddCommentService; use DrupalRector\Set\Drupal9SetList; use Rector\Config\RectorConfig; -use Rector\PHPUnit\Set\PHPUnitLevelSetList; +use Rector\PHPUnit\Set\PHPUnitSetList; return static function (RectorConfig $rectorConfig): void { $rectorConfig->singleton(AddCommentService::class, function () { @@ -17,7 +17,7 @@ Drupal9SetList::DRUPAL_92, Drupal9SetList::DRUPAL_93, Drupal9SetList::DRUPAL_94, - PHPUnitLevelSetList::UP_TO_PHPUNIT_90, + PHPUnitSetList::PHPUNIT_90, ]); $rectorConfig->bootstrapFiles([ From a9d8364f8b74b434adbae6ab9671894f91208566 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 25 Feb 2024 09:32:29 +0100 Subject: [PATCH 02/46] feat: upgrade to rector 1.0 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 2bb3d2ea..60e89c5c 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ "ast" ], "require": { - "rector/rector": "~0.19.0", + "rector/rector": "^1.0", "webflo/drupal-finder": "^1.2" }, "license": "MIT", From a9d47b01ddf0d6f5e511a276b40e1e363e68a5e4 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 25 Feb 2024 09:37:36 +0100 Subject: [PATCH 03/46] chore: codestyle fix --- .../Rector/ValueObject/AssertLegacyTraitConfiguration.php | 2 +- src/Rector/PHPUnit/ShouldCallParentMethodsRector.php | 2 +- src/Utility/GetDeclaringSourceTrait.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Drupal9/Rector/ValueObject/AssertLegacyTraitConfiguration.php b/src/Drupal9/Rector/ValueObject/AssertLegacyTraitConfiguration.php index e57041cf..f321fb32 100644 --- a/src/Drupal9/Rector/ValueObject/AssertLegacyTraitConfiguration.php +++ b/src/Drupal9/Rector/ValueObject/AssertLegacyTraitConfiguration.php @@ -22,7 +22,7 @@ class AssertLegacyTraitConfiguration * @param bool $processFirstArgumentOnly toggle to reduce the number of arguments passed to 1 * @param string $declaringSource the class that declares the deprecated method */ - public function __construct(string $deprecatedMethodName, string $methodName, string $comment = '', bool $isAssertSessionMethod = true, bool $processFirstArgumentOnly = false, string $declaringSource = 'Drupal\FunctionalTests\AssertLegacyTrait', string $prependArgument = null) + public function __construct(string $deprecatedMethodName, string $methodName, string $comment = '', bool $isAssertSessionMethod = true, bool $processFirstArgumentOnly = false, string $declaringSource = 'Drupal\FunctionalTests\AssertLegacyTrait', ?string $prependArgument = null) { $this->deprecatedMethodName = $deprecatedMethodName; $this->methodName = $methodName; diff --git a/src/Rector/PHPUnit/ShouldCallParentMethodsRector.php b/src/Rector/PHPUnit/ShouldCallParentMethodsRector.php index 934ef7fa..d142d486 100644 --- a/src/Rector/PHPUnit/ShouldCallParentMethodsRector.php +++ b/src/Rector/PHPUnit/ShouldCallParentMethodsRector.php @@ -25,7 +25,7 @@ public function getNodeTypes(): array * @param Node $node * @param Scope $scope * - * @return \PhpParser\Node|null + * @return Node|null */ public function refactorWithScope(Node $node, Scope $scope) { diff --git a/src/Utility/GetDeclaringSourceTrait.php b/src/Utility/GetDeclaringSourceTrait.php index 24dcd56c..1a4ce402 100644 --- a/src/Utility/GetDeclaringSourceTrait.php +++ b/src/Utility/GetDeclaringSourceTrait.php @@ -14,7 +14,7 @@ trait GetDeclaringSourceTrait /** * Gets a method or property's declaring source (trait or class.). * - * @param node\Expr\MethodCall|Node\Expr\PropertyFetch $expr + * @param Node\Expr\MethodCall|Node\Expr\PropertyFetch $expr * The expression * * @return string|null From 18a3ea50be2fe8b023b45a865f59d0fce30897cf Mon Sep 17 00:00:00 2001 From: Timo Huisman Date: Mon, 4 Mar 2024 08:49:01 +0100 Subject: [PATCH 04/46] feat: Add rector rule for deprecated GDToolkit (#289) * feat: add rector rule for deprecated GDToolkit resource methods and properties in 10.2 * fix: remove renaming ::resource since we see no usage for that and its protected anyways. * fix: style fixes --------- Co-authored-by: bjorn --- config/drupal-10/drupal-10.2-deprecations.php | 8 ++++++++ .../config/configured_rule.php | 2 ++ .../MethodToMethodWithCheckRector/fixture/basic.php.inc | 8 ++++++++ 3 files changed, 18 insertions(+) diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index e7c3122c..9e7d547e 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -3,7 +3,9 @@ declare(strict_types=1); use DrupalRector\Rector\Deprecation\FunctionToStaticRector; +use DrupalRector\Rector\Deprecation\MethodToMethodWithCheckRector; use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration; +use DrupalRector\Rector\ValueObject\MethodToMethodWithCheckConfiguration; use Rector\Config\RectorConfig; return static function (RectorConfig $rectorConfig): void { @@ -11,4 +13,10 @@ $rectorConfig->ruleWithConfiguration(FunctionToStaticRector::class, [ new FunctionToStaticConfiguration('10.2.0', 'format_size', '\Drupal\Core\StringTranslation\ByteSizeMarkup', 'create'), ]); + + // https://www.drupal.org/node/3265963 + $rectorConfig->ruleWithConfiguration(MethodToMethodWithCheckRector::class, [ + new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'getResource', 'getImage'), + new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'setResource', 'setImage'), + ]); }; diff --git a/tests/src/Rector/Deprecation/MethodToMethodWithCheckRector/config/configured_rule.php b/tests/src/Rector/Deprecation/MethodToMethodWithCheckRector/config/configured_rule.php index 736c7322..9e886e74 100644 --- a/tests/src/Rector/Deprecation/MethodToMethodWithCheckRector/config/configured_rule.php +++ b/tests/src/Rector/Deprecation/MethodToMethodWithCheckRector/config/configured_rule.php @@ -11,5 +11,7 @@ DeprecationBase::addClass(MethodToMethodWithCheckRector::class, $rectorConfig, true, [ new MethodToMethodWithCheckConfiguration('Drupal\Core\Session\MetadataBag', 'clearCsrfTokenSeed', 'stampNew'), new MethodToMethodWithCheckConfiguration('Drupal\Core\Entity\EntityInterface', 'urlInfo', 'toUrl'), + new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'getResource', 'getImage'), + new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'setResource', 'setImage'), ]); }; diff --git a/tests/src/Rector/Deprecation/MethodToMethodWithCheckRector/fixture/basic.php.inc b/tests/src/Rector/Deprecation/MethodToMethodWithCheckRector/fixture/basic.php.inc index 75b9b885..c4d2afdd 100644 --- a/tests/src/Rector/Deprecation/MethodToMethodWithCheckRector/fixture/basic.php.inc +++ b/tests/src/Rector/Deprecation/MethodToMethodWithCheckRector/fixture/basic.php.inc @@ -7,6 +7,10 @@ function simple_example() { /** @var \Drupal\Core\Entity\EntityInterface $untranslated_entity */ $untranslated_entity = \Drupal::entityTypeManager()->getStorage('node')->load(123); $form_state->setRedirectUrl($untranslated_entity->urlInfo('canonical')); + + $toolkit = new \Drupal\system\Plugin\ImageToolkit\GDToolkit; + $toolkit->getResource(); + $toolkit->setResource(); } ?> ----- @@ -19,5 +23,9 @@ function simple_example() { /** @var \Drupal\Core\Entity\EntityInterface $untranslated_entity */ $untranslated_entity = \Drupal::entityTypeManager()->getStorage('node')->load(123); $form_state->setRedirectUrl($untranslated_entity->toUrl('canonical')); + + $toolkit = new \Drupal\system\Plugin\ImageToolkit\GDToolkit; + $toolkit->getImage(); + $toolkit->setImage(); } ?> From 27e1ef5419e72f007c92d2288f91cd28e99d1628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Brala?= Date: Tue, 5 Mar 2024 20:37:18 +0100 Subject: [PATCH 05/46] fix: Add proper levels for all symfony versions deprecated in the different versions of Drupal (#293) --- config/drupal-10/drupal-10.0-deprecations.php | 7 +++++++ config/drupal-10/drupal-10.2-deprecations.php | 5 +++++ 2 files changed, 12 insertions(+) diff --git a/config/drupal-10/drupal-10.0-deprecations.php b/config/drupal-10/drupal-10.0-deprecations.php index 5d97596c..1c9e42f8 100644 --- a/config/drupal-10/drupal-10.0-deprecations.php +++ b/config/drupal-10/drupal-10.0-deprecations.php @@ -11,6 +11,13 @@ return static function (RectorConfig $rectorConfig): void { $rectorConfig->sets([ PHPUnitSetList::PHPUNIT_90, + SymfonySetList::SYMFONY_50, + SymfonySetList::SYMFONY_51, + SymfonySetList::SYMFONY_52, + SymfonySetList::SYMFONY_53, + SymfonySetList::SYMFONY_54, + SymfonySetList::SYMFONY_60, + SymfonySetList::SYMFONY_61, SymfonySetList::SYMFONY_62, TwigSetList::TWIG_240, ]); diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index 9e7d547e..869a4838 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -7,8 +7,13 @@ use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration; use DrupalRector\Rector\ValueObject\MethodToMethodWithCheckConfiguration; use Rector\Config\RectorConfig; +use Rector\Symfony\Set\SymfonySetList; return static function (RectorConfig $rectorConfig): void { + $rectorConfig->sets([ + SymfonySetList::SYMFONY_64, + ]); + // https://www.drupal.org/node/2999981 $rectorConfig->ruleWithConfiguration(FunctionToStaticRector::class, [ new FunctionToStaticConfiguration('10.2.0', 'format_size', '\Drupal\Core\StringTranslation\ByteSizeMarkup', 'create'), From 6a753649e923ba3e655d2e1364dbc696bdc97073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Brala?= Date: Tue, 5 Mar 2024 20:41:06 +0100 Subject: [PATCH 06/46] Add bbrala to authors Think by now I should be in the authors of this repo hehe --- composer.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/composer.json b/composer.json index 60e89c5c..62b6748d 100644 --- a/composer.json +++ b/composer.json @@ -30,6 +30,10 @@ { "name": "Matt Glaman", "email": "nmd.matt@gmail.com" + }, + { + "name": "Björn Brala", + "email": "drupal@bjorn.dev" } ], "autoload": { From 1b8c349044e503501c74e5dd58107669f3ae8765 Mon Sep 17 00:00:00 2001 From: Andy Postnikov Date: Sun, 29 Oct 2023 03:09:58 +0100 Subject: [PATCH 07/46] WIP: Rule to convert action to attributes --- config/drupal-10/drupal-10.2-deprecations.php | 4 + .../ActionAnnotationToAttributeRector.php | 171 ++++++++++++++++++ src/Set/Drupal10SetList.php | 2 +- 3 files changed, 176 insertions(+), 1 deletion(-) create mode 100644 src/Rector/Deprecation/ActionAnnotationToAttributeRector.php diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index 869a4838..4fb03f20 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -2,6 +2,7 @@ declare(strict_types=1); +use DrupalRector\Rector\Deprecation\ActionAnnotationToAttributeRector; use DrupalRector\Rector\Deprecation\FunctionToStaticRector; use DrupalRector\Rector\Deprecation\MethodToMethodWithCheckRector; use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration; @@ -24,4 +25,7 @@ new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'getResource', 'getImage'), new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'setResource', 'setImage'), ]); + + // @see https://www.drupal.org/node/3395575 + $rectorConfig->rule(\DrupalRector\Rector\Deprecation\ActionAnnotationToAttributeRector::class); }; diff --git a/src/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Rector/Deprecation/ActionAnnotationToAttributeRector.php new file mode 100644 index 00000000..d4f975c6 --- /dev/null +++ b/src/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -0,0 +1,171 @@ +phpDocTagRemover = $phpDocTagRemover; + $this->docBlockUpdater = $docBlockUpdater; + $this->phpDocInfoFactory = $phpDocInfoFactory; + $this->arrayParser = $arrayParser; + $this->tokenIteratorFactory = $tokenIteratorFactory; + } + public function getRuleDefinition() : RuleDefinition + { + return new RuleDefinition('Change annotations with value to attribute', [new CodeSample(<<<'CODE_SAMPLE' + +namespace Drupal\Core\Action\Plugin\Action; + +use Drupal\Core\Session\AccountInterface; + +/** + * Publishes an entity. + * + * @Action( + * id = "entity:publish_action", + * action_label = @Translation("Publish"), + * deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver", + * ) + */ +class PublishAction extends EntityActionBase { +CODE_SAMPLE +, <<<'CODE_SAMPLE' + +namespace Drupal\Core\Action\Plugin\Action; + +use Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver; +use Drupal\Core\Action\Attribute\Action; +use Drupal\Core\Session\AccountInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; + +/** + * Publishes an entity. + */ +#[Action( + id: 'entity:publish_action', + action_label: new TranslatableMarkup('Publish'), + deriver: EntityPublishedActionDeriver::class +)] +class PublishAction extends EntityActionBase { +CODE_SAMPLE +)]); + } + /** + * @return array> + */ + public function getNodeTypes() : array + { + return [Class_::class]; + } + public function provideMinPhpVersion() : int + { + return PhpVersion::PHP_81; + } + /** + * @param Class_|ClassMethod $node + */ + public function refactor(Node $node) : ?Node + { + $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); + if (!$phpDocInfo instanceof PhpDocInfo) { + return null; + } + /** @var PhpDocTagNode[] $tagsByName */ + $tagsByName = $phpDocInfo->getTagsByName('Action'); + if ($tagsByName === []) { + return null; + } + $hasChanged = \false; + foreach ($tagsByName as $valueNode) { + if (!$valueNode->value instanceof GenericTagValueNode) { + continue; + } + $stringValue = $valueNode->value->value; + $stringValue = '{' . trim($stringValue, '()') . '}'; + $tokenIterator = $this->tokenIteratorFactory->create($stringValue); + $data = $this->arrayParser->parseCurlyArray($tokenIterator, $node); + $attribute = $this->createAttribute($data); + $node->attrGroups[] = new AttributeGroup([$attribute]); + // cleanup + $this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $valueNode); + $hasChanged = \true; + } + if ($hasChanged) { + $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + return $node; + } + return null; + } + private function createAttribute(array $parsedArgs) : Attribute + { + $fullyQualified = new FullyQualified(Action::class); + $args = []; + foreach ($parsedArgs as $value) { + if ($value->key === 'label') { + $arg = new Node\Expr\New_(new Node\Name(TranslatableMarkup::class), [new Arg(new String_($value->value->values[0]->value->value))]); + } + else { + $arg = new String_($value->value->value); + } + $args[] = new Arg($arg, \false, \false, [], new Node\Identifier($value->key)); + } + return new Attribute($fullyQualified, $args); + } +} diff --git a/src/Set/Drupal10SetList.php b/src/Set/Drupal10SetList.php index 768e2eba..9c9b1856 100644 --- a/src/Set/Drupal10SetList.php +++ b/src/Set/Drupal10SetList.php @@ -11,5 +11,5 @@ final class Drupal10SetList implements SetListInterface public const DRUPAL_10 = __DIR__.'/../../config/drupal-10/drupal-10-all-deprecations.php'; public const DRUPAL_100 = __DIR__.'/../../config/drupal-10/drupal-10.0-deprecations.php'; public const DRUPAL_101 = __DIR__.'/../../config/drupal-10/drupal-10.1-deprecations.php'; - public const DRUPAL_102 = __DIR__.'/../../config/drupal-10/drupal-10.2-deprecations.php'; + public const DRUPAL_102 = __DIR__ . '/../../config/drupal-10/drupal-10.2-deprecations.php'; } From 4ec11777430237504a4f54e414bc9569dcf5aac5 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 09:36:45 +0100 Subject: [PATCH 08/46] Rebase on main and move rector to Drupal10 namespace --- .../Rector/Deprecation/ActionAnnotationToAttributeRector.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename src/{ => Drupal10}/Rector/Deprecation/ActionAnnotationToAttributeRector.php (99%) diff --git a/src/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php similarity index 99% rename from src/Rector/Deprecation/ActionAnnotationToAttributeRector.php rename to src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index d4f975c6..42342fc5 100644 --- a/src/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -1,6 +1,6 @@ Date: Sun, 10 Dec 2023 09:37:14 +0100 Subject: [PATCH 09/46] Add basic unit test for ActionAnnotationToAttributeRector. --- .../ActionAnnotationToAttributeRectorTest.php | 35 +++++++++++++++++++ .../config/configured_rule.php | 12 +++++++ .../fixture/basic_fixture.php.inc | 27 ++++++++++++++ 3 files changed, 74 insertions(+) create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/ActionAnnotationToAttributeRectorTest.php create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/ActionAnnotationToAttributeRectorTest.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/ActionAnnotationToAttributeRectorTest.php new file mode 100644 index 00000000..f29f94cf --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/ActionAnnotationToAttributeRectorTest.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/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php new file mode 100644 index 00000000..f053fd2f --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php @@ -0,0 +1,12 @@ + + +----- + From 407fb522d93a524c1a62114f4d8f32fcf06668a5 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 09:42:37 +0100 Subject: [PATCH 10/46] Fix codestyle --- config/drupal-10/drupal-10.2-deprecations.php | 2 +- .../ActionAnnotationToAttributeRector.php | 45 ++++++++++++------- src/Set/Drupal10SetList.php | 2 +- .../config/configured_rule.php | 1 - 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index 4fb03f20..c27e3f6c 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -27,5 +27,5 @@ ]); // @see https://www.drupal.org/node/3395575 - $rectorConfig->rule(\DrupalRector\Rector\Deprecation\ActionAnnotationToAttributeRector::class); + $rectorConfig->rule(ActionAnnotationToAttributeRector::class); }; diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index 42342fc5..2ba83478 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -1,4 +1,6 @@ -phpDocTagRemover = $phpDocTagRemover; @@ -67,7 +75,8 @@ public function __construct(PhpDocTagRemover $phpDocTagRemover, DocBlockUpdater $this->arrayParser = $arrayParser; $this->tokenIteratorFactory = $tokenIteratorFactory; } - public function getRuleDefinition() : RuleDefinition + + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Change annotations with value to attribute', [new CodeSample(<<<'CODE_SAMPLE' @@ -86,7 +95,7 @@ public function getRuleDefinition() : RuleDefinition */ class PublishAction extends EntityActionBase { CODE_SAMPLE -, <<<'CODE_SAMPLE' + , <<<'CODE_SAMPLE' namespace Drupal\Core\Action\Plugin\Action; @@ -105,23 +114,26 @@ class PublishAction extends EntityActionBase { )] class PublishAction extends EntityActionBase { CODE_SAMPLE -)]); + )]); } + /** * @return array> */ - public function getNodeTypes() : array + public function getNodeTypes(): array { return [Class_::class]; } - public function provideMinPhpVersion() : int + + public function provideMinPhpVersion(): int { return PhpVersion::PHP_81; } + /** * @param Class_|ClassMethod $node */ - public function refactor(Node $node) : ?Node + public function refactor(Node $node): ?Node { $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); if (!$phpDocInfo instanceof PhpDocInfo) { @@ -138,7 +150,7 @@ public function refactor(Node $node) : ?Node continue; } $stringValue = $valueNode->value->value; - $stringValue = '{' . trim($stringValue, '()') . '}'; + $stringValue = '{'.trim($stringValue, '()').'}'; $tokenIterator = $this->tokenIteratorFactory->create($stringValue); $data = $this->arrayParser->parseCurlyArray($tokenIterator, $node); $attribute = $this->createAttribute($data); @@ -149,23 +161,26 @@ public function refactor(Node $node) : ?Node } if ($hasChanged) { $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); + return $node; } + return null; } - private function createAttribute(array $parsedArgs) : Attribute + + private function createAttribute(array $parsedArgs): Attribute { $fullyQualified = new FullyQualified(Action::class); $args = []; foreach ($parsedArgs as $value) { if ($value->key === 'label') { $arg = new Node\Expr\New_(new Node\Name(TranslatableMarkup::class), [new Arg(new String_($value->value->values[0]->value->value))]); - } - else { + } else { $arg = new String_($value->value->value); } $args[] = new Arg($arg, \false, \false, [], new Node\Identifier($value->key)); } + return new Attribute($fullyQualified, $args); } } diff --git a/src/Set/Drupal10SetList.php b/src/Set/Drupal10SetList.php index 9c9b1856..768e2eba 100644 --- a/src/Set/Drupal10SetList.php +++ b/src/Set/Drupal10SetList.php @@ -11,5 +11,5 @@ final class Drupal10SetList implements SetListInterface public const DRUPAL_10 = __DIR__.'/../../config/drupal-10/drupal-10-all-deprecations.php'; public const DRUPAL_100 = __DIR__.'/../../config/drupal-10/drupal-10.0-deprecations.php'; public const DRUPAL_101 = __DIR__.'/../../config/drupal-10/drupal-10.1-deprecations.php'; - public const DRUPAL_102 = __DIR__ . '/../../config/drupal-10/drupal-10.2-deprecations.php'; + public const DRUPAL_102 = __DIR__.'/../../config/drupal-10/drupal-10.2-deprecations.php'; } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php index f053fd2f..f2d6a510 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php @@ -3,7 +3,6 @@ declare(strict_types=1); use DrupalRector\Drupal10\Rector\Deprecation\ActionAnnotationToAttributeRector; -use DrupalRector\Rector\ValueObject\DrupalIntroducedVersionConfiguration; use DrupalRector\Tests\Rector\Deprecation\DeprecationBase; use Rector\Config\RectorConfig; From d936f393825287e841b48a5939d648785d3441db Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 09:47:16 +0100 Subject: [PATCH 11/46] Fix namespace in config for ActionAnnotationToAttributeRector --- config/drupal-10/drupal-10.2-deprecations.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index c27e3f6c..7dd9ae8f 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -2,7 +2,7 @@ declare(strict_types=1); -use DrupalRector\Rector\Deprecation\ActionAnnotationToAttributeRector; +use DrupalRector\Drupal10\Rector\Deprecation\ActionAnnotationToAttributeRector; use DrupalRector\Rector\Deprecation\FunctionToStaticRector; use DrupalRector\Rector\Deprecation\MethodToMethodWithCheckRector; use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration; From bbe8c0397853b725d10bb3d6bce49caacdf3aced Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 09:57:47 +0100 Subject: [PATCH 12/46] The label should be "action_label", --- .../Deprecation/ActionAnnotationToAttributeRector.php | 9 ++++----- .../fixture/basic_fixture.php.inc | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index 2ba83478..59318144 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -4,8 +4,6 @@ namespace DrupalRector\Drupal10\Rector\Deprecation; -use Drupal\Core\Action\Attribute\Action; -use Drupal\Core\StringTranslation\TranslatableMarkup; use PhpParser\Node; use PhpParser\Node\Arg; use PhpParser\Node\Attribute; @@ -16,6 +14,7 @@ use PhpParser\Node\Stmt\ClassMethod; use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; +use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use Rector\BetterPhpDocParser\PhpDocInfo\TokenIteratorFactory; @@ -170,11 +169,11 @@ public function refactor(Node $node): ?Node private function createAttribute(array $parsedArgs): Attribute { - $fullyQualified = new FullyQualified(Action::class); + $fullyQualified = new FullyQualified('Drupal\Core\Action\Attribute\Action'); $args = []; foreach ($parsedArgs as $value) { - if ($value->key === 'label') { - $arg = new Node\Expr\New_(new Node\Name(TranslatableMarkup::class), [new Arg(new String_($value->value->values[0]->value->value))]); + if ($value->key === 'action_label') { + $arg = new Node\Expr\New_(new Node\Name('Drupal\Core\StringTranslation\TranslatableMarkup'), [new Arg(new String_($value->value->values[0]->value->value))]); } else { $arg = new String_($value->value->value); } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc index 659e5203..4b4d78d9 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc @@ -5,7 +5,7 @@ * * @Action( * id = "action_example_basic_action", - * label = @Translation("Action Example: A basic example action that does nothing"), + * action_label = @Translation("Action Example: A basic example action that does nothing"), * type = "system" * ) */ @@ -20,7 +20,7 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface /** * A basic example action that does nothing. */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } From b383c0497577c45222edd7af793ed667ca61b698 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 09:57:54 +0100 Subject: [PATCH 13/46] Fix phpstan --- .../Rector/Deprecation/ActionAnnotationToAttributeRector.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index 59318144..bd769964 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -167,6 +167,11 @@ public function refactor(Node $node): ?Node return null; } + /** + * @param array|ArrayItemNode[] $parsedArgs + * + * @return \PhpParser\Node\Attribute + */ private function createAttribute(array $parsedArgs): Attribute { $fullyQualified = new FullyQualified('Drupal\Core\Action\Attribute\Action'); From c0fbf2e7c81de5c304c0c1ea8c5febe1a6549d1e Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 10:39:40 +0100 Subject: [PATCH 14/46] Add test for other possible translation attribute arguments --- .../multiple_translation_arguments.php.inc | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc new file mode 100644 index 00000000..bcc8d7ba --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc @@ -0,0 +1,27 @@ + + +----- + 'Argument'], ['context' => 'Validation']), type: 'system')] +class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { + +} +?> From 47c1bccfd3b649ff1adbbcbd5833f0579704a78c Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 10:39:58 +0100 Subject: [PATCH 15/46] Add test for situation where the attribute already exists --- .../existing_attribute_fixture.php.inc | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc new file mode 100644 index 00000000..8b197dfe --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc @@ -0,0 +1,28 @@ + + +----- + From 0947c657f6a7c067c3c5826f85c0a574046693d5 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 21:10:57 +0100 Subject: [PATCH 16/46] If action attribute is already present, do not add it again. --- .../ActionAnnotationToAttributeRector.php | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index bd769964..ac86333b 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -143,17 +143,32 @@ public function refactor(Node $node): ?Node if ($tagsByName === []) { return null; } + + $hasAttribute = false; + foreach ($node->attrGroups as $attrGroup) { + foreach ($attrGroup->attrs as $attr) { + if ($attr->name->toString() === 'Drupal\Core\Action\Attribute\Action') { + $hasAttribute = true; + break 2; + } + } + } + $hasChanged = \false; foreach ($tagsByName as $valueNode) { if (!$valueNode->value instanceof GenericTagValueNode) { continue; } - $stringValue = $valueNode->value->value; - $stringValue = '{'.trim($stringValue, '()').'}'; - $tokenIterator = $this->tokenIteratorFactory->create($stringValue); - $data = $this->arrayParser->parseCurlyArray($tokenIterator, $node); - $attribute = $this->createAttribute($data); - $node->attrGroups[] = new AttributeGroup([$attribute]); + + if ($hasAttribute === false) { + $stringValue = $valueNode->value->value; + $stringValue = '{'.trim($stringValue, '()').'}'; + $tokenIterator = $this->tokenIteratorFactory->create($stringValue); + $data = $this->arrayParser->parseCurlyArray($tokenIterator, $node); + $attribute = $this->createAttribute($data); + $node->attrGroups[] = new AttributeGroup([$attribute]); + } + // cleanup $this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $valueNode); $hasChanged = \true; From 75a061e28d49f4050fb0e553c9e0557f2e0345d7 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 22:00:48 +0100 Subject: [PATCH 17/46] ActionAnnotationToAttributeRector now also parses extra @Translate arguments. --- .../ActionAnnotationToAttributeRector.php | 46 ++++++++++++++++++- .../multiple_translation_arguments.php.inc | 2 +- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index ac86333b..201fad79 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -15,6 +15,7 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode; +use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use Rector\BetterPhpDocParser\PhpDocInfo\TokenIteratorFactory; @@ -169,7 +170,7 @@ public function refactor(Node $node): ?Node $node->attrGroups[] = new AttributeGroup([$attribute]); } - // cleanup + // @todo This cleanup needs some extra logic for BC $this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $valueNode); $hasChanged = \true; } @@ -193,7 +194,7 @@ private function createAttribute(array $parsedArgs): Attribute $args = []; foreach ($parsedArgs as $value) { if ($value->key === 'action_label') { - $arg = new Node\Expr\New_(new Node\Name('Drupal\Core\StringTranslation\TranslatableMarkup'), [new Arg(new String_($value->value->values[0]->value->value))]); + $arg = $this->convertTranslateAnnotation($value); } else { $arg = new String_($value->value->value); } @@ -202,4 +203,45 @@ private function createAttribute(array $parsedArgs): Attribute return new Attribute($fullyQualified, $args); } + + public function convertTranslateAnnotation(ArrayItemNode $value): ?Node\Expr\New_ { + // Check the annotation type, this will be helpful later. + if (!$value->value instanceof DoctrineAnnotationTagValueNode || $value->value->identifierTypeNode->name === 'Translation') { + return null; + } + + $valueArg = null; + $argumentArg = null; + $contextArg = null; + + // Loop through the values of the annotation, just to make 100% sure we have the correct argument order + foreach ($value->value->values as $translateValue) { + if ($translateValue->key === null) { + $valueArg = $this->nodeFactory->createArg($translateValue->value->value); + } + if ($translateValue->key === 'context') { + $contextArg = $this->nodeFactory->createArg(['context' => $translateValue->value->value]); + } + if ($translateValue->key === 'arguments') { + $argumentArg = []; + foreach ($translateValue->value->values as $argumentValue) { + $argumentArg[$argumentValue->key->value] = $argumentValue->value->value; + } + $argumentArg = $this->nodeFactory->createArg($argumentArg); + } + } + + $argArray = []; + if ($valueArg !== null) { + $argArray[] = $valueArg; + } + if ($argumentArg !== null) { + $argArray[] = $argumentArg; + } + if ($contextArg !== null) { + $argArray[] = $contextArg; + } + + return new Node\Expr\New_(new Node\Name('Drupal\Core\StringTranslation\TranslatableMarkup'), $argArray); + } } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc index bcc8d7ba..8b1ef848 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc @@ -20,7 +20,7 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface /** * A basic example action that does nothing. */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing', ['@argument' => 'Argument'], ['context' => 'Validation']), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing and has an @argument', ['@argument' => 'Argument'], ['context' => 'Validation']), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } From 283d96b7ffc9d54494a6ef65aec4d8083a95c440 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 10 Dec 2023 22:03:27 +0100 Subject: [PATCH 18/46] Fix code-style --- .../Rector/Deprecation/ActionAnnotationToAttributeRector.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index 201fad79..32f7e8f7 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -204,7 +204,8 @@ private function createAttribute(array $parsedArgs): Attribute return new Attribute($fullyQualified, $args); } - public function convertTranslateAnnotation(ArrayItemNode $value): ?Node\Expr\New_ { + public function convertTranslateAnnotation(ArrayItemNode $value): ?Node\Expr\New_ + { // Check the annotation type, this will be helpful later. if (!$value->value instanceof DoctrineAnnotationTagValueNode || $value->value->identifierTypeNode->name === 'Translation') { return null; From 98faa8d9200222b0494552928419fe82ceb2049a Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 11 Dec 2023 16:03:06 +0100 Subject: [PATCH 19/46] Refactor some methods in AbstractDrupalCoreRector --- src/Rector/AbstractDrupalCoreRector.php | 42 ++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 4 deletions(-) diff --git a/src/Rector/AbstractDrupalCoreRector.php b/src/Rector/AbstractDrupalCoreRector.php index 55bf1777..3bf5272f 100644 --- a/src/Rector/AbstractDrupalCoreRector.php +++ b/src/Rector/AbstractDrupalCoreRector.php @@ -58,10 +58,8 @@ protected function isInBackwardsCompatibleCall(Node $node): bool public function refactor(Node $node) { - $drupalVersion = str_replace(['.x-dev', '-dev'], '.0', \Drupal::VERSION); - foreach ($this->configuration as $configuration) { - if (version_compare($drupalVersion, $configuration->getIntroducedVersion(), '<')) { + if ($this->rectorShouldApplyToDrupalVersion($configuration)) { continue; } @@ -82,7 +80,7 @@ public function refactor(Node $node) // The reason for this is that will start supplying patches for // Drupal 10 when 10.0 is already out of support. This means that // we will not support running drupal-rector on Drupal 10.0.x. - if (version_compare($drupalVersion, '10.1.0', '<') || version_compare($configuration->getIntroducedVersion(), '10.0.0', '<')) { + if ($this->supportBackwardsCompatibility($configuration) === false) { return $result; } @@ -115,4 +113,40 @@ private function createBcCallOnCallLike(Node\Expr\CallLike $node, Node\Expr\Call new ArrowFunction(['expr' => $clonedNode]), ]); } + + /** + * @param \DrupalRector\Contract\VersionedConfigurationInterface $configuration + * + * @return bool|int + */ + public function rectorShouldApplyToDrupalVersion(VersionedConfigurationInterface $configuration) { + return version_compare($this->installedDrupalVersion(), $configuration->getIntroducedVersion(), '<'); + } + + /** + * @phpstan-return non-empty-string + */ + public function installedDrupalVersion(): string { + return str_replace([ + '.x-dev', + '-dev' + ], '.0', \Drupal::VERSION); + } + + /** + * Check if Drupal version and the introduced version support backward + * compatible calls. Although it was introduced in Drupal 10.1 we + * also supply these patches for changes introduced in Drupal 10.0. + * The reason for this is that will start supplying patches for + * Drupal 10 when 10.0 is already out of support. This means that + * we will not support running drupal-rector on Drupal 10.0.x. + * + * @param \DrupalRector\Contract\VersionedConfigurationInterface $configuration + * + * @return bool + */ + public function supportBackwardsCompatibility(VersionedConfigurationInterface $configuration): bool { + return !(version_compare($this->installedDrupalVersion(), '10.1.0', '<') || version_compare($configuration->getIntroducedVersion(), '10.0.0', '<')); + } + } From 331b6318860fae5320820125e4b6f25cf94f1eb4 Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 11 Dec 2023 16:39:41 +0100 Subject: [PATCH 20/46] Fix some logic in AbstractDrupalCoreRector so its more readable (and return types match the method names). --- src/Rector/AbstractDrupalCoreRector.php | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Rector/AbstractDrupalCoreRector.php b/src/Rector/AbstractDrupalCoreRector.php index 3bf5272f..30db74ee 100644 --- a/src/Rector/AbstractDrupalCoreRector.php +++ b/src/Rector/AbstractDrupalCoreRector.php @@ -59,7 +59,7 @@ protected function isInBackwardsCompatibleCall(Node $node): bool public function refactor(Node $node) { foreach ($this->configuration as $configuration) { - if ($this->rectorShouldApplyToDrupalVersion($configuration)) { + if ($this->rectorShouldApplyToDrupalVersion($configuration) === false) { continue; } @@ -119,17 +119,19 @@ private function createBcCallOnCallLike(Node\Expr\CallLike $node, Node\Expr\Call * * @return bool|int */ - public function rectorShouldApplyToDrupalVersion(VersionedConfigurationInterface $configuration) { - return version_compare($this->installedDrupalVersion(), $configuration->getIntroducedVersion(), '<'); + public function rectorShouldApplyToDrupalVersion(VersionedConfigurationInterface $configuration) + { + return version_compare($this->installedDrupalVersion(), $configuration->getIntroducedVersion(), '>='); } /** * @phpstan-return non-empty-string */ - public function installedDrupalVersion(): string { + public function installedDrupalVersion(): string + { return str_replace([ '.x-dev', - '-dev' + '-dev', ], '.0', \Drupal::VERSION); } @@ -145,8 +147,8 @@ public function installedDrupalVersion(): string { * * @return bool */ - public function supportBackwardsCompatibility(VersionedConfigurationInterface $configuration): bool { + public function supportBackwardsCompatibility(VersionedConfigurationInterface $configuration): bool + { return !(version_compare($this->installedDrupalVersion(), '10.1.0', '<') || version_compare($configuration->getIntroducedVersion(), '10.0.0', '<')); } - } From 99225899bcc38727746c08ba4d5faa4641d32370 Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 11 Dec 2023 16:40:23 +0100 Subject: [PATCH 21/46] Introduce DrupalIntroducedAndRemovalVersionConfiguration and refactor ActionAnnotationToAttributeRector to use AbstractDrupalCoreRector (mostly) --- .../ActionAnnotationToAttributeRector.php | 96 ++++++++++++------- ...troducedAndRemovalVersionConfiguration.php | 30 ++++++ 2 files changed, 89 insertions(+), 37 deletions(-) create mode 100644 src/Drupal10/Rector/ValueObject/DrupalIntroducedAndRemovalVersionConfiguration.php diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index 32f7e8f7..52cc1ecb 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -4,6 +4,10 @@ namespace DrupalRector\Drupal10\Rector\Deprecation; +use DrupalRector\Contract\VersionedConfigurationInterface; +use DrupalRector\Drupal10\Rector\ValueObject\DrupalIntroducedAndRemovalVersionConfiguration; +use DrupalRector\Rector\AbstractDrupalCoreRector; +use DrupalRector\Rector\ValueObject\DrupalIntroducedVersionConfiguration; use PhpParser\Node; use PhpParser\Node\Arg; use PhpParser\Node\Attribute; @@ -13,7 +17,6 @@ use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; -use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode; use Rector\BetterPhpDocParser\PhpDoc\ArrayItemNode; use Rector\BetterPhpDocParser\PhpDoc\DoctrineAnnotationTagValueNode; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; @@ -22,7 +25,6 @@ use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover; use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser\ArrayParser; use Rector\Comments\NodeDocBlock\DocBlockUpdater; -use Rector\Core\Rector\AbstractRector; use Rector\Core\ValueObject\PhpVersion; use Rector\VersionBonding\Contract\MinPhpVersionInterface; use RectorPrefix202310\PHPUnit\Framework\Attributes\Ticket; @@ -34,38 +36,22 @@ * * @see \Rector\PHPUnit\Tests\AnnotationsToAttributes\Rector\Class_\TicketAnnotationToAttributeRector\TicketAnnotationToAttributeRectorTest */ -final class ActionAnnotationToAttributeRector extends AbstractRector implements MinPhpVersionInterface +final class ActionAnnotationToAttributeRector extends AbstractDrupalCoreRector implements MinPhpVersionInterface { /** - * @readonly - * - * @var \Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover - */ - private $phpDocTagRemover; - /** - * @readonly - * - * @var \Rector\Comments\NodeDocBlock\DocBlockUpdater + * @var array|DrupalIntroducedAndRemovalVersionConfiguration[] */ - private $docBlockUpdater; - /** - * @readonly - * - * @var \Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser\ArrayParser - */ - private $arrayParser; - /** - * @readonly - * - * @var \Rector\BetterPhpDocParser\PhpDocInfo\TokenIteratorFactory - */ - private $tokenIteratorFactory; - /** - * @readonly - * - * @var \Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory - */ - private $phpDocInfoFactory; + protected array $configuration = []; + + private PhpDocTagRemover $phpDocTagRemover; + + private DocBlockUpdater $docBlockUpdater; + + private ArrayParser $arrayParser; + + private TokenIteratorFactory $tokenIteratorFactory; + + private PhpDocInfoFactory $phpDocInfoFactory; public function __construct(PhpDocTagRemover $phpDocTagRemover, DocBlockUpdater $docBlockUpdater, PhpDocInfoFactory $phpDocInfoFactory, ArrayParser $arrayParser, TokenIteratorFactory $tokenIteratorFactory) { @@ -76,6 +62,17 @@ public function __construct(PhpDocTagRemover $phpDocTagRemover, DocBlockUpdater $this->tokenIteratorFactory = $tokenIteratorFactory; } + public function configure(array $configuration): void + { + foreach ($configuration as $value) { + if (!($value instanceof DrupalIntroducedAndRemovalVersionConfiguration)) { + throw new \InvalidArgumentException(sprintf('Each configuration item must be an instance of "%s"', DrupalIntroducedVersionConfiguration::class)); + } + } + + parent::configure($configuration); + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Change annotations with value to attribute', [new CodeSample(<<<'CODE_SAMPLE' @@ -134,12 +131,36 @@ public function provideMinPhpVersion(): int * @param Class_|ClassMethod $node */ public function refactor(Node $node): ?Node + { + foreach ($this->configuration as $configuration) { + if ($this->rectorShouldApplyToDrupalVersion($configuration) === false) { + continue; + } + + $result = $this->refactorWithConfiguration($node, $configuration); + + // Skip if no result. + if ($result === null) { + continue; + } + + return $result; + } + + return null; + } + + /** + * @param Class_|ClassMethod $node + * @param DrupalIntroducedAndRemovalVersionConfiguration $configuration + */ + public function refactorWithConfiguration(Node $node, VersionedConfigurationInterface $configuration): ?Node { $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); if (!$phpDocInfo instanceof PhpDocInfo) { return null; } - /** @var PhpDocTagNode[] $tagsByName */ + $tagsByName = $phpDocInfo->getTagsByName('Action'); if ($tagsByName === []) { return null; @@ -155,7 +176,7 @@ public function refactor(Node $node): ?Node } } - $hasChanged = \false; + $docBlockHasChanged = \false; foreach ($tagsByName as $valueNode) { if (!$valueNode->value instanceof GenericTagValueNode) { continue; @@ -170,11 +191,12 @@ public function refactor(Node $node): ?Node $node->attrGroups[] = new AttributeGroup([$attribute]); } - // @todo This cleanup needs some extra logic for BC - $this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $valueNode); - $hasChanged = \true; + if (version_compare($this->installedDrupalVersion(), $configuration->getRemoveVersion(), '>=')) { + $this->phpDocTagRemover->removeTagValueFromNode($phpDocInfo, $valueNode); + $docBlockHasChanged = \true; + } } - if ($hasChanged) { + if ($docBlockHasChanged) { $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node); return $node; diff --git a/src/Drupal10/Rector/ValueObject/DrupalIntroducedAndRemovalVersionConfiguration.php b/src/Drupal10/Rector/ValueObject/DrupalIntroducedAndRemovalVersionConfiguration.php new file mode 100644 index 00000000..3c7399ac --- /dev/null +++ b/src/Drupal10/Rector/ValueObject/DrupalIntroducedAndRemovalVersionConfiguration.php @@ -0,0 +1,30 @@ +introducedVersion = $introducedVersion; + $this->removeVersion = $removeVersion; + } + + public function getIntroducedVersion(): string + { + return $this->introducedVersion; + } + + public function getRemoveVersion(): string + { + return $this->removeVersion; + } +} From 6dad2676ff5b4194570036995dcabf1e7d508f3f Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 11 Dec 2023 16:41:34 +0100 Subject: [PATCH 22/46] Add tests for BC path and update default tests to expect no BC path --- ...yActionAnnotationToAttributeRectorTest.php | 40 +++++++++++++++++++ .../config/configured_rule.php | 5 ++- .../configured_rule_simulate_next_major.php | 14 +++++++ .../bc_basic_fixture.php.inc | 27 +++++++++++++ .../bc_existing_attribute_fixture.php.inc | 28 +++++++++++++ .../bc_multiple_translation_arguments.php.inc | 27 +++++++++++++ .../fixture/basic_fixture.php.inc | 6 +++ .../existing_attribute_fixture.php.inc | 6 +++ .../multiple_translation_arguments.php.inc | 6 +++ 9 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/BackwardsCompatibilityActionAnnotationToAttributeRectorTest.php create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule_simulate_next_major.php create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_basic_fixture.php.inc create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_existing_attribute_fixture.php.inc create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_multiple_translation_arguments.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/BackwardsCompatibilityActionAnnotationToAttributeRectorTest.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/BackwardsCompatibilityActionAnnotationToAttributeRectorTest.php new file mode 100644 index 00000000..194f05a8 --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/BackwardsCompatibilityActionAnnotationToAttributeRectorTest.php @@ -0,0 +1,40 @@ +doTestFile($filePath); + } + + /** + * @return Iterator<> + */ + public static function provideData(): \Iterator + { + return self::yieldFilesFromDirectory(__DIR__.'/fixture-next-major'); + } + + public function provideConfigFilePath(): string + { + // must be implemented + return __DIR__.'/config/configured_rule_simulate_next_major.php'; + } +} diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php index f2d6a510..2bfff066 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php @@ -3,9 +3,12 @@ declare(strict_types=1); use DrupalRector\Drupal10\Rector\Deprecation\ActionAnnotationToAttributeRector; +use DrupalRector\Drupal10\Rector\ValueObject\DrupalIntroducedAndRemovalVersionConfiguration; use DrupalRector\Tests\Rector\Deprecation\DeprecationBase; use Rector\Config\RectorConfig; return static function (RectorConfig $rectorConfig): void { - DeprecationBase::addClass(ActionAnnotationToAttributeRector::class, $rectorConfig, false); + DeprecationBase::addClass(ActionAnnotationToAttributeRector::class, $rectorConfig, false, [ + new DrupalIntroducedAndRemovalVersionConfiguration('10.2.0', '11.0.0'), + ]); }; diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule_simulate_next_major.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule_simulate_next_major.php new file mode 100644 index 00000000..4bbf6710 --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule_simulate_next_major.php @@ -0,0 +1,14 @@ + + +----- + diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_existing_attribute_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_existing_attribute_fixture.php.inc new file mode 100644 index 00000000..8b197dfe --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_existing_attribute_fixture.php.inc @@ -0,0 +1,28 @@ + + +----- + diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_multiple_translation_arguments.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_multiple_translation_arguments.php.inc new file mode 100644 index 00000000..8b1ef848 --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_multiple_translation_arguments.php.inc @@ -0,0 +1,27 @@ + + +----- + 'Argument'], ['context' => 'Validation']), type: 'system')] +class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { + +} +?> diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc index 4b4d78d9..b2d29312 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc @@ -19,6 +19,12 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface /** * A basic example action that does nothing. + * + * @Action( + * id = "action_example_basic_action", + * action_label = @Translation("Action Example: A basic example action that does nothing"), + * type = "system" + * ) */ #[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc index 8b197dfe..b61b3c69 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc @@ -20,6 +20,12 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface /** * A basic example action that does nothing. + * + * @Action( + * id = "action_example_basic_action", + * action_label = @Translation("Action Example: A basic example action that does nothing"), + * type = "system" + * ) */ #[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc index 8b1ef848..0a17041b 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc @@ -19,6 +19,12 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface /** * A basic example action that does nothing. + * + * @Action( + * id = "action_example_basic_action", + * action_label = @Translation("Action Example: A basic example action that does nothing and has an @argument", context = "Validation", arguments = {"@argument" = "Argument"}), + * type = "system" + * ) */ #[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing and has an @argument', ['@argument' => 'Argument'], ['context' => 'Validation']), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { From 651332f808c01ba1c9de2df079442e494ca9ffec Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 11 Dec 2023 21:19:30 +0100 Subject: [PATCH 23/46] Fix convertTranslateAnnotation early return. Also simplify a little by taking the actual annotation instead of its container. --- .../Deprecation/ActionAnnotationToAttributeRector.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index 52cc1ecb..50133cc3 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -216,7 +216,7 @@ private function createAttribute(array $parsedArgs): Attribute $args = []; foreach ($parsedArgs as $value) { if ($value->key === 'action_label') { - $arg = $this->convertTranslateAnnotation($value); + $arg = $this->convertTranslateAnnotation($value->value); } else { $arg = new String_($value->value->value); } @@ -226,10 +226,10 @@ private function createAttribute(array $parsedArgs): Attribute return new Attribute($fullyQualified, $args); } - public function convertTranslateAnnotation(ArrayItemNode $value): ?Node\Expr\New_ + public function convertTranslateAnnotation(DoctrineAnnotationTagValueNode $value): ?Node\Expr\New_ { // Check the annotation type, this will be helpful later. - if (!$value->value instanceof DoctrineAnnotationTagValueNode || $value->value->identifierTypeNode->name === 'Translation') { + if ($value->identifierTypeNode->name !== '@Translation') { return null; } @@ -238,7 +238,7 @@ public function convertTranslateAnnotation(ArrayItemNode $value): ?Node\Expr\New $contextArg = null; // Loop through the values of the annotation, just to make 100% sure we have the correct argument order - foreach ($value->value->values as $translateValue) { + foreach ($value->values as $translateValue) { if ($translateValue->key === null) { $valueArg = $this->nodeFactory->createArg($translateValue->value->value); } From 773255a33776a978f3d7aa5e3aa917c100c47ca2 Mon Sep 17 00:00:00 2001 From: bjorn Date: Sun, 14 Jan 2024 16:21:07 +0100 Subject: [PATCH 24/46] Fix style --- .../Rector/Deprecation/ActionAnnotationToAttributeRector.php | 4 ++-- src/Rector/AbstractDrupalCoreRector.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index 50133cc3..93291603 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -25,7 +25,7 @@ use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover; use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser\ArrayParser; use Rector\Comments\NodeDocBlock\DocBlockUpdater; -use Rector\Core\ValueObject\PhpVersion; +use Rector\ValueObject\PhpVersion; use Rector\VersionBonding\Contract\MinPhpVersionInterface; use RectorPrefix202310\PHPUnit\Framework\Attributes\Ticket; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -208,7 +208,7 @@ public function refactorWithConfiguration(Node $node, VersionedConfigurationInte /** * @param array|ArrayItemNode[] $parsedArgs * - * @return \PhpParser\Node\Attribute + * @return Attribute */ private function createAttribute(array $parsedArgs): Attribute { diff --git a/src/Rector/AbstractDrupalCoreRector.php b/src/Rector/AbstractDrupalCoreRector.php index 30db74ee..89ac7c5b 100644 --- a/src/Rector/AbstractDrupalCoreRector.php +++ b/src/Rector/AbstractDrupalCoreRector.php @@ -115,7 +115,7 @@ private function createBcCallOnCallLike(Node\Expr\CallLike $node, Node\Expr\Call } /** - * @param \DrupalRector\Contract\VersionedConfigurationInterface $configuration + * @param VersionedConfigurationInterface $configuration * * @return bool|int */ @@ -143,7 +143,7 @@ public function installedDrupalVersion(): string * Drupal 10 when 10.0 is already out of support. This means that * we will not support running drupal-rector on Drupal 10.0.x. * - * @param \DrupalRector\Contract\VersionedConfigurationInterface $configuration + * @param VersionedConfigurationInterface $configuration * * @return bool */ From f249f01851f9c4ad6c674aaf6736d38e9bca0533 Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Mar 2024 10:01:14 +0100 Subject: [PATCH 25/46] Remove prefixed class from use statements. --- .../Rector/Deprecation/ActionAnnotationToAttributeRector.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php index 93291603..f2c14612 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php @@ -27,7 +27,6 @@ use Rector\Comments\NodeDocBlock\DocBlockUpdater; use Rector\ValueObject\PhpVersion; use Rector\VersionBonding\Contract\MinPhpVersionInterface; -use RectorPrefix202310\PHPUnit\Framework\Attributes\Ticket; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; From 262dffa0be23ef9b70e42dbe8c85199c0a5425e9 Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Mar 2024 10:37:51 +0100 Subject: [PATCH 26/46] Allow rule to be configured so we can use it on multiple rules. Rename configuration to more targetted. --- config/drupal-10/drupal-10.2-deprecations.php | 11 +++++++-- ...or.php => AnnotationToAttributeRector.php} | 24 +++++++++---------- ...=> AnnotationToAttributeConfiguration.php} | 20 ++++++++++++++-- .../config/configured_rule.php | 8 +++---- .../configured_rule_simulate_next_major.php | 8 +++---- 5 files changed, 47 insertions(+), 24 deletions(-) rename src/Drupal10/Rector/Deprecation/{ActionAnnotationToAttributeRector.php => AnnotationToAttributeRector.php} (89%) rename src/Drupal10/Rector/ValueObject/{DrupalIntroducedAndRemovalVersionConfiguration.php => AnnotationToAttributeConfiguration.php} (54%) diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index 7dd9ae8f..5bc5bf51 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -2,7 +2,8 @@ declare(strict_types=1); -use DrupalRector\Drupal10\Rector\Deprecation\ActionAnnotationToAttributeRector; +use DrupalRector\Drupal10\Rector\Deprecation\AnnotationToAttributeRector; +use DrupalRector\Drupal10\Rector\ValueObject\AnnotationToAttributeConfiguration; use DrupalRector\Rector\Deprecation\FunctionToStaticRector; use DrupalRector\Rector\Deprecation\MethodToMethodWithCheckRector; use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration; @@ -27,5 +28,11 @@ ]); // @see https://www.drupal.org/node/3395575 - $rectorConfig->rule(ActionAnnotationToAttributeRector::class); + $rectorConfig->ruleWithConfiguration(AnnotationToAttributeRector::class, [ + new AnnotationToAttributeConfiguration('10.2.0', '12.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), + ]); + // This rule is disabled from now to first see how it performs on core. + $rectorConfig->skip([ + AnnotationToAttributeRector::class, + ]); }; diff --git a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php similarity index 89% rename from src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php rename to src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php index f2c14612..a52493be 100644 --- a/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php @@ -5,7 +5,7 @@ namespace DrupalRector\Drupal10\Rector\Deprecation; use DrupalRector\Contract\VersionedConfigurationInterface; -use DrupalRector\Drupal10\Rector\ValueObject\DrupalIntroducedAndRemovalVersionConfiguration; +use DrupalRector\Drupal10\Rector\ValueObject\AnnotationToAttributeConfiguration; use DrupalRector\Rector\AbstractDrupalCoreRector; use DrupalRector\Rector\ValueObject\DrupalIntroducedVersionConfiguration; use PhpParser\Node; @@ -35,10 +35,10 @@ * * @see \Rector\PHPUnit\Tests\AnnotationsToAttributes\Rector\Class_\TicketAnnotationToAttributeRector\TicketAnnotationToAttributeRectorTest */ -final class ActionAnnotationToAttributeRector extends AbstractDrupalCoreRector implements MinPhpVersionInterface +final class AnnotationToAttributeRector extends AbstractDrupalCoreRector implements MinPhpVersionInterface { /** - * @var array|DrupalIntroducedAndRemovalVersionConfiguration[] + * @var array|AnnotationToAttributeConfiguration[] */ protected array $configuration = []; @@ -64,7 +64,7 @@ public function __construct(PhpDocTagRemover $phpDocTagRemover, DocBlockUpdater public function configure(array $configuration): void { foreach ($configuration as $value) { - if (!($value instanceof DrupalIntroducedAndRemovalVersionConfiguration)) { + if (!($value instanceof AnnotationToAttributeConfiguration)) { throw new \InvalidArgumentException(sprintf('Each configuration item must be an instance of "%s"', DrupalIntroducedVersionConfiguration::class)); } } @@ -150,8 +150,8 @@ public function refactor(Node $node): ?Node } /** - * @param Class_|ClassMethod $node - * @param DrupalIntroducedAndRemovalVersionConfiguration $configuration + * @param Class_|ClassMethod $node + * @param AnnotationToAttributeConfiguration $configuration */ public function refactorWithConfiguration(Node $node, VersionedConfigurationInterface $configuration): ?Node { @@ -160,7 +160,7 @@ public function refactorWithConfiguration(Node $node, VersionedConfigurationInte return null; } - $tagsByName = $phpDocInfo->getTagsByName('Action'); + $tagsByName = $phpDocInfo->getTagsByName($configuration->getAnnotation()); if ($tagsByName === []) { return null; } @@ -168,7 +168,7 @@ public function refactorWithConfiguration(Node $node, VersionedConfigurationInte $hasAttribute = false; foreach ($node->attrGroups as $attrGroup) { foreach ($attrGroup->attrs as $attr) { - if ($attr->name->toString() === 'Drupal\Core\Action\Attribute\Action') { + if ($attr->name->toString() === $configuration->getAttributeClass()) { $hasAttribute = true; break 2; } @@ -186,7 +186,7 @@ public function refactorWithConfiguration(Node $node, VersionedConfigurationInte $stringValue = '{'.trim($stringValue, '()').'}'; $tokenIterator = $this->tokenIteratorFactory->create($stringValue); $data = $this->arrayParser->parseCurlyArray($tokenIterator, $node); - $attribute = $this->createAttribute($data); + $attribute = $this->createAttribute($configuration->getAttributeClass(), $data); $node->attrGroups[] = new AttributeGroup([$attribute]); } @@ -209,12 +209,12 @@ public function refactorWithConfiguration(Node $node, VersionedConfigurationInte * * @return Attribute */ - private function createAttribute(array $parsedArgs): Attribute + private function createAttribute(string $attributeClass, array $parsedArgs): Attribute { - $fullyQualified = new FullyQualified('Drupal\Core\Action\Attribute\Action'); + $fullyQualified = new FullyQualified($attributeClass); $args = []; foreach ($parsedArgs as $value) { - if ($value->key === 'action_label') { + if ($value->value instanceof DoctrineAnnotationTagValueNode) { $arg = $this->convertTranslateAnnotation($value->value); } else { $arg = new String_($value->value->value); diff --git a/src/Drupal10/Rector/ValueObject/DrupalIntroducedAndRemovalVersionConfiguration.php b/src/Drupal10/Rector/ValueObject/AnnotationToAttributeConfiguration.php similarity index 54% rename from src/Drupal10/Rector/ValueObject/DrupalIntroducedAndRemovalVersionConfiguration.php rename to src/Drupal10/Rector/ValueObject/AnnotationToAttributeConfiguration.php index 3c7399ac..7d8ee0e5 100644 --- a/src/Drupal10/Rector/ValueObject/DrupalIntroducedAndRemovalVersionConfiguration.php +++ b/src/Drupal10/Rector/ValueObject/AnnotationToAttributeConfiguration.php @@ -6,16 +6,22 @@ use DrupalRector\Contract\VersionedConfigurationInterface; -class DrupalIntroducedAndRemovalVersionConfiguration implements VersionedConfigurationInterface +class AnnotationToAttributeConfiguration implements VersionedConfigurationInterface { private string $introducedVersion; private string $removeVersion; - public function __construct(string $introducedVersion, string $removeVersion) + private string $annotation; + + private string $attributeClass; + + public function __construct(string $introducedVersion, string $removeVersion, string $annotation, string $attributeClass) { $this->introducedVersion = $introducedVersion; $this->removeVersion = $removeVersion; + $this->annotation = $annotation; + $this->attributeClass = $attributeClass; } public function getIntroducedVersion(): string @@ -27,4 +33,14 @@ public function getRemoveVersion(): string { return $this->removeVersion; } + + public function getAnnotation(): string + { + return $this->annotation; + } + + public function getAttributeClass(): string + { + return $this->attributeClass; + } } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php index 2bfff066..41ea4d74 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php @@ -2,13 +2,13 @@ declare(strict_types=1); -use DrupalRector\Drupal10\Rector\Deprecation\ActionAnnotationToAttributeRector; -use DrupalRector\Drupal10\Rector\ValueObject\DrupalIntroducedAndRemovalVersionConfiguration; +use DrupalRector\Drupal10\Rector\Deprecation\AnnotationToAttributeRector; +use DrupalRector\Drupal10\Rector\ValueObject\AnnotationToAttributeConfiguration; use DrupalRector\Tests\Rector\Deprecation\DeprecationBase; use Rector\Config\RectorConfig; return static function (RectorConfig $rectorConfig): void { - DeprecationBase::addClass(ActionAnnotationToAttributeRector::class, $rectorConfig, false, [ - new DrupalIntroducedAndRemovalVersionConfiguration('10.2.0', '11.0.0'), + DeprecationBase::addClass(AnnotationToAttributeRector::class, $rectorConfig, false, [ + new AnnotationToAttributeConfiguration('10.2.0', '11.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), ]); }; diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule_simulate_next_major.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule_simulate_next_major.php index 4bbf6710..65aac890 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule_simulate_next_major.php +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule_simulate_next_major.php @@ -2,13 +2,13 @@ declare(strict_types=1); -use DrupalRector\Drupal10\Rector\Deprecation\ActionAnnotationToAttributeRector; -use DrupalRector\Drupal10\Rector\ValueObject\DrupalIntroducedAndRemovalVersionConfiguration; +use DrupalRector\Drupal10\Rector\Deprecation\AnnotationToAttributeRector; +use DrupalRector\Drupal10\Rector\ValueObject\AnnotationToAttributeConfiguration; use DrupalRector\Tests\Rector\Deprecation\DeprecationBase; use Rector\Config\RectorConfig; return static function (RectorConfig $rectorConfig): void { - DeprecationBase::addClass(ActionAnnotationToAttributeRector::class, $rectorConfig, false, [ - new DrupalIntroducedAndRemovalVersionConfiguration('10.2.0', '10.0.0'), + DeprecationBase::addClass(AnnotationToAttributeRector::class, $rectorConfig, false, [ + new AnnotationToAttributeConfiguration('10.2.0', '10.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), ]); }; From 8f0fedaa0ed4cc0f8e71b55a964e19c3440f3d0b Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Mar 2024 12:16:17 +0100 Subject: [PATCH 27/46] Rename fixtures to add plugin id --- ...ic_fixture.php.inc => action_bc_basic_fixture.php.inc} | 0 ...p.inc => action_bc_existing_attribute_fixture.php.inc} | 0 ...c => action_bc_multiple_translation_arguments.php.inc} | 0 ...basic_fixture.php.inc => action_basic_fixture.php.inc} | 0 ....php.inc => action_existing_attribute_fixture.php.inc} | 0 ....inc => action_multiple_translation_arguments.php.inc} | 8 +++++--- 6 files changed, 5 insertions(+), 3 deletions(-) rename tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/{bc_basic_fixture.php.inc => action_bc_basic_fixture.php.inc} (100%) rename tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/{bc_existing_attribute_fixture.php.inc => action_bc_existing_attribute_fixture.php.inc} (100%) rename tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/{bc_multiple_translation_arguments.php.inc => action_bc_multiple_translation_arguments.php.inc} (100%) rename tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/{basic_fixture.php.inc => action_basic_fixture.php.inc} (100%) rename tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/{existing_attribute_fixture.php.inc => action_existing_attribute_fixture.php.inc} (100%) rename tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/{multiple_translation_arguments.php.inc => action_multiple_translation_arguments.php.inc} (74%) diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_basic_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_basic_fixture.php.inc similarity index 100% rename from tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_basic_fixture.php.inc rename to tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_basic_fixture.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_existing_attribute_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_existing_attribute_fixture.php.inc similarity index 100% rename from tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_existing_attribute_fixture.php.inc rename to tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_existing_attribute_fixture.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_multiple_translation_arguments.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_multiple_translation_arguments.php.inc similarity index 100% rename from tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/bc_multiple_translation_arguments.php.inc rename to tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_multiple_translation_arguments.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_basic_fixture.php.inc similarity index 100% rename from tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/basic_fixture.php.inc rename to tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_basic_fixture.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_existing_attribute_fixture.php.inc similarity index 100% rename from tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/existing_attribute_fixture.php.inc rename to tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_existing_attribute_fixture.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_multiple_translation_arguments.php.inc similarity index 74% rename from tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc rename to tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_multiple_translation_arguments.php.inc index 0a17041b..fc1736ee 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/multiple_translation_arguments.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_multiple_translation_arguments.php.inc @@ -6,7 +6,8 @@ * @Action( * id = "action_example_basic_action", * action_label = @Translation("Action Example: A basic example action that does nothing and has an @argument", context = "Validation", arguments = {"@argument" = "Argument"}), - * type = "system" + * type = "system", + * deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver" * ) */ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { @@ -23,10 +24,11 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface * @Action( * id = "action_example_basic_action", * action_label = @Translation("Action Example: A basic example action that does nothing and has an @argument", context = "Validation", arguments = {"@argument" = "Argument"}), - * type = "system" + * type = "system", + * deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver" * ) */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing and has an @argument', ['@argument' => 'Argument'], ['context' => 'Validation']), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing and has an @argument', ['@argument' => 'Argument'], ['context' => 'Validation']), type: 'system', deriver: \Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver::class)] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } From 58566af38ce9b850e1303038d8ad3675aa7d9003 Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Mar 2024 12:16:31 +0100 Subject: [PATCH 28/46] Add block test and configuration --- .../config/configured_rule.php | 1 + .../fixture/block_basic_fixture.php.inc | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/block_basic_fixture.php.inc diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php index 41ea4d74..b7d8687c 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php @@ -10,5 +10,6 @@ return static function (RectorConfig $rectorConfig): void { DeprecationBase::addClass(AnnotationToAttributeRector::class, $rectorConfig, false, [ new AnnotationToAttributeConfiguration('10.2.0', '11.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), + new AnnotationToAttributeConfiguration('10.2.0', '11.0.0', 'Block', 'Drupal\Core\Action\Attribute\Block'), ]); }; diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/block_basic_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/block_basic_fixture.php.inc new file mode 100644 index 00000000..14ee6b23 --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/block_basic_fixture.php.inc @@ -0,0 +1,37 @@ + + +----- + false])] +class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { + +} +?> From ce8ad533d25909aa78b0f403b90f23f8f7c1fe6b Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Mar 2024 12:16:47 +0100 Subject: [PATCH 29/46] Add missing deriver key --- .../Rector/Deprecation/AnnotationToAttributeRector.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php index a52493be..c6bb9770 100644 --- a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php @@ -214,7 +214,9 @@ private function createAttribute(string $attributeClass, array $parsedArgs): Att $fullyQualified = new FullyQualified($attributeClass); $args = []; foreach ($parsedArgs as $value) { - if ($value->value instanceof DoctrineAnnotationTagValueNode) { + if ($value->key == 'deriver') { + $arg = $this->nodeFactory->createClassConstFetch($value->value->value,'class'); + } elseif ($value->value instanceof DoctrineAnnotationTagValueNode) { $arg = $this->convertTranslateAnnotation($value->value); } else { $arg = new String_($value->value->value); From fc50d58833f6223778e35db5ad0a503985aec94e Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Mar 2024 12:17:18 +0100 Subject: [PATCH 30/46] Use built in AnnotationToAttribute mapper for forms value in Block annotation --- .../Deprecation/AnnotationToAttributeRector.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php index c6bb9770..d0943905 100644 --- a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php @@ -25,6 +25,7 @@ use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTagRemover; use Rector\BetterPhpDocParser\PhpDocParser\StaticDoctrineAnnotationParser\ArrayParser; use Rector\Comments\NodeDocBlock\DocBlockUpdater; +use Rector\PhpAttribute\AnnotationToAttributeMapper; use Rector\ValueObject\PhpVersion; use Rector\VersionBonding\Contract\MinPhpVersionInterface; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; @@ -52,13 +53,19 @@ final class AnnotationToAttributeRector extends AbstractDrupalCoreRector impleme private PhpDocInfoFactory $phpDocInfoFactory; - public function __construct(PhpDocTagRemover $phpDocTagRemover, DocBlockUpdater $docBlockUpdater, PhpDocInfoFactory $phpDocInfoFactory, ArrayParser $arrayParser, TokenIteratorFactory $tokenIteratorFactory) + /** + * @var \Rector\PhpAttribute\AnnotationToAttributeMapper + */ + private AnnotationToAttributeMapper $annotationToAttributeMapper; + + public function __construct(PhpDocTagRemover $phpDocTagRemover, DocBlockUpdater $docBlockUpdater, PhpDocInfoFactory $phpDocInfoFactory, ArrayParser $arrayParser, TokenIteratorFactory $tokenIteratorFactory, AnnotationToAttributeMapper $annotationToAttributeMapper) { $this->phpDocTagRemover = $phpDocTagRemover; $this->docBlockUpdater = $docBlockUpdater; $this->phpDocInfoFactory = $phpDocInfoFactory; $this->arrayParser = $arrayParser; $this->tokenIteratorFactory = $tokenIteratorFactory; + $this->annotationToAttributeMapper = $annotationToAttributeMapper; } public function configure(array $configuration): void @@ -218,9 +225,13 @@ private function createAttribute(string $attributeClass, array $parsedArgs): Att $arg = $this->nodeFactory->createClassConstFetch($value->value->value,'class'); } elseif ($value->value instanceof DoctrineAnnotationTagValueNode) { $arg = $this->convertTranslateAnnotation($value->value); + } elseif ($value->key === 'forms') { + $attribute = $this->annotationToAttributeMapper->map($value); + $arg = $attribute->value; } else { $arg = new String_($value->value->value); } + $args[] = new Arg($arg, \false, \false, [], new Node\Identifier($value->key)); } From 0d26dd5d96d64f4924f5f44590ff57c03530b365 Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Mar 2024 16:00:22 +0100 Subject: [PATCH 31/46] Fix codestyle --- .../Rector/Deprecation/AnnotationToAttributeRector.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php index d0943905..4623909f 100644 --- a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php @@ -54,7 +54,7 @@ final class AnnotationToAttributeRector extends AbstractDrupalCoreRector impleme private PhpDocInfoFactory $phpDocInfoFactory; /** - * @var \Rector\PhpAttribute\AnnotationToAttributeMapper + * @var AnnotationToAttributeMapper */ private AnnotationToAttributeMapper $annotationToAttributeMapper; @@ -222,7 +222,7 @@ private function createAttribute(string $attributeClass, array $parsedArgs): Att $args = []; foreach ($parsedArgs as $value) { if ($value->key == 'deriver') { - $arg = $this->nodeFactory->createClassConstFetch($value->value->value,'class'); + $arg = $this->nodeFactory->createClassConstFetch($value->value->value, 'class'); } elseif ($value->value instanceof DoctrineAnnotationTagValueNode) { $arg = $this->convertTranslateAnnotation($value->value); } elseif ($value->key === 'forms') { From 85f4742bed7095c0803f890ce6c6e7b941d15d6e Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Mar 2024 16:12:18 +0100 Subject: [PATCH 32/46] Fully remove annotations from drupal 10 set for now until we have better validation on these. --- config/drupal-10/drupal-10.2-deprecations.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index 5bc5bf51..570884e9 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -27,12 +27,4 @@ new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'setResource', 'setImage'), ]); - // @see https://www.drupal.org/node/3395575 - $rectorConfig->ruleWithConfiguration(AnnotationToAttributeRector::class, [ - new AnnotationToAttributeConfiguration('10.2.0', '12.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), - ]); - // This rule is disabled from now to first see how it performs on core. - $rectorConfig->skip([ - AnnotationToAttributeRector::class, - ]); }; From 12ebdc7bf87ea0b73991a7b11ab21b3e3381f82b Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 8 Mar 2024 16:21:30 +0100 Subject: [PATCH 33/46] Protected to public --- config/drupal-10/drupal-10.2-deprecations.php | 3 --- .../Rector/Deprecation/AnnotationToAttributeRector.php | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index 570884e9..869a4838 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -2,8 +2,6 @@ declare(strict_types=1); -use DrupalRector\Drupal10\Rector\Deprecation\AnnotationToAttributeRector; -use DrupalRector\Drupal10\Rector\ValueObject\AnnotationToAttributeConfiguration; use DrupalRector\Rector\Deprecation\FunctionToStaticRector; use DrupalRector\Rector\Deprecation\MethodToMethodWithCheckRector; use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration; @@ -26,5 +24,4 @@ new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'getResource', 'getImage'), new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'setResource', 'setImage'), ]); - }; diff --git a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php index 4623909f..e34d84a9 100644 --- a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php @@ -160,7 +160,7 @@ public function refactor(Node $node): ?Node * @param Class_|ClassMethod $node * @param AnnotationToAttributeConfiguration $configuration */ - public function refactorWithConfiguration(Node $node, VersionedConfigurationInterface $configuration): ?Node + protected function refactorWithConfiguration(Node $node, VersionedConfigurationInterface $configuration): ?Node { $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node); if (!$phpDocInfo instanceof PhpDocInfo) { From 4ad1fc5bc54aa991144f3592b4d3118cfc9f5257 Mon Sep 17 00:00:00 2001 From: Ken Rickard Date: Fri, 8 Mar 2024 12:05:12 -0500 Subject: [PATCH 34/46] Add ken to authors. (#295) Update authors --- composer.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/composer.json b/composer.json index 62b6748d..77faedc0 100644 --- a/composer.json +++ b/composer.json @@ -34,6 +34,10 @@ { "name": "Björn Brala", "email": "drupal@bjorn.dev" + }, + { + "name": "Ken Rickard", + "email": "agentrickard@gmail.com" } ], "autoload": { From 2af405c68ac19a887034b7105c5ebb354932bb9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Brala?= Date: Fri, 8 Mar 2024 18:44:07 +0100 Subject: [PATCH 35/46] New rector (9.1): ClassConstantToClassConstantRector to rename class constants to a new class. (#282) * ConstantToClassConstantRector serves d8 and d9, it should be in the generic space * New rector (9.1): ClassConstantToClassConstantRector to rename class constants to a new class. * 0.19 changes --------- Co-authored-by: Ken Rickard --- config/drupal-8/drupal-8.5-deprecations.php | 4 +- config/drupal-8/drupal-8.7-deprecations.php | 4 +- config/drupal-9/drupal-9.1-deprecations.php | 24 ++++ config/drupal-9/drupal-9.3-deprecations.php | 4 +- docs/rules_overview.md | 34 +++--- .../ClassConstantToClassConstantRector.php | 112 ++++++++++++++++++ .../ConstantToClassConstantRector.php | 8 +- ...ssConstantToClassConstantConfiguration.php | 49 ++++++++ .../ConstantToClassConfiguration.php | 2 +- .../ConstantToClassConstantRectorTest.php | 35 ++++++ .../config/configured_rule.php | 31 +++++ .../fixture/fixture.php.inc | 19 +++ .../ConstantToClassConstantRectorTest.php | 2 +- .../config/configured_rule.php | 4 +- .../fixture/fixture.php.inc | 0 15 files changed, 301 insertions(+), 31 deletions(-) create mode 100644 src/Rector/Deprecation/ClassConstantToClassConstantRector.php rename src/{Drupal8 => }/Rector/Deprecation/ConstantToClassConstantRector.php (90%) create mode 100644 src/Rector/ValueObject/ClassConstantToClassConstantConfiguration.php rename src/{Drupal8 => }/Rector/ValueObject/ConstantToClassConfiguration.php (94%) 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 rename tests/src/{Drupal8 => }/Rector/Deprecation/ConstantToClassConstantRector/ConstantToClassConstantRectorTest.php (90%) rename tests/src/{Drupal8 => }/Rector/Deprecation/ConstantToClassConstantRector/config/configured_rule.php (83%) rename tests/src/{Drupal8 => }/Rector/Deprecation/ConstantToClassConstantRector/fixture/fixture.php.inc (100%) diff --git a/config/drupal-8/drupal-8.5-deprecations.php b/config/drupal-8/drupal-8.5-deprecations.php index 64067b13..f0430179 100644 --- a/config/drupal-8/drupal-8.5-deprecations.php +++ b/config/drupal-8/drupal-8.5-deprecations.php @@ -2,9 +2,9 @@ declare(strict_types=1); -use DrupalRector\Drupal8\Rector\Deprecation\ConstantToClassConstantRector; use DrupalRector\Drupal8\Rector\Deprecation\DrupalSetMessageRector; -use DrupalRector\Drupal8\Rector\ValueObject\ConstantToClassConfiguration; +use DrupalRector\Rector\Deprecation\ConstantToClassConstantRector; +use DrupalRector\Rector\ValueObject\ConstantToClassConfiguration; use DrupalRector\Services\AddCommentService; use Rector\Config\RectorConfig; diff --git a/config/drupal-8/drupal-8.7-deprecations.php b/config/drupal-8/drupal-8.7-deprecations.php index 678e8b30..e21f5eda 100644 --- a/config/drupal-8/drupal-8.7-deprecations.php +++ b/config/drupal-8/drupal-8.7-deprecations.php @@ -2,9 +2,9 @@ declare(strict_types=1); -use DrupalRector\Drupal8\Rector\Deprecation\ConstantToClassConstantRector; -use DrupalRector\Drupal8\Rector\ValueObject\ConstantToClassConfiguration; +use DrupalRector\Rector\Deprecation\ConstantToClassConstantRector; use DrupalRector\Rector\Deprecation\FunctionToServiceRector; +use DrupalRector\Rector\ValueObject\ConstantToClassConfiguration; use DrupalRector\Rector\ValueObject\FunctionToServiceConfiguration; use DrupalRector\Services\AddCommentService; use Rector\Config\RectorConfig; 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/config/drupal-9/drupal-9.3-deprecations.php b/config/drupal-9/drupal-9.3-deprecations.php index 6b6166a3..f93b1445 100644 --- a/config/drupal-9/drupal-9.3-deprecations.php +++ b/config/drupal-9/drupal-9.3-deprecations.php @@ -2,8 +2,6 @@ declare(strict_types=1); -use DrupalRector\Drupal8\Rector\Deprecation\ConstantToClassConstantRector; -use DrupalRector\Drupal8\Rector\ValueObject\ConstantToClassConfiguration; use DrupalRector\Drupal9\Rector\Deprecation\ExtensionPathRector; use DrupalRector\Drupal9\Rector\Deprecation\FileBuildUriRector; use DrupalRector\Drupal9\Rector\Deprecation\FunctionToEntityTypeStorageMethod; @@ -15,8 +13,10 @@ use DrupalRector\Drupal9\Rector\ValueObject\ExtensionPathConfiguration; use DrupalRector\Drupal9\Rector\ValueObject\FunctionToEntityTypeStorageConfiguration; use DrupalRector\Drupal9\Rector\ValueObject\FunctionToFirstArgMethodConfiguration; +use DrupalRector\Rector\Deprecation\ConstantToClassConstantRector; use DrupalRector\Rector\Deprecation\FunctionToServiceRector; use DrupalRector\Rector\Deprecation\FunctionToStaticRector; +use DrupalRector\Rector\ValueObject\ConstantToClassConfiguration; use DrupalRector\Rector\ValueObject\FunctionToServiceConfiguration; use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration; use DrupalRector\Services\AddCommentService; diff --git a/docs/rules_overview.md b/docs/rules_overview.md index c6d108cd..1a80073f 100644 --- a/docs/rules_overview.md +++ b/docs/rules_overview.md @@ -6,11 +6,11 @@ - [Drupal10](#drupal10) (2) -- [Drupal8](#drupal8) (19) +- [Drupal8](#drupal8) (18) - [Drupal9](#drupal9) (26) -- [DrupalRector](#drupalrector) (5) +- [DrupalRector](#drupalrector) (6)
@@ -56,21 +56,6 @@ Fixes deprecated watchdog_exception('update', `$exception)` calls ## Drupal8 -### ConstantToClassConstantRector - -Fixes deprecated contant use - -:wrench: **configure it!** - -- class: [`DrupalRector\Drupal8\Rector\Deprecation\ConstantToClassConstantRector`](../src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector.php) - -```diff --$result = file_unmanaged_copy($source, $destination, DEPRECATED_CONSTANT); -+$result = file_unmanaged_copy($source, $destination, \Drupal\MyClass::CONSTANT); -``` - -
- ### DBRector Fixes deprecated `db_delete()` calls @@ -858,6 +843,21 @@ Fixes deprecated `user_password()` calls ## DrupalRector +### ConstantToClassConstantRector + +Fixes deprecated contant use, used in Drupal 8 and 9 deprecations + +:wrench: **configure it!** + +- class: [`DrupalRector\Rector\Deprecation\ConstantToClassConstantRector`](../src/Rector/Deprecation/ConstantToClassConstantRector.php) + +```diff +-$result = file_unmanaged_copy($source, $destination, DEPRECATED_CONSTANT); ++$result = file_unmanaged_copy($source, $destination, \Drupal\MyClass::CONSTANT); +``` + +
+ ### DeprecationHelperRemoveRector Remove DeprecationHelper calls for versions before configured minimum requirement diff --git a/src/Rector/Deprecation/ClassConstantToClassConstantRector.php b/src/Rector/Deprecation/ClassConstantToClassConstantRector.php new file mode 100644 index 00000000..de78184c --- /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/Drupal8/Rector/Deprecation/ConstantToClassConstantRector.php b/src/Rector/Deprecation/ConstantToClassConstantRector.php similarity index 90% rename from src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector.php rename to src/Rector/Deprecation/ConstantToClassConstantRector.php index 3ee74eb7..cb1cc7ae 100644 --- a/src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector.php +++ b/src/Rector/Deprecation/ConstantToClassConstantRector.php @@ -2,9 +2,9 @@ declare(strict_types=1); -namespace DrupalRector\Drupal8\Rector\Deprecation; +namespace DrupalRector\Rector\Deprecation; -use DrupalRector\Drupal8\Rector\ValueObject\ConstantToClassConfiguration; +use DrupalRector\Rector\ValueObject\ConstantToClassConfiguration; use PhpParser\Node; use Rector\Contract\Rector\ConfigurableRectorInterface; use Rector\Rector\AbstractRector; @@ -20,7 +20,7 @@ class ConstantToClassConstantRector extends AbstractRector implements ConfigurableRectorInterface { /** - * @var \DrupalRector\Drupal8\Rector\ValueObject\ConstantToClassConfiguration[] + * @var ConstantToClassConfiguration[] */ private array $constantToClassRenames; @@ -40,7 +40,7 @@ public function configure(array $configuration): void */ public function getRuleDefinition(): RuleDefinition { - return new RuleDefinition('Fixes deprecated contant use', [ + return new RuleDefinition('Fixes deprecated contant use, used in Drupal 8 and 9 deprecations', [ new ConfiguredCodeSample( <<<'CODE_BEFORE' $result = file_unmanaged_copy($source, $destination, DEPRECATED_CONSTANT); diff --git a/src/Rector/ValueObject/ClassConstantToClassConstantConfiguration.php b/src/Rector/ValueObject/ClassConstantToClassConstantConfiguration.php new file mode 100644 index 00000000..24a3d574 --- /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/src/Drupal8/Rector/ValueObject/ConstantToClassConfiguration.php b/src/Rector/ValueObject/ConstantToClassConfiguration.php similarity index 94% rename from src/Drupal8/Rector/ValueObject/ConstantToClassConfiguration.php rename to src/Rector/ValueObject/ConstantToClassConfiguration.php index b8bfe544..98a5c16d 100644 --- a/src/Drupal8/Rector/ValueObject/ConstantToClassConfiguration.php +++ b/src/Rector/ValueObject/ConstantToClassConfiguration.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace DrupalRector\Drupal8\Rector\ValueObject; +namespace DrupalRector\Rector\ValueObject; use Rector\Validation\RectorAssert; 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 @@ + +----- + diff --git a/tests/src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector/ConstantToClassConstantRectorTest.php b/tests/src/Rector/Deprecation/ConstantToClassConstantRector/ConstantToClassConstantRectorTest.php similarity index 90% rename from tests/src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector/ConstantToClassConstantRectorTest.php rename to tests/src/Rector/Deprecation/ConstantToClassConstantRector/ConstantToClassConstantRectorTest.php index e15349ad..b7698b1e 100644 --- a/tests/src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector/ConstantToClassConstantRectorTest.php +++ b/tests/src/Rector/Deprecation/ConstantToClassConstantRector/ConstantToClassConstantRectorTest.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace Drupal8\Rector\Deprecation\ConstantToClassConstantRector; +namespace DrupalRector\Rector\Deprecation\ConstantToClassConstantRector; use Iterator; use Rector\Testing\PHPUnit\AbstractRectorTestCase; diff --git a/tests/src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector/config/configured_rule.php b/tests/src/Rector/Deprecation/ConstantToClassConstantRector/config/configured_rule.php similarity index 83% rename from tests/src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector/config/configured_rule.php rename to tests/src/Rector/Deprecation/ConstantToClassConstantRector/config/configured_rule.php index aeec0664..fe541df3 100644 --- a/tests/src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector/config/configured_rule.php +++ b/tests/src/Rector/Deprecation/ConstantToClassConstantRector/config/configured_rule.php @@ -2,8 +2,8 @@ declare(strict_types=1); -use DrupalRector\Drupal8\Rector\Deprecation\ConstantToClassConstantRector; -use DrupalRector\Drupal8\Rector\ValueObject\ConstantToClassConfiguration; +use DrupalRector\Rector\Deprecation\ConstantToClassConstantRector; +use DrupalRector\Rector\ValueObject\ConstantToClassConfiguration; use DrupalRector\Tests\Rector\Deprecation\DeprecationBase; use Rector\Config\RectorConfig; diff --git a/tests/src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector/fixture/fixture.php.inc b/tests/src/Rector/Deprecation/ConstantToClassConstantRector/fixture/fixture.php.inc similarity index 100% rename from tests/src/Drupal8/Rector/Deprecation/ConstantToClassConstantRector/fixture/fixture.php.inc rename to tests/src/Rector/Deprecation/ConstantToClassConstantRector/fixture/fixture.php.inc From dc2e858a5f5cea2ef3e2b770350169f0d0af926b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Brala?= Date: Sat, 9 Mar 2024 20:12:48 +0100 Subject: [PATCH 36/46] feat: Optimize AnnotationToAttributeRector and add core plugin conversion documentation (#296) * feat: add PluralTranslation and test for ConfigEntityType * fix: codestyle * fix:L ContentEntityType * fix: overmatching ) * fix: tests and style * fix: new Drupal\Core\StringTranslation\TranslatableMarkup should be new \Drupal\Core\StringTranslation\TranslatableMarkup * feat: add documentation for core plugin conversion * fix: correct paths for rector.php --- docs/core_plugin_conversion.md | 88 +++++++++ .../AnnotationToAttributeRector.php | 36 +++- .../config/configured_rule.php | 5 +- .../action_bc_basic_fixture.php.inc | 2 +- ...tion_bc_existing_attribute_fixture.php.inc | 4 +- ..._bc_multiple_translation_arguments.php.inc | 2 +- .../fixture/action_basic_fixture.php.inc | 2 +- .../action_existing_attribute_fixture.php.inc | 4 +- ...ion_multiple_translation_arguments.php.inc | 2 +- .../fixture/block_basic_fixture.php.inc | 2 +- .../content_entity_type_fixture.php.inc | 175 +++++++++++++++++ ...ententitytype_blockcontent_fixture.php.inc | 180 ++++++++++++++++++ 12 files changed, 485 insertions(+), 17 deletions(-) create mode 100644 docs/core_plugin_conversion.md create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/content_entity_type_fixture.php.inc create mode 100644 tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/contententitytype_blockcontent_fixture.php.inc diff --git a/docs/core_plugin_conversion.md b/docs/core_plugin_conversion.md new file mode 100644 index 00000000..60b9d8d9 --- /dev/null +++ b/docs/core_plugin_conversion.md @@ -0,0 +1,88 @@ +# Core annotation to attribute conversion + +To convert a plugin in core from an annotation to an attribute, you need to do the following: + +## Install drupal-rector +```bash +composer require --dev palantirnet/drupal-rector +``` + +## Configure drupal-rector (rector.php) + +Create the folling file in the root of core. In this example we are converting the `ContentEntityType` and `ConfigEntityType` annotations to attributes. If you want to convert other annotations, you will need to configure the `AnnotationToAttributeRector` with the appropriate `AnnotationToAttributeConfiguration` objects. + +```php +ruleWithConfiguration(\DrupalRector\Drupal10\Rector\Deprecation\AnnotationToAttributeRector::class, [ + + // Setting both introduce and remove version to 10.x means the comments are not kept. Which is good for core. ;) + new \DrupalRector\Drupal10\Rector\ValueObject\AnnotationToAttributeConfiguration('10.0.0', '10.0.0', 'ContentEntityType', 'Drupal\Core\Entity\Attribute\ContentEntityType'), + new \DrupalRector\Drupal10\Rector\ValueObject\AnnotationToAttributeConfiguration('10.0.0', '10.0.0', 'ConfigEntityType', 'Drupal\Core\Entity\Attribute\ConfigEntityType'), + ]); + + $rectorConfig->autoloadPaths([ + './core/lib', + './core/modules', + './core/profiles', + './core/themes' + ]); + + + $rectorConfig->skip([ + '*/upgrade_status/tests/modules/*', + '*/ProxyClass/*', + '*/tests/fixtures/*', + '*/vendor/*', + ]); + $rectorConfig->fileExtensions([ + 'php', + 'module', + 'theme', + 'install', + 'profile', + 'inc', + 'engine' + ]); + $rectorConfig->importNames(FALSE, FALSE); + $rectorConfig->importShortClasses(FALSE); +}; +``` +## Running rector against core + +Running will take a while. You can run against specific directories like so: + +```bash +vendor/bin/rector process ./core/lib +vendor/bin/rector process ./core/modules +vendor/bin/rector process ./core/themes +``` + +Or run against speific modules: + +```bash +vendor/bin/rector process ./core/modules/system +vendor/bin/rector process ./core/modules/user +``` + +Or if you have horsepower, run against the whole of core: + +```bash +vendor/bin/rector process ./core +``` + +## Review the changes + +Always review the changes. Rector is a tool to help you, not to do the work for you. It will not be able to convert everything, and it may make mistakes. Make sure you understand the changes and that they are correct. + +## Reporting errors + +If you find an error, please report it to the rector project. You can do this by creating an issue in the rector project on Drupal.org. + +We are also available on the #rector channel on Drupal Slack. + +@bbrala @mglaman @agentrickard diff --git a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php index e34d84a9..5f0c0e94 100644 --- a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php @@ -13,7 +13,6 @@ use PhpParser\Node\Attribute; use PhpParser\Node\AttributeGroup; use PhpParser\Node\Name\FullyQualified; -use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode; @@ -224,12 +223,15 @@ private function createAttribute(string $attributeClass, array $parsedArgs): Att if ($value->key == 'deriver') { $arg = $this->nodeFactory->createClassConstFetch($value->value->value, 'class'); } elseif ($value->value instanceof DoctrineAnnotationTagValueNode) { - $arg = $this->convertTranslateAnnotation($value->value); - } elseif ($value->key === 'forms') { + $arg = $this->convertAnnotation($value->value); + } else { $attribute = $this->annotationToAttributeMapper->map($value); $arg = $attribute->value; - } else { - $arg = new String_($value->value->value); + } + + // Sometimes the end ) matches. We need to remove it. + if ($value->key === null) { + continue; } $args[] = new Arg($arg, \false, \false, [], new Node\Identifier($value->key)); @@ -238,6 +240,28 @@ private function createAttribute(string $attributeClass, array $parsedArgs): Att return new Attribute($fullyQualified, $args); } + public function convertAnnotation(DoctrineAnnotationTagValueNode $value): ?Node\Expr + { + return match ($value->identifierTypeNode->name) { + '@Translation' => $this->convertTranslateAnnotation($value), + '@PluralTranslation' => $this->convertPluralTranslationAnnotation($value), + default => null, + }; + } + + public function convertPluralTranslationAnnotation(DoctrineAnnotationTagValueNode $value): ?Node\Expr + { + // Check the annotation type, this will be helpful later. + if ($value->identifierTypeNode->name !== '@PluralTranslation') { + return null; + } + + return $this->nodeFactory->createArray([ + $value->values[0]->key => $value->values[0]->value->value, + $value->values[1]->key => $value->values[1]->value->value, + ]); + } + public function convertTranslateAnnotation(DoctrineAnnotationTagValueNode $value): ?Node\Expr\New_ { // Check the annotation type, this will be helpful later. @@ -277,6 +301,6 @@ public function convertTranslateAnnotation(DoctrineAnnotationTagValueNode $value $argArray[] = $contextArg; } - return new Node\Expr\New_(new Node\Name('Drupal\Core\StringTranslation\TranslatableMarkup'), $argArray); + return new Node\Expr\New_(new Node\Name('\Drupal\Core\StringTranslation\TranslatableMarkup'), $argArray); } } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php index b7d8687c..712150a7 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/config/configured_rule.php @@ -9,7 +9,8 @@ return static function (RectorConfig $rectorConfig): void { DeprecationBase::addClass(AnnotationToAttributeRector::class, $rectorConfig, false, [ - new AnnotationToAttributeConfiguration('10.2.0', '11.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), - new AnnotationToAttributeConfiguration('10.2.0', '11.0.0', 'Block', 'Drupal\Core\Action\Attribute\Block'), + new AnnotationToAttributeConfiguration('10.2.0', '12.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), + new AnnotationToAttributeConfiguration('10.2.0', '12.0.0', 'Block', 'Drupal\Core\Action\Attribute\Block'), + new AnnotationToAttributeConfiguration('10.2.0', '12.0.0', 'ContentEntityType', 'Drupal\Core\Entity\Attribute\ContentEntityType'), ]); }; diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_basic_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_basic_fixture.php.inc index 4b4d78d9..02dda630 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_basic_fixture.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_basic_fixture.php.inc @@ -20,7 +20,7 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface /** * A basic example action that does nothing. */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_existing_attribute_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_existing_attribute_fixture.php.inc index 8b197dfe..147f5e32 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_existing_attribute_fixture.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_existing_attribute_fixture.php.inc @@ -9,7 +9,7 @@ * type = "system" * ) */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } @@ -21,7 +21,7 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface /** * A basic example action that does nothing. */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_multiple_translation_arguments.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_multiple_translation_arguments.php.inc index 8b1ef848..85aa674d 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_multiple_translation_arguments.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture-next-major/action_bc_multiple_translation_arguments.php.inc @@ -20,7 +20,7 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface /** * A basic example action that does nothing. */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing and has an @argument', ['@argument' => 'Argument'], ['context' => 'Validation']), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing and has an @argument', ['@argument' => 'Argument'], ['context' => 'Validation']), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_basic_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_basic_fixture.php.inc index b2d29312..c2d1efc6 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_basic_fixture.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_basic_fixture.php.inc @@ -26,7 +26,7 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface * type = "system" * ) */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_existing_attribute_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_existing_attribute_fixture.php.inc index b61b3c69..a9c13f4e 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_existing_attribute_fixture.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_existing_attribute_fixture.php.inc @@ -9,7 +9,7 @@ * type = "system" * ) */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } @@ -27,7 +27,7 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface * type = "system" * ) */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing'), type: 'system')] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_multiple_translation_arguments.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_multiple_translation_arguments.php.inc index fc1736ee..f3d8f52c 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_multiple_translation_arguments.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/action_multiple_translation_arguments.php.inc @@ -28,7 +28,7 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface * deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver" * ) */ -#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing and has an @argument', ['@argument' => 'Argument'], ['context' => 'Validation']), type: 'system', deriver: \Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver::class)] +#[\Drupal\Core\Action\Attribute\Action(id: 'action_example_basic_action', action_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Action Example: A basic example action that does nothing and has an @argument', ['@argument' => 'Argument'], ['context' => 'Validation']), type: 'system', deriver: \Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver::class)] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/block_basic_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/block_basic_fixture.php.inc index 14ee6b23..28814b8c 100644 --- a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/block_basic_fixture.php.inc +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/block_basic_fixture.php.inc @@ -30,7 +30,7 @@ class BasicExample extends ActionBase implements ContainerFactoryPluginInterface * }, * ) */ -#[\Drupal\Core\Action\Attribute\Block(id: 'page_title_block', admin_label: new Drupal\Core\StringTranslation\TranslatableMarkup('Page title'), forms: ['settings_tray' => false])] +#[\Drupal\Core\Action\Attribute\Block(id: 'page_title_block', admin_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Page title'), forms: ['settings_tray' => false])] class BasicExample extends ActionBase implements ContainerFactoryPluginInterface { } diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/content_entity_type_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/content_entity_type_fixture.php.inc new file mode 100644 index 00000000..3a73132b --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/content_entity_type_fixture.php.inc @@ -0,0 +1,175 @@ + '@count content item', 'plural' => '@count content items'], bundle_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Content type'), handlers: ['storage' => 'Drupal\node\NodeStorage', 'storage_schema' => 'Drupal\node\NodeStorageSchema', 'view_builder' => 'Drupal\node\NodeViewBuilder', 'access' => 'Drupal\node\NodeAccessControlHandler', 'views_data' => 'Drupal\node\NodeViewsData', 'form' => ['default' => 'Drupal\node\NodeForm', 'delete' => 'Drupal\node\Form\NodeDeleteForm', 'edit' => 'Drupal\node\NodeForm', 'delete-multiple-confirm' => 'Drupal\node\Form\DeleteMultiple'], 'route_provider' => ['html' => 'Drupal\node\Entity\NodeRouteProvider'], 'list_builder' => 'Drupal\node\NodeListBuilder', 'translation' => 'Drupal\node\NodeTranslationHandler'], base_table: 'node', data_table: 'node_field_data', revision_table: 'node_revision', revision_data_table: 'node_field_revision', show_revision_ui: true, translatable: true, list_cache_contexts: ['user.node_grants:view'], entity_keys: ['id' => 'nid', 'revision' => 'vid', 'bundle' => 'type', 'label' => 'title', 'langcode' => 'langcode', 'uuid' => 'uuid', 'status' => 'status', 'published' => 'status', 'uid' => 'uid', 'owner' => 'uid'], revision_metadata_keys: ['revision_user' => 'revision_uid', 'revision_created' => 'revision_timestamp', 'revision_log_message' => 'revision_log'], bundle_entity_type: 'node_type', field_ui_base_route: 'entity.node_type.edit_form', common_reference_target: true, permission_granularity: 'bundle', links: ['canonical' => '/node/{node}', 'delete-form' => '/node/{node}/delete', 'delete-multiple-form' => '/admin/content/node/delete', 'edit-form' => '/node/{node}/edit', 'version-history' => '/node/{node}/revisions', 'revision' => '/node/{node}/revisions/{node_revision}/view', 'create' => '/node'])] +class Node extends EditorialContentEntityBase implements NodeInterface { + +} diff --git a/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/contententitytype_blockcontent_fixture.php.inc b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/contententitytype_blockcontent_fixture.php.inc new file mode 100644 index 00000000..3440a703 --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/ActionAnnotationToAttributeRector/fixture/contententitytype_blockcontent_fixture.php.inc @@ -0,0 +1,180 @@ + '@count content block', 'plural' => '@count content blocks'], bundle_label: new \Drupal\Core\StringTranslation\TranslatableMarkup('Block type'), handlers: ['storage' => 'Drupal\Core\Entity\Sql\SqlContentEntityStorage', 'access' => 'Drupal\block_content\BlockContentAccessControlHandler', 'list_builder' => 'Drupal\block_content\BlockContentListBuilder', 'view_builder' => 'Drupal\block_content\BlockContentViewBuilder', 'views_data' => 'Drupal\block_content\BlockContentViewsData', 'form' => ['add' => 'Drupal\block_content\BlockContentForm', 'edit' => 'Drupal\block_content\BlockContentForm', 'delete' => 'Drupal\block_content\Form\BlockContentDeleteForm', 'default' => 'Drupal\block_content\BlockContentForm', 'revision-delete' => \Drupal\Core\Entity\Form\RevisionDeleteForm::class, 'revision-revert' => \Drupal\Core\Entity\Form\RevisionRevertForm::class], 'route_provider' => ['revision' => \Drupal\Core\Entity\Routing\RevisionHtmlRouteProvider::class], 'translation' => 'Drupal\block_content\BlockContentTranslationHandler'], admin_permission: 'administer block content', base_table: 'block_content', revision_table: 'block_content_revision', data_table: 'block_content_field_data', revision_data_table: 'block_content_field_revision', show_revision_ui: true, links: ['canonical' => '/admin/content/block/{block_content}', 'delete-form' => '/admin/content/block/{block_content}/delete', 'edit-form' => '/admin/content/block/{block_content}', 'collection' => '/admin/content/block', 'create' => '/block', 'revision-delete-form' => '/admin/content/block/{block_content}/revision/{block_content_revision}/delete', 'revision-revert-form' => '/admin/content/block/{block_content}/revision/{block_content_revision}/revert', 'version-history' => '/admin/content/block/{block_content}/revisions'], translatable: true, entity_keys: ['id' => 'id', 'revision' => 'revision_id', 'bundle' => 'type', 'label' => 'info', 'langcode' => 'langcode', 'uuid' => 'uuid', 'published' => 'status'], revision_metadata_keys: ['revision_user' => 'revision_user', 'revision_created' => 'revision_created', 'revision_log_message' => 'revision_log'], bundle_entity_type: 'block_content_type', field_ui_base_route: 'entity.block_content_type.edit_form', render_cache: false)] +class BlockContent extends EditorialContentEntityBase implements BlockContentInterface { + +} From 712c84f3129dbed164c388661eb8f3e5ff7c5ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Brala?= Date: Mon, 11 Mar 2024 23:06:28 +0100 Subject: [PATCH 37/46] Update core_plugin_conversion.md (#298) --- docs/core_plugin_conversion.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/core_plugin_conversion.md b/docs/core_plugin_conversion.md index 60b9d8d9..ef186192 100644 --- a/docs/core_plugin_conversion.md +++ b/docs/core_plugin_conversion.md @@ -1,10 +1,13 @@ # Core annotation to attribute conversion -To convert a plugin in core from an annotation to an attribute, you need to do the following: +To convert a plugin in core from an annotation to an attribute, you need to do the following after checking out core. ## Install drupal-rector + +Adding `-W` since PHPStan needs updateing. + ```bash -composer require --dev palantirnet/drupal-rector +composer require --dev palantirnet/drupal-rector -W ``` ## Configure drupal-rector (rector.php) From 0b07b964e58d8a3cc327b567f47871f9fcfb6161 Mon Sep 17 00:00:00 2001 From: bjorn Date: Fri, 15 Mar 2024 14:53:03 +0100 Subject: [PATCH 38/46] doc: Fix doc for AnnotationToAttributeRector and generate new docs. --- docs/rules_overview.md | 60 ++++++++++++++++++- .../AnnotationToAttributeRector.php | 8 ++- 2 files changed, 63 insertions(+), 5 deletions(-) diff --git a/docs/rules_overview.md b/docs/rules_overview.md index 1a80073f..ccf94f13 100644 --- a/docs/rules_overview.md +++ b/docs/rules_overview.md @@ -1,21 +1,56 @@ -# 52 Rules Overview +# 54 Rules Overview
## Categories -- [Drupal10](#drupal10) (2) +- [Drupal10](#drupal10) (3) - [Drupal8](#drupal8) (18) - [Drupal9](#drupal9) (26) -- [DrupalRector](#drupalrector) (6) +- [DrupalRector](#drupalrector) (7)
## Drupal10 +### AnnotationToAttributeRector + +Change annotations with value to attribute + +:wrench: **configure it!** + +- class: [`DrupalRector\Drupal10\Rector\Deprecation\AnnotationToAttributeRector`](../src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php) + +```diff + namespace Drupal\Core\Action\Plugin\Action; + ++use Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver; ++use Drupal\Core\Action\Attribute\Action; + use Drupal\Core\Session\AccountInterface; ++use Drupal\Core\StringTranslation\TranslatableMarkup; + + /** + * Publishes an entity. +- * +- * @Action( +- * id = "entity:publish_action", +- * action_label = @Translation("Publish"), +- * deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver", +- * ) + */ ++#[Action( ++ id: 'entity:publish_action', ++ action_label: new TranslatableMarkup('Publish'), ++ deriver: EntityPublishedActionDeriver::class ++)] + class PublishAction extends EntityActionBase { +``` + +
+ ### SystemTimeZonesRector Fixes deprecated `system_time_zones()` calls @@ -843,6 +878,25 @@ Fixes deprecated `user_password()` calls ## DrupalRector +### ClassConstantToClassConstantRector + +Fixes deprecated class contant use, used in Drupal 9.1 deprecations + +:wrench: **configure it!** + +- class: [`DrupalRector\Rector\Deprecation\ClassConstantToClassConstantRector`](../src/Rector/Deprecation/ClassConstantToClassConstantRector.php) + +```diff +-$value = Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_NAME; +-$value2 = Symfony\Cmf\Component\Routing\RouteObjectInterface::ROUTE_OBJECT; +-$value3 = Symfony\Cmf\Component\Routing\RouteObjectInterface::CONTROLLER_NAME; ++$value = \Drupal\Core\Routing\RouteObjectInterface::ROUTE_NAME; ++$value2 = \Drupal\Core\Routing\RouteObjectInterface::ROUTE_OBJECT; ++$value3 = \Drupal\Core\Routing\RouteObjectInterface::CONTROLLER_NAME; +``` + +
+ ### ConstantToClassConstantRector Fixes deprecated contant use, used in Drupal 8 and 9 deprecations diff --git a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php index 5f0c0e94..95c48f2a 100644 --- a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php @@ -28,6 +28,7 @@ use Rector\ValueObject\PhpVersion; use Rector\VersionBonding\Contract\MinPhpVersionInterface; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; +use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** @@ -80,7 +81,7 @@ public function configure(array $configuration): void public function getRuleDefinition(): RuleDefinition { - return new RuleDefinition('Change annotations with value to attribute', [new CodeSample(<<<'CODE_SAMPLE' + return new RuleDefinition('Change annotations with value to attribute', [new ConfiguredCodeSample(<<<'CODE_SAMPLE' namespace Drupal\Core\Action\Plugin\Action; @@ -116,7 +117,10 @@ class PublishAction extends EntityActionBase { )] class PublishAction extends EntityActionBase { CODE_SAMPLE - )]); + , + [ + new AnnotationToAttributeConfiguration('10.2.0', '12.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), + ])]); } /** From c0f67f48ff6b8a9b55f72be417c8d1bacb1c46df Mon Sep 17 00:00:00 2001 From: bjorn Date: Sat, 16 Mar 2024 15:53:21 +0100 Subject: [PATCH 39/46] fix: remove extra use statement --- .../Rector/Deprecation/AnnotationToAttributeRector.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php index 95c48f2a..ba2b311b 100644 --- a/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php +++ b/src/Drupal10/Rector/Deprecation/AnnotationToAttributeRector.php @@ -27,7 +27,6 @@ use Rector\PhpAttribute\AnnotationToAttributeMapper; use Rector\ValueObject\PhpVersion; use Rector\VersionBonding\Contract\MinPhpVersionInterface; -use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -117,10 +116,10 @@ class PublishAction extends EntityActionBase { )] class PublishAction extends EntityActionBase { CODE_SAMPLE - , - [ - new AnnotationToAttributeConfiguration('10.2.0', '12.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), - ])]); + , + [ + new AnnotationToAttributeConfiguration('10.2.0', '12.0.0', 'Action', 'Drupal\Core\Action\Attribute\Action'), + ])]); } /** From b5ad678aacd657a00ad5b17e4942467e2a3afce2 Mon Sep 17 00:00:00 2001 From: Ken Rickard Date: Mon, 8 Apr 2024 04:34:24 -0400 Subject: [PATCH 40/46] Upgrade project tooling to PHP 8.2 (#300) * Php 8.2 * Wait for 12.1.11 release of symplify/rule-doc-generator/tags * Stylf fix (line endings?) --------- Co-authored-by: bjorn --- .github/workflows/codestyle.yml | 2 +- .../workflows/functional_test__rector_examples.yml | 3 +++ .github/workflows/phpstan.yml | 2 +- .github/workflows/phpunit.yml | 2 +- composer.json | 6 +++--- src/Drupal8/Rector/Deprecation/DrupalLRector.php | 2 +- .../Rector/Deprecation/SafeMarkupFormatRector.php | 12 ++++++------ 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/.github/workflows/codestyle.yml b/.github/workflows/codestyle.yml index 93c9f18e..08d499ac 100644 --- a/.github/workflows/codestyle.yml +++ b/.github/workflows/codestyle.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v3 - uses: shivammathur/setup-php@v2 with: - php-version: 8.1 + php-version: 8.2 coverage: none # disable xdebug, pcov tools: composer:v2 extensions: zip diff --git a/.github/workflows/functional_test__rector_examples.yml b/.github/workflows/functional_test__rector_examples.yml index 2402ecf3..dc4657ff 100644 --- a/.github/workflows/functional_test__rector_examples.yml +++ b/.github/workflows/functional_test__rector_examples.yml @@ -30,6 +30,9 @@ jobs: - php-version: "8.1" drupal: "^10.0" fixture: "d10" + - php-version: "8.2" + drupal: "^10.0" + fixture: "d10" runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 4e7e99ba..af3574ca 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -19,7 +19,7 @@ jobs: - uses: actions/checkout@v3 - uses: shivammathur/setup-php@v2 with: - php-version: 8.1 + php-version: 8.2 coverage: none # disable xdebug, pcov tools: composer:v2 extensions: dom, curl, libxml, mbstring, zip, pdo, mysql, pdo_mysql, bcmath, gd, exif, iconv diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index 6a968ed3..5af6600d 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -17,7 +17,7 @@ jobs: strategy: matrix: php-version: - - "8.1" + - "8.2" steps: - uses: actions/checkout@v3 - uses: shivammathur/setup-php@v2 diff --git a/composer.json b/composer.json index 77faedc0..e436e109 100644 --- a/composer.json +++ b/composer.json @@ -74,15 +74,15 @@ "enable-patching": true }, "require-dev": { - "php": "^8.1", + "php": "^8.2", "cweagans/composer-patches": "^1.7.2", - "friendsofphp/php-cs-fixer": "^3.38", + "friendsofphp/php-cs-fixer": "^3.0", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.0", "phpstan/phpstan-deprecation-rules": "^1.0", "phpunit/phpunit": "^10.0", "symfony/yaml": "^5 || ^6", - "symplify/rule-doc-generator": "^12.0", + "symplify/rule-doc-generator": "dev-main", "symplify/vendor-patches": "^11.0" }, "scripts": { diff --git a/src/Drupal8/Rector/Deprecation/DrupalLRector.php b/src/Drupal8/Rector/Deprecation/DrupalLRector.php index ce176653..16b84240 100644 --- a/src/Drupal8/Rector/Deprecation/DrupalLRector.php +++ b/src/Drupal8/Rector/Deprecation/DrupalLRector.php @@ -46,7 +46,7 @@ public function getRuleDefinition(): RuleDefinition public function getNodeTypes(): array { return [ - Node\Expr\StaticCall::class, + Node\Expr\StaticCall::class, ]; } diff --git a/src/Drupal8/Rector/Deprecation/SafeMarkupFormatRector.php b/src/Drupal8/Rector/Deprecation/SafeMarkupFormatRector.php index d59b7acd..74059525 100644 --- a/src/Drupal8/Rector/Deprecation/SafeMarkupFormatRector.php +++ b/src/Drupal8/Rector/Deprecation/SafeMarkupFormatRector.php @@ -27,15 +27,15 @@ final class SafeMarkupFormatRector extends AbstractRector public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Fixes deprecated SafeMarkup::format() calls', [ - new CodeSample( - <<<'CODE_BEFORE' + new CodeSample( + <<<'CODE_BEFORE' $safe_string_markup_object = \Drupal\Component\Utility\SafeMarkup::format('hello world'); CODE_BEFORE - , - <<<'CODE_AFTER' + , + <<<'CODE_AFTER' $safe_string_markup_object = new \Drupal\Component\Render\FormattableMarkup('hello world'); CODE_AFTER - ), + ), ]); } @@ -45,7 +45,7 @@ public function getRuleDefinition(): RuleDefinition public function getNodeTypes(): array { return [ - Node\Expr\StaticCall::class, + Node\Expr\StaticCall::class, ]; } From 37670e2a5ac10b90739e07eb1441ee6dabbc3253 Mon Sep 17 00:00:00 2001 From: bjorn Date: Thu, 18 Apr 2024 08:56:46 +0200 Subject: [PATCH 41/46] New rector: Rector for _drupal_flush_css_js through new VersionedFunctionToServiceRector --- config/drupal-10/drupal-10.2-deprecations.php | 7 ++ .../VersionedFunctionToServiceRector.php | 84 +++++++++++++++++++ ...ersionedFunctionToServiceConfiguration.php | 55 ++++++++++++ .../VersionedFunctionToServiceRectorTest.php | 35 ++++++++ .../config/configured_rule.php | 14 ++++ .../fixture/fixture.php.inc | 13 +++ 6 files changed, 208 insertions(+) create mode 100644 src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector.php create mode 100644 src/Drupal10/Rector/ValueObject/VersionedFunctionToServiceConfiguration.php create mode 100644 tests/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector/VersionedFunctionToServiceRectorTest.php create mode 100644 tests/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector/config/configured_rule.php create mode 100644 tests/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector/fixture/fixture.php.inc diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index 869a4838..6e343b9a 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -2,6 +2,8 @@ declare(strict_types=1); +use DrupalRector\Drupal10\Rector\Deprecation\VersionedFunctionToServiceRector; +use DrupalRector\Drupal10\Rector\ValueObject\VersionedFunctionToServiceConfiguration; use DrupalRector\Rector\Deprecation\FunctionToStaticRector; use DrupalRector\Rector\Deprecation\MethodToMethodWithCheckRector; use DrupalRector\Rector\ValueObject\FunctionToStaticConfiguration; @@ -24,4 +26,9 @@ new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'getResource', 'getImage'), new MethodToMethodWithCheckConfiguration('Drupal\system\Plugin\ImageToolkit\GDToolkit', 'setResource', 'setImage'), ]); + + // https://www.drupal.org/node/3358337 + $rectorConfig->ruleWithConfiguration(VersionedFunctionToServiceRector::class, [ + new VersionedFunctionToServiceConfiguration('10.2.0', '_drupal_flush_css_js', 'asset.query_string', 'reset'), + ]); }; diff --git a/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector.php b/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector.php new file mode 100644 index 00000000..4b166826 --- /dev/null +++ b/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector.php @@ -0,0 +1,84 @@ +getName($node->name) === $configuration->getDeprecatedFunctionName()) { + // This creates a service call like `\Drupal::service('file_system'). + $service = new Node\Expr\StaticCall(new Node\Name\FullyQualified('Drupal'), 'service', [new Node\Arg(new Node\Scalar\String_($configuration->getServiceName()))]); + + $method_name = new Node\Identifier($configuration->getServiceMethodName()); + + return new Node\Expr\MethodCall($service, $method_name, $node->args); + } + + return null; + } + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition('Fixes deprecated function to service calls, used in Drupal 8 and 9 deprecations', [ + new ConfiguredCodeSample( + <<<'CODE_BEFORE' +_drupal_flush_css_js(); +CODE_BEFORE + , + <<<'CODE_AFTER' +\Drupal::service('asset.query_string')->reset(); +CODE_AFTER + , + [ + new VersionedFunctionToServiceConfiguration('10.2.0', '_drupal_flush_css_js', 'asset.query_string', 'reset'), + ] + ), + ]); + } +} diff --git a/src/Drupal10/Rector/ValueObject/VersionedFunctionToServiceConfiguration.php b/src/Drupal10/Rector/ValueObject/VersionedFunctionToServiceConfiguration.php new file mode 100644 index 00000000..e0068162 --- /dev/null +++ b/src/Drupal10/Rector/ValueObject/VersionedFunctionToServiceConfiguration.php @@ -0,0 +1,55 @@ +deprecatedFunctionName = $deprecatedFunctionName; + $this->serviceName = $serviceName; + $this->serviceMethodName = $serviceMethodName; + $this->introducedVersion = $introducedVersion; + } + + public function getDeprecatedFunctionName(): string + { + return $this->deprecatedFunctionName; + } + + public function getServiceName(): string + { + return $this->serviceName; + } + + public function getServiceMethodName(): string + { + return $this->serviceMethodName; + } + + public function getIntroducedVersion(): string + { + return $this->introducedVersion; + } +} diff --git a/tests/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector/VersionedFunctionToServiceRectorTest.php b/tests/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector/VersionedFunctionToServiceRectorTest.php new file mode 100644 index 00000000..930edc55 --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector/VersionedFunctionToServiceRectorTest.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/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector/config/configured_rule.php b/tests/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector/config/configured_rule.php new file mode 100644 index 00000000..24b63efd --- /dev/null +++ b/tests/src/Drupal10/Rector/Deprecation/VersionedFunctionToServiceRector/config/configured_rule.php @@ -0,0 +1,14 @@ + +----- + \Drupal::service('asset.query_string')->reset(), fn() => _drupal_flush_css_js()); +} +?> From b7fe789a44dcb165f41ff62f159151e579f2b82d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Brala?= Date: Thu, 18 Apr 2024 09:10:00 +0200 Subject: [PATCH 42/46] fix: remove extra \ from Drupal\Core\StringTranslation\ByteSizeMarkup (#301) --- config/drupal-10/drupal-10.2-deprecations.php | 2 +- .../FunctionToStaticRector/config/configured_rule.php | 2 +- .../fixture/function_to_static_call.php.inc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/drupal-10/drupal-10.2-deprecations.php b/config/drupal-10/drupal-10.2-deprecations.php index 869a4838..7dcc09e2 100644 --- a/config/drupal-10/drupal-10.2-deprecations.php +++ b/config/drupal-10/drupal-10.2-deprecations.php @@ -16,7 +16,7 @@ // https://www.drupal.org/node/2999981 $rectorConfig->ruleWithConfiguration(FunctionToStaticRector::class, [ - new FunctionToStaticConfiguration('10.2.0', 'format_size', '\Drupal\Core\StringTranslation\ByteSizeMarkup', 'create'), + new FunctionToStaticConfiguration('10.2.0', 'format_size', 'Drupal\Core\StringTranslation\ByteSizeMarkup', 'create'), ]); // https://www.drupal.org/node/3265963 diff --git a/tests/src/Rector/Deprecation/FunctionToStaticRector/config/configured_rule.php b/tests/src/Rector/Deprecation/FunctionToStaticRector/config/configured_rule.php index eba3a534..c3777670 100644 --- a/tests/src/Rector/Deprecation/FunctionToStaticRector/config/configured_rule.php +++ b/tests/src/Rector/Deprecation/FunctionToStaticRector/config/configured_rule.php @@ -11,6 +11,6 @@ DeprecationBase::addClass(FunctionToStaticRector::class, $rectorConfig, false, [ new FunctionToStaticConfiguration('8.1.0', 'file_directory_os_temp', 'Drupal\Component\FileSystem\FileSystem', 'getOsTemporaryDirectory'), new FunctionToStaticConfiguration('10.1.0', 'drupal_rewrite_settings', 'Drupal\Core\Site\SettingsEditor', 'rewrite', [0 => 1, 1 => 0]), - new FunctionToStaticConfiguration('10.2.0', 'format_size', '\Drupal\Core\StringTranslation\ByteSizeMarkup', 'create'), + new FunctionToStaticConfiguration('10.2.0', 'format_size', 'Drupal\Core\StringTranslation\ByteSizeMarkup', 'create'), ]); }; diff --git a/tests/src/Rector/Deprecation/FunctionToStaticRector/fixture/function_to_static_call.php.inc b/tests/src/Rector/Deprecation/FunctionToStaticRector/fixture/function_to_static_call.php.inc index 2f2d5767..9d42c5d2 100644 --- a/tests/src/Rector/Deprecation/FunctionToStaticRector/fixture/function_to_static_call.php.inc +++ b/tests/src/Rector/Deprecation/FunctionToStaticRector/fixture/function_to_static_call.php.inc @@ -34,6 +34,6 @@ function simple_example_os_temp() { } function simple_example_format_size() { - $size_literal = \Drupal\Component\Utility\DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.2.0', fn() => \\Drupal\Core\StringTranslation\ByteSizeMarkup::create(81862076662), fn() => format_size(81862076662)); + $size_literal = \Drupal\Component\Utility\DeprecationHelper::backwardsCompatibleCall(\Drupal::VERSION, '10.2.0', fn() => \Drupal\Core\StringTranslation\ByteSizeMarkup::create(81862076662), fn() => format_size(81862076662)); } ?> From 3cbbcd2bc39d5ce7e3ec409e64414afad0336ca5 Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 11 Mar 2024 10:54:38 +0100 Subject: [PATCH 43/46] Refactor to configurable rule --- .../Deprecation/FunctionToServiceRector.php | 48 ++++++++++--------- .../FunctionToServiceConfiguration.php | 14 +++++- 2 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/Rector/Deprecation/FunctionToServiceRector.php b/src/Rector/Deprecation/FunctionToServiceRector.php index 3465c936..4b08d0ad 100644 --- a/src/Rector/Deprecation/FunctionToServiceRector.php +++ b/src/Rector/Deprecation/FunctionToServiceRector.php @@ -4,6 +4,8 @@ namespace DrupalRector\Rector\Deprecation; +use DrupalRector\Contract\VersionedConfigurationInterface; +use DrupalRector\Rector\AbstractDrupalCoreRector; use DrupalRector\Rector\ValueObject\FunctionToServiceConfiguration; use PhpParser\Node; use Rector\Contract\Rector\ConfigurableRectorInterface; @@ -20,12 +22,12 @@ * Improvement opportunities * - Dependency injection */ -class FunctionToServiceRector extends AbstractRector implements ConfigurableRectorInterface +class FunctionToServiceRector extends AbstractDrupalCoreRector { /** * @var FunctionToServiceConfiguration[] */ - private array $functionToServiceConfigs; + protected array $configuration; public function configure(array $configuration): void { @@ -35,7 +37,7 @@ public function configure(array $configuration): void } } - $this->functionToServiceConfigs = $configuration; + $this->configuration = $configuration; } /** @@ -51,10 +53,11 @@ public function getNodeTypes(): array /** * {@inheritdoc} */ - public function refactor(Node $node): ?Node + public function refactorWithConfiguration(Node $node, VersionedConfigurationInterface $configuration): ?Node { - foreach ($this->functionToServiceConfigs as $configuration) { - /** @var Node\Expr\FuncCall $node */ + assert($configuration instanceof FunctionToServiceConfiguration); + assert($node instanceof Node\Expr\FuncCall); + if ($this->getName($node->name) === $configuration->getDeprecatedFunctionName()) { // This creates a service call like `\Drupal::service('file_system'). $service = new Node\Expr\StaticCall(new Node\Name\FullyQualified('Drupal'), 'service', [new Node\Arg(new Node\Scalar\String_($configuration->getServiceName()))]); @@ -63,7 +66,6 @@ public function refactor(Node $node): ?Node return new Node\Expr\MethodCall($service, $method_name, $node->args); } - } return null; } @@ -82,7 +84,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('drupal_realpath', 'file_system', 'realpath'), + new FunctionToServiceConfiguration('8.0.0', 'drupal_realpath', 'file_system', 'realpath'), ] ), new ConfiguredCodeSample( @@ -95,7 +97,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('drupal_render', 'renderer', 'render'), + new FunctionToServiceConfiguration('8.0.0', 'drupal_render', 'renderer', 'render'), ] ), new ConfiguredCodeSample( @@ -108,7 +110,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('drupal_render_root', 'renderer', 'renderRoot'), + new FunctionToServiceConfiguration('8.0.0', 'drupal_render_root', 'renderer', 'renderRoot'), ] ), new ConfiguredCodeSample( @@ -122,7 +124,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('entity_get_display', 'entity_display.repository', 'getViewDisplay'), + new FunctionToServiceConfiguration('8.8.0', 'entity_get_display', 'entity_display.repository', 'getViewDisplay'), ] ), new ConfiguredCodeSample( @@ -136,7 +138,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('entity_get_form_display', 'entity_display.repository', 'getFormDisplay'), + new FunctionToServiceConfiguration('8.8.0', 'entity_get_form_display', 'entity_display.repository', 'getFormDisplay'), ] ), new ConfiguredCodeSample( @@ -149,7 +151,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('file_copy', 'file.repository', 'copy'), + new FunctionToServiceConfiguration('9.3.0', 'file_copy', 'file.repository', 'copy'), ] ), new ConfiguredCodeSample( @@ -162,7 +164,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('file_directory_temp', 'file_system', 'getTempDirectory'), + new FunctionToServiceConfiguration('8.0.0', 'file_directory_temp', 'file_system', 'getTempDirectory'), ] ), new ConfiguredCodeSample( @@ -175,7 +177,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('file_move', 'file.repository', 'move'), + new FunctionToServiceConfiguration('9.3.0', 'file_move', 'file.repository', 'move'), ] ), new ConfiguredCodeSample( @@ -188,7 +190,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('file_prepare_directory', 'file_system', 'prepareDirectory'), + new FunctionToServiceConfiguration('8.7.0', 'file_prepare_directory', 'file_system', 'prepareDirectory'), ] ), new ConfiguredCodeSample( @@ -201,7 +203,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('file_save_data', 'file.repository', 'writeData'), + new FunctionToServiceConfiguration('8.7.0', 'file_save_data', 'file.repository', 'writeData'), ] ), new ConfiguredCodeSample( @@ -214,7 +216,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('file_scan_directory', 'file_system', 'scanDirectory'), + new FunctionToServiceConfiguration('8.8.0', 'file_scan_directory', 'file_system', 'scanDirectory'), ] ), new ConfiguredCodeSample( @@ -227,7 +229,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('file_unmanaged_save_data', 'file_system', 'saveData'), + new FunctionToServiceConfiguration('9.3.0', 'file_unmanaged_save_data', 'file_system', 'saveData'), ] ), new ConfiguredCodeSample( @@ -240,7 +242,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('file_uri_target', 'stream_wrapper_manager', 'getTarget'), + new FunctionToServiceConfiguration('8.8.0', 'file_uri_target', 'stream_wrapper_manager', 'getTarget'), ] ), new ConfiguredCodeSample( @@ -253,7 +255,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('format_date', 'date.formatter', 'format'), + new FunctionToServiceConfiguration('8.0.0', 'format_date', 'date.formatter', 'format'), ] ), new ConfiguredCodeSample( @@ -266,7 +268,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('format_date', 'date.formatter', 'format'), + new FunctionToServiceConfiguration('8.0.0' , 'format_date', 'date.formatter', 'format'), ] ), new ConfiguredCodeSample( @@ -279,7 +281,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('render', 'renderer', 'render'), + new FunctionToServiceConfiguration('9.3.0', 'render', 'renderer', 'render'), ] ), ]); diff --git a/src/Rector/ValueObject/FunctionToServiceConfiguration.php b/src/Rector/ValueObject/FunctionToServiceConfiguration.php index c48ea3c1..7a8e4de1 100644 --- a/src/Rector/ValueObject/FunctionToServiceConfiguration.php +++ b/src/Rector/ValueObject/FunctionToServiceConfiguration.php @@ -4,7 +4,9 @@ namespace DrupalRector\Rector\ValueObject; -class FunctionToServiceConfiguration +use DrupalRector\Contract\VersionedConfigurationInterface; + +class FunctionToServiceConfiguration implements VersionedConfigurationInterface { /** * The deprecated function name. @@ -21,11 +23,14 @@ class FunctionToServiceConfiguration */ protected string $serviceMethodName; - public function __construct(string $deprecatedFunctionName, string $serviceName, string $serviceMethodName) + protected string $introducedVersion; + + public function __construct(string $introducedVersion, string $deprecatedFunctionName, string $serviceName, string $serviceMethodName) { $this->deprecatedFunctionName = $deprecatedFunctionName; $this->serviceName = $serviceName; $this->serviceMethodName = $serviceMethodName; + $this->introducedVersion = $introducedVersion; } public function getDeprecatedFunctionName(): string @@ -42,4 +47,9 @@ public function getServiceMethodName(): string { return $this->serviceMethodName; } + + public function getIntroducedVersion(): string { + return $this->introducedVersion; + } + } From 5bd0087d952f8975bee119c1977b910a57175a60 Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 11 Mar 2024 10:54:46 +0100 Subject: [PATCH 44/46] add test --- .../config/configured_rule.php | 9 ++++---- .../fixture/drupal_theme_rebuild.php.inc | 21 +++++++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 tests/src/Rector/Deprecation/FunctionToServiceRector/fixture/drupal_theme_rebuild.php.inc diff --git a/tests/src/Rector/Deprecation/FunctionToServiceRector/config/configured_rule.php b/tests/src/Rector/Deprecation/FunctionToServiceRector/config/configured_rule.php index 7807be5d..984b6730 100644 --- a/tests/src/Rector/Deprecation/FunctionToServiceRector/config/configured_rule.php +++ b/tests/src/Rector/Deprecation/FunctionToServiceRector/config/configured_rule.php @@ -9,9 +9,10 @@ return static function (RectorConfig $rectorConfig): void { DeprecationBase::addClass(FunctionToServiceRector::class, $rectorConfig, false, [ - new FunctionToServiceConfiguration('render', 'renderer', 'render'), - new FunctionToServiceConfiguration('file_copy', 'file.repository', 'copy'), - new FunctionToServiceConfiguration('file_move', 'file.repository', 'move'), - new FunctionToServiceConfiguration('file_save_data', 'file.repository', 'writeData'), + new FunctionToServiceConfiguration('9.3.0', 'render', 'renderer', 'render'), + new FunctionToServiceConfiguration('8.0.0', 'file_copy', 'file.repository', 'copy'), + new FunctionToServiceConfiguration('9.3.0', 'file_move', 'file.repository', 'move'), + new FunctionToServiceConfiguration('9.3.0', 'file_save_data', 'file.repository', 'writeData'), + new FunctionToServiceConfiguration('10.1.0', 'drupal_theme_rebuild', 'theme.registry', 'reset'), ]); }; diff --git a/tests/src/Rector/Deprecation/FunctionToServiceRector/fixture/drupal_theme_rebuild.php.inc b/tests/src/Rector/Deprecation/FunctionToServiceRector/fixture/drupal_theme_rebuild.php.inc new file mode 100644 index 00000000..b3eb1fc3 --- /dev/null +++ b/tests/src/Rector/Deprecation/FunctionToServiceRector/fixture/drupal_theme_rebuild.php.inc @@ -0,0 +1,21 @@ + \Drupal::service('theme.registry')->reset(), fn() => drupal_theme_rebuild()); +} + From 7f08987f594dce3a566a835629c3bbf3548c449b Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 11 Mar 2024 10:55:03 +0100 Subject: [PATCH 45/46] Refactor old rules to new configuration object --- config/drupal-8/drupal-8.0-deprecations.php | 8 ++++---- config/drupal-8/drupal-8.7-deprecations.php | 4 ++-- config/drupal-8/drupal-8.8-deprecations.php | 10 +++++----- config/drupal-9/drupal-9.3-deprecations.php | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/config/drupal-8/drupal-8.0-deprecations.php b/config/drupal-8/drupal-8.0-deprecations.php index 9acf9045..ac787c6a 100644 --- a/config/drupal-8/drupal-8.0-deprecations.php +++ b/config/drupal-8/drupal-8.0-deprecations.php @@ -43,13 +43,13 @@ $rectorConfig->ruleWithConfiguration(FunctionToServiceRector::class, [ // https://www.drupal.org/node/2418133 - new FunctionToServiceConfiguration('drupal_realpath', 'file_system', 'realpath'), + new FunctionToServiceConfiguration('8.0.0', 'drupal_realpath', 'file_system', 'realpath'), // https://www.drupal.org/node/2912696 - new FunctionToServiceConfiguration('drupal_render', 'renderer', 'render'), + new FunctionToServiceConfiguration('8.0.0', 'drupal_render', 'renderer', 'render'), // https://www.drupal.org/node/2912696 - new FunctionToServiceConfiguration('drupal_render_root', 'renderer', 'renderRoot'), + new FunctionToServiceConfiguration('8.0.0', 'drupal_render_root', 'renderer', 'renderRoot'), // https://www.drupal.org/node/1876852 - new FunctionToServiceConfiguration('format_date', 'date.formatter', 'format'), + new FunctionToServiceConfiguration('8.0.0', 'format_date', 'date.formatter', 'format'), ]); $rectorConfig->rule(EntityInterfaceLinkRector::class); diff --git a/config/drupal-8/drupal-8.7-deprecations.php b/config/drupal-8/drupal-8.7-deprecations.php index e21f5eda..1942122b 100644 --- a/config/drupal-8/drupal-8.7-deprecations.php +++ b/config/drupal-8/drupal-8.7-deprecations.php @@ -15,9 +15,9 @@ }); $rectorConfig->ruleWithConfiguration(FunctionToServiceRector::class, [ // https://www.drupal.org/node/3006851 - new FunctionToServiceConfiguration('file_prepare_directory', 'file_system', 'prepareDirectory'), + new FunctionToServiceConfiguration('8.7.0', 'file_prepare_directory', 'file_system', 'prepareDirectory'), // https://www.drupal.org/node/3006851 - new FunctionToServiceConfiguration('file_unmanaged_save_data', 'file_system', 'saveData'), + new FunctionToServiceConfiguration('8.7.0', 'file_unmanaged_save_data', 'file_system', 'saveData'), ]); /** diff --git a/config/drupal-8/drupal-8.8-deprecations.php b/config/drupal-8/drupal-8.8-deprecations.php index 40360618..ad10ee45 100644 --- a/config/drupal-8/drupal-8.8-deprecations.php +++ b/config/drupal-8/drupal-8.8-deprecations.php @@ -30,15 +30,15 @@ $rectorConfig->ruleWithConfiguration(FunctionToServiceRector::class, [ // https://www.drupal.org/node/2835616 - new FunctionToServiceConfiguration('entity_get_display', 'entity_display.repository', 'getViewDisplay'), + new FunctionToServiceConfiguration('8.8.0', 'entity_get_display', 'entity_display.repository', 'getViewDisplay'), // https://www.drupal.org/node/2835616 - new FunctionToServiceConfiguration('entity_get_form_display', 'entity_display.repository', 'getFormDisplay'), + new FunctionToServiceConfiguration('8.8.0', 'entity_get_form_display', 'entity_display.repository', 'getFormDisplay'), // https://www.drupal.org/node/3039255 - new FunctionToServiceConfiguration('file_directory_temp', 'file_system', 'getTempDirectory'), + new FunctionToServiceConfiguration('8.8.0', 'file_directory_temp', 'file_system', 'getTempDirectory'), // https://www.drupal.org/node/3038437 - new FunctionToServiceConfiguration('file_scan_directory', 'file_system', 'scanDirectory'), + new FunctionToServiceConfiguration('8.8.0', 'file_scan_directory', 'file_system', 'scanDirectory'), // https://www.drupal.org/node/3035273 - new FunctionToServiceConfiguration('file_uri_target', 'stream_wrapper_manager', 'getTarget'), + new FunctionToServiceConfiguration('8.8.0', 'file_uri_target', 'stream_wrapper_manager', 'getTarget'), ]); $rectorConfig->ruleWithConfiguration(MethodToMethodWithCheckRector::class, [ diff --git a/config/drupal-9/drupal-9.3-deprecations.php b/config/drupal-9/drupal-9.3-deprecations.php index f93b1445..c51996a4 100644 --- a/config/drupal-9/drupal-9.3-deprecations.php +++ b/config/drupal-9/drupal-9.3-deprecations.php @@ -39,11 +39,11 @@ // Change record: https://www.drupal.org/node/3223520 $rectorConfig->ruleWithConfiguration(FunctionToServiceRector::class, [ - new FunctionToServiceConfiguration('file_copy', 'file.repository', 'copy'), - new FunctionToServiceConfiguration('file_move', 'file.repository', 'move'), - new FunctionToServiceConfiguration('file_save_data', 'file.repository', 'writeData'), + new FunctionToServiceConfiguration('9.3.0', 'file_copy', 'file.repository', 'copy'), + new FunctionToServiceConfiguration('9.3.0', 'file_move', 'file.repository', 'move'), + new FunctionToServiceConfiguration('9.3.0', 'file_save_data', 'file.repository', 'writeData'), // Change record: https://www.drupal.org/node/2939099 - new FunctionToServiceConfiguration('render', 'renderer', 'render'), + new FunctionToServiceConfiguration('9.3.0', 'render', 'renderer', 'render'), ]); // Change record: https://www.drupal.org/node/3223091. From 213cddee258370c5e9338f4e1d715fc7009dc23e Mon Sep 17 00:00:00 2001 From: bjorn Date: Mon, 11 Mar 2024 10:57:50 +0100 Subject: [PATCH 46/46] Fix codestyle --- .../Deprecation/FunctionToServiceRector.php | 16 +++++++--------- .../FunctionToServiceConfiguration.php | 4 ++-- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/Rector/Deprecation/FunctionToServiceRector.php b/src/Rector/Deprecation/FunctionToServiceRector.php index 4b08d0ad..26b5a7ef 100644 --- a/src/Rector/Deprecation/FunctionToServiceRector.php +++ b/src/Rector/Deprecation/FunctionToServiceRector.php @@ -8,8 +8,6 @@ use DrupalRector\Rector\AbstractDrupalCoreRector; use DrupalRector\Rector\ValueObject\FunctionToServiceConfiguration; use PhpParser\Node; -use Rector\Contract\Rector\ConfigurableRectorInterface; -use Rector\Rector\AbstractRector; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -58,14 +56,14 @@ public function refactorWithConfiguration(Node $node, VersionedConfigurationInte assert($configuration instanceof FunctionToServiceConfiguration); assert($node instanceof Node\Expr\FuncCall); - if ($this->getName($node->name) === $configuration->getDeprecatedFunctionName()) { - // This creates a service call like `\Drupal::service('file_system'). - $service = new Node\Expr\StaticCall(new Node\Name\FullyQualified('Drupal'), 'service', [new Node\Arg(new Node\Scalar\String_($configuration->getServiceName()))]); + if ($this->getName($node->name) === $configuration->getDeprecatedFunctionName()) { + // This creates a service call like `\Drupal::service('file_system'). + $service = new Node\Expr\StaticCall(new Node\Name\FullyQualified('Drupal'), 'service', [new Node\Arg(new Node\Scalar\String_($configuration->getServiceName()))]); - $method_name = new Node\Identifier($configuration->getServiceMethodName()); + $method_name = new Node\Identifier($configuration->getServiceMethodName()); - return new Node\Expr\MethodCall($service, $method_name, $node->args); - } + return new Node\Expr\MethodCall($service, $method_name, $node->args); + } return null; } @@ -268,7 +266,7 @@ public function getRuleDefinition(): RuleDefinition CODE_AFTER , [ - new FunctionToServiceConfiguration('8.0.0' , 'format_date', 'date.formatter', 'format'), + new FunctionToServiceConfiguration('8.0.0', 'format_date', 'date.formatter', 'format'), ] ), new ConfiguredCodeSample( diff --git a/src/Rector/ValueObject/FunctionToServiceConfiguration.php b/src/Rector/ValueObject/FunctionToServiceConfiguration.php index 7a8e4de1..737aaeb1 100644 --- a/src/Rector/ValueObject/FunctionToServiceConfiguration.php +++ b/src/Rector/ValueObject/FunctionToServiceConfiguration.php @@ -48,8 +48,8 @@ public function getServiceMethodName(): string return $this->serviceMethodName; } - public function getIntroducedVersion(): string { + public function getIntroducedVersion(): string + { return $this->introducedVersion; } - }