diff --git a/phpstan.neon b/phpstan.neon index 509d12096c6..3172a1b7504 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -392,6 +392,5 @@ parameters: - identifier: rector.noIntegerRefactorReturn paths: - - rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php - rules/Php80/Rector/Switch_/ChangeSwitchToMatchRector.php - tests/Issues/InfiniteLoop/Rector/MethodCall/InfinityLoopRector.php diff --git a/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/include_class_const.php.inc b/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/include_class_const.php.inc new file mode 100644 index 00000000000..2656ff1960d --- /dev/null +++ b/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/include_class_const.php.inc @@ -0,0 +1,25 @@ + +----- + diff --git a/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/skip_dynamic_variable.php.inc b/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/skip_dynamic_variable.php.inc index f601691f034..d2364d972e5 100644 --- a/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/skip_dynamic_variable.php.inc +++ b/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/skip_dynamic_variable.php.inc @@ -2,7 +2,7 @@ namespace Rector\Tests\Php55\Rector\String_\StringClassNameToClassConstantRector\Fixture; -class SkipDynamicVariable +final class SkipDynamicVariable { public function bar() { @@ -12,4 +12,13 @@ class SkipDynamicVariable ${'field'.$i} = $employee->data['dd'.$i]; } } -} \ No newline at end of file + + public function foo() + { + $dd1 = 1; + + for ($i=1; $i <= 2; $i++) { + ${'field'.$i} = ${'dd'.$i}; + } + } +} diff --git a/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/skip_dynamic_variable2.php.inc b/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/skip_dynamic_variable2.php.inc deleted file mode 100644 index 6d3e88f6580..00000000000 --- a/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/Fixture/skip_dynamic_variable2.php.inc +++ /dev/null @@ -1,15 +0,0 @@ - ------ - diff --git a/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/KeepPreSlashTest.php b/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/KeepPreSlashTest.php deleted file mode 100644 index abe469117a1..00000000000 --- a/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/KeepPreSlashTest.php +++ /dev/null @@ -1,28 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/FixtureKeepPreSlash'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule_keep_pre_slash.php'; - } -} diff --git a/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/config/configured_rule_keep_pre_slash.php b/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/config/configured_rule_keep_pre_slash.php deleted file mode 100644 index 7b59c61d15d..00000000000 --- a/rules-tests/Php55/Rector/String_/StringClassNameToClassConstantRector/config/configured_rule_keep_pre_slash.php +++ /dev/null @@ -1,18 +0,0 @@ -ruleWithConfiguration(StringClassNameToClassConstantRector::class, [ - 'Nette\*', - 'Error', - 'Exception', - - // keep '\\' prefix string on string '\Foo\Bar' - StringClassNameToClassConstantRector::SHOULD_KEEP_PRE_SLASH => true, - ]); -}; diff --git a/rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php b/rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php index fc243eab971..e0fc179fcc2 100644 --- a/rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php +++ b/rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php @@ -5,15 +5,12 @@ namespace Rector\Php55\Rector\String_; use PhpParser\Node; -use PhpParser\Node\Expr\BinaryOp\Concat; use PhpParser\Node\Expr\ClassConstFetch; -use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Scalar\String_; -use PhpParser\Node\Stmt\ClassConst; -use PhpParser\NodeVisitor; use PHPStan\Reflection\ReflectionProvider; use Rector\Contract\Rector\ConfigurableRectorInterface; +use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\Rector\AbstractRector; use Rector\ValueObject\PhpVersionFeature; use Rector\VersionBonding\Contract\MinPhpVersionInterface; @@ -27,6 +24,7 @@ final class StringClassNameToClassConstantRector extends AbstractRector implements MinPhpVersionInterface, ConfigurableRectorInterface { /** + * @deprecated since 2.2.12. Default behavior now. * @var string */ public const SHOULD_KEEP_PRE_SLASH = 'should_keep_pre_slash'; @@ -36,8 +34,6 @@ final class StringClassNameToClassConstantRector extends AbstractRector implemen */ private array $classesToSkip = []; - private bool $shouldKeepPreslash = false; - public function __construct( private readonly ReflectionProvider $reflectionProvider, ) { @@ -75,11 +71,7 @@ public function run() } CODE_SAMPLE , - [ - 'ClassName', - 'AnotherClassName', - self::SHOULD_KEEP_PRE_SLASH => false, - ], + ['ClassName', 'AnotherClassName'], ), ]); } @@ -89,26 +81,15 @@ public function run() */ public function getNodeTypes(): array { - return [String_::class, FuncCall::class, ClassConst::class]; + return [String_::class]; } /** - * @param String_|FuncCall|ClassConst $node - * @return Concat|ClassConstFetch|null|NodeVisitor::DONT_TRAVERSE_CHILDREN + * @param String_ $node */ - public function refactor(Node $node): Concat|ClassConstFetch|null|int + public function refactor(Node $node): ClassConstFetch|null { - // allow class strings to be part of class const arrays, as probably on purpose - if ($node instanceof ClassConst) { - return NodeVisitor::DONT_TRAVERSE_CHILDREN; - } - - // keep allowed string as condition - if ($node instanceof FuncCall) { - if ($this->isName($node, 'is_a')) { - return NodeVisitor::DONT_TRAVERSE_CHILDREN; - } - + if ($this->shouldSkipIsA($node)) { return null; } @@ -125,14 +106,6 @@ public function refactor(Node $node): Concat|ClassConstFetch|null|int } $fullyQualified = new FullyQualified($classLikeName); - if ($this->shouldKeepPreslash && $classLikeName !== $node->value) { - $preSlashCount = strlen($node->value) - strlen($classLikeName); - $preSlash = str_repeat('\\', $preSlashCount); - $string = new String_($preSlash); - - return new Concat($string, new ClassConstFetch($fullyQualified, 'class')); - } - return new ClassConstFetch($fullyQualified, 'class'); } @@ -141,13 +114,6 @@ public function refactor(Node $node): Concat|ClassConstFetch|null|int */ public function configure(array $configuration): void { - if (isset($configuration[self::SHOULD_KEEP_PRE_SLASH]) && is_bool( - $configuration[self::SHOULD_KEEP_PRE_SLASH] - )) { - $this->shouldKeepPreslash = $configuration[self::SHOULD_KEEP_PRE_SLASH]; - unset($configuration[self::SHOULD_KEEP_PRE_SLASH]); - } - Assert::allString($configuration); $this->classesToSkip = $configuration; @@ -190,4 +156,15 @@ private function shouldSkip(string $classLikeName): bool return false; } + + private function shouldSkipIsA(String_ $string): bool + { + if (! $string->getAttribute(AttributeKey::IS_ARG_VALUE, false)) { + return false; + } + + $funcCallName = $string->getAttribute(AttributeKey::FROM_FUNC_CALL_NAME); + + return $funcCallName === 'is_a'; + } } diff --git a/src/NodeTypeResolver/PHPStan/Scope/NodeVisitor/ArgNodeVisitor.php b/src/NodeTypeResolver/PHPStan/Scope/NodeVisitor/ArgNodeVisitor.php index 0088f49ba56..c6941070fa1 100644 --- a/src/NodeTypeResolver/PHPStan/Scope/NodeVisitor/ArgNodeVisitor.php +++ b/src/NodeTypeResolver/PHPStan/Scope/NodeVisitor/ArgNodeVisitor.php @@ -5,8 +5,6 @@ namespace Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor; use PhpParser\Node; -use PhpParser\Node\Expr\Array_; -use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name; use PhpParser\NodeVisitorAbstract; @@ -32,14 +30,7 @@ public function enterNode(Node $node): ?Node $funcCallName = $node->name->toString(); foreach ($node->getArgs() as $arg) { - if ($arg->value instanceof Array_) { - $arg->value->setAttribute(AttributeKey::FROM_FUNC_CALL_NAME, $funcCallName); - continue; - } - - if ($arg->value instanceof ArrayDimFetch) { - $arg->value->setAttribute(AttributeKey::FROM_FUNC_CALL_NAME, $funcCallName); - } + $arg->value->setAttribute(AttributeKey::FROM_FUNC_CALL_NAME, $funcCallName); } return null;