mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-28 23:10:51 +00:00
Add new rector to replace hardcoded class name reference in string with class
keyword reference
This commit is contained in:
parent
5e908d9810
commit
4a3fdf3705
|
@ -1,4 +1,4 @@
|
|||
# All 512 Rectors Overview
|
||||
# All 513 Rectors Overview
|
||||
|
||||
- [Projects](#projects)
|
||||
- [General](#general)
|
||||
|
@ -11,7 +11,7 @@
|
|||
- [CakePHP](#cakephp) (6)
|
||||
- [Celebrity](#celebrity) (3)
|
||||
- [CodeQuality](#codequality) (54)
|
||||
- [CodingStyle](#codingstyle) (32)
|
||||
- [CodingStyle](#codingstyle) (33)
|
||||
- [DeadCode](#deadcode) (40)
|
||||
- [Decouple](#decouple) (1)
|
||||
- [Doctrine](#doctrine) (16)
|
||||
|
@ -2239,6 +2239,19 @@ Change under_score names to pascalCase
|
|||
|
||||
<br><br>
|
||||
|
||||
### `UseClassKeywordForClassNameResolutionRector`
|
||||
|
||||
- class: [`Rector\CodingStyle\Rector\String_\UseClassKeywordForClassNameResolutionRector`](/../master/rules/coding-style/src/Rector/String_/UseClassKeywordForClassNameResolutionRector.php)
|
||||
|
||||
Use `class` keyword for class name resolution in string instead of hardcoded string reference
|
||||
|
||||
```diff
|
||||
-$value = 'App\SomeClass::someMethod()';
|
||||
+$value = \App\SomeClass . '::someMethod()';
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `UseIncrementAssignRector`
|
||||
|
||||
- class: [`Rector\CodingStyle\Rector\Assign\UseIncrementAssignRector`](/../master/rules/coding-style/src/Rector/Assign/UseIncrementAssignRector.php)
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\CodingStyle\Rector\String_;
|
||||
|
||||
use Nette\Utils\Strings;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\BinaryOp\Concat;
|
||||
use PhpParser\Node\Expr\ClassConstFetch;
|
||||
use PhpParser\Node\Name\FullyQualified;
|
||||
use PhpParser\Node\Scalar\String_;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
|
||||
/**
|
||||
* @see \Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\UseClassKeywordForClassNameResolutionTest
|
||||
*/
|
||||
final class UseClassKeywordForClassNameResolutionRector extends AbstractRector
|
||||
{
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition(
|
||||
'Use `class` keyword for class name resolution in string instead of hardcoded string reference',
|
||||
[
|
||||
new CodeSample(
|
||||
<<<'PHP'
|
||||
$value = 'App\SomeClass::someMethod()';
|
||||
PHP
|
||||
,
|
||||
<<<'PHP'
|
||||
$value = \App\SomeClass . '::someMethod()';
|
||||
PHP
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [String_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param String_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if (substr_count($node->value, '::') !== 1) {
|
||||
return null;
|
||||
}
|
||||
// a possible static call reference
|
||||
// @see https://regex101.com/r/Vv41Qr/1/
|
||||
[$before, $possibleClass, $after] = Strings::split($node->value, '#([\\\\a-zA-Z0-9_\\x80-\\xff]*)::#');
|
||||
|
||||
if (! $possibleClass || ! class_exists($possibleClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$classConstFetch = new ClassConstFetch(new FullyQualified(ltrim($possibleClass, '\\')), 'class');
|
||||
|
||||
$concat = new Concat($classConstFetch, new String_('::' . $after));
|
||||
if (! empty($before)) {
|
||||
$concat = new Concat(new String_($before), $classConstFetch);
|
||||
$concat = new Concat($concat, new String_('::' . $after));
|
||||
}
|
||||
|
||||
return $concat;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture;
|
||||
|
||||
class EmptyStringBeforeClassName
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return 'Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture\EmptyStringBeforeClassName::staticCall()) { ?>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture;
|
||||
|
||||
class EmptyStringBeforeClassName
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return \Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture\EmptyStringBeforeClassName::class . '::staticCall()) { ?>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return '<?php if (Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture\SomeClass::staticCall()) { ?>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return '<?php if (' . \Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture\SomeClass::class . '::staticCall()) { ?>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture;
|
||||
|
||||
class NonExistingClassName
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return '<?php if (Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector\Fixture\SomeClassThatDoesntExist::staticCall()) { ?>';
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\CodingStyle\Tests\Rector\String_\UseClassKeywordForClassNameResolutionRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\CodingStyle\Rector\String_\UseClassKeywordForClassNameResolutionRector;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class UseClassKeywordForClassNameResolutionTest extends AbstractRectorTestCase
|
||||
{
|
||||
/**
|
||||
* @dataProvider provideData()
|
||||
*/
|
||||
public function test(SmartFileInfo $file): void
|
||||
{
|
||||
$this->doTestFileInfo($file);
|
||||
}
|
||||
|
||||
public function provideData(): Iterator
|
||||
{
|
||||
return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture');
|
||||
}
|
||||
|
||||
protected function getRectorClass(): string
|
||||
{
|
||||
return UseClassKeywordForClassNameResolutionRector::class;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user