[PHP 5.5] Make StringClassNameToClassConstantRector as part of constants (#5634)

This commit is contained in:
Tomas Votruba 2021-02-20 21:53:11 +01:00 committed by GitHub
parent 0e5a777b00
commit da535f7809
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 14 deletions

View File

@ -9,13 +9,14 @@ use PhpParser\Node\Arg;
use PhpParser\Node\Expr\ClassConstFetch;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Scalar\String_;
use PhpParser\Node\Stmt\ClassConst;
use Rector\Core\Contract\Rector\ConfigurableRectorInterface;
use Rector\Core\Rector\AbstractRector;
use Rector\Core\Util\StaticRectorStrings;
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\ClassExistenceStaticHelper;
use Rector\NodeTypeResolver\Node\AttributeKey;
use ReflectionClass;
use Symplify\PackageBuilder\Reflection\ClassLikeExistenceChecker;
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
@ -31,7 +32,7 @@ final class StringClassNameToClassConstantRector extends AbstractRector implemen
* @api
* @var string
*/
public const CLASSES_TO_SKIP = '$classesToSkip';
public const CLASSES_TO_SKIP = 'classes_to_skip';
/**
* @var string[]
@ -52,6 +53,16 @@ final class StringClassNameToClassConstantRector extends AbstractRector implemen
*/
private $sensitiveNonExistingClasses = [];
/**
* @var ClassLikeExistenceChecker
*/
private $classLikeExistenceChecker;
public function __construct(ClassLikeExistenceChecker $classLikeExistenceChecker)
{
$this->classLikeExistenceChecker = $classLikeExistenceChecker;
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Replace string class names by <class>::class constant', [
@ -116,15 +127,7 @@ CODE_SAMPLE
return null;
}
if (! $this->classLikeSensitiveExists($classLikeName)) {
return null;
}
if (StaticRectorStrings::isInArrayInsensitive($classLikeName, $this->classesToSkip)) {
return null;
}
if ($this->isPartOfIsAFuncCall($node)) {
if ($this->shouldSkip($classLikeName, $node)) {
return null;
}
@ -136,16 +139,21 @@ CODE_SAMPLE
return new ClassConstFetch($fullyQualified, 'class');
}
/**
* @param array<string, string[]> $configuration
*/
public function configure(array $configuration): void
{
if (isset($configuration[self::CLASSES_TO_SKIP])) {
$this->classesToSkip = $configuration[self::CLASSES_TO_SKIP];
if (! isset($configuration[self::CLASSES_TO_SKIP])) {
return;
}
$this->classesToSkip = $configuration[self::CLASSES_TO_SKIP];
}
private function classLikeSensitiveExists(string $classLikeName): bool
{
if (! ClassExistenceStaticHelper::doesClassLikeExist($classLikeName)) {
if (! $this->classLikeExistenceChecker->doesClassLikeExist($classLikeName)) {
return false;
}
@ -175,6 +183,7 @@ CODE_SAMPLE
if (! $parent instanceof Arg) {
return false;
}
$parentParent = $parent->getAttribute(AttributeKey::PARENT_NODE);
if (! $parentParent instanceof Node) {
return false;
@ -182,4 +191,23 @@ CODE_SAMPLE
return $this->isFuncCallName($parentParent, 'is_a');
}
private function shouldSkip(string $classLikeName, String_ $string): bool
{
if (! $this->classLikeSensitiveExists($classLikeName)) {
return true;
}
if (StaticRectorStrings::isInArrayInsensitive($classLikeName, $this->classesToSkip)) {
return true;
}
if ($this->isPartOfIsAFuncCall($string)) {
return true;
}
// allow class strings to be part of class const arrays, as probably on purpose
$parentClassConst = $this->betterNodeFinder->findParentType($string, ClassConst::class);
return $parentClassConst instanceof ClassConst;
}
}

View File

@ -0,0 +1,10 @@
<?php
namespace Rector\Php55\Tests\Rector\String_\StringClassNameToClassConstantRector\Fixture;
final class SkipInArrayConstant
{
const SKIP_TYPES = [
'Rector\Php55\Tests\Rector\String_\StringClassNameToClassConstantRector\Source\SomeUser'
];
}