Skip to content

Commit

Permalink
[Transform] Skip transitional interface in AddInterfaceByTraitRector (#…
Browse files Browse the repository at this point in the history
…2898)

Co-authored-by: buffcode <buffcode@users.noreply.github.com>
  • Loading branch information
TomasVotruba and buffcode committed Sep 2, 2022
1 parent e9bcacc commit a911c08
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 26 deletions.
12 changes: 0 additions & 12 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,6 @@ parameters:
paths:
- src/Rector/AbstractRector.php

- '#Cannot call method getSmartFileInfo\(\) on Rector\\Core\\ValueObject\\Application\\File\|null#'

- '#Method Rector\\BetterPhpDocParser\\PhpDocParser\\BetterPhpDocParser\:\:parseChildAndStoreItsPositions\(\) should return PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTagNode\|PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocTextNode but returns PHPStan\\PhpDocParser\\Ast\\PhpDoc\\PhpDocChildNode#'

# deserves better architecture
Expand Down Expand Up @@ -386,7 +384,6 @@ parameters:
- rules/EarlyReturn/Rector/If_/ChangeNestedIfsToEarlyReturnRector.php
- rules/Php70/EregToPcreTransformer.php
- rules/CodeQuality/Rector/PropertyFetch/ExplicitMethodCallOverMagicGetSetRector.php
- src/Kernel/RectorKernel.php
- rules/Php72/Rector/Assign/ReplaceEachAssignmentWithKeyCurrentRector.php
- rules/PSR4/Rector/FileWithoutNamespace/NormalizeNamespaceByPSR4ComposerAutoloadRector.php

Expand Down Expand Up @@ -730,9 +727,6 @@ parameters:
message: '#Creating new PHPStan\\Parser\\(CachedParser|SimpleParser) is not covered by backward compatibility promise\. The class might change in a minor PHPStan version#'
path: packages/PhpDocParser/PhpParser/SmartPhpParserFactory.php

# allowed
- '#Instead of "Symfony\\Component\\Filesystem\\Filesystem" class/interface use "Symplify\\SmartFileSystem\\SmartFileSystem"#'

# used in a trait
- '#Class constant "TEMP_FIXTURE_DIRECTORY" is never used#'

Expand Down Expand Up @@ -760,12 +754,6 @@ parameters:
- rules/TypeDeclaration/TypeInferer/ParamTypeInferer/PHPUnitDataProviderParamTypeInferer.php
- packages/NodeTypeResolver/NodeTypeResolver/ParamTypeResolver.php

-
message: '#Content of method "areExclusiveExprReturns\(\)" is duplicated\. Use unique content or service instead#'
paths:
- rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictNativeFunctionReturnTypeAnalyzer.php
- rules/TypeDeclaration/NodeAnalyzer/ReturnTypeAnalyzer/StrictReturnNewAnalyzer.php

-
message: '#Content of method "resolveAssignVar\(\)" is duplicated\. Use unique content or service instead#'
paths:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Fixture;

use Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Source\AnotherTrait;
use Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Source\MiddleInterface;

final class SkipTransitionalInterface implements MiddleInterface
{
use AnotherTrait;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
declare(strict_types=1);

namespace Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Source;

trait AnotherTrait
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Source;

interface MiddleInterface extends TopMostInterface
{

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Source;

interface TopMostInterface
{

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Source\AnotherTrait;
use Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Source\SomeInterface;
use Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Source\SomeTrait;
use Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\Source\TopMostInterface;
use Rector\Transform\Rector\Class_\AddInterfaceByTraitRector;

return static function (RectorConfig $rectorConfig): void {
$rectorConfig
->ruleWithConfiguration(AddInterfaceByTraitRector::class, [
SomeTrait::class => SomeInterface::class,
AnotherTrait::class => TopMostInterface::class,
]);
};
21 changes: 7 additions & 14 deletions rules/Transform/Rector/Class_/AddInterfaceByTraitRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,24 @@
use PhpParser\Node;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\Class_;
use PHPStan\Analyser\Scope;
use PHPStan\Reflection\ClassReflection;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Reflection\ReflectionResolver;
use Rector\Core\Rector\AbstractScopeAwareRector;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
use Webmozart\Assert\Assert;

/**
* @see \Rector\Tests\Transform\Rector\Class_\AddInterfaceByTraitRector\AddInterfaceByTraitRectorTest
*/
final class AddInterfaceByTraitRector extends AbstractRector implements ConfigurableRectorInterface
final class AddInterfaceByTraitRector extends AbstractScopeAwareRector implements ConfigurableRectorInterface
{
/**
* @var array<string, string>
*/
private array $interfaceByTrait = [];

public function __construct(private readonly ReflectionResolver $reflectionResolver)
{
}

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Add interface by used trait', [
Expand Down Expand Up @@ -65,9 +61,9 @@ public function getNodeTypes(): array
/**
* @param Class_ $node
*/
public function refactor(Node $node): ?Node
public function refactorWithScope(Node $node, Scope $scope): ?Node
{
$classReflection = $this->reflectionResolver->resolveClassReflection($node);
$classReflection = $scope->getClassReflection();
if (! $classReflection instanceof ClassReflection) {
return null;
}
Expand All @@ -78,10 +74,8 @@ public function refactor(Node $node): ?Node
continue;
}

foreach ($node->implements as $implement) {
if ($this->isName($implement, $interfaceName)) {
continue 2;
}
if ($classReflection->implementsInterface($interfaceName)) {
continue;
}

$node->implements[] = new FullyQualified($interfaceName);
Expand All @@ -96,7 +90,6 @@ public function refactor(Node $node): ?Node
}

/**
* @todo complex configuration, introduce value object!
* @param mixed[] $configuration
*/
public function configure(array $configuration): void
Expand Down

0 comments on commit a911c08

Please sign in to comment.