mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-28 23:10:51 +00:00
Merge CoreRectorInterface (#5762)
This commit is contained in:
parent
bfa5416077
commit
382f146eaf
2
.github/workflows/build_scoped_rector.yaml
vendored
2
.github/workflows/build_scoped_rector.yaml
vendored
|
@ -26,7 +26,7 @@ jobs:
|
|||
COMPOSER_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
|
||||
# 1. prepare dependencies
|
||||
- run: sh build-rector-scoped.sh
|
||||
- run: sh build/build-rector-scoped.sh
|
||||
|
||||
# 2. publish it to remote repository
|
||||
-
|
||||
|
|
|
@ -27,7 +27,7 @@ jobs:
|
|||
COMPOSER_TOKEN: ${{ secrets.ACCESS_TOKEN }}
|
||||
|
||||
# 1. prepare dependencies
|
||||
- run: sh build-rector-scoped.sh
|
||||
- run: sh build/build-rector-scoped.sh
|
||||
|
||||
# 2. get tag - see https://github.com/WyriHaximus/github-action-get-previous-tag
|
||||
-
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# 667 Rules Overview
|
||||
# 672 Rules Overview
|
||||
|
||||
<br>
|
||||
|
||||
|
@ -56,8 +56,6 @@
|
|||
|
||||
- [MockeryToProphecy](#mockerytoprophecy) (2)
|
||||
|
||||
- [MockistaToMockery](#mockistatomockery) (2)
|
||||
|
||||
- [MysqlToMysqli](#mysqltomysqli) (4)
|
||||
|
||||
- [Naming](#naming) (12)
|
||||
|
@ -108,6 +106,8 @@
|
|||
|
||||
- [PhpSpecToPHPUnit](#phpspectophpunit) (7)
|
||||
|
||||
- [PostRector](#postrector) (7)
|
||||
|
||||
- [Privatization](#privatization) (15)
|
||||
|
||||
- [RectorGenerator](#rectorgenerator) (1)
|
||||
|
@ -7204,54 +7204,6 @@ Changes mockery mock creation to Prophesize
|
|||
|
||||
<br>
|
||||
|
||||
## MockistaToMockery
|
||||
|
||||
### MockeryTearDownRector
|
||||
|
||||
Add `Mockery::close()` in `tearDown()` method if not yet
|
||||
|
||||
- class: [`Rector\MockistaToMockery\Rector\Class_\MockeryTearDownRector`](/rules/mockista-to-mockery/src/Rector/Class_/MockeryTearDownRector.php)
|
||||
|
||||
```diff
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class SomeTest extends TestCase
|
||||
{
|
||||
+ protected function tearDown(): void
|
||||
+ {
|
||||
+ Mockery::close();
|
||||
+ }
|
||||
public function test()
|
||||
{
|
||||
$mockUser = mock(User::class);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### MockistaMockToMockeryMockRector
|
||||
|
||||
Change functions to static calls, so composer can autoload them
|
||||
|
||||
- class: [`Rector\MockistaToMockery\Rector\ClassMethod\MockistaMockToMockeryMockRector`](/rules/mockista-to-mockery/src/Rector/ClassMethod/MockistaMockToMockeryMockRector.php)
|
||||
|
||||
```diff
|
||||
class SomeTest
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
- $mockUser = mock(User::class);
|
||||
- $mockUser->getId()->once->andReturn(1);
|
||||
- $mockUser->freeze();
|
||||
+ $mockUser = Mockery::mock(User::class);
|
||||
+ $mockUser->expects()->getId()->once()->andReturn(1);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## MysqlToMysqli
|
||||
|
||||
### MysqlAssignToMysqliRector
|
||||
|
@ -7691,14 +7643,16 @@ Use `Nette\Utils\Strings::endsWith()` over bare string-functions
|
|||
- class: [`Rector\Nette\Rector\Identical\EndsWithFunctionToNetteUtilsStringsRector`](/rules/nette/src/Rector/Identical/EndsWithFunctionToNetteUtilsStringsRector.php)
|
||||
|
||||
```diff
|
||||
+use Nette\Utils\Strings;
|
||||
+
|
||||
class SomeClass
|
||||
{
|
||||
public function end($needle)
|
||||
{
|
||||
$content = 'Hi, my name is Tom';
|
||||
|
||||
-
|
||||
- $yes = substr($content, -strlen($needle)) === $needle;
|
||||
+ $yes = \Nette\Utils\Strings::endsWith($content, $needle);
|
||||
+ $yes = Strings::endsWith($content, $needle);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
@ -7948,15 +7902,16 @@ Use `Nette\Utils\Strings::startsWith()` over bare string-functions
|
|||
- class: [`Rector\Nette\Rector\Identical\StartsWithFunctionToNetteUtilsStringsRector`](/rules/nette/src/Rector/Identical/StartsWithFunctionToNetteUtilsStringsRector.php)
|
||||
|
||||
```diff
|
||||
+use Nette\Utils\Strings;
|
||||
+
|
||||
class SomeClass
|
||||
{
|
||||
public function start($needle)
|
||||
{
|
||||
$content = 'Hi, my name is Tom';
|
||||
|
||||
- $yes = substr($content, 0, strlen($needle)) === $needle;
|
||||
+ $yes = \Nette\Utils\Strings::startsWith($content, $needle);
|
||||
}
|
||||
public function start($needle)
|
||||
{
|
||||
$content = 'Hi, my name is Tom';
|
||||
- $yes = substr($content, 0, strlen($needle)) === $needle;
|
||||
+ $yes = Strings::startsWith($content, $needle);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -12108,6 +12063,142 @@ Rename "*Spec.php" file to "*Test.php" file
|
|||
|
||||
<br>
|
||||
|
||||
## PostRector
|
||||
|
||||
### ClassRenamingPostRector
|
||||
|
||||
Rename references for classes that were renamed during Rector run
|
||||
|
||||
- class: [`Rector\PostRector\Rector\ClassRenamingPostRector`](/packages/post-rector/src/Rector/ClassRenamingPostRector.php)
|
||||
|
||||
```diff
|
||||
-function (OriginalClass $someClass)
|
||||
+function (RenamedClass $someClass)
|
||||
{
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### NameImportingPostRector
|
||||
|
||||
Imports fully qualified names
|
||||
|
||||
- class: [`Rector\PostRector\Rector\NameImportingPostRector`](/packages/post-rector/src/Rector/NameImportingPostRector.php)
|
||||
|
||||
```diff
|
||||
+use App\AnotherClass;
|
||||
+
|
||||
class SomeClass
|
||||
{
|
||||
- public function run(App\AnotherClass $anotherClass)
|
||||
+ public function run(AnotherClass $anotherClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### NodeAddingPostRector
|
||||
|
||||
Add nodes on weird positions
|
||||
|
||||
- class: [`Rector\PostRector\Rector\NodeAddingPostRector`](/packages/post-rector/src/Rector/NodeAddingPostRector.php)
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function run($value)
|
||||
{
|
||||
- return 1;
|
||||
+ if ($value) {
|
||||
+ return 1;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### NodeRemovingPostRector
|
||||
|
||||
Remove nodes from weird positions
|
||||
|
||||
- class: [`Rector\PostRector\Rector\NodeRemovingPostRector`](/packages/post-rector/src/Rector/NodeRemovingPostRector.php)
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function run($value)
|
||||
{
|
||||
- if ($value) {
|
||||
- return 1;
|
||||
- }
|
||||
+ return 1;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### NodeToReplacePostRector
|
||||
|
||||
Replaces nodes on weird positions
|
||||
|
||||
- class: [`Rector\PostRector\Rector\NodeToReplacePostRector`](/packages/post-rector/src/Rector/NodeToReplacePostRector.php)
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function run($value)
|
||||
{
|
||||
- return 1;
|
||||
+ return $value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### PropertyAddingPostRector
|
||||
|
||||
Add dependency properties
|
||||
|
||||
- class: [`Rector\PostRector\Rector\PropertyAddingPostRector`](/packages/post-rector/src/Rector/PropertyAddingPostRector.php)
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
+ private $value;
|
||||
public function run()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
### UseAddingPostRector
|
||||
|
||||
Add unique use imports collected during Rector run
|
||||
|
||||
- class: [`Rector\PostRector\Rector\UseAddingPostRector`](/packages/post-rector/src/Rector/UseAddingPostRector.php)
|
||||
|
||||
```diff
|
||||
+use App\AnotherClass;
|
||||
+
|
||||
class SomeClass
|
||||
{
|
||||
public function run(AnotherClass $anotherClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
## Privatization
|
||||
|
||||
### ChangeGlobalVariablesToPropertiesRector
|
||||
|
|
|
@ -4,7 +4,6 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\ChangesReporting\ValueObject;
|
||||
|
||||
use Rector\Core\Contract\Rector\CoreRectorInterface;
|
||||
use Rector\Core\Contract\Rector\RectorInterface;
|
||||
|
||||
final class RectorWithFileAndLineChange
|
||||
|
@ -33,12 +32,8 @@ final class RectorWithFileAndLineChange
|
|||
|
||||
public function getRectorDefinitionsDescription(): string
|
||||
{
|
||||
if ($this->rector instanceof CoreRectorInterface) {
|
||||
$ruleDefinition = $this->rector->getRuleDefinition();
|
||||
return $ruleDefinition->getDescription();
|
||||
}
|
||||
|
||||
return '';
|
||||
$ruleDefinition = $this->rector->getRuleDefinition();
|
||||
return $ruleDefinition->getDescription();
|
||||
}
|
||||
|
||||
public function getRectorClass(): string
|
||||
|
|
12
packages/post-rector/src/Rector/AbstractPostRector.php
Normal file
12
packages/post-rector/src/Rector/AbstractPostRector.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\PostRector\Rector;
|
||||
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\PostRector\Contract\Rector\PostRectorInterface;
|
||||
|
||||
abstract class AbstractPostRector extends NodeVisitorAbstract implements PostRectorInterface
|
||||
{
|
||||
}
|
|
@ -5,12 +5,12 @@ declare(strict_types=1);
|
|||
namespace Rector\PostRector\Rector;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\PostRector\Contract\Rector\PostRectorInterface;
|
||||
use Rector\PSR4\Collector\RenamedClassesCollector;
|
||||
use Rector\Renaming\NodeManipulator\ClassRenamer;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
final class ClassRenamingPostRector extends NodeVisitorAbstract implements PostRectorInterface
|
||||
final class ClassRenamingPostRector extends AbstractPostRector
|
||||
{
|
||||
/**
|
||||
* @var RenamedClassesCollector
|
||||
|
@ -43,4 +43,23 @@ final class ClassRenamingPostRector extends NodeVisitorAbstract implements PostR
|
|||
|
||||
return $this->classRenamer->renameNode($node, $oldToNewClasses);
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Rename references for classes that were renamed during Rector run', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
function (OriginalClass $someClass)
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
function (RenamedClass $someClass)
|
||||
{
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ namespace Rector\PostRector\Rector;
|
|||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\CodingStyle\ClassNameImport\ClassNameImportSkipper;
|
||||
|
@ -14,10 +13,11 @@ use Rector\CodingStyle\Node\NameImporter;
|
|||
use Rector\Core\Configuration\Option;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockNameImporter;
|
||||
use Rector\PostRector\Contract\Rector\PostRectorInterface;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
final class NameImportingPostRector extends NodeVisitorAbstract implements PostRectorInterface
|
||||
final class NameImportingPostRector extends AbstractPostRector
|
||||
{
|
||||
/**
|
||||
* @var ParameterProvider
|
||||
|
@ -99,6 +99,33 @@ final class NameImportingPostRector extends NodeVisitorAbstract implements PostR
|
|||
return 600;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Imports fully qualified names', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run(App\AnotherClass $anotherClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
use App\AnotherClass;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run(AnotherClass $anotherClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
private function processNodeName(Name $name): ?Node
|
||||
{
|
||||
if ($name->isSpecialClassName()) {
|
||||
|
|
|
@ -5,9 +5,9 @@ declare(strict_types=1);
|
|||
namespace Rector\PostRector\Rector;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\PostRector\Collector\NodesToAddCollector;
|
||||
use Rector\PostRector\Contract\Rector\PostRectorInterface;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* This class collects all to-be-added expresssions (= 1 line in code)
|
||||
|
@ -20,7 +20,7 @@ use Rector\PostRector\Contract\Rector\PostRectorInterface;
|
|||
* - $this->someCall();
|
||||
* - $value = this->someNewCall(); // added expression
|
||||
*/
|
||||
final class NodeAddingPostRector extends NodeVisitorAbstract implements PostRectorInterface
|
||||
final class NodeAddingPostRector extends AbstractPostRector
|
||||
{
|
||||
/**
|
||||
* @var NodesToAddCollector
|
||||
|
@ -62,4 +62,33 @@ final class NodeAddingPostRector extends NodeVisitorAbstract implements PostRect
|
|||
|
||||
return $newNodes;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Add nodes on weird positions', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($value)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($value)
|
||||
{
|
||||
if ($value) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
), ]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,14 +8,14 @@ use PhpParser\Node;
|
|||
use PhpParser\Node\Expr\BinaryOp;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\NodeTraverser;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\PostRector\Collector\NodesToRemoveCollector;
|
||||
use Rector\PostRector\Contract\Rector\PostRectorInterface;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
final class NodeRemovingPostRector extends NodeVisitorAbstract implements PostRectorInterface
|
||||
final class NodeRemovingPostRector extends AbstractPostRector
|
||||
{
|
||||
/**
|
||||
* @var NodesToRemoveCollector
|
||||
|
@ -107,6 +107,35 @@ final class NodeRemovingPostRector extends NodeVisitorAbstract implements PostRe
|
|||
return $node;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Remove nodes from weird positions', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($value)
|
||||
{
|
||||
if ($value) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($value)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
), ]
|
||||
);
|
||||
}
|
||||
|
||||
private function isChainMethodCallNodeToBeRemoved(
|
||||
MethodCall $mainMethodCall,
|
||||
MethodCall $toBeRemovedMethodCall
|
||||
|
|
|
@ -5,11 +5,11 @@ declare(strict_types=1);
|
|||
namespace Rector\PostRector\Rector;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\PostRector\Collector\NodesToReplaceCollector;
|
||||
use Rector\PostRector\Contract\Rector\PostRectorInterface;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
final class NodeToReplacePostRector extends NodeVisitorAbstract implements PostRectorInterface
|
||||
final class NodeToReplacePostRector extends AbstractPostRector
|
||||
{
|
||||
/**
|
||||
* @var NodesToReplaceCollector
|
||||
|
@ -36,4 +36,31 @@ final class NodeToReplacePostRector extends NodeVisitorAbstract implements PostR
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Replaces nodes on weird positions', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($value)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
), ]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,17 +6,17 @@ namespace Rector\PostRector\Rector;
|
|||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\Core\NodeManipulator\ClassDependencyManipulator;
|
||||
use Rector\Core\NodeManipulator\ClassInsertManipulator;
|
||||
use Rector\PostRector\Collector\PropertyToAddCollector;
|
||||
use Rector\PostRector\Contract\Rector\PostRectorInterface;
|
||||
use Rector\PostRector\NodeAnalyzer\NetteInjectDetector;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
/**
|
||||
* Adds new private properties to class + to constructor
|
||||
*/
|
||||
final class PropertyAddingPostRector extends NodeVisitorAbstract implements PostRectorInterface
|
||||
final class PropertyAddingPostRector extends AbstractPostRector
|
||||
{
|
||||
/**
|
||||
* @var ClassDependencyManipulator
|
||||
|
@ -70,6 +70,34 @@ final class PropertyAddingPostRector extends NodeVisitorAbstract implements Post
|
|||
return $node;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Add dependency properties', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
private $value;
|
||||
public function run()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
), ]
|
||||
);
|
||||
}
|
||||
|
||||
private function addConstants(Class_ $class): void
|
||||
{
|
||||
$constants = $this->propertyToAddCollector->getConstantsByClass($class);
|
||||
|
|
|
@ -8,7 +8,6 @@ use Nette\Utils\Strings;
|
|||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Namespace_;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use Rector\CodingStyle\Application\UseImportsAdder;
|
||||
use Rector\CodingStyle\Application\UseImportsRemover;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
|
@ -16,11 +15,12 @@ use Rector\Core\PhpParser\Node\CustomNode\FileWithoutNamespace;
|
|||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
|
||||
use Rector\PostRector\Collector\UseNodesToAddCollector;
|
||||
use Rector\PostRector\Contract\Rector\PostRectorInterface;
|
||||
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class UseAddingPostRector extends NodeVisitorAbstract implements PostRectorInterface
|
||||
final class UseAddingPostRector extends AbstractPostRector
|
||||
{
|
||||
/**
|
||||
* @var UseImportsAdder
|
||||
|
@ -122,6 +122,33 @@ final class UseAddingPostRector extends NodeVisitorAbstract implements PostRecto
|
|||
return 500;
|
||||
}
|
||||
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Add unique use imports collected during Rector run', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class SomeClass
|
||||
{
|
||||
public function run(AnotherClass $anotherClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
use App\AnotherClass;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
public function run(AnotherClass $anotherClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
), ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $nodes
|
||||
*/
|
||||
|
|
10
phpstan.neon
10
phpstan.neon
|
@ -253,7 +253,7 @@ parameters:
|
|||
# merging comments
|
||||
- packages/better-php-doc-parser/tests/PhpDocInfo/PhpDocInfo/PhpDocInfoTest.php
|
||||
- src/PhpParser/NodeTransformer.php
|
||||
- src/Rector/AbstractTemporaryRector.php
|
||||
- src/Rector/AbstractRector.php
|
||||
# playing around with doc block format
|
||||
- packages/comments/src/CommentRemover.php
|
||||
- rules/coding-style/src/Rector/Assign/PHPStormVarAnnotationRector.php
|
||||
|
@ -370,6 +370,7 @@ parameters:
|
|||
message: '#Property with protected modifier is not allowed\. Use interface contract method instead#'
|
||||
paths:
|
||||
- rules/defluent/src/ValueObject/*
|
||||
- src/Rector/AbstractRector.php
|
||||
|
||||
- '#Parameter \#1 \$keyName of method Rector\\AttributeAwarePhpDoc\\Ast\\Type\\AttributeAwareArrayShapeItemNode\:\:createKeyWithSpacePattern\(\) expects PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprIntegerNode\|PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode\|null, PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprIntegerNode\|PHPStan\\PhpDocParser\\Ast\\ConstExpr\\ConstExprStringNode\|PHPStan\\PhpDocParser\\Ast\\Type\\IdentifierTypeNode\|null given#'
|
||||
- '#AttributeAwarePhpDocNode#'
|
||||
|
@ -440,7 +441,7 @@ parameters:
|
|||
-
|
||||
message: '#\$this as argument is not allowed\. Refactor method to service composition#'
|
||||
paths:
|
||||
- src/Rector/AbstractTemporaryRector.php
|
||||
- src/Rector/AbstractRector.php
|
||||
# setter to avoid circular dependency in nested collector
|
||||
- rules/nette-code-quality/src/NodeResolver/MethodNamesByInputNamesResolver.php
|
||||
- packages/static-type-mapper/src/StaticTypeMapper.php
|
||||
|
@ -613,3 +614,8 @@ parameters:
|
|||
message: '#Argument and options "debug" got confused#'
|
||||
paths:
|
||||
- src/Console/Command/ProcessCommand.php
|
||||
|
||||
-
|
||||
message: '#Class cognitive complexity is 31, keep it under 30#'
|
||||
paths:
|
||||
- src/Rector/AbstractRector.php
|
||||
|
|
|
@ -75,9 +75,7 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
StringClassNameToClassConstantRector::class,
|
||||
SplitStringClassConstantToClassConstFetchRector::class,
|
||||
|
||||
PrivatizeLocalPropertyToPrivatePropertyRector::class => [
|
||||
__DIR__ . '/src/Rector/AbstractTemporaryRector.php',
|
||||
],
|
||||
PrivatizeLocalPropertyToPrivatePropertyRector::class => [__DIR__ . '/src/Rector/AbstractRector.php'],
|
||||
|
||||
// test paths
|
||||
'*/Fixture/*',
|
||||
|
|
|
@ -311,4 +311,14 @@ CODE_SAMPLE
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function getNextExpression(Node $node): ?Node
|
||||
{
|
||||
$currentExpression = $node->getAttribute(AttributeKey::CURRENT_STATEMENT);
|
||||
if (! $currentExpression instanceof Expression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $currentExpression->getAttribute(AttributeKey::NEXT_NODE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Composer\Contract\Rector;
|
||||
|
||||
use Symplify\RuleDocGenerator\Contract\DocumentedRuleInterface;
|
||||
|
||||
interface CoreComposerRectorInterface extends ComposerRectorInterface, DocumentedRuleInterface
|
||||
{
|
||||
}
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Composer\Rector;
|
||||
|
||||
use Rector\Composer\Contract\Rector\CoreComposerRectorInterface;
|
||||
use Rector\Composer\Contract\Rector\ComposerRectorInterface;
|
||||
use Rector\Composer\Guard\VersionGuard;
|
||||
use Rector\Composer\ValueObject\PackageAndVersion;
|
||||
use Symplify\ComposerJsonManipulator\ValueObject\ComposerJson;
|
||||
|
@ -14,7 +14,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
/**
|
||||
* @see \Rector\Composer\Tests\Rector\AddPackageToRequireComposerRector\AddPackageToRequireComposerRectorTest
|
||||
*/
|
||||
final class AddPackageToRequireComposerRector implements CoreComposerRectorInterface
|
||||
final class AddPackageToRequireComposerRector implements ComposerRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
|
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Composer\Rector;
|
||||
|
||||
use Rector\Composer\Contract\Rector\CoreComposerRectorInterface;
|
||||
use Rector\Composer\Contract\Rector\ComposerRectorInterface;
|
||||
use Rector\Composer\Guard\VersionGuard;
|
||||
use Rector\Composer\ValueObject\PackageAndVersion;
|
||||
use Symplify\ComposerJsonManipulator\ValueObject\ComposerJson;
|
||||
|
@ -14,7 +14,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
/**
|
||||
* @see \Rector\Composer\Tests\Rector\AddPackageToRequireDevComposerRector\AddPackageToRequireDevComposerRectorTest
|
||||
*/
|
||||
final class AddPackageToRequireDevComposerRector implements CoreComposerRectorInterface
|
||||
final class AddPackageToRequireDevComposerRector implements ComposerRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
|
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Composer\Rector;
|
||||
|
||||
use Rector\Composer\Contract\Rector\CoreComposerRectorInterface;
|
||||
use Rector\Composer\Contract\Rector\ComposerRectorInterface;
|
||||
use Rector\Composer\Guard\VersionGuard;
|
||||
use Rector\Composer\ValueObject\PackageAndVersion;
|
||||
use Symplify\ComposerJsonManipulator\ValueObject\ComposerJson;
|
||||
|
@ -14,7 +14,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
/**
|
||||
* @see \Rector\Composer\Tests\Rector\ChangePackageVersionComposerRector\ChangePackageVersionComposerRectorTest
|
||||
*/
|
||||
final class ChangePackageVersionComposerRector implements CoreComposerRectorInterface
|
||||
final class ChangePackageVersionComposerRector implements ComposerRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
|
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Composer\Rector;
|
||||
|
||||
use Rector\Composer\Contract\Rector\CoreComposerRectorInterface;
|
||||
use Rector\Composer\Contract\Rector\ComposerRectorInterface;
|
||||
use Symplify\ComposerJsonManipulator\ValueObject\ComposerJson;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\ConfiguredCodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
@ -12,7 +12,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
/**
|
||||
* @see \Rector\Composer\Tests\Rector\RemovePackageComposerRector\RemovePackageComposerRectorTest
|
||||
*/
|
||||
final class RemovePackageComposerRector implements CoreComposerRectorInterface
|
||||
final class RemovePackageComposerRector implements ComposerRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
|
|
|
@ -4,7 +4,7 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Composer\Rector;
|
||||
|
||||
use Rector\Composer\Contract\Rector\CoreComposerRectorInterface;
|
||||
use Rector\Composer\Contract\Rector\ComposerRectorInterface;
|
||||
use Rector\Composer\Guard\VersionGuard;
|
||||
use Rector\Composer\ValueObject\ReplacePackageAndVersion;
|
||||
use Symplify\ComposerJsonManipulator\ValueObject\ComposerJson;
|
||||
|
@ -14,7 +14,7 @@ use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
|||
/**
|
||||
* @see \Rector\Composer\Tests\Rector\ReplacePackageAndVersionComposerRector\ReplacePackageAndVersionComposerRectorTest
|
||||
*/
|
||||
final class ReplacePackageAndVersionComposerRector implements CoreComposerRectorInterface
|
||||
final class ReplacePackageAndVersionComposerRector implements ComposerRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
|
|
|
@ -119,7 +119,7 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
if ($this->isNumberType($node->var)) {
|
||||
if ($this->nodeTypeResolver->isNumberType($node->var)) {
|
||||
return $node->var;
|
||||
}
|
||||
}
|
||||
|
@ -129,7 +129,7 @@ CODE_SAMPLE
|
|||
if (! $this->valueResolver->isValue($node->expr, 1)) {
|
||||
return null;
|
||||
}
|
||||
if ($this->isNumberType($node->var)) {
|
||||
if ($this->nodeTypeResolver->isNumberType($node->var)) {
|
||||
return $node->var;
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +159,9 @@ CODE_SAMPLE
|
|||
*/
|
||||
private function processBinaryPlusAndMinus(BinaryOp $binaryOp): ?Expr
|
||||
{
|
||||
if ($this->valueResolver->isValue($binaryOp->left, 0) && $this->isNumberType($binaryOp->right)) {
|
||||
if ($this->valueResolver->isValue($binaryOp->left, 0) && $this->nodeTypeResolver->isNumberType(
|
||||
$binaryOp->right
|
||||
)) {
|
||||
if ($binaryOp instanceof Minus) {
|
||||
return new UnaryMinus($binaryOp->right);
|
||||
}
|
||||
|
@ -168,7 +170,7 @@ CODE_SAMPLE
|
|||
if (! $this->valueResolver->isValue($binaryOp->right, 0)) {
|
||||
return null;
|
||||
}
|
||||
if (! $this->isNumberType($binaryOp->left)) {
|
||||
if (! $this->nodeTypeResolver->isNumberType($binaryOp->left)) {
|
||||
return null;
|
||||
}
|
||||
return $binaryOp->left;
|
||||
|
@ -179,15 +181,16 @@ CODE_SAMPLE
|
|||
*/
|
||||
private function processBinaryMulAndDiv(BinaryOp $binaryOp): ?Expr
|
||||
{
|
||||
if ($binaryOp instanceof Mul && $this->valueResolver->isValue($binaryOp->left, 1) && $this->isNumberType(
|
||||
$binaryOp->right
|
||||
)) {
|
||||
if ($binaryOp instanceof Mul && $this->valueResolver->isValue(
|
||||
$binaryOp->left,
|
||||
1
|
||||
) && $this->nodeTypeResolver->isNumberType($binaryOp->right)) {
|
||||
return $binaryOp->right;
|
||||
}
|
||||
if (! $this->valueResolver->isValue($binaryOp->right, 1)) {
|
||||
return null;
|
||||
}
|
||||
if (! $this->isNumberType($binaryOp->left)) {
|
||||
if (! $this->nodeTypeResolver->isNumberType($binaryOp->left)) {
|
||||
return null;
|
||||
}
|
||||
return $binaryOp->left;
|
||||
|
|
|
@ -198,7 +198,7 @@ CODE_SAMPLE
|
|||
$isExprFoundInReturn = (bool) $this->betterNodeFinder->findFirst($return->expr, function (Node $node) use (
|
||||
$expr
|
||||
): bool {
|
||||
return $this->areNodesEqual($node, $expr);
|
||||
return $this->nodeComparator->areNodesEqual($node, $expr);
|
||||
});
|
||||
if ($isExprFoundInReturn) {
|
||||
return true;
|
||||
|
|
|
@ -145,7 +145,7 @@ CODE_SAMPLE
|
|||
return null;
|
||||
}
|
||||
|
||||
if (! $this->isNumberType($argExpr)) {
|
||||
if (! $this->nodeTypeResolver->isNumberType($argExpr)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -76,13 +76,17 @@ CODE_SAMPLE
|
|||
if ($node instanceof Coalesce) {
|
||||
return null;
|
||||
}
|
||||
if ($this->isStringOrStaticNonNumbericString($node->left) && $this->isNumberType($node->right)) {
|
||||
if ($this->isStringOrStaticNonNumbericString($node->left) && $this->nodeTypeResolver->isNumberType(
|
||||
$node->right
|
||||
)) {
|
||||
$node->left = new LNumber(0);
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
if ($this->isStringOrStaticNonNumbericString($node->right) && $this->isNumberType($node->left)) {
|
||||
if ($this->isStringOrStaticNonNumbericString($node->right) && $this->nodeTypeResolver->isNumberType(
|
||||
$node->left
|
||||
)) {
|
||||
$node->right = new LNumber(0);
|
||||
|
||||
return $node;
|
||||
|
|
|
@ -7,9 +7,11 @@ namespace Rector\Php73\Rector\FuncCall;
|
|||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\FuncCall;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PHPStan\Reflection\ReflectionProvider;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
|
@ -147,4 +149,14 @@ CODE_SAMPLE
|
|||
|
||||
return ! $this->reflectionProvider->hasFunction(new Name(self::ARRAY_KEY_LAST), null);
|
||||
}
|
||||
|
||||
private function getNextExpression(FuncCall $funcCall): ?Node
|
||||
{
|
||||
$currentExpression = $funcCall->getAttribute(AttributeKey::CURRENT_STATEMENT);
|
||||
if (! $currentExpression instanceof Expression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $currentExpression->getAttribute(AttributeKey::NEXT_NODE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Contract\Rector;
|
||||
|
||||
use Symplify\RuleDocGenerator\Contract\DocumentedRuleInterface;
|
||||
|
||||
interface CorePhpRectorInterface extends PhpRectorInterface, DocumentedRuleInterface
|
||||
{
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Contract\Rector;
|
||||
|
||||
use Symplify\RuleDocGenerator\Contract\DocumentedRuleInterface;
|
||||
|
||||
interface CoreRectorInterface extends RectorInterface, DocumentedRuleInterface
|
||||
{
|
||||
}
|
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Core\Contract\Rector;
|
||||
|
||||
interface RectorInterface
|
||||
use Symplify\RuleDocGenerator\Contract\DocumentedRuleInterface;
|
||||
|
||||
interface RectorInterface extends DocumentedRuleInterface
|
||||
{
|
||||
}
|
||||
|
|
|
@ -4,11 +4,614 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Core\Rector;
|
||||
|
||||
use Rector\Core\Contract\Rector\CorePhpRectorInterface;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\ChangesReporting\Collector\RectorChangeCollector;
|
||||
use Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector;
|
||||
use Rector\Core\Configuration\CurrentNodeProvider;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\Contract\Rector\PhpRectorInterface;
|
||||
use Rector\Core\Exclusion\ExclusionManager;
|
||||
use Rector\Core\Logging\CurrentRectorProvider;
|
||||
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\PhpParser\Comparing\NodeComparator;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
|
||||
use Rector\Core\ValueObject\ProjectType;
|
||||
use Rector\NodeCollector\NodeCollector\NodeRepository;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeRemoval\NodeRemover;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\PostRector\Collector\NodesToAddCollector;
|
||||
use Rector\PostRector\Collector\NodesToRemoveCollector;
|
||||
use Rector\PostRector\DependencyInjection\PropertyAdder;
|
||||
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Symplify\Skipper\Skipper\Skipper;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
/**
|
||||
* @see \Rector\Testing\PHPUnit\AbstractRectorTestCase
|
||||
*/
|
||||
abstract class AbstractRector extends AbstractTemporaryRector implements CorePhpRectorInterface
|
||||
abstract class AbstractRector extends NodeVisitorAbstract implements PhpRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private const ATTRIBUTES_TO_MIRROR = [
|
||||
AttributeKey::PARENT_NODE,
|
||||
AttributeKey::CLASS_NODE,
|
||||
AttributeKey::CLASS_NAME,
|
||||
AttributeKey::FILE_INFO,
|
||||
AttributeKey::METHOD_NODE,
|
||||
AttributeKey::USE_NODES,
|
||||
AttributeKey::SCOPE,
|
||||
AttributeKey::METHOD_NAME,
|
||||
AttributeKey::NAMESPACE_NAME,
|
||||
AttributeKey::NAMESPACE_NODE,
|
||||
AttributeKey::RESOLVED_NAME,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
protected $nodeNameResolver;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
protected $nodeTypeResolver;
|
||||
|
||||
/**
|
||||
* @var BetterStandardPrinter
|
||||
*/
|
||||
protected $betterStandardPrinter;
|
||||
|
||||
/**
|
||||
* @var RemovedAndAddedFilesCollector
|
||||
*/
|
||||
protected $removedAndAddedFilesCollector;
|
||||
|
||||
/**
|
||||
* @var ParameterProvider
|
||||
*/
|
||||
protected $parameterProvider;
|
||||
|
||||
/**
|
||||
* @var PhpVersionProvider
|
||||
*/
|
||||
protected $phpVersionProvider;
|
||||
|
||||
/**
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
protected $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @var PhpDocInfoFactory
|
||||
*/
|
||||
protected $phpDocInfoFactory;
|
||||
|
||||
/**
|
||||
* @var NodeFactory
|
||||
*/
|
||||
protected $nodeFactory;
|
||||
|
||||
/**
|
||||
* @var VisibilityManipulator
|
||||
*/
|
||||
protected $visibilityManipulator;
|
||||
|
||||
/**
|
||||
* @var ValueResolver
|
||||
*/
|
||||
protected $valueResolver;
|
||||
|
||||
/**
|
||||
* @var NodeRepository
|
||||
*/
|
||||
protected $nodeRepository;
|
||||
|
||||
/**
|
||||
* @var BetterNodeFinder
|
||||
*/
|
||||
protected $betterNodeFinder;
|
||||
|
||||
/**
|
||||
* @var ClassAnalyzer
|
||||
*/
|
||||
protected $classNodeAnalyzer;
|
||||
|
||||
/**
|
||||
* @var NodeRemover
|
||||
*/
|
||||
protected $nodeRemover;
|
||||
|
||||
/**
|
||||
* @var RectorChangeCollector
|
||||
*/
|
||||
protected $rectorChangeCollector;
|
||||
|
||||
/**
|
||||
* @var NodeComparator
|
||||
*/
|
||||
protected $nodeComparator;
|
||||
|
||||
/**
|
||||
* @var PropertyAdder
|
||||
*/
|
||||
protected $propertyAdder;
|
||||
|
||||
/**
|
||||
* @var SimpleCallableNodeTraverser
|
||||
*/
|
||||
private $simpleCallableNodeTraverser;
|
||||
|
||||
/**
|
||||
* @var SymfonyStyle
|
||||
*/
|
||||
private $symfonyStyle;
|
||||
|
||||
/**
|
||||
* @var ExclusionManager
|
||||
*/
|
||||
private $exclusionManager;
|
||||
|
||||
/**
|
||||
* @var CurrentRectorProvider
|
||||
*/
|
||||
private $currentRectorProvider;
|
||||
|
||||
/**
|
||||
* @var CurrentNodeProvider
|
||||
*/
|
||||
private $currentNodeProvider;
|
||||
|
||||
/**
|
||||
* @var Skipper
|
||||
*/
|
||||
private $skipper;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $previousAppliedClass;
|
||||
|
||||
/**
|
||||
* @var NodesToRemoveCollector
|
||||
*/
|
||||
private $nodesToRemoveCollector;
|
||||
|
||||
/**
|
||||
* @var NodesToAddCollector
|
||||
*/
|
||||
private $nodesToAddCollector;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function autowireAbstractRector(
|
||||
NodesToRemoveCollector $nodesToRemoveCollector,
|
||||
NodesToAddCollector $nodesToAddCollector,
|
||||
RectorChangeCollector $rectorChangeCollector,
|
||||
NodeRemover $nodeRemover,
|
||||
PropertyAdder $propertyAdder,
|
||||
RemovedAndAddedFilesCollector $removedAndAddedFilesCollector,
|
||||
BetterStandardPrinter $betterStandardPrinter,
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
|
||||
VisibilityManipulator $visibilityManipulator,
|
||||
NodeFactory $nodeFactory,
|
||||
PhpDocInfoFactory $phpDocInfoFactory,
|
||||
SymfonyStyle $symfonyStyle,
|
||||
PhpVersionProvider $phpVersionProvider,
|
||||
ExclusionManager $exclusionManager,
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
ParameterProvider $parameterProvider,
|
||||
CurrentRectorProvider $currentRectorProvider,
|
||||
ClassAnalyzer $classAnalyzer,
|
||||
CurrentNodeProvider $currentNodeProvider,
|
||||
Skipper $skipper,
|
||||
ValueResolver $valueResolver,
|
||||
NodeRepository $nodeRepository,
|
||||
BetterNodeFinder $betterNodeFinder,
|
||||
NodeComparator $nodeComparator
|
||||
): void {
|
||||
$this->nodesToRemoveCollector = $nodesToRemoveCollector;
|
||||
$this->nodesToAddCollector = $nodesToAddCollector;
|
||||
$this->rectorChangeCollector = $rectorChangeCollector;
|
||||
$this->nodeRemover = $nodeRemover;
|
||||
$this->propertyAdder = $propertyAdder;
|
||||
$this->removedAndAddedFilesCollector = $removedAndAddedFilesCollector;
|
||||
$this->betterStandardPrinter = $betterStandardPrinter;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
|
||||
$this->visibilityManipulator = $visibilityManipulator;
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||
$this->symfonyStyle = $symfonyStyle;
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
$this->exclusionManager = $exclusionManager;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->parameterProvider = $parameterProvider;
|
||||
$this->currentRectorProvider = $currentRectorProvider;
|
||||
$this->classNodeAnalyzer = $classAnalyzer;
|
||||
$this->currentNodeProvider = $currentNodeProvider;
|
||||
$this->skipper = $skipper;
|
||||
$this->valueResolver = $valueResolver;
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->nodeComparator = $nodeComparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Node[]|null
|
||||
*/
|
||||
public function beforeTraverse(array $nodes): ?array
|
||||
{
|
||||
$this->previousAppliedClass = null;
|
||||
|
||||
return parent::beforeTraverse($nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Expression|Node|null
|
||||
*/
|
||||
final public function enterNode(Node $node)
|
||||
{
|
||||
$nodeClass = get_class($node);
|
||||
if (! $this->isMatchingNodeType($nodeClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->currentRectorProvider->changeCurrentRector($this);
|
||||
// for PHP doc info factory and change notifier
|
||||
$this->currentNodeProvider->setNode($node);
|
||||
|
||||
// already removed
|
||||
if ($this->shouldSkipCurrentNode($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// show current Rector class on --debug
|
||||
$this->printDebugApplying();
|
||||
|
||||
$originalNode = $node->getAttribute(AttributeKey::ORIGINAL_NODE) ?? clone $node;
|
||||
$originalNodeWithAttributes = clone $node;
|
||||
|
||||
$node = $this->refactor($node);
|
||||
|
||||
// nothing to change → continue
|
||||
if (! $node instanceof Node) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// changed!
|
||||
if ($this->hasNodeChanged($originalNode, $node)) {
|
||||
$this->mirrorAttributes($originalNodeWithAttributes, $node);
|
||||
$this->updateAttributes($node);
|
||||
$this->keepFileInfoAttribute($node, $originalNode);
|
||||
$this->rectorChangeCollector->notifyNodeFileInfo($node);
|
||||
}
|
||||
|
||||
// if stmt ("$value;") was replaced by expr ("$value"), add the ending ";" (Expression) to prevent breaking the code
|
||||
if ($originalNode instanceof Stmt && $node instanceof Expr) {
|
||||
return new Expression($node);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
protected function isName(Node $node, string $name): bool
|
||||
{
|
||||
return $this->nodeNameResolver->isName($node, $name);
|
||||
}
|
||||
|
||||
protected function areNamesEqual(Node $firstNode, Node $secondNode): bool
|
||||
{
|
||||
return $this->nodeNameResolver->areNamesEqual($firstNode, $secondNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $names
|
||||
*/
|
||||
protected function isNames(Node $node, array $names): bool
|
||||
{
|
||||
return $this->nodeNameResolver->isNames($node, $names);
|
||||
}
|
||||
|
||||
protected function getName(Node $node): ?string
|
||||
{
|
||||
return $this->nodeNameResolver->getName($node);
|
||||
}
|
||||
|
||||
protected function isObjectType(Node $node, ObjectType $objectType): bool
|
||||
{
|
||||
return $this->nodeTypeResolver->isObjectType($node, $objectType);
|
||||
}
|
||||
|
||||
protected function getStaticType(Node $node): Type
|
||||
{
|
||||
return $this->nodeTypeResolver->getStaticType($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use getStaticType() instead, as single method to get types
|
||||
*/
|
||||
protected function getObjectType(Node $node): Type
|
||||
{
|
||||
return $this->nodeTypeResolver->resolve($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node|Node[] $nodes
|
||||
*/
|
||||
protected function traverseNodesWithCallable($nodes, callable $callable): void
|
||||
{
|
||||
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, $callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node|Node[]|null $node
|
||||
*/
|
||||
protected function print($node): string
|
||||
{
|
||||
return $this->betterStandardPrinter->print($node);
|
||||
}
|
||||
|
||||
protected function isAtLeastPhpVersion(int $version): bool
|
||||
{
|
||||
return $this->phpVersionProvider->isAtLeastPhpVersion($version);
|
||||
}
|
||||
|
||||
protected function mirrorComments(Node $newNode, Node $oldNode): void
|
||||
{
|
||||
$newNode->setAttribute(AttributeKey::PHP_DOC_INFO, $oldNode->getAttribute(AttributeKey::PHP_DOC_INFO));
|
||||
$newNode->setAttribute(AttributeKey::COMMENTS, $oldNode->getAttribute(AttributeKey::COMMENTS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Stmt[] $stmts
|
||||
*/
|
||||
protected function unwrapStmts(array $stmts, Node $node): void
|
||||
{
|
||||
// move /* */ doc block from if to first element to keep it
|
||||
$currentPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
|
||||
foreach ($stmts as $key => $ifStmt) {
|
||||
if ($key === 0) {
|
||||
$ifStmt->setAttribute(AttributeKey::PHP_DOC_INFO, $currentPhpDocInfo);
|
||||
|
||||
// move // comments
|
||||
$ifStmt->setAttribute(AttributeKey::COMMENTS, $node->getComments());
|
||||
}
|
||||
|
||||
$this->addNodeAfterNode($ifStmt, $node);
|
||||
}
|
||||
}
|
||||
|
||||
protected function isOnClassMethodCall(Node $node, ObjectType $objectType, string $methodName): bool
|
||||
{
|
||||
if (! $node instanceof MethodCall) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->isObjectType($node->var, $objectType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->isName($node->name, $methodName);
|
||||
}
|
||||
|
||||
protected function isOpenSourceProjectType(): bool
|
||||
{
|
||||
$projectType = $this->parameterProvider->provideStringParameter(Option::PROJECT_TYPE);
|
||||
return $projectType === ProjectType::OPEN_SOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Arg[] $newArgs
|
||||
* @param Arg[] $appendingArgs
|
||||
* @return Arg[]
|
||||
*/
|
||||
protected function appendArgs(array $newArgs, array $appendingArgs): array
|
||||
{
|
||||
foreach ($appendingArgs as $oldArgument) {
|
||||
$newArgs[] = new Arg($oldArgument->value);
|
||||
}
|
||||
|
||||
return $newArgs;
|
||||
}
|
||||
|
||||
protected function unwrapExpression(Stmt $stmt): Node
|
||||
{
|
||||
if ($stmt instanceof Expression) {
|
||||
return $stmt->expr;
|
||||
}
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $newNodes
|
||||
*/
|
||||
protected function addNodesAfterNode(array $newNodes, Node $positionNode): void
|
||||
{
|
||||
$this->nodesToAddCollector->addNodesAfterNode($newNodes, $positionNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $newNodes
|
||||
*/
|
||||
protected function addNodesBeforeNode(array $newNodes, Node $positionNode): void
|
||||
{
|
||||
$this->nodesToAddCollector->addNodesBeforeNode($newNodes, $positionNode);
|
||||
}
|
||||
|
||||
protected function addNodeAfterNode(Node $newNode, Node $positionNode): void
|
||||
{
|
||||
$this->nodesToAddCollector->addNodeAfterNode($newNode, $positionNode);
|
||||
}
|
||||
|
||||
protected function addNodeBeforeNode(Node $newNode, Node $positionNode): void
|
||||
{
|
||||
$this->nodesToAddCollector->addNodeBeforeNode($newNode, $positionNode);
|
||||
}
|
||||
|
||||
protected function addConstructorDependencyToClass(
|
||||
Class_ $class,
|
||||
Type $propertyType,
|
||||
string $propertyName,
|
||||
int $propertyFlags = 0
|
||||
): void {
|
||||
$this->propertyAdder->addConstructorDependencyToClass($class, $propertyType, $propertyName, $propertyFlags);
|
||||
}
|
||||
|
||||
protected function removeNode(Node $node): void
|
||||
{
|
||||
$this->nodeRemover->removeNode($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_|ClassMethod|Function_ $nodeWithStatements
|
||||
*/
|
||||
protected function removeNodeFromStatements(Node $nodeWithStatements, Node $nodeToRemove): void
|
||||
{
|
||||
$this->nodeRemover->removeNodeFromStatements($nodeWithStatements, $nodeToRemove);
|
||||
}
|
||||
|
||||
protected function isNodeRemoved(Node $node): bool
|
||||
{
|
||||
return $this->nodesToRemoveCollector->isNodeRemoved($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $nodes
|
||||
*/
|
||||
protected function removeNodes(array $nodes): void
|
||||
{
|
||||
$this->nodeRemover->removeNodes($nodes);
|
||||
}
|
||||
|
||||
private function isMatchingNodeType(string $nodeClass): bool
|
||||
{
|
||||
foreach ($this->getNodeTypes() as $nodeType) {
|
||||
if (is_a($nodeClass, $nodeType, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function shouldSkipCurrentNode(Node $node): bool
|
||||
{
|
||||
if ($this->isNodeRemoved($node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->exclusionManager->isNodeSkippedByRector($node, $this)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$fileInfo = $node->getAttribute(AttributeKey::FILE_INFO);
|
||||
if (! $fileInfo instanceof SmartFileInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->skipper->shouldSkipElementAndFileInfo($this, $fileInfo);
|
||||
}
|
||||
|
||||
private function printDebugApplying(): void
|
||||
{
|
||||
if (! $this->symfonyStyle->isDebug()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->previousAppliedClass === static::class) {
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent spamming with the same class over and over
|
||||
// indented on purpose to improve log nesting under [refactoring]
|
||||
$this->symfonyStyle->writeln(' [applying] ' . static::class);
|
||||
$this->previousAppliedClass = static::class;
|
||||
}
|
||||
|
||||
private function hasNodeChanged(Node $originalNode, Node $node): bool
|
||||
{
|
||||
if ($this->isNameIdentical($node, $originalNode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! $this->nodeComparator->areNodesEqual($originalNode, $node);
|
||||
}
|
||||
|
||||
private function mirrorAttributes(Node $oldNode, Node $newNode): void
|
||||
{
|
||||
foreach ($oldNode->getAttributes() as $attributeName => $oldNodeAttributeValue) {
|
||||
if (! in_array($attributeName, self::ATTRIBUTES_TO_MIRROR, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newNode->setAttribute($attributeName, $oldNodeAttributeValue);
|
||||
}
|
||||
}
|
||||
|
||||
private function updateAttributes(Node $node): void
|
||||
{
|
||||
// update Resolved name attribute if name is changed
|
||||
if ($node instanceof Name) {
|
||||
$node->setAttribute(AttributeKey::RESOLVED_NAME, $node->toString());
|
||||
}
|
||||
}
|
||||
|
||||
private function keepFileInfoAttribute(Node $node, Node $originalNode): void
|
||||
{
|
||||
$fileInfo = $node->getAttribute(AttributeKey::FILE_INFO);
|
||||
if ($fileInfo instanceof SmartFileInfo) {
|
||||
return;
|
||||
}
|
||||
$fileInfo = $originalNode->getAttribute(AttributeKey::FILE_INFO);
|
||||
|
||||
$originalParent = $originalNode->getAttribute(AttributeKey::PARENT_NODE);
|
||||
|
||||
if ($fileInfo !== null) {
|
||||
$node->setAttribute(AttributeKey::FILE_INFO, $originalNode->getAttribute(AttributeKey::FILE_INFO));
|
||||
} elseif ($originalParent instanceof Node) {
|
||||
$node->setAttribute(AttributeKey::FILE_INFO, $originalParent->getAttribute(AttributeKey::FILE_INFO));
|
||||
}
|
||||
}
|
||||
|
||||
private function isNameIdentical(Node $node, Node $originalNode): bool
|
||||
{
|
||||
if (! $originalNode instanceof Name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// names are the same
|
||||
return $this->nodeComparator->areNodesEqual($originalNode->getAttribute(AttributeKey::ORIGINAL_NAME), $node);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,640 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Core\Rector;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Name;
|
||||
use PhpParser\Node\Stmt;
|
||||
use PhpParser\Node\Stmt\Class_;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Function_;
|
||||
use PhpParser\NodeVisitorAbstract;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
|
||||
use Rector\ChangesReporting\Collector\RectorChangeCollector;
|
||||
use Rector\Core\Application\FileSystem\RemovedAndAddedFilesCollector;
|
||||
use Rector\Core\Configuration\CurrentNodeProvider;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\Contract\Rector\PhpRectorInterface;
|
||||
use Rector\Core\Exclusion\ExclusionManager;
|
||||
use Rector\Core\Logging\CurrentRectorProvider;
|
||||
use Rector\Core\NodeAnalyzer\ClassAnalyzer;
|
||||
use Rector\Core\Php\PhpVersionProvider;
|
||||
use Rector\Core\PhpParser\Comparing\NodeComparator;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\Node\NodeFactory;
|
||||
use Rector\Core\PhpParser\Node\Value\ValueResolver;
|
||||
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
|
||||
use Rector\Core\ValueObject\ProjectType;
|
||||
use Rector\NodeCollector\NodeCollector\NodeRepository;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeRemoval\NodeRemover;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\PostRector\Collector\NodesToAddCollector;
|
||||
use Rector\PostRector\Collector\NodesToRemoveCollector;
|
||||
use Rector\PostRector\DependencyInjection\PropertyAdder;
|
||||
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
|
||||
use Rector\StaticTypeMapper\StaticTypeMapper;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symplify\Astral\NodeTraverser\SimpleCallableNodeTraverser;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Symplify\Skipper\Skipper\Skipper;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
abstract class AbstractTemporaryRector extends NodeVisitorAbstract implements PhpRectorInterface
|
||||
{
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
private const ATTRIBUTES_TO_MIRROR = [
|
||||
AttributeKey::PARENT_NODE,
|
||||
AttributeKey::CLASS_NODE,
|
||||
AttributeKey::CLASS_NAME,
|
||||
AttributeKey::FILE_INFO,
|
||||
AttributeKey::METHOD_NODE,
|
||||
AttributeKey::USE_NODES,
|
||||
AttributeKey::SCOPE,
|
||||
AttributeKey::METHOD_NAME,
|
||||
AttributeKey::NAMESPACE_NAME,
|
||||
AttributeKey::NAMESPACE_NODE,
|
||||
AttributeKey::RESOLVED_NAME,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var NodeNameResolver
|
||||
*/
|
||||
protected $nodeNameResolver;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
protected $nodeTypeResolver;
|
||||
|
||||
/**
|
||||
* @var BetterStandardPrinter
|
||||
*/
|
||||
protected $betterStandardPrinter;
|
||||
|
||||
/**
|
||||
* @var RemovedAndAddedFilesCollector
|
||||
*/
|
||||
protected $removedAndAddedFilesCollector;
|
||||
|
||||
/**
|
||||
* @var ParameterProvider
|
||||
*/
|
||||
protected $parameterProvider;
|
||||
|
||||
/**
|
||||
* @var PhpVersionProvider
|
||||
*/
|
||||
protected $phpVersionProvider;
|
||||
|
||||
/**
|
||||
* @var StaticTypeMapper
|
||||
*/
|
||||
protected $staticTypeMapper;
|
||||
|
||||
/**
|
||||
* @var PhpDocInfoFactory
|
||||
*/
|
||||
protected $phpDocInfoFactory;
|
||||
|
||||
/**
|
||||
* @var NodeFactory
|
||||
*/
|
||||
protected $nodeFactory;
|
||||
|
||||
/**
|
||||
* @var VisibilityManipulator
|
||||
*/
|
||||
protected $visibilityManipulator;
|
||||
|
||||
/**
|
||||
* @var ValueResolver
|
||||
*/
|
||||
protected $valueResolver;
|
||||
|
||||
/**
|
||||
* @var NodeRepository
|
||||
*/
|
||||
protected $nodeRepository;
|
||||
|
||||
/**
|
||||
* @var BetterNodeFinder
|
||||
*/
|
||||
protected $betterNodeFinder;
|
||||
|
||||
/**
|
||||
* @var ClassAnalyzer
|
||||
*/
|
||||
protected $classNodeAnalyzer;
|
||||
|
||||
/**
|
||||
* @var NodeRemover
|
||||
*/
|
||||
protected $nodeRemover;
|
||||
|
||||
/**
|
||||
* @var RectorChangeCollector
|
||||
*/
|
||||
protected $rectorChangeCollector;
|
||||
|
||||
/**
|
||||
* @var NodeComparator
|
||||
*/
|
||||
protected $nodeComparator;
|
||||
|
||||
/**
|
||||
* @var PropertyAdder
|
||||
*/
|
||||
protected $propertyAdder;
|
||||
|
||||
/**
|
||||
* @var SimpleCallableNodeTraverser
|
||||
*/
|
||||
private $simpleCallableNodeTraverser;
|
||||
|
||||
/**
|
||||
* @var SymfonyStyle
|
||||
*/
|
||||
private $symfonyStyle;
|
||||
|
||||
/**
|
||||
* @var ExclusionManager
|
||||
*/
|
||||
private $exclusionManager;
|
||||
|
||||
/**
|
||||
* @var CurrentRectorProvider
|
||||
*/
|
||||
private $currentRectorProvider;
|
||||
|
||||
/**
|
||||
* @var CurrentNodeProvider
|
||||
*/
|
||||
private $currentNodeProvider;
|
||||
|
||||
/**
|
||||
* @var Skipper
|
||||
*/
|
||||
private $skipper;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $previousAppliedClass;
|
||||
|
||||
/**
|
||||
* @var NodesToRemoveCollector
|
||||
*/
|
||||
private $nodesToRemoveCollector;
|
||||
|
||||
/**
|
||||
* @var NodesToAddCollector
|
||||
*/
|
||||
private $nodesToAddCollector;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function autowireAbstractTemporaryRector(
|
||||
NodesToRemoveCollector $nodesToRemoveCollector,
|
||||
NodesToAddCollector $nodesToAddCollector,
|
||||
RectorChangeCollector $rectorChangeCollector,
|
||||
NodeRemover $nodeRemover,
|
||||
PropertyAdder $propertyAdder,
|
||||
RemovedAndAddedFilesCollector $removedAndAddedFilesCollector,
|
||||
BetterStandardPrinter $betterStandardPrinter,
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
SimpleCallableNodeTraverser $simpleCallableNodeTraverser,
|
||||
VisibilityManipulator $visibilityManipulator,
|
||||
NodeFactory $nodeFactory,
|
||||
PhpDocInfoFactory $phpDocInfoFactory,
|
||||
SymfonyStyle $symfonyStyle,
|
||||
PhpVersionProvider $phpVersionProvider,
|
||||
ExclusionManager $exclusionManager,
|
||||
StaticTypeMapper $staticTypeMapper,
|
||||
ParameterProvider $parameterProvider,
|
||||
CurrentRectorProvider $currentRectorProvider,
|
||||
ClassAnalyzer $classAnalyzer,
|
||||
CurrentNodeProvider $currentNodeProvider,
|
||||
Skipper $skipper,
|
||||
ValueResolver $valueResolver,
|
||||
NodeRepository $nodeRepository,
|
||||
BetterNodeFinder $betterNodeFinder,
|
||||
NodeComparator $nodeComparator
|
||||
): void {
|
||||
$this->nodesToRemoveCollector = $nodesToRemoveCollector;
|
||||
$this->nodesToAddCollector = $nodesToAddCollector;
|
||||
$this->rectorChangeCollector = $rectorChangeCollector;
|
||||
$this->nodeRemover = $nodeRemover;
|
||||
$this->propertyAdder = $propertyAdder;
|
||||
$this->removedAndAddedFilesCollector = $removedAndAddedFilesCollector;
|
||||
$this->betterStandardPrinter = $betterStandardPrinter;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
$this->simpleCallableNodeTraverser = $simpleCallableNodeTraverser;
|
||||
$this->visibilityManipulator = $visibilityManipulator;
|
||||
$this->nodeFactory = $nodeFactory;
|
||||
$this->phpDocInfoFactory = $phpDocInfoFactory;
|
||||
$this->symfonyStyle = $symfonyStyle;
|
||||
$this->phpVersionProvider = $phpVersionProvider;
|
||||
$this->exclusionManager = $exclusionManager;
|
||||
$this->staticTypeMapper = $staticTypeMapper;
|
||||
$this->parameterProvider = $parameterProvider;
|
||||
$this->currentRectorProvider = $currentRectorProvider;
|
||||
$this->classNodeAnalyzer = $classAnalyzer;
|
||||
$this->currentNodeProvider = $currentNodeProvider;
|
||||
$this->skipper = $skipper;
|
||||
$this->valueResolver = $valueResolver;
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->nodeComparator = $nodeComparator;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Node[]|null
|
||||
*/
|
||||
public function beforeTraverse(array $nodes): ?array
|
||||
{
|
||||
$this->previousAppliedClass = null;
|
||||
|
||||
return parent::beforeTraverse($nodes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Expression|Node|null
|
||||
*/
|
||||
final public function enterNode(Node $node)
|
||||
{
|
||||
$nodeClass = get_class($node);
|
||||
if (! $this->isMatchingNodeType($nodeClass)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->currentRectorProvider->changeCurrentRector($this);
|
||||
// for PHP doc info factory and change notifier
|
||||
$this->currentNodeProvider->setNode($node);
|
||||
|
||||
// already removed
|
||||
if ($this->shouldSkipCurrentNode($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// show current Rector class on --debug
|
||||
$this->printDebugApplying();
|
||||
|
||||
$originalNode = $node->getAttribute(AttributeKey::ORIGINAL_NODE) ?? clone $node;
|
||||
$originalNodeWithAttributes = clone $node;
|
||||
|
||||
$node = $this->refactor($node);
|
||||
|
||||
// nothing to change → continue
|
||||
if (! $node instanceof Node) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// changed!
|
||||
if ($this->hasNodeChanged($originalNode, $node)) {
|
||||
$this->mirrorAttributes($originalNodeWithAttributes, $node);
|
||||
$this->updateAttributes($node);
|
||||
$this->keepFileInfoAttribute($node, $originalNode);
|
||||
$this->rectorChangeCollector->notifyNodeFileInfo($node);
|
||||
}
|
||||
|
||||
// if stmt ("$value;") was replaced by expr ("$value"), add the ending ";" (Expression) to prevent breaking the code
|
||||
if ($originalNode instanceof Stmt && $node instanceof Expr) {
|
||||
return new Expression($node);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
||||
protected function isName(Node $node, string $name): bool
|
||||
{
|
||||
return $this->nodeNameResolver->isName($node, $name);
|
||||
}
|
||||
|
||||
protected function areNamesEqual(Node $firstNode, Node $secondNode): bool
|
||||
{
|
||||
return $this->nodeNameResolver->areNamesEqual($firstNode, $secondNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $names
|
||||
*/
|
||||
protected function isNames(Node $node, array $names): bool
|
||||
{
|
||||
return $this->nodeNameResolver->isNames($node, $names);
|
||||
}
|
||||
|
||||
protected function getName(Node $node): ?string
|
||||
{
|
||||
return $this->nodeNameResolver->getName($node);
|
||||
}
|
||||
|
||||
protected function isObjectType(Node $node, ObjectType $objectType): bool
|
||||
{
|
||||
return $this->nodeTypeResolver->isObjectType($node, $objectType);
|
||||
}
|
||||
|
||||
protected function isNumberType(Node $node): bool
|
||||
{
|
||||
return $this->nodeTypeResolver->isNumberType($node);
|
||||
}
|
||||
|
||||
protected function getStaticType(Node $node): Type
|
||||
{
|
||||
return $this->nodeTypeResolver->getStaticType($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use getStaticType() instead, as single method to get types
|
||||
*/
|
||||
protected function getObjectType(Node $node): Type
|
||||
{
|
||||
return $this->nodeTypeResolver->resolve($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node|Node[] $nodes
|
||||
*/
|
||||
protected function traverseNodesWithCallable($nodes, callable $callable): void
|
||||
{
|
||||
$this->simpleCallableNodeTraverser->traverseNodesWithCallable($nodes, $callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node|Node[]|null $node
|
||||
*/
|
||||
protected function print($node): string
|
||||
{
|
||||
return $this->betterStandardPrinter->print($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all comments from both nodes
|
||||
*
|
||||
* @param Node|Node[]|null $firstNode
|
||||
* @param Node|Node[]|null $secondNode
|
||||
*/
|
||||
protected function areNodesEqual($firstNode, $secondNode): bool
|
||||
{
|
||||
return $this->nodeComparator->areNodesEqual($firstNode, $secondNode);
|
||||
}
|
||||
|
||||
protected function getNextExpression(Node $node): ?Node
|
||||
{
|
||||
$currentExpression = $node->getAttribute(AttributeKey::CURRENT_STATEMENT);
|
||||
if (! $currentExpression instanceof Expression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $currentExpression->getAttribute(AttributeKey::NEXT_NODE);
|
||||
}
|
||||
|
||||
protected function isAtLeastPhpVersion(int $version): bool
|
||||
{
|
||||
return $this->phpVersionProvider->isAtLeastPhpVersion($version);
|
||||
}
|
||||
|
||||
protected function mirrorComments(Node $newNode, Node $oldNode): void
|
||||
{
|
||||
$newNode->setAttribute(AttributeKey::PHP_DOC_INFO, $oldNode->getAttribute(AttributeKey::PHP_DOC_INFO));
|
||||
$newNode->setAttribute(AttributeKey::COMMENTS, $oldNode->getAttribute(AttributeKey::COMMENTS));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Stmt[] $stmts
|
||||
*/
|
||||
protected function unwrapStmts(array $stmts, Node $node): void
|
||||
{
|
||||
// move /* */ doc block from if to first element to keep it
|
||||
$currentPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
|
||||
|
||||
foreach ($stmts as $key => $ifStmt) {
|
||||
if ($key === 0) {
|
||||
$ifStmt->setAttribute(AttributeKey::PHP_DOC_INFO, $currentPhpDocInfo);
|
||||
|
||||
// move // comments
|
||||
$ifStmt->setAttribute(AttributeKey::COMMENTS, $node->getComments());
|
||||
}
|
||||
|
||||
$this->addNodeAfterNode($ifStmt, $node);
|
||||
}
|
||||
}
|
||||
|
||||
protected function isOnClassMethodCall(Node $node, ObjectType $objectType, string $methodName): bool
|
||||
{
|
||||
if (! $node instanceof MethodCall) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (! $this->isObjectType($node->var, $objectType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->isName($node->name, $methodName);
|
||||
}
|
||||
|
||||
protected function isOpenSourceProjectType(): bool
|
||||
{
|
||||
$projectType = $this->parameterProvider->provideStringParameter(Option::PROJECT_TYPE);
|
||||
return $projectType === ProjectType::OPEN_SOURCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Arg[] $newArgs
|
||||
* @param Arg[] $appendingArgs
|
||||
* @return Arg[]
|
||||
*/
|
||||
protected function appendArgs(array $newArgs, array $appendingArgs): array
|
||||
{
|
||||
foreach ($appendingArgs as $oldArgument) {
|
||||
$newArgs[] = new Arg($oldArgument->value);
|
||||
}
|
||||
|
||||
return $newArgs;
|
||||
}
|
||||
|
||||
protected function unwrapExpression(Stmt $stmt): Node
|
||||
{
|
||||
if ($stmt instanceof Expression) {
|
||||
return $stmt->expr;
|
||||
}
|
||||
|
||||
return $stmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $newNodes
|
||||
*/
|
||||
protected function addNodesAfterNode(array $newNodes, Node $positionNode): void
|
||||
{
|
||||
$this->nodesToAddCollector->addNodesAfterNode($newNodes, $positionNode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $newNodes
|
||||
*/
|
||||
protected function addNodesBeforeNode(array $newNodes, Node $positionNode): void
|
||||
{
|
||||
$this->nodesToAddCollector->addNodesBeforeNode($newNodes, $positionNode);
|
||||
}
|
||||
|
||||
protected function addNodeAfterNode(Node $newNode, Node $positionNode): void
|
||||
{
|
||||
$this->nodesToAddCollector->addNodeAfterNode($newNode, $positionNode);
|
||||
}
|
||||
|
||||
protected function addNodeBeforeNode(Node $newNode, Node $positionNode): void
|
||||
{
|
||||
$this->nodesToAddCollector->addNodeBeforeNode($newNode, $positionNode);
|
||||
}
|
||||
|
||||
protected function addConstructorDependencyToClass(
|
||||
Class_ $class,
|
||||
Type $propertyType,
|
||||
string $propertyName,
|
||||
int $propertyFlags = 0
|
||||
): void {
|
||||
$this->propertyAdder->addConstructorDependencyToClass($class, $propertyType, $propertyName, $propertyFlags);
|
||||
}
|
||||
|
||||
protected function removeNode(Node $node): void
|
||||
{
|
||||
$this->nodeRemover->removeNode($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Class_|ClassMethod|Function_ $nodeWithStatements
|
||||
*/
|
||||
protected function removeNodeFromStatements(Node $nodeWithStatements, Node $nodeToRemove): void
|
||||
{
|
||||
$this->nodeRemover->removeNodeFromStatements($nodeWithStatements, $nodeToRemove);
|
||||
}
|
||||
|
||||
protected function isNodeRemoved(Node $node): bool
|
||||
{
|
||||
return $this->nodesToRemoveCollector->isNodeRemoved($node);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Node[] $nodes
|
||||
*/
|
||||
protected function removeNodes(array $nodes): void
|
||||
{
|
||||
$this->nodeRemover->removeNodes($nodes);
|
||||
}
|
||||
|
||||
private function isMatchingNodeType(string $nodeClass): bool
|
||||
{
|
||||
foreach ($this->getNodeTypes() as $nodeType) {
|
||||
if (is_a($nodeClass, $nodeType, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function shouldSkipCurrentNode(Node $node): bool
|
||||
{
|
||||
if ($this->isNodeRemoved($node)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($this->exclusionManager->isNodeSkippedByRector($node, $this)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$fileInfo = $node->getAttribute(AttributeKey::FILE_INFO);
|
||||
if (! $fileInfo instanceof SmartFileInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->skipper->shouldSkipElementAndFileInfo($this, $fileInfo);
|
||||
}
|
||||
|
||||
private function printDebugApplying(): void
|
||||
{
|
||||
if (! $this->symfonyStyle->isDebug()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->previousAppliedClass === static::class) {
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent spamming with the same class over and over
|
||||
// indented on purpose to improve log nesting under [refactoring]
|
||||
$this->symfonyStyle->writeln(' [applying] ' . static::class);
|
||||
$this->previousAppliedClass = static::class;
|
||||
}
|
||||
|
||||
private function hasNodeChanged(Node $originalNode, Node $node): bool
|
||||
{
|
||||
if ($this->isNameIdentical($node, $originalNode)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ! $this->nodeComparator->areNodesEqual($originalNode, $node);
|
||||
}
|
||||
|
||||
private function mirrorAttributes(Node $oldNode, Node $newNode): void
|
||||
{
|
||||
foreach ($oldNode->getAttributes() as $attributeName => $oldNodeAttributeValue) {
|
||||
if (! in_array($attributeName, self::ATTRIBUTES_TO_MIRROR, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$newNode->setAttribute($attributeName, $oldNodeAttributeValue);
|
||||
}
|
||||
}
|
||||
|
||||
private function updateAttributes(Node $node): void
|
||||
{
|
||||
// update Resolved name attribute if name is changed
|
||||
if ($node instanceof Name) {
|
||||
$node->setAttribute(AttributeKey::RESOLVED_NAME, $node->toString());
|
||||
}
|
||||
}
|
||||
|
||||
private function keepFileInfoAttribute(Node $node, Node $originalNode): void
|
||||
{
|
||||
$fileInfo = $node->getAttribute(AttributeKey::FILE_INFO);
|
||||
if ($fileInfo instanceof SmartFileInfo) {
|
||||
return;
|
||||
}
|
||||
$fileInfo = $originalNode->getAttribute(AttributeKey::FILE_INFO);
|
||||
|
||||
$originalParent = $originalNode->getAttribute(AttributeKey::PARENT_NODE);
|
||||
|
||||
if ($fileInfo !== null) {
|
||||
$node->setAttribute(AttributeKey::FILE_INFO, $originalNode->getAttribute(AttributeKey::FILE_INFO));
|
||||
} elseif ($originalParent instanceof Node) {
|
||||
$node->setAttribute(AttributeKey::FILE_INFO, $originalParent->getAttribute(AttributeKey::FILE_INFO));
|
||||
}
|
||||
}
|
||||
|
||||
private function isNameIdentical(Node $node, Node $originalNode): bool
|
||||
{
|
||||
if (! $originalNode instanceof Name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// names are the same
|
||||
return $this->nodeComparator->areNodesEqual($originalNode->getAttribute(AttributeKey::ORIGINAL_NAME), $node);
|
||||
}
|
||||
}
|
|
@ -4,15 +4,42 @@ declare(strict_types=1);
|
|||
|
||||
namespace Rector\Utils\DoctrineAnnotationParserSyncer\Rector\StaticCall;
|
||||
|
||||
use Doctrine\Common\Annotations\AnnotationRegistry;
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\StaticCall;
|
||||
use PHPStan\Type\ObjectType;
|
||||
use Rector\Core\Rector\AbstractTemporaryRector;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Utils\DoctrineAnnotationParserSyncer\Contract\Rector\ClassSyncerRectorInterface;
|
||||
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
|
||||
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
|
||||
|
||||
final class RemoveAnnotationRegistryRegisterFileRector extends AbstractTemporaryRector implements ClassSyncerRectorInterface
|
||||
final class RemoveAnnotationRegistryRegisterFileRector extends AbstractRector implements ClassSyncerRectorInterface
|
||||
{
|
||||
public function getRuleDefinition(): RuleDefinition
|
||||
{
|
||||
return new RuleDefinition('Remove registerFile() static calls from AnnotationParser', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
class AnnotationParser
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
Doctrine\Common\Annotations\AnnotationRegistry::registerFile('...');
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
class AnnotationParser
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
}
|
||||
}
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<class-string<\PhpParser\Node>>
|
||||
*/
|
||||
|
@ -35,7 +62,11 @@ final class RemoveAnnotationRegistryRegisterFileRector extends AbstractTemporary
|
|||
return null;
|
||||
}
|
||||
|
||||
if (! $this->nodeNameResolver->isStaticCallNamed($node, AnnotationRegistry::class, 'registerFile')) {
|
||||
if (! $this->nodeNameResolver->isStaticCallNamed(
|
||||
$node,
|
||||
'Doctrine\Common\Annotations\AnnotationRegistry',
|
||||
'registerFile'
|
||||
)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ services:
|
|||
- PHPStan\Type\StaticType
|
||||
- Rector\BetterPhpDocParser\PhpDocNodeFactory\AbstractPhpDocNodeFactory
|
||||
- PHPStan\PhpDocParser\Parser\PhpDocParser
|
||||
- Rector\PostRector\Rector\AbstractPostRector
|
||||
# value objects
|
||||
- Rector\Defluent\ValueObject\AbstractRootExpr
|
||||
- Symplify\SetConfigResolver\Provider\AbstractSetProvider
|
||||
|
|
|
@ -10,6 +10,7 @@ use PHPStan\Analyser\Scope;
|
|||
use PHPStan\Reflection\MethodReflection;
|
||||
use PHPStan\Type\DynamicMethodReturnTypeExtension;
|
||||
use PHPStan\Type\Type;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Core\Rector\AbstractTemporaryRector;
|
||||
use Rector\PHPStanExtensions\TypeResolver\MethodCallTypeResolver;
|
||||
|
||||
|
@ -32,7 +33,7 @@ final class NameResolverReturnTypeAbstractRectorExtension implements DynamicMeth
|
|||
|
||||
public function getClass(): string
|
||||
{
|
||||
return AbstractTemporaryRector::class;
|
||||
return AbstractRector::class;
|
||||
}
|
||||
|
||||
public function isMethodSupported(MethodReflection $methodReflection): bool
|
||||
|
|
Loading…
Reference in New Issue
Block a user