Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Rector\Tests\Php55\Rector\String_\StringClassNameToClassConstantRector\Fixture;

final class IncludeClassConst
{
const SKIP_TYPES = [
'Rector\Tests\Php55\Rector\String_\StringClassNameToClassConstantRector\Source\SomeUser'
];
}

?>
-----
<?php

namespace Rector\Tests\Php55\Rector\String_\StringClassNameToClassConstantRector\Fixture;

final class IncludeClassConst
{
const SKIP_TYPES = [
\Rector\Tests\Php55\Rector\String_\StringClassNameToClassConstantRector\Source\SomeUser::class
];
}

?>
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Rector\Tests\Php55\Rector\String_\StringClassNameToClassConstantRector\Fixture;

class SkipDynamicVariable
final class SkipDynamicVariable
{
public function bar()
{
Expand All @@ -12,4 +12,13 @@ class SkipDynamicVariable
${'field'.$i} = $employee->data['dd'.$i];
}
}
}

public function foo()
{
$dd1 = 1;

for ($i=1; $i <= 2; $i++) {
${'field'.$i} = ${'dd'.$i};
}
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

59 changes: 18 additions & 41 deletions rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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';
Expand All @@ -36,8 +34,6 @@ final class StringClassNameToClassConstantRector extends AbstractRector implemen
*/
private array $classesToSkip = [];

private bool $shouldKeepPreslash = false;

public function __construct(
private readonly ReflectionProvider $reflectionProvider,
) {
Expand Down Expand Up @@ -75,11 +71,7 @@ public function run()
}
CODE_SAMPLE
,
[
'ClassName',
'AnotherClassName',
self::SHOULD_KEEP_PRE_SLASH => false,
],
['ClassName', 'AnotherClassName'],
),
]);
}
Expand All @@ -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;
}

Expand All @@ -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');
}

Expand All @@ -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;
Expand Down Expand Up @@ -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';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down