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. diff --git a/src/Rector/Deprecation/FunctionToServiceRector.php b/src/Rector/Deprecation/FunctionToServiceRector.php index 3465c936..26b5a7ef 100644 --- a/src/Rector/Deprecation/FunctionToServiceRector.php +++ b/src/Rector/Deprecation/FunctionToServiceRector.php @@ -4,10 +4,10 @@ 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; -use Rector\Rector\AbstractRector; use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -20,12 +20,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 +35,7 @@ public function configure(array $configuration): void } } - $this->functionToServiceConfigs = $configuration; + $this->configuration = $configuration; } /** @@ -51,18 +51,18 @@ 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 */ - 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()))]); + assert($configuration instanceof FunctionToServiceConfiguration); + assert($node instanceof Node\Expr\FuncCall); - $method_name = new Node\Identifier($configuration->getServiceMethodName()); + 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()))]); - return new Node\Expr\MethodCall($service, $method_name, $node->args); - } + $method_name = new Node\Identifier($configuration->getServiceMethodName()); + + return new Node\Expr\MethodCall($service, $method_name, $node->args); } return null; @@ -82,7 +82,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 +95,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 +108,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 +122,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 +136,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 +149,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 +162,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 +175,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 +188,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 +201,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 +214,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 +227,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 +240,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 +253,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 +266,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 +279,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..737aaeb1 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; + } } 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()); +} +