Skip to content

Commit

Permalink
New rector (9.1): ClassConstantToClassConstantRector to rename class …
Browse files Browse the repository at this point in the history
…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 <[email protected]>
  • Loading branch information
bbrala and agentrickard authored Mar 8, 2024
1 parent 4ad1fc5 commit 2af405c
Show file tree
Hide file tree
Showing 15 changed files with 301 additions and 31 deletions.
4 changes: 2 additions & 2 deletions config/drupal-8/drupal-8.5-deprecations.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
4 changes: 2 additions & 2 deletions config/drupal-8/drupal-8.7-deprecations.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
24 changes: 24 additions & 0 deletions config/drupal-9/drupal-9.1-deprecations.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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',
),
]);
};
4 changes: 2 additions & 2 deletions config/drupal-9/drupal-9.3-deprecations.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
34 changes: 17 additions & 17 deletions docs/rules_overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

- [Drupal10](#drupal10) (2)

- [Drupal8](#drupal8) (19)
- [Drupal8](#drupal8) (18)

- [Drupal9](#drupal9) (26)

- [DrupalRector](#drupalrector) (5)
- [DrupalRector](#drupalrector) (6)

<br>

Expand Down Expand Up @@ -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);
```

<br>

### DBRector

Fixes deprecated `db_delete()` calls
Expand Down Expand Up @@ -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);
```

<br>

### DeprecationHelperRemoveRector

Remove DeprecationHelper calls for versions before configured minimum requirement
Expand Down
112 changes: 112 additions & 0 deletions src/Rector/Deprecation/ClassConstantToClassConstantRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

declare(strict_types=1);

namespace DrupalRector\Rector\Deprecation;

use DrupalRector\Rector\ValueObject\ClassConstantToClassConstantConfiguration;
use DrupalRector\Rector\ValueObject\ConstantToClassConfiguration;
use PhpParser\Node;
use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

/**
* Replaces deprecated constant with class constant.
*
* What is covered:
* - Replacement with a use statement.
*/
class ClassConstantToClassConstantRector extends AbstractRector implements ConfigurableRectorInterface
{
/**
* @var ClassConstantToClassConstantConfiguration[]
*/
private array $constantToClassRenames;

public function configure(array $configuration): void
{
foreach ($configuration as $value) {
if (!($value instanceof ClassConstantToClassConstantConfiguration)) {
throw new \InvalidArgumentException(sprintf('Each configuration item must be an instance of "%s"', ConstantToClassConfiguration::class));
}
}

$this->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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -20,7 +20,7 @@
class ConstantToClassConstantRector extends AbstractRector implements ConfigurableRectorInterface
{
/**
* @var \DrupalRector\Drupal8\Rector\ValueObject\ConstantToClassConfiguration[]
* @var ConstantToClassConfiguration[]
*/
private array $constantToClassRenames;

Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?php

declare(strict_types=1);

namespace DrupalRector\Rector\ValueObject;

use Rector\Validation\RectorAssert;

final class ClassConstantToClassConstantConfiguration
{
private string $deprecated;
private string $class;
private string $constant;

private string $deprecatedClass;

public function __construct(string $deprecatedClass, string $deprecated, string $class, string $constant)
{
$this->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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace DrupalRector\Drupal8\Rector\ValueObject;
namespace DrupalRector\Rector\ValueObject;

use Rector\Validation\RectorAssert;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace DrupalRector\Rector\Deprecation\ClassConstantToClassConstantRector;

use Iterator;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

class ClassConstantToClassConstantRectorTest extends AbstractRectorTestCase
{
/**
* @covers ::refactor
*
* @dataProvider provideData
*/
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

/**
* @return Iterator<<string>>
*/
public static function provideData(): \Iterator
{
return self::yieldFilesFromDirectory(__DIR__.'/fixture');
}

public function provideConfigFilePath(): string
{
// must be implemented
return __DIR__.'/config/configured_rule.php';
}
}
Loading

0 comments on commit 2af405c

Please sign in to comment.