-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Config - Ignored classes from vendor
- Loading branch information
1 parent
2da4064
commit c7f6304
Showing
5 changed files
with
343 additions
and
272 deletions.
There are no files selected for viewing
50 changes: 50 additions & 0 deletions
50
...andEmbassyCodingStandard/Rector/MabeEnumMethodCallToEnumConstRector/ClassNameProvider.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace BrandEmbassyCodingStandard\Rector\MabeEnumMethodCallToEnumConstRector; | ||
|
||
use PhpParser\Node; | ||
use PHPStan\Type\TypeWithClassName; | ||
use Rector\NodeNameResolver\NodeNameResolver; | ||
use Rector\NodeTypeResolver\NodeTypeResolver; | ||
|
||
/** | ||
* @final | ||
*/ | ||
class ClassNameProvider | ||
{ | ||
public function __construct( | ||
private readonly NodeTypeResolver $nodeTypeResolver, | ||
private readonly NodeNameResolver $nodeNameResolver, | ||
) { | ||
} | ||
|
||
|
||
/** | ||
* @return class-string|null | ||
*/ | ||
public function getClassNameFromVar(Node $node): ?string | ||
{ | ||
$type = $this->nodeTypeResolver->getType($node); | ||
|
||
if (!$type instanceof TypeWithClassName) { | ||
return null; | ||
} | ||
|
||
/** @var class-string $className */ | ||
$className = $type->getClassName(); | ||
|
||
return $className; | ||
} | ||
|
||
|
||
/** | ||
* @return class-string|null | ||
*/ | ||
public function getClassNameFromClass(Node $node): ?string | ||
{ | ||
/** @var class-string|null $name */ | ||
$name = $this->nodeNameResolver->getName($node); | ||
|
||
return $name; | ||
} | ||
} |
35 changes: 0 additions & 35 deletions
35
...Standard/Rector/MabeEnumMethodCallToEnumConstRector/Fixture/mabeEnum_ignored_enum.php.inc
This file was deleted.
Oops, something went wrong.
277 changes: 277 additions & 0 deletions
277
...BrandEmbassyCodingStandard/Rector/MabeEnumMethodCallToEnumConstRector/MabeEnumFactory.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,277 @@ | ||
<?php declare(strict_types = 1); | ||
|
||
namespace BrandEmbassyCodingStandard\Rector\MabeEnumMethodCallToEnumConstRector; | ||
|
||
use PhpParser\Node; | ||
use PhpParser\Node\Arg; | ||
use PhpParser\Node\ArrayItem as ArrayItemNode; | ||
use PhpParser\Node\Expr; | ||
use PhpParser\Node\Expr\Array_; | ||
use PhpParser\Node\Expr\ArrayItem; | ||
use PhpParser\Node\Expr\BinaryOp\Identical; | ||
use PhpParser\Node\Expr\ClassConstFetch; | ||
use PhpParser\Node\Expr\MethodCall; | ||
use PhpParser\Node\Expr\PropertyFetch; | ||
use PhpParser\Node\Expr\StaticCall; | ||
use PhpParser\Node\Expr\Variable; | ||
use PhpParser\Node\Identifier; | ||
use PhpParser\Node\Scalar\String_; | ||
use PHPStan\Type\ObjectType; | ||
use Rector\NodeNameResolver\NodeNameResolver; | ||
use Rector\NodeTypeResolver\NodeTypeResolver; | ||
use Rector\PhpParser\Node\NodeFactory; | ||
use ReflectionClass; | ||
use function array_map; | ||
use function str_contains; | ||
use function strtoupper; | ||
|
||
/** | ||
* @final | ||
*/ | ||
class MabeEnumFactory | ||
{ | ||
private const MABE_ENUM_CLASS_NAME = 'MabeEnum\\Enum'; | ||
|
||
private NodeFactory $nodeFactory; | ||
|
||
private NodeTypeResolver $nodeTypeResolver; | ||
|
||
private NodeNameResolver $nodeNameResolver; | ||
|
||
private ClassNameProvider $classNameProvider; | ||
|
||
private bool $ignoredClassFromVendor = true; | ||
|
||
|
||
public function __construct( | ||
NodeFactory $nodeFactory, | ||
NodeTypeResolver $nodeTypeResolver, | ||
NodeNameResolver $nodeNameResolver, | ||
ClassNameProvider $classNameProvider, | ||
) { | ||
$this->nodeFactory = $nodeFactory; | ||
$this->nodeTypeResolver = $nodeTypeResolver; | ||
$this->nodeNameResolver = $nodeNameResolver; | ||
$this->classNameProvider = $classNameProvider; | ||
} | ||
|
||
|
||
public function createFromNode(StaticCall|MethodCall|Array_ $node, bool $ignoreClassesFromVendor = true): ?Expr | ||
{ | ||
$this->ignoredClassFromVendor = $ignoreClassesFromVendor; | ||
|
||
if ($node instanceof Array_) { | ||
return $this->refactorArray($node); | ||
} | ||
|
||
if ($node->name instanceof Expr) { | ||
return null; | ||
} | ||
|
||
$enumCaseName = $this->nodeNameResolver->getName($node->name); | ||
if ($enumCaseName === null) { | ||
return null; | ||
} | ||
|
||
if ($node instanceof StaticCall) { | ||
return $this->refactorStaticCall($node, $enumCaseName); | ||
} | ||
|
||
return $this->refactorMethodCall($node, $enumCaseName); | ||
} | ||
|
||
|
||
private function refactorArray(Array_ $array): ?Expr | ||
{ | ||
if ($array->items === []) { | ||
return null; | ||
} | ||
|
||
/** @var ArrayItem[] $arrayItems */ | ||
$arrayItems = $array->items; | ||
|
||
/** @var ArrayItemNode[] $refactoredArrayItems */ | ||
$refactoredArrayItems = array_map(fn( | ||
ArrayItem $arrayItem | ||
): ArrayItem => $this->refactorArrayItemKeys($arrayItem), $arrayItems); | ||
|
||
$array->items = $refactoredArrayItems; | ||
|
||
return $array; | ||
} | ||
|
||
|
||
private function refactorArrayItemKeys(ArrayItem $arrayItem): ArrayItem | ||
{ | ||
$key = $arrayItem->key; | ||
|
||
if ($key === null) { | ||
return $arrayItem; | ||
} | ||
|
||
if ($key instanceof ClassConstFetch && $this->isMabeEnum($key->class)) { | ||
$key = $this->createPropertyValueFetch($key); | ||
$arrayItem->key = $key; | ||
} | ||
|
||
return $arrayItem; | ||
} | ||
|
||
|
||
private function createPropertyValueFetch(Expr $expr): PropertyFetch | ||
{ | ||
return $this->nodeFactory->createPropertyFetch($expr, 'value'); | ||
} | ||
|
||
|
||
private function refactorStaticCall(StaticCall $staticCall, string $staticCallName): ?Expr | ||
{ | ||
$className = $this->classNameProvider->getClassNameFromClass($staticCall->class); | ||
|
||
if ($className === null) { | ||
return null; | ||
} | ||
|
||
if ($this->isClassIgnored($className)) { | ||
return null; | ||
} | ||
|
||
if (strtoupper($staticCallName) === $staticCallName) { | ||
return $this->nodeFactory->createClassConstFetch($className, $staticCallName); | ||
} | ||
|
||
if ($staticCallName === 'get') { | ||
return $this->refactorGetStaticCall($staticCall); | ||
} | ||
|
||
if ($staticCallName === 'getEnumerators') { | ||
return $this->nodeFactory->createStaticCall($className, 'cases'); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
|
||
private function refactorMethodCall(MethodCall $methodCall, string $methodName): ?Expr | ||
{ | ||
if (!$this->isMabeEnum($methodCall->var)) { | ||
return null; | ||
} | ||
|
||
$className = $this->classNameProvider->getClassNameFromVar($methodCall->var); | ||
|
||
if ($className === null) { | ||
return null; | ||
} | ||
|
||
if ($this->isClassIgnored($className)) { | ||
return null; | ||
} | ||
|
||
if ($methodName === 'is') { | ||
return $this->refactorIsMethodCall($methodCall); | ||
} | ||
|
||
if ($methodName === 'getValue') { | ||
return $this->createPropertyValueFetch($methodCall->var); | ||
} | ||
|
||
if ($methodName === 'getName') { | ||
return $this->nodeFactory->createPropertyFetch($methodCall->var, 'name'); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
|
||
private function refactorGetStaticCall(StaticCall $staticCall): ?Expr | ||
{ | ||
$value = $staticCall->getArgs()[0]->value; | ||
|
||
if ($value instanceof ClassConstFetch) { | ||
$name = $value->name; | ||
|
||
if (!$name instanceof Identifier) { | ||
return null; | ||
} | ||
|
||
$className = $this->nodeNameResolver->getName($value->class); | ||
|
||
if ($className === null) { | ||
return null; | ||
} | ||
|
||
return $this->nodeFactory->createClassConstFetch( | ||
$className, | ||
$name->name, | ||
); | ||
} | ||
|
||
if ($value instanceof String_ || $value instanceof Variable) { | ||
$className = $this->nodeNameResolver->getName($staticCall->class); | ||
|
||
if ($className === null) { | ||
return null; | ||
} | ||
|
||
return $this->nodeFactory->createStaticCall($className, 'from', [$value]); | ||
} | ||
|
||
return null; | ||
} | ||
|
||
|
||
private function refactorIsMethodCall(MethodCall $methodCall): ?Identical | ||
{ | ||
$expr = $methodCall->var; | ||
|
||
if ($expr instanceof StaticCall) { | ||
$expr = $expr->getArgs()[0]->value; | ||
} | ||
|
||
$arg = $methodCall->getArgs()[0] ?? null; | ||
if (!$arg instanceof Arg) { | ||
return null; | ||
} | ||
|
||
$right = $arg->value; | ||
if ($right instanceof StaticCall) { | ||
$right = $right->getArgs()[0]->value; | ||
} | ||
|
||
if ($arg->value instanceof ClassConstFetch) { | ||
$right = $arg->value; | ||
} | ||
|
||
return new Identical($expr, $right); | ||
} | ||
|
||
|
||
/** | ||
* @param class-string $className | ||
*/ | ||
private function isClassIgnored(string $className): bool | ||
{ | ||
return $this->ignoredClassFromVendor && $this->isClassFromVendor($className); | ||
} | ||
|
||
|
||
private function isMabeEnum(Node $node): bool | ||
{ | ||
return $this->nodeTypeResolver->isObjectType( | ||
$node, | ||
new ObjectType(self::MABE_ENUM_CLASS_NAME), | ||
); | ||
} | ||
|
||
|
||
/** | ||
* @param class-string $className | ||
*/ | ||
private function isClassFromVendor(string $className): bool | ||
{ | ||
$classReflection = new ReflectionClass($className); | ||
|
||
return $classReflection->getFileName() !== false && str_contains($classReflection->getFileName(), 'vendor'); | ||
} | ||
} |
Oops, something went wrong.