Skip to content

Commit

Permalink
IBX-8534: Added rule for replacing interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
ViniTou committed Sep 16, 2024
1 parent f13f869 commit 7671886
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/contracts/Sets/ibexa-50.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

use Ibexa\Rector\Rule\PropertyToGetterRector;
use Ibexa\Rector\Rule\RemoveArgumentFromMethodCallRector;
use Ibexa\Rector\Rule\ReplaceInterfaceRector;
use Rector\Config\RectorConfig;
use Rector\Renaming\Rector\ClassConstFetch\RenameClassConstFetchRector;
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
Expand Down Expand Up @@ -114,4 +115,12 @@
],
]
);

$rectorConfig->ruleWithConfiguration(
ReplaceInterfaceRector::class,
[
'to_replace' => 'Ibexa\Bundle\Core\Imagine\VariationPathGenerator',
'replace_with' => 'Ibexa\Contracts\Core\Variation\VariationPathGenerator',
]
);
};
74 changes: 74 additions & 0 deletions src/lib/Rule/ReplaceInterfaceRector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Rector\Rule;

use PhpParser\Node;
use PhpParser\Node\Name;
use PhpParser\Node\Stmt\Class_;
use Rector\Contract\Rector\ConfigurableRectorInterface;
use Rector\Rector\AbstractRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;

final class ReplaceInterfaceRector extends AbstractRector implements ConfigurableRectorInterface
{
/** @var class-string */
private string $interfaceToBeReplaced;

/** @var class-string */
private string $interfaceToReplaceWith;

/**
* @throws \Exception
*/
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Replace OldInterface with NewInterface', [new ConfiguredCodeSample(
<<<'CODE_SAMPLE'
class SomeClass implements OldInterface
{
}
CODE_SAMPLE,
<<<'CODE_SAMPLE'
class SomeClass implements NewInterface
{
}
CODE_SAMPLE,
['var_dump']
)]);
}

/**
* @return array<class-string<Node>>
*/
public function getNodeTypes(): array
{
return [Class_::class];
}

/**
* @param \PhpParser\Node\Stmt\Class_ $node
*/
public function refactor(Node $node): ?Node
{
foreach ($node->implements as $key => $implement) {
if ($this->isName($implement, $this->interfaceToBeReplaced)) {
$node->implements[$key] = new Name($this->interfaceToReplaceWith);
}
}

return $node;
}

public function configure(array $configuration): void
{
$this->interfaceToBeReplaced = $configuration['to_replace'];
$this->interfaceToReplaceWith = $configuration['replace_with'];
}
}
19 changes: 19 additions & 0 deletions tests/lib/Rule/ReplaceInterfaceRector/Fixture/some_class.php.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php /** @noinspection ALL */

namespace Ibexa\Rector\Tests\Rule\ReplaceInterfaceRector\Fixture;

class SomeClass implements \SomeInterface
{
}

?>
-----
<?php /** @noinspection ALL */

namespace Ibexa\Rector\Tests\Rule\ReplaceInterfaceRector\Fixture;

class SomeClass implements SomeOtherInterface
{
}

?>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Rector\Tests\Rule\ReplaceInterfaceRector;

use PHPUnit\Framework\Attributes\DataProvider;
use Rector\Testing\PHPUnit\AbstractRectorTestCase;

final class ReplaceInterfaceRectorTest extends AbstractRectorTestCase
{
/**
* @throws \Rector\Exception\ShouldNotHappenException
*/
#[DataProvider('provideData')]
public function test(string $filePath): void
{
$this->doTestFile($filePath);
}

public static function provideData(): \Iterator
{
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
}

public function provideConfigFilePath(): string
{
return __DIR__ . '/config/configured_rule.php';
}
}
21 changes: 21 additions & 0 deletions tests/lib/Rule/ReplaceInterfaceRector/config/configured_rule.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

Check warning on line 1 in tests/lib/Rule/ReplaceInterfaceRector/config/configured_rule.php

View workflow job for this annotation

GitHub Actions / Run code style check (8.3)

Found violation(s) of type: trailing_comma_in_multiline

Check warning on line 1 in tests/lib/Rule/ReplaceInterfaceRector/config/configured_rule.php

View workflow job for this annotation

GitHub Actions / Run code style check (8.3)

Found violation(s) of type: no_unused_imports

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

use Ibexa\Rector\Rule\PropertyToGetterRector;
use Ibexa\Rector\Rule\ReplaceInterfaceRector;
use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig->ruleWithConfiguration(
ReplaceInterfaceRector::class,
[
'to_replace' => 'SomeInterface',
'replace_with' => 'SomeOtherInterface'
]
);
};
23 changes: 23 additions & 0 deletions tests/lib/Sets/Ibexa50/Fixture/rename_variation_interface.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace Ibexa\Rector\Tests\Sets\Ibexa50\Fixture;

use Ibexa\Bundle\Core\Imagine\VariationPathGenerator;

class SomeFormatVariationGenerator implements VariationPathGenerator
{
}

?>
-----
<?php

namespace Ibexa\Rector\Tests\Sets\Ibexa50\Fixture;

use Ibexa\Contracts\Core\Variation\VariationPathGenerator;

class SomeFormatVariationGenerator implements VariationPathGenerator
{
}

?>

0 comments on commit 7671886

Please sign in to comment.