mirror of
https://github.com/rectorphp/rector.git
synced 2024-05-30 07:50:53 +00:00
[Defluent] Refactoring to multiple rules (#4400)
* [Defluent] Refactoring to multiple rules * [Defluent] Decouple defluent-only set, it deserved to have own domain * cleanup * [rector] cleanup * [cs] cleanup * fixup! cleanup * static fixes Co-authored-by: rector-bot <tomas@getrector.org>
This commit is contained in:
parent
d017e5417e
commit
8af70b5ac0
|
@ -44,6 +44,7 @@
|
|||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"nette/application": "^3.0",
|
||||
"nette/di": "^3.0",
|
||||
"nette/forms": "^3.0",
|
||||
"ocramius/package-versions": "^1.9",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.2",
|
||||
|
@ -109,6 +110,7 @@
|
|||
"Rector\\NetteToSymfony\\": "rules/nette-to-symfony/src",
|
||||
"Rector\\NetteUtilsCodeQuality\\": "rules/nette-utils-code-quality/src",
|
||||
"Rector\\Nette\\": "rules/nette/src",
|
||||
"Rector\\Defluent\\": "rules/defluent/src",
|
||||
"Rector\\NodeCollector\\": "packages/node-collector/src",
|
||||
"Rector\\NodeNameResolver\\": "packages/node-name-resolver/src",
|
||||
"Rector\\NodeNestingScope\\": "packages/node-nesting-scope/src",
|
||||
|
@ -194,7 +196,8 @@
|
|||
"rules/type-declaration/tests/Rector/FunctionLike/ReturnTypeDeclarationRector/Source/MyBar.php",
|
||||
"rules/type-declaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Source/EventDispatcher.php",
|
||||
"stubs/Nette/Localization/ITranslation.php",
|
||||
"vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php"
|
||||
"vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php",
|
||||
"tests/debug_functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Rector\\Architecture\\Tests\\": "rules/architecture/tests",
|
||||
|
@ -222,6 +225,7 @@
|
|||
"Rector\\JMS\\Tests\\": "rules/jms/tests",
|
||||
"Rector\\Laravel\\Tests\\": "rules/laravel/tests",
|
||||
"Rector\\Legacy\\Tests\\": "rules/legacy/tests",
|
||||
"Rector\\Defluent\\Tests\\": "rules/defluent/tests",
|
||||
"Rector\\MagicDisclosure\\Tests\\": "rules/magic-disclosure/tests",
|
||||
"Rector\\MockeryToProphecy\\Tests\\": "rules/mockery-to-prophecy/tests",
|
||||
"Rector\\MockistaToMockery\\Tests\\": "rules/mockista-to-mockery/tests",
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\MagicDisclosure\Rector\ClassMethod\ReturnThisRemoveRector;
|
||||
use Rector\MagicDisclosure\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector;
|
||||
use Rector\MagicDisclosure\Rector\MethodCall\InArgFluentChainMethodCallToStandaloneMethodCallRector;
|
||||
use Rector\MagicDisclosure\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector;
|
||||
use Rector\MagicDisclosure\Rector\Return_\DefluentReturnMethodCallRector;
|
||||
use Rector\Defluent\Rector\ClassMethod\ReturnThisRemoveRector;
|
||||
use Rector\Defluent\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector;
|
||||
use Rector\Defluent\Rector\MethodCall\InArgFluentChainMethodCallToStandaloneMethodCallRector;
|
||||
use Rector\Defluent\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector;
|
||||
use Rector\Defluent\Rector\MethodCall\NewFluentChainMethodCallToNonFluentRector;
|
||||
use Rector\Defluent\Rector\Return_\DefluentReturnMethodCallRector;
|
||||
use Rector\Defluent\Rector\Return_\ReturnFluentChainMethodCallToNormalMethodCallRector;
|
||||
use Rector\Defluent\Rector\Return_\ReturnNewFluentChainMethodCallToNonFluentRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
// @see https://ocramius.github.io/blog/fluent-interfaces-are-evil/
|
||||
|
@ -15,9 +18,16 @@ use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigura
|
|||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
// variable/property
|
||||
$services->set(FluentChainMethodCallToNormalMethodCallRector::class);
|
||||
$services->set(ReturnFluentChainMethodCallToNormalMethodCallRector::class);
|
||||
|
||||
// new
|
||||
$services->set(NewFluentChainMethodCallToNonFluentRector::class);
|
||||
$services->set(ReturnNewFluentChainMethodCallToNonFluentRector::class);
|
||||
|
||||
$services->set(ReturnThisRemoveRector::class);
|
||||
$services->set(DefluentReturnMethodCallRector::class);
|
||||
$services->set(FluentChainMethodCallToNormalMethodCallRector::class);
|
||||
$services->set(MethodCallOnSetterMethodCallToStandaloneAssignRector::class);
|
||||
$services->set(InArgFluentChainMethodCallToStandaloneMethodCallRector::class);
|
||||
};
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Rector\MagicDisclosure\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector;
|
||||
use Rector\Defluent\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector;
|
||||
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
|
||||
use Rector\Renaming\ValueObject\MethodCallRename;
|
||||
use function Rector\SymfonyPhpConfig\inline_value_objects;
|
||||
|
@ -16,7 +16,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
$services = $containerConfigurator->services();
|
||||
|
||||
# both uses "%classes_to_defluent%
|
||||
#diff-810cdcfdd8a6b9e1fc0d1e96d7786874
|
||||
$services->set(FluentChainMethodCallToNormalMethodCallRector::class);
|
||||
|
||||
$configuration = [
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# All 588 Rectors Overview
|
||||
# All 592 Rectors Overview
|
||||
|
||||
- [Projects](#projects)
|
||||
---
|
||||
|
@ -12,6 +12,7 @@
|
|||
- [CodingStyle](#codingstyle) (33)
|
||||
- [DeadCode](#deadcode) (40)
|
||||
- [Decouple](#decouple) (1)
|
||||
- [Defluent](#defluent) (8)
|
||||
- [Doctrine](#doctrine) (17)
|
||||
- [DoctrineCodeQuality](#doctrinecodequality) (8)
|
||||
- [DoctrineGedmoToKnplabs](#doctrinegedmotoknplabs) (7)
|
||||
|
@ -26,7 +27,7 @@
|
|||
- [JMS](#jms) (2)
|
||||
- [Laravel](#laravel) (3)
|
||||
- [Legacy](#legacy) (4)
|
||||
- [MagicDisclosure](#magicdisclosure) (8)
|
||||
- [MagicDisclosure](#magicdisclosure) (3)
|
||||
- [MockeryToProphecy](#mockerytoprophecy) (2)
|
||||
- [MockistaToMockery](#mockistatomockery) (2)
|
||||
- [MysqlToMysqli](#mysqltomysqli) (4)
|
||||
|
@ -3492,6 +3493,171 @@ class NewDecoupledClass extends AddedParentClass
|
|||
|
||||
<br><br>
|
||||
|
||||
## Defluent
|
||||
|
||||
### `DefluentReturnMethodCallRector`
|
||||
|
||||
- class: [`Rector\Defluent\Rector\Return_\DefluentReturnMethodCallRector`](/rules/defluent/src/Rector/Return_/DefluentReturnMethodCallRector.php)
|
||||
- [test fixtures](/rules/defluent/tests/Rector/Return_/DefluentReturnMethodCallRector/Fixture)
|
||||
|
||||
Turns return of fluent, to standalone call line and return of value
|
||||
|
||||
```diff
|
||||
$someClass = new SomeClass();
|
||||
-return $someClass->someFunction();
|
||||
+$someClass->someFunction();
|
||||
+return $someClass;
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `FluentChainMethodCallToNormalMethodCallRector`
|
||||
|
||||
- class: [`Rector\Defluent\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector`](/rules/defluent/src/Rector/MethodCall/FluentChainMethodCallToNormalMethodCallRector.php)
|
||||
- [test fixtures](/rules/defluent/tests/Rector/MethodCall/FluentChainMethodCallToNormalMethodCallRector/Fixture)
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
```diff
|
||||
$someClass = new SomeClass();
|
||||
-$someClass->someFunction()
|
||||
- ->otherFunction();
|
||||
+$someClass->someFunction();
|
||||
+$someClass->otherFunction();
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `InArgFluentChainMethodCallToStandaloneMethodCallRector`
|
||||
|
||||
- class: [`Rector\Defluent\Rector\MethodCall\InArgFluentChainMethodCallToStandaloneMethodCallRector`](/rules/defluent/src/Rector/MethodCall/InArgFluentChainMethodCallToStandaloneMethodCallRector.php)
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
```diff
|
||||
class UsedAsParameter
|
||||
{
|
||||
public function someFunction(FluentClass $someClass)
|
||||
{
|
||||
- $this->processFluentClass($someClass->someFunction()->otherFunction());
|
||||
+ $someClass->someFunction();
|
||||
+ $someClass->otherFunction();
|
||||
+ $this->processFluentClass($someClass);
|
||||
}
|
||||
|
||||
public function processFluentClass(FluentClass $someClass)
|
||||
{
|
||||
}
|
||||
-}
|
||||
+}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `MethodCallOnSetterMethodCallToStandaloneAssignRector`
|
||||
|
||||
- class: [`Rector\Defluent\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector`](/rules/defluent/src/Rector/MethodCall/MethodCallOnSetterMethodCallToStandaloneAssignRector.php)
|
||||
- [test fixtures](/rules/defluent/tests/Rector/MethodCall/MethodCallOnSetterMethodCallToStandaloneAssignRector/Fixture)
|
||||
|
||||
Change method call on setter to standalone assign before the setter
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function some()
|
||||
{
|
||||
- $this->anotherMethod(new AnotherClass())
|
||||
- ->someFunction();
|
||||
+ $anotherClass = new AnotherClass();
|
||||
+ $anotherClass->someFunction();
|
||||
+ $this->anotherMethod($anotherClass);
|
||||
}
|
||||
|
||||
public function anotherMethod(AnotherClass $anotherClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `NewFluentChainMethodCallToNonFluentRector`
|
||||
|
||||
- class: [`Rector\Defluent\Rector\MethodCall\NewFluentChainMethodCallToNonFluentRector`](/rules/defluent/src/Rector/MethodCall/NewFluentChainMethodCallToNonFluentRector.php)
|
||||
- [test fixtures](/rules/defluent/tests/Rector/MethodCall/NewFluentChainMethodCallToNonFluentRector/Fixture)
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
```diff
|
||||
-(new SomeClass())->someFunction()
|
||||
- ->otherFunction();
|
||||
+$someClass = new SomeClass();
|
||||
+$someClass->someFunction();
|
||||
+$someClass->otherFunction();
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `ReturnFluentChainMethodCallToNormalMethodCallRector`
|
||||
|
||||
- class: [`Rector\Defluent\Rector\Return_\ReturnFluentChainMethodCallToNormalMethodCallRector`](/rules/defluent/src/Rector/Return_/ReturnFluentChainMethodCallToNormalMethodCallRector.php)
|
||||
- [test fixtures](/rules/defluent/tests/Rector/Return_/ReturnFluentChainMethodCallToNormalMethodCallRector/Fixture)
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
```diff
|
||||
$someClass = new SomeClass();
|
||||
-return $someClass->someFunction()
|
||||
- ->otherFunction();
|
||||
+$someClass->someFunction();
|
||||
+$someClass->otherFunction();
|
||||
+return $someClass;
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `ReturnNewFluentChainMethodCallToNonFluentRector`
|
||||
|
||||
- class: [`Rector\Defluent\Rector\Return_\ReturnNewFluentChainMethodCallToNonFluentRector`](/rules/defluent/src/Rector/Return_/ReturnNewFluentChainMethodCallToNonFluentRector.php)
|
||||
- [test fixtures](/rules/defluent/tests/Rector/Return_/ReturnNewFluentChainMethodCallToNonFluentRector/Fixture)
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
```diff
|
||||
-return (new SomeClass())->someFunction()
|
||||
- ->otherFunction();
|
||||
+$someClass = new SomeClass();
|
||||
+$someClass->someFunction();
|
||||
+$someClass->otherFunction();
|
||||
+return $someClass;
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `ReturnThisRemoveRector`
|
||||
|
||||
- class: [`Rector\Defluent\Rector\ClassMethod\ReturnThisRemoveRector`](/rules/defluent/src/Rector/ClassMethod/ReturnThisRemoveRector.php)
|
||||
- [test fixtures](/rules/defluent/tests/Rector/ClassMethod/ReturnThisRemoveRector/Fixture)
|
||||
|
||||
Removes "return `$this;"` from *fluent interfaces* for specified classes.
|
||||
|
||||
```diff
|
||||
class SomeExampleClass
|
||||
{
|
||||
public function someFunction()
|
||||
{
|
||||
- return $this;
|
||||
}
|
||||
|
||||
public function otherFunction()
|
||||
{
|
||||
- return $this;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
## Doctrine
|
||||
|
||||
### `AddEntityIdByConditionRector`
|
||||
|
@ -7118,39 +7284,6 @@ Remove includes (include, include_once, require, require_once) from source
|
|||
|
||||
## MagicDisclosure
|
||||
|
||||
### `DefluentReturnMethodCallRector`
|
||||
|
||||
- class: [`Rector\MagicDisclosure\Rector\Return_\DefluentReturnMethodCallRector`](/rules/magic-disclosure/src/Rector/Return_/DefluentReturnMethodCallRector.php)
|
||||
- [test fixtures](/rules/magic-disclosure/tests/Rector/Return_/DefluentReturnMethodCallRector/Fixture)
|
||||
|
||||
Turns return of fluent, to standalone call line and return of value
|
||||
|
||||
```diff
|
||||
$someClass = new SomeClass();
|
||||
-return $someClass->someFunction();
|
||||
+$someClass->someFunction();
|
||||
+return $someClass;
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `FluentChainMethodCallToNormalMethodCallRector`
|
||||
|
||||
- class: [`Rector\MagicDisclosure\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector`](/rules/magic-disclosure/src/Rector/MethodCall/FluentChainMethodCallToNormalMethodCallRector.php)
|
||||
- [test fixtures](/rules/magic-disclosure/tests/Rector/MethodCall/FluentChainMethodCallToNormalMethodCallRector/Fixture)
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
```diff
|
||||
$someClass = new SomeClass();
|
||||
-$someClass->someFunction()
|
||||
- ->otherFunction();
|
||||
+$someClass->someFunction();
|
||||
+$someClass->otherFunction();
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `GetAndSetToMethodCallRector`
|
||||
|
||||
- class: [`Rector\MagicDisclosure\Rector\Assign\GetAndSetToMethodCallRector`](/rules/magic-disclosure/src/Rector/Assign/GetAndSetToMethodCallRector.php)
|
||||
|
@ -7219,83 +7352,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
|
|||
|
||||
<br><br>
|
||||
|
||||
### `InArgFluentChainMethodCallToStandaloneMethodCallRector`
|
||||
|
||||
- class: [`Rector\MagicDisclosure\Rector\MethodCall\InArgFluentChainMethodCallToStandaloneMethodCallRector`](/rules/magic-disclosure/src/Rector/MethodCall/InArgFluentChainMethodCallToStandaloneMethodCallRector.php)
|
||||
|
||||
Turns fluent interface calls to classic ones.
|
||||
|
||||
```diff
|
||||
class UsedAsParameter
|
||||
{
|
||||
public function someFunction(FluentClass $someClass)
|
||||
{
|
||||
- $this->processFluentClass($someClass->someFunction()->otherFunction());
|
||||
+ $someClass->someFunction();
|
||||
+ $someClass->otherFunction();
|
||||
+ $this->processFluentClass($someClass);
|
||||
}
|
||||
|
||||
public function processFluentClass(FluentClass $someClass)
|
||||
{
|
||||
}
|
||||
-}
|
||||
+}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `MethodCallOnSetterMethodCallToStandaloneAssignRector`
|
||||
|
||||
- class: [`Rector\MagicDisclosure\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector`](/rules/magic-disclosure/src/Rector/MethodCall/MethodCallOnSetterMethodCallToStandaloneAssignRector.php)
|
||||
- [test fixtures](/rules/magic-disclosure/tests/Rector/MethodCall/MethodCallOnSetterMethodCallToStandaloneAssignRector/Fixture)
|
||||
|
||||
Change method call on setter to standalone assign before the setter
|
||||
|
||||
```diff
|
||||
class SomeClass
|
||||
{
|
||||
public function some()
|
||||
{
|
||||
- $this->anotherMethod(new AnotherClass())
|
||||
- ->someFunction();
|
||||
+ $anotherClass = new AnotherClass();
|
||||
+ $anotherClass->someFunction();
|
||||
+ $this->anotherMethod($anotherClass);
|
||||
}
|
||||
|
||||
public function anotherMethod(AnotherClass $anotherClass)
|
||||
{
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `ReturnThisRemoveRector`
|
||||
|
||||
- class: [`Rector\MagicDisclosure\Rector\ClassMethod\ReturnThisRemoveRector`](/rules/magic-disclosure/src/Rector/ClassMethod/ReturnThisRemoveRector.php)
|
||||
- [test fixtures](/rules/magic-disclosure/tests/Rector/ClassMethod/ReturnThisRemoveRector/Fixture)
|
||||
|
||||
Removes "return `$this;"` from *fluent interfaces* for specified classes.
|
||||
|
||||
```diff
|
||||
class SomeExampleClass
|
||||
{
|
||||
public function someFunction()
|
||||
{
|
||||
- return $this;
|
||||
}
|
||||
|
||||
public function otherFunction()
|
||||
{
|
||||
- return $this;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<br><br>
|
||||
|
||||
### `ToStringToMethodCallRector`
|
||||
|
||||
- class: [`Rector\MagicDisclosure\Rector\String_\ToStringToMethodCallRector`](/rules/magic-disclosure/src/Rector/String_/ToStringToMethodCallRector.php)
|
||||
|
@ -8609,7 +8665,7 @@ Rename "*.phpt" file to "*Test.php" file
|
|||
|
||||
### `DeleteFactoryInterfaceRector`
|
||||
|
||||
- class: [`Rector\NetteToSymfony\Rector\Interface_\DeleteFactoryInterfaceRector`](/rules/nette-to-symfony/src/Rector/FileSystem/DeleteFactoryInterfaceRector.php)
|
||||
- class: [`Rector\NetteToSymfony\Rector\Interface_\DeleteFactoryInterfaceRector`](/rules/nette-to-symfony/src/Rector/Interface_/DeleteFactoryInterfaceRector.php)
|
||||
|
||||
Interface factories are not needed in Symfony. Clear constructor injection is used instead
|
||||
|
||||
|
@ -13889,8 +13945,8 @@ Restore accidentally shortened class names to its fully qualified form.
|
|||
|
||||
### `UpdateFileNameByClassNameFileSystemRector`
|
||||
|
||||
- class: [`Rector\Restoration\Rector\ClassLike\UpdateFileNameByClassNameFileSystemRector`](/rules/restoration/src/Rector/FileSystem/UpdateFileNameByClassNameFileSystemRector.php)
|
||||
- [test fixtures](/rules/restoration/tests/Rector/FileSystem/UpdateFileNameByClassNameFileSystemRector/Fixture)
|
||||
- class: [`Rector\Restoration\Rector\ClassLike\UpdateFileNameByClassNameFileSystemRector`](/rules/restoration/src/Rector/ClassLike/UpdateFileNameByClassNameFileSystemRector.php)
|
||||
- [test fixtures](/rules/restoration/tests/Rector/ClassLike/UpdateFileNameByClassNameFileSystemRector/Fixture)
|
||||
|
||||
Rename file to respect class name
|
||||
|
||||
|
|
|
@ -5,15 +5,11 @@ declare(strict_types=1);
|
|||
namespace Rector\NodeTypeResolver\Tests\PerNodeTypeResolver;
|
||||
|
||||
use PhpParser\Node;
|
||||
use Rector\Core\Configuration\Option;
|
||||
use Rector\Core\HttpKernel\RectorKernel;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\Core\PhpParser\Parser\Parser;
|
||||
use Rector\NodeTypeResolver\NodeScopeAndMetadataDecorator;
|
||||
use Rector\Core\Testing\TestingParser\TestingParser;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Symplify\PackageBuilder\Parameter\ParameterProvider;
|
||||
use Symplify\PackageBuilder\Tests\AbstractKernelTestCase;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
abstract class AbstractNodeTypeResolverTest extends AbstractKernelTestCase
|
||||
{
|
||||
|
@ -28,29 +24,17 @@ abstract class AbstractNodeTypeResolverTest extends AbstractKernelTestCase
|
|||
private $betterNodeFinder;
|
||||
|
||||
/**
|
||||
* @var Parser
|
||||
* @var TestingParser
|
||||
*/
|
||||
private $parser;
|
||||
|
||||
/**
|
||||
* @var NodeScopeAndMetadataDecorator
|
||||
*/
|
||||
private $nodeScopeAndMetadataDecorator;
|
||||
|
||||
/**
|
||||
* @var ParameterProvider
|
||||
*/
|
||||
private $parameterProvider;
|
||||
private $testingParser;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->bootKernel(RectorKernel::class);
|
||||
|
||||
$this->betterNodeFinder = self::$container->get(BetterNodeFinder::class);
|
||||
$this->parameterProvider = self::$container->get(ParameterProvider::class);
|
||||
$this->testingParser = self::$container->get(TestingParser::class);
|
||||
$this->nodeTypeResolver = self::$container->get(NodeTypeResolver::class);
|
||||
$this->parser = self::$container->get(Parser::class);
|
||||
$this->nodeScopeAndMetadataDecorator = self::$container->get(NodeScopeAndMetadataDecorator::class);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,22 +42,8 @@ abstract class AbstractNodeTypeResolverTest extends AbstractKernelTestCase
|
|||
*/
|
||||
protected function getNodesForFileOfType(string $file, string $type): array
|
||||
{
|
||||
$nodes = $this->getNodesForFile($file);
|
||||
$nodes = $this->testingParser->parseFileToDecoratedNodes($file);
|
||||
|
||||
return $this->betterNodeFinder->findInstanceOf($nodes, $type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Node[]
|
||||
*/
|
||||
private function getNodesForFile(string $file): array
|
||||
{
|
||||
$smartFileInfo = new SmartFileInfo($file);
|
||||
|
||||
$this->parameterProvider->changeParameter(Option::SOURCE, [$file]);
|
||||
|
||||
$nodes = $this->parser->parseFileInfo($smartFileInfo);
|
||||
|
||||
return $this->nodeScopeAndMetadataDecorator->decorateNodesFromFile($nodes, $smartFileInfo);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -892,3 +892,8 @@ parameters:
|
|||
message: '#Multiple class/interface/trait is not allowed in a file#'
|
||||
paths:
|
||||
- src/PhpParser/NodeTraverser/CallableNodeTraverser.php
|
||||
|
||||
-
|
||||
message: '#Function "dump\(\)" cannot be used/left in the code#'
|
||||
paths:
|
||||
- tests/debug_functions.php
|
||||
|
|
16
rules/defluent/config/config.php
Normal file
16
rules/defluent/config/config.php
Normal file
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
return static function (ContainerConfigurator $containerConfigurator): void {
|
||||
$services = $containerConfigurator->services();
|
||||
|
||||
$services->defaults()
|
||||
->public()
|
||||
->autowire();
|
||||
|
||||
$services->load('Rector\Defluent\\', __DIR__ . '/../src')
|
||||
->exclude([__DIR__ . '/../src/Rector', __DIR__ . '/../src/ValueObject']);
|
||||
};
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\ConflictGuard;
|
||||
namespace Rector\Defluent\ConflictGuard;
|
||||
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use PHPStan\Reflection\ClassReflection;
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Contract\ValueObject;
|
||||
|
||||
interface FirstCallFactoryAwareInterface
|
||||
{
|
||||
public function isFirstCallFactory(): bool;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Contract\ValueObject;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
|
||||
interface RootExprAwareInterface
|
||||
{
|
||||
public function getRootExpr(): Expr;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\NodeAnalyzer;
|
||||
namespace Rector\Defluent\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PHPStan\Type\TypeWithClassName;
|
|
@ -2,12 +2,11 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\NodeAnalyzer;
|
||||
namespace Rector\Defluent\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use Rector\MagicDisclosure\ValueObject\AssignAndRootExpr;
|
||||
|
||||
final class ChainCallsStaticTypeResolver
|
||||
final class FluentCallStaticTypeResolver
|
||||
{
|
||||
/**
|
||||
* @var ExprStringTypeResolver
|
||||
|
@ -23,15 +22,17 @@ final class ChainCallsStaticTypeResolver
|
|||
* @param MethodCall[] $chainMethodCalls
|
||||
* @return string[]
|
||||
*/
|
||||
public function resolveCalleeUniqueTypes(AssignAndRootExpr $assignAndRootExpr, array $chainMethodCalls): array
|
||||
public function resolveCalleeUniqueTypes(array $chainMethodCalls): array
|
||||
{
|
||||
$rootClassType = $this->exprStringTypeResolver->resolve($assignAndRootExpr->getRootExpr());
|
||||
if ($rootClassType === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$callerClassTypes = [];
|
||||
$callerClassTypes[] = $rootClassType;
|
||||
|
||||
$lastMethodCallKey = array_key_last($chainMethodCalls);
|
||||
$lastMethodCall = $chainMethodCalls[$lastMethodCallKey];
|
||||
|
||||
$rootType = $this->exprStringTypeResolver->resolve($lastMethodCall->var);
|
||||
if ($rootType !== null) {
|
||||
$callerClassTypes[] = $rootType;
|
||||
}
|
||||
|
||||
// chain method calls are inversed
|
||||
$lastChainMethodCallKey = array_key_first($chainMethodCalls);
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\NodeAnalyzer;
|
||||
namespace Rector\Defluent\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
|
@ -177,7 +177,7 @@ final class FluentChainMethodCallNodeAnalyzer
|
|||
->yes();
|
||||
}
|
||||
|
||||
public function resolveRootVariable(MethodCall $methodCall): Node
|
||||
public function resolveRootExpr(MethodCall $methodCall): Node
|
||||
{
|
||||
$callerNode = $methodCall->var;
|
||||
|
|
@ -2,31 +2,31 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\NodeManipulator;
|
||||
namespace Rector\Defluent\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\PhpParser\Node\BetterNodeFinder;
|
||||
use Rector\MagicDisclosure\NodeAnalyzer\ExprStringTypeResolver;
|
||||
use Rector\MagicDisclosure\ValueObject\AssignAndRootExpr;
|
||||
use Rector\Defluent\ValueObject\AssignAndRootExpr;
|
||||
use Rector\Defluent\ValueObject\FluentCallsKind;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\NetteKdyby\Naming\VariableNaming;
|
||||
use Rector\NodeNameResolver\NodeNameResolver;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
use Rector\PHPStan\Type\FullyQualifiedObjectType;
|
||||
|
||||
/**
|
||||
* @see \Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\FluentChainMethodCallRootExtractorTest
|
||||
*/
|
||||
final class FluentChainMethodCallRootExtractor
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const KIND_IN_ARGS = 'in_args';
|
||||
|
||||
/**
|
||||
* @var PropertyNaming
|
||||
*/
|
||||
|
@ -52,18 +52,25 @@ final class FluentChainMethodCallRootExtractor
|
|||
*/
|
||||
private $exprStringTypeResolver;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
public function __construct(
|
||||
BetterNodeFinder $betterNodeFinder,
|
||||
NodeNameResolver $nodeNameResolver,
|
||||
PropertyNaming $propertyNaming,
|
||||
VariableNaming $variableNaming,
|
||||
ExprStringTypeResolver $exprStringTypeResolver
|
||||
ExprStringTypeResolver $exprStringTypeResolver,
|
||||
NodeTypeResolver $nodeTypeResolver
|
||||
) {
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
$this->betterNodeFinder = $betterNodeFinder;
|
||||
$this->nodeNameResolver = $nodeNameResolver;
|
||||
$this->variableNaming = $variableNaming;
|
||||
$this->exprStringTypeResolver = $exprStringTypeResolver;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,15 +78,19 @@ final class FluentChainMethodCallRootExtractor
|
|||
*/
|
||||
public function extractFromMethodCalls(array $methodCalls, string $kind): ?AssignAndRootExpr
|
||||
{
|
||||
// we need at least 2 method call for fluent
|
||||
if (count($methodCalls) < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($methodCalls as $methodCall) {
|
||||
if ($methodCall->var instanceof Variable || $methodCall->var instanceof PropertyFetch) {
|
||||
$isFirstCallFactory = $this->resolveIsFirstCallFactory($methodCall);
|
||||
return new AssignAndRootExpr($methodCall->var, $methodCall->var, null, $isFirstCallFactory);
|
||||
return $this->createAssignAndRootExprForVariableOrPropertyFetch($methodCall);
|
||||
}
|
||||
|
||||
if ($methodCall->var instanceof New_) {
|
||||
// direct = no parent
|
||||
if ($kind === self::KIND_IN_ARGS) {
|
||||
if ($kind === FluentCallsKind::IN_ARGS) {
|
||||
return $this->resolveKindInArgs($methodCall);
|
||||
}
|
||||
|
||||
|
@ -95,7 +106,7 @@ final class FluentChainMethodCallRootExtractor
|
|||
* A. FLUENT: $cook->bake()->serve() // only "Cook"
|
||||
* B. FACTORY: $food = $cook->bake()->warmUp(); // only "Food"
|
||||
*/
|
||||
private function resolveIsFirstCallFactory(MethodCall $methodCall): bool
|
||||
public function resolveIsFirstMethodCallFactory(MethodCall $methodCall): bool
|
||||
{
|
||||
$variableStaticType = $this->exprStringTypeResolver->resolve($methodCall->var);
|
||||
$calledMethodStaticType = $this->exprStringTypeResolver->resolve($methodCall);
|
||||
|
@ -118,6 +129,26 @@ final class FluentChainMethodCallRootExtractor
|
|||
return $variableStaticType !== $calledMethodStaticType;
|
||||
}
|
||||
|
||||
private function createAssignAndRootExprForVariableOrPropertyFetch(MethodCall $methodCall): AssignAndRootExpr
|
||||
{
|
||||
$isFirstCallFactory = $this->resolveIsFirstMethodCallFactory($methodCall);
|
||||
|
||||
// the method call, does not belong to the
|
||||
$staticType = $this->nodeTypeResolver->getStaticType($methodCall);
|
||||
|
||||
// no assign
|
||||
if ($methodCall->getAttribute(AttributeKey::PARENT_NODE) instanceof Expression) {
|
||||
$variableName = $this->propertyNaming->fqnToVariableName($staticType);
|
||||
|
||||
// the assign expresison must be break
|
||||
// pesuero code bsaed on type
|
||||
$variable = new Variable($variableName);
|
||||
return new AssignAndRootExpr($methodCall->var, $methodCall->var, $variable, $isFirstCallFactory);
|
||||
}
|
||||
|
||||
return new AssignAndRootExpr($methodCall->var, $methodCall->var, null, $isFirstCallFactory);
|
||||
}
|
||||
|
||||
private function resolveKindInArgs(MethodCall $methodCall): AssignAndRootExpr
|
||||
{
|
||||
$variableName = $this->variableNaming->resolveFromNode($methodCall->var);
|
34
rules/defluent/src/NodeAnalyzer/GetterMethodCallAnalyzer.php
Normal file
34
rules/defluent/src/NodeAnalyzer/GetterMethodCallAnalyzer.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
||||
final class GetterMethodCallAnalyzer
|
||||
{
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
public function __construct(NodeTypeResolver $nodeTypeResolver)
|
||||
{
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
}
|
||||
|
||||
public function isGetterMethodCall(MethodCall $methodCall): bool
|
||||
{
|
||||
if ($methodCall->var instanceof MethodCall) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$methodCallStaticType = $this->nodeTypeResolver->getStaticType($methodCall);
|
||||
$methodCallVarStaticType = $this->nodeTypeResolver->getStaticType($methodCall->var);
|
||||
|
||||
// getter short call type
|
||||
return ! $methodCallStaticType->equals($methodCallVarStaticType);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\NodeAnalyzer;
|
||||
namespace Rector\Defluent\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\NodeAnalyzer;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\ClassMethod;
|
||||
use Rector\Defluent\Contract\ValueObject\FirstCallFactoryAwareInterface;
|
||||
use Rector\NodeCollector\NodeCollector\NodeRepository;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class SameClassMethodCallAnalyzer
|
||||
{
|
||||
/**
|
||||
* @var NodeRepository
|
||||
*/
|
||||
private $nodeRepository;
|
||||
|
||||
public function __construct(NodeRepository $nodeRepository)
|
||||
{
|
||||
$this->nodeRepository = $nodeRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall[] $chainMethodCalls
|
||||
*/
|
||||
public function haveSingleClass(array $chainMethodCalls): bool
|
||||
{
|
||||
// are method calls located in the same class?
|
||||
$classOfClassMethod = [];
|
||||
foreach ($chainMethodCalls as $chainMethodCall) {
|
||||
$classMethod = $this->nodeRepository->findClassMethodByMethodCall($chainMethodCall);
|
||||
|
||||
if ($classMethod instanceof ClassMethod) {
|
||||
$classOfClassMethod[] = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
|
||||
} else {
|
||||
$classOfClassMethod[] = null;
|
||||
}
|
||||
}
|
||||
|
||||
$uniqueClasses = array_unique($classOfClassMethod);
|
||||
return count($uniqueClasses) < 2;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $calleeUniqueTypes
|
||||
*/
|
||||
public function isCorrectTypeCount(
|
||||
array $calleeUniqueTypes,
|
||||
FirstCallFactoryAwareInterface $firstCallFactoryAware
|
||||
): bool {
|
||||
if (count($calleeUniqueTypes) === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// in case of factory method, 2 methods are allowed
|
||||
if ($firstCallFactoryAware->isFirstCallFactory()) {
|
||||
return count($calleeUniqueTypes) === 2;
|
||||
}
|
||||
|
||||
return count($calleeUniqueTypes) === 1;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\NodeFactory;
|
||||
namespace Rector\Defluent\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
|
@ -12,9 +12,9 @@ use PhpParser\Node\Expr\Variable;
|
|||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\MagicDisclosure\NodeAnalyzer\FluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\MagicDisclosure\NodeManipulator\FluentChainMethodCallRootExtractor;
|
||||
use Rector\MagicDisclosure\ValueObject\AssignAndRootExpr;
|
||||
use Rector\Defluent\NodeAnalyzer\FluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\Defluent\ValueObject\AssignAndRootExpr;
|
||||
use Rector\Defluent\ValueObject\FluentCallsKind;
|
||||
use Rector\NetteKdyby\Naming\VariableNaming;
|
||||
|
||||
final class NonFluentChainMethodCallFactory
|
||||
|
@ -73,7 +73,7 @@ final class NonFluentChainMethodCallFactory
|
|||
public function createFromAssignObjectAndMethodCalls(
|
||||
AssignAndRootExpr $assignAndRootExpr,
|
||||
array $chainMethodCalls,
|
||||
string $kind = 'normal'
|
||||
string $kind
|
||||
): array {
|
||||
$nodesToAdd = [];
|
||||
|
||||
|
@ -90,7 +90,7 @@ final class NonFluentChainMethodCallFactory
|
|||
|
||||
$nodesToAdd = array_merge($nodesToAdd, $decoupledMethodCalls);
|
||||
|
||||
if ($assignAndRootExpr->getSilentVariable() !== null && $kind !== FluentChainMethodCallRootExtractor::KIND_IN_ARGS) {
|
||||
if ($assignAndRootExpr->getSilentVariable() !== null && $kind !== FluentCallsKind::IN_ARGS) {
|
||||
$nodesToAdd[] = $assignAndRootExpr->getReturnSilentVariable();
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\NodeFactory;
|
||||
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use Rector\Defluent\NodeAnalyzer\FluentChainMethodCallRootExtractor;
|
||||
use Rector\Defluent\ValueObject\FirstAssignFluentCall;
|
||||
use Rector\Defluent\ValueObject\FluentMethodCalls;
|
||||
use Rector\Naming\Naming\PropertyNaming;
|
||||
use Rector\NodeTypeResolver\NodeTypeResolver;
|
||||
|
||||
final class ReturnFluentMethodCallFactory
|
||||
{
|
||||
/**
|
||||
* @var FluentChainMethodCallRootExtractor
|
||||
*/
|
||||
private $fluentChainMethodCallRootExtractor;
|
||||
|
||||
/**
|
||||
* @var NodeTypeResolver
|
||||
*/
|
||||
private $nodeTypeResolver;
|
||||
|
||||
/**
|
||||
* @var PropertyNaming
|
||||
*/
|
||||
private $propertyNaming;
|
||||
|
||||
public function __construct(
|
||||
FluentChainMethodCallRootExtractor $fluentChainMethodCallRootExtractor,
|
||||
NodeTypeResolver $nodeTypeResolver,
|
||||
PropertyNaming $propertyNaming
|
||||
) {
|
||||
$this->fluentChainMethodCallRootExtractor = $fluentChainMethodCallRootExtractor;
|
||||
$this->nodeTypeResolver = $nodeTypeResolver;
|
||||
$this->propertyNaming = $propertyNaming;
|
||||
}
|
||||
|
||||
public function createFromFluentMethodCalls(FluentMethodCalls $fluentMethodCalls): FirstAssignFluentCall
|
||||
{
|
||||
$rootMethodCall = $fluentMethodCalls->getRootMethodCall();
|
||||
|
||||
// this means the 1st method creates different object then it runs on
|
||||
// e.g. $sheet->getRow(), creates a "Row" object
|
||||
$isFirstMethodCallFactory = $this->fluentChainMethodCallRootExtractor->resolveIsFirstMethodCallFactory(
|
||||
$rootMethodCall
|
||||
);
|
||||
|
||||
$lastMethodCall = $fluentMethodCalls->getRootMethodCall();
|
||||
|
||||
if ($lastMethodCall->var instanceof PropertyFetch) {
|
||||
$assignExpr = $lastMethodCall->var;
|
||||
} else {
|
||||
// we need a variable to assign the stuff into
|
||||
// the method call, does not belong to the
|
||||
$staticType = $this->nodeTypeResolver->getStaticType($rootMethodCall);
|
||||
$variableName = $this->propertyNaming->fqnToVariableName($staticType);
|
||||
$assignExpr = new Variable($variableName);
|
||||
}
|
||||
|
||||
return new FirstAssignFluentCall(
|
||||
$assignExpr,
|
||||
$rootMethodCall,
|
||||
$isFirstMethodCallFactory,
|
||||
$fluentMethodCalls
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\NodeFactory;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\PropertyFetch;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Defluent\ValueObject\FirstAssignFluentCall;
|
||||
use Rector\Defluent\ValueObject\FluentMethodCalls;
|
||||
|
||||
final class SeparateReturnMethodCallFactory
|
||||
{
|
||||
/**
|
||||
* @return Node[]
|
||||
*/
|
||||
public function createReturnFromFirstAssignFluentCallAndFluentMethodCalls(
|
||||
FirstAssignFluentCall $firstAssignFluentCall,
|
||||
FluentMethodCalls $fluentMethodCalls
|
||||
): array {
|
||||
$nodesToAdd = [];
|
||||
|
||||
if (! $firstAssignFluentCall->getAssignExpr() instanceof PropertyFetch) {
|
||||
$nodesToAdd[] = $firstAssignFluentCall->createFirstAssign();
|
||||
}
|
||||
|
||||
$decoupledMethodCalls = $this->createNonFluentMethodCalls(
|
||||
$fluentMethodCalls->getFluentMethodCalls(),
|
||||
$firstAssignFluentCall,
|
||||
true
|
||||
);
|
||||
|
||||
$nodesToAdd = array_merge($nodesToAdd, $decoupledMethodCalls);
|
||||
|
||||
// return the first value
|
||||
$nodesToAdd[] = new Return_($firstAssignFluentCall->getAssignExpr());
|
||||
|
||||
return $nodesToAdd;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall[] $chainMethodCalls
|
||||
* @return MethodCall[]
|
||||
*/
|
||||
private function createNonFluentMethodCalls(
|
||||
array $chainMethodCalls,
|
||||
FirstAssignFluentCall $firstAssignFluentCall,
|
||||
bool $isNewNodeNeeded
|
||||
): array {
|
||||
$decoupledMethodCalls = [];
|
||||
|
||||
$lastKey = array_key_last($chainMethodCalls);
|
||||
|
||||
foreach ($chainMethodCalls as $key => $chainMethodCall) {
|
||||
// skip first, already handled
|
||||
if ($key === $lastKey && $firstAssignFluentCall->isFirstCallFactory() && $isNewNodeNeeded) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$chainMethodCall->var = $this->resolveMethodCallVar($firstAssignFluentCall, $key);
|
||||
$decoupledMethodCalls[] = $chainMethodCall;
|
||||
}
|
||||
|
||||
return array_reverse($decoupledMethodCalls);
|
||||
}
|
||||
|
||||
private function resolveMethodCallVar(FirstAssignFluentCall $firstAssignFluentCall, int $key): Expr
|
||||
{
|
||||
if (! $firstAssignFluentCall->isFirstCallFactory()) {
|
||||
return $firstAssignFluentCall->getCallerExpr();
|
||||
}
|
||||
|
||||
// very first call
|
||||
if ($key !== 0) {
|
||||
return $firstAssignFluentCall->getCallerExpr();
|
||||
}
|
||||
|
||||
return $firstAssignFluentCall->getFactoryAssignVariable();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Rector;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\Rector\AbstractRector;
|
||||
use Rector\Defluent\NodeAnalyzer\FluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\Defluent\NodeAnalyzer\FluentChainMethodCallRootExtractor;
|
||||
use Rector\Defluent\NodeAnalyzer\SameClassMethodCallAnalyzer;
|
||||
use Rector\Defluent\NodeFactory\NonFluentChainMethodCallFactory;
|
||||
use Rector\Defluent\Skipper\FluentMethodCallSkipper;
|
||||
use Rector\Defluent\ValueObject\AssignAndRootExprAndNodesToAdd;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
abstract class AbstractFluentChainMethodCallRector extends AbstractRector
|
||||
{
|
||||
/**
|
||||
* @var FluentChainMethodCallNodeAnalyzer
|
||||
*/
|
||||
protected $fluentChainMethodCallNodeAnalyzer;
|
||||
|
||||
/**
|
||||
* @var NonFluentChainMethodCallFactory
|
||||
*/
|
||||
protected $nonFluentChainMethodCallFactory;
|
||||
|
||||
/**
|
||||
* @var FluentChainMethodCallRootExtractor
|
||||
*/
|
||||
protected $fluentChainMethodCallRootExtractor;
|
||||
|
||||
/**
|
||||
* @var SameClassMethodCallAnalyzer
|
||||
*/
|
||||
protected $sameClassMethodCallAnalyzer;
|
||||
|
||||
/**
|
||||
* @var FluentMethodCallSkipper
|
||||
*/
|
||||
protected $fluentMethodCallSkipper;
|
||||
|
||||
/**
|
||||
* @required
|
||||
*/
|
||||
public function autowireAbstractFluentChainMethodCallRector(
|
||||
FluentChainMethodCallNodeAnalyzer $fluentChainMethodCallNodeAnalyzer,
|
||||
FluentChainMethodCallRootExtractor $fluentChainMethodCallRootExtractor,
|
||||
NonFluentChainMethodCallFactory $nonFluentChainMethodCallFactory,
|
||||
SameClassMethodCallAnalyzer $sameClassMethodCallAnalyzer,
|
||||
FluentMethodCallSkipper $fluentMethodCallSkipper
|
||||
): void {
|
||||
$this->fluentChainMethodCallNodeAnalyzer = $fluentChainMethodCallNodeAnalyzer;
|
||||
$this->fluentChainMethodCallRootExtractor = $fluentChainMethodCallRootExtractor;
|
||||
$this->nonFluentChainMethodCallFactory = $nonFluentChainMethodCallFactory;
|
||||
$this->sameClassMethodCallAnalyzer = $sameClassMethodCallAnalyzer;
|
||||
$this->fluentMethodCallSkipper = $fluentMethodCallSkipper;
|
||||
}
|
||||
|
||||
protected function createStandaloneNodesToAddFromChainMethodCalls(
|
||||
MethodCall $methodCall,
|
||||
string $kind
|
||||
): ?AssignAndRootExprAndNodesToAdd {
|
||||
$chainMethodCalls = $this->fluentChainMethodCallNodeAnalyzer->collectAllMethodCallsInChain($methodCall);
|
||||
if (! $this->sameClassMethodCallAnalyzer->haveSingleClass($chainMethodCalls)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$assignAndRootExpr = $this->fluentChainMethodCallRootExtractor->extractFromMethodCalls(
|
||||
$chainMethodCalls,
|
||||
$kind
|
||||
);
|
||||
|
||||
if ($assignAndRootExpr === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->fluentMethodCallSkipper->shouldSkipMethodCalls($assignAndRootExpr, $chainMethodCalls)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$nodesToAdd = $this->nonFluentChainMethodCallFactory->createFromAssignObjectAndMethodCalls(
|
||||
$assignAndRootExpr,
|
||||
$chainMethodCalls,
|
||||
$kind
|
||||
);
|
||||
|
||||
return new AssignAndRootExprAndNodesToAdd($assignAndRootExpr, $nodesToAdd);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall|Return_ $node
|
||||
*/
|
||||
protected function removeCurrentNode(Node $node): void
|
||||
{
|
||||
$parent = $node->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if ($parent instanceof Assign) {
|
||||
$this->removeNode($parent);
|
||||
return;
|
||||
}
|
||||
|
||||
// part of method call
|
||||
if ($parent instanceof Arg) {
|
||||
$parentParent = $parent->getAttribute(AttributeKey::PARENT_NODE);
|
||||
if ($parentParent instanceof MethodCall) {
|
||||
$this->removeNode($parentParent);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->removeNode($node);
|
||||
}
|
||||
|
||||
protected function shouldSkipMethodCall(MethodCall $methodCall): bool
|
||||
{
|
||||
return $this->fluentMethodCallSkipper->shouldSkipRootMethodCall($methodCall);
|
||||
}
|
||||
|
||||
protected function matchReturnMethodCall(Return_ $return): ?MethodCall
|
||||
{
|
||||
if ($return->expr === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! $return->expr instanceof MethodCall) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $return->expr;
|
||||
}
|
||||
|
||||
protected function shouldSkipMethodCallIncludingNew(MethodCall $methodCall): bool
|
||||
{
|
||||
if ($this->shouldSkipMethodCall($methodCall)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$chainRootExpr = $this->fluentChainMethodCallNodeAnalyzer->resolveRootExpr($methodCall);
|
||||
return $chainRootExpr instanceof New_;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Rector\ClassMethod;
|
||||
namespace Rector\Defluent\Rector\ClassMethod;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Identifier;
|
||||
|
@ -14,11 +14,11 @@ use Rector\Core\Rector\AbstractRector;
|
|||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Core\ValueObject\PhpVersionFeature;
|
||||
use Rector\MagicDisclosure\ConflictGuard\ParentClassMethodTypeOverrideGuard;
|
||||
use Rector\Defluent\ConflictGuard\ParentClassMethodTypeOverrideGuard;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* @see \Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\ReturnThisRemoveRectorTest
|
||||
* @see \Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\ReturnThisRemoveRectorTest
|
||||
*/
|
||||
final class ReturnThisRemoveRector extends AbstractRector
|
||||
{
|
|
@ -0,0 +1,91 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Rector\MethodCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
use Rector\Defluent\Rector\Return_\DefluentReturnMethodCallRector;
|
||||
use Rector\Defluent\ValueObject\FluentCallsKind;
|
||||
|
||||
/**
|
||||
* @see https://ocramius.github.io/blog/fluent-interfaces-are-evil/
|
||||
* @see https://www.yegor256.com/2018/03/13/fluent-interfaces.html
|
||||
*
|
||||
* @see \Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\FluentChainMethodCallToNormalMethodCallRectorTest
|
||||
*/
|
||||
final class FluentChainMethodCallToNormalMethodCallRector extends AbstractFluentChainMethodCallRector
|
||||
{
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Turns fluent interface calls to classic ones.', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
$someClass = new SomeClass();
|
||||
$someClass->someFunction()
|
||||
->otherFunction();
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
$someClass = new SomeClass();
|
||||
$someClass->someFunction();
|
||||
$someClass->otherFunction();
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [MethodCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->isHandledByAnotherRule($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->shouldSkipMethodCallIncludingNew($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$assignAndRootExprAndNodesToAdd = $this->createStandaloneNodesToAddFromChainMethodCalls(
|
||||
$node,
|
||||
FluentCallsKind::NORMAL
|
||||
);
|
||||
|
||||
if ($assignAndRootExprAndNodesToAdd === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->removeCurrentNode($node);
|
||||
$this->addNodesAfterNode($assignAndRootExprAndNodesToAdd->getNodesToAdd(), $node);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is handled by:
|
||||
* @see DefluentReturnMethodCallRector
|
||||
* @see InArgFluentChainMethodCallToStandaloneMethodCallRector
|
||||
*
|
||||
* @param MethodCall|Return_ $node
|
||||
*/
|
||||
private function isHandledByAnotherRule(Node $node): bool
|
||||
{
|
||||
return $this->hasParentTypes($node, [Return_::class, Arg::class]);
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Rector\MethodCall;
|
||||
namespace Rector\Defluent\Rector\MethodCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
|
@ -12,15 +12,16 @@ use PhpParser\Node\Expr\Variable;
|
|||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\MagicDisclosure\NodeAnalyzer\NewFluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\MagicDisclosure\NodeManipulator\FluentChainMethodCallRootExtractor;
|
||||
use Rector\Defluent\NodeAnalyzer\NewFluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
use Rector\Defluent\ValueObject\FluentCallsKind;
|
||||
use Rector\NetteKdyby\Naming\VariableNaming;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
/**
|
||||
* @sponsor Thanks https://amateri.com for sponsoring this rule - visit them on https://www.startupjobs.cz/startup/scrumworks-s-r-o
|
||||
*
|
||||
* @see \Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest
|
||||
* @see \Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest
|
||||
*/
|
||||
final class InArgFluentChainMethodCallToStandaloneMethodCallRector extends AbstractFluentChainMethodCallRector
|
||||
{
|
||||
|
@ -113,7 +114,7 @@ CODE_SAMPLE
|
|||
|
||||
$assignAndRootExprAndNodesToAdd = $this->createStandaloneNodesToAddFromChainMethodCalls(
|
||||
$node,
|
||||
FluentChainMethodCallRootExtractor::KIND_IN_ARGS
|
||||
FluentCallsKind::IN_ARGS
|
||||
);
|
||||
|
||||
if ($assignAndRootExprAndNodesToAdd === null) {
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Rector\MethodCall;
|
||||
namespace Rector\Defluent\Rector\MethodCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
|
@ -12,13 +12,14 @@ use PhpParser\Node\Expr\Variable;
|
|||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\MagicDisclosure\NodeAnalyzer\NewFluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\Defluent\NodeAnalyzer\NewFluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
use Rector\NetteKdyby\Naming\VariableNaming;
|
||||
|
||||
/**
|
||||
* @sponsor Thanks https://amateri.com for sponsoring this rule - visit them on https://www.startupjobs.cz/startup/scrumworks-s-r-o
|
||||
*
|
||||
* @see \Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\MethodCallOnSetterMethodCallToStandaloneAssignRectorTest
|
||||
* @see \Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\MethodCallOnSetterMethodCallToStandaloneAssignRectorTest
|
||||
*/
|
||||
final class MethodCallOnSetterMethodCallToStandaloneAssignRector extends AbstractFluentChainMethodCallRector
|
||||
{
|
||||
|
@ -91,7 +92,7 @@ CODE_SAMPLE
|
|||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
if ($this->shouldSkip($node)) {
|
||||
if ($this->shouldSkipMethodCall($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -115,15 +116,6 @@ CODE_SAMPLE
|
|||
return $rootMethodCall;
|
||||
}
|
||||
|
||||
private function shouldSkip(MethodCall $methodCall): bool
|
||||
{
|
||||
if (! $methodCall->var instanceof MethodCall) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ! $this->fluentChainMethodCallNodeAnalyzer->isLastChainMethodCall($methodCall);
|
||||
}
|
||||
|
||||
private function crateVariableFromNew(New_ $new): Variable
|
||||
{
|
||||
$variableName = $this->variableNaming->resolveFromNode($new);
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Rector\MethodCall;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Arg;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
use Rector\Defluent\ValueObject\FluentCallsKind;
|
||||
|
||||
/**
|
||||
* @see https://ocramius.github.io/blog/fluent-interfaces-are-evil/
|
||||
* @see https://www.yegor256.com/2018/03/13/fluent-interfaces.html
|
||||
*
|
||||
* @see \Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\FluentChainMethodCallToNormalMethodCallRectorTest
|
||||
* @see \Rector\Defluent\Tests\Rector\MethodCall\NewFluentChainMethodCallToNonFluentRector\NewFluentChainMethodCallToNonFluentRectorTest
|
||||
*/
|
||||
final class NewFluentChainMethodCallToNonFluentRector extends AbstractFluentChainMethodCallRector
|
||||
{
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Turns fluent interface calls to classic ones.', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
(new SomeClass())->someFunction()
|
||||
->otherFunction();
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
$someClass = new SomeClass();
|
||||
$someClass->someFunction();
|
||||
$someClass->otherFunction();
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [MethodCall::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
// handled by another rule
|
||||
if ($this->hasParentTypes($node, [Return_::class, Arg::class])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->shouldSkipMethodCall($node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$assignAndRootExprAndNodesToAdd = $this->createStandaloneNodesToAddFromChainMethodCalls(
|
||||
$node,
|
||||
FluentCallsKind::NORMAL
|
||||
);
|
||||
if ($assignAndRootExprAndNodesToAdd === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->removeCurrentNode($node);
|
||||
$this->addNodesAfterNode($assignAndRootExprAndNodesToAdd->getNodesToAdd(), $node);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Rector\Return_;
|
||||
namespace Rector\Defluent\Rector\Return_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
|
@ -10,12 +10,12 @@ use PhpParser\Node\Expr\Variable;
|
|||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\MagicDisclosure\Rector\MethodCall\AbstractFluentChainMethodCallRector;
|
||||
use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
|
||||
/**
|
||||
* @sponsor Thanks https://amateri.com for sponsoring this rule - visit them on https://www.startupjobs.cz/startup/scrumworks-s-r-o
|
||||
*
|
||||
* @see \Rector\MagicDisclosure\Tests\Rector\Return_\DefluentReturnMethodCallRector\DefluentReturnMethodCallRectorTest
|
||||
* @see \Rector\Defluent\Tests\Rector\Return_\DefluentReturnMethodCallRector\DefluentReturnMethodCallRectorTest
|
||||
*/
|
||||
final class DefluentReturnMethodCallRector extends AbstractFluentChainMethodCallRector
|
||||
{
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Rector\Return_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\New_;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Defluent\NodeFactory\ReturnFluentMethodCallFactory;
|
||||
use Rector\Defluent\NodeFactory\SeparateReturnMethodCallFactory;
|
||||
use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
use Rector\Defluent\ValueObjectFactory\FluentMethodCallsFactory;
|
||||
|
||||
/**
|
||||
* @see https://ocramius.github.io/blog/fluent-interfaces-are-evil/
|
||||
* @see https://www.yegor256.com/2018/03/13/fluent-interfaces.html
|
||||
*
|
||||
* @see \Rector\Defluent\Tests\Rector\Return_\ReturnFluentChainMethodCallToNormalMethodCallRector\ReturnFluentChainMethodCallToNormalMethodCallRectorTest
|
||||
*/
|
||||
final class ReturnFluentChainMethodCallToNormalMethodCallRector extends AbstractFluentChainMethodCallRector
|
||||
{
|
||||
/**
|
||||
* @var ReturnFluentMethodCallFactory
|
||||
*/
|
||||
private $returnFluentMethodCallFactory;
|
||||
|
||||
/**
|
||||
* @var FluentMethodCallsFactory
|
||||
*/
|
||||
private $fluentMethodCallsFactory;
|
||||
|
||||
/**
|
||||
* @var SeparateReturnMethodCallFactory
|
||||
*/
|
||||
private $separateReturnMethodCallFactory;
|
||||
|
||||
public function __construct(
|
||||
ReturnFluentMethodCallFactory $returnFluentMethodCallFactory,
|
||||
FluentMethodCallsFactory $fluentMethodCallsFactory,
|
||||
SeparateReturnMethodCallFactory $separateReturnMethodCallFactory
|
||||
) {
|
||||
$this->returnFluentMethodCallFactory = $returnFluentMethodCallFactory;
|
||||
$this->fluentMethodCallsFactory = $fluentMethodCallsFactory;
|
||||
$this->separateReturnMethodCallFactory = $separateReturnMethodCallFactory;
|
||||
}
|
||||
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Turns fluent interface calls to classic ones.', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
$someClass = new SomeClass();
|
||||
return $someClass->someFunction()
|
||||
->otherFunction();
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
$someClass = new SomeClass();
|
||||
$someClass->someFunction();
|
||||
$someClass->otherFunction();
|
||||
return $someClass;
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Return_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Return_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$methodCall = $this->matchReturnMethodCall($node);
|
||||
if ($methodCall === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->shouldSkipMethodCallIncludingNew($methodCall)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$nodesToAdd = $this->createStandaloneNodesToAddFromReturnFluentMethodCalls($methodCall);
|
||||
if ($nodesToAdd === []) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->removeCurrentNode($node);
|
||||
$this->addNodesAfterNode($nodesToAdd, $node);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function shouldSkipMethodCallIncludingNew(MethodCall $methodCall): bool
|
||||
{
|
||||
if ($this->shouldSkipMethodCall($methodCall)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$rootVariable = $this->fluentChainMethodCallNodeAnalyzer->resolveRootExpr($methodCall);
|
||||
return $rootVariable instanceof New_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Node[]
|
||||
*/
|
||||
private function createStandaloneNodesToAddFromReturnFluentMethodCalls(MethodCall $methodCall): array
|
||||
{
|
||||
$fluentMethodCalls = $this->fluentMethodCallsFactory->createFromLastMethodCall($methodCall);
|
||||
if ($fluentMethodCalls === null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$firstAssignFluentCall = $this->returnFluentMethodCallFactory->createFromFluentMethodCalls(
|
||||
$fluentMethodCalls
|
||||
);
|
||||
|
||||
// should be skipped?
|
||||
if ($this->fluentMethodCallSkipper->shouldSkipFirstAssignFluentCall($firstAssignFluentCall)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $this->separateReturnMethodCallFactory->createReturnFromFirstAssignFluentCallAndFluentMethodCalls(
|
||||
$firstAssignFluentCall,
|
||||
$fluentMethodCalls
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Rector\Return_;
|
||||
|
||||
use PhpParser\Node;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\RectorDefinition\CodeSample;
|
||||
use Rector\Core\RectorDefinition\RectorDefinition;
|
||||
use Rector\Defluent\Rector\AbstractFluentChainMethodCallRector;
|
||||
use Rector\Defluent\ValueObject\FluentCallsKind;
|
||||
|
||||
/**
|
||||
* @see https://ocramius.github.io/blog/fluent-interfaces-are-evil/
|
||||
* @see https://www.yegor256.com/2018/03/13/fluent-interfaces.html
|
||||
*
|
||||
* @see \Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\FluentChainMethodCallToNormalMethodCallRectorTest
|
||||
* @see \Rector\Defluent\Tests\Rector\Return_\ReturnNewFluentChainMethodCallToNonFluentRector\ReturnNewFluentChainMethodCallToNonFluentRectorTest
|
||||
*/
|
||||
final class ReturnNewFluentChainMethodCallToNonFluentRector extends AbstractFluentChainMethodCallRector
|
||||
{
|
||||
public function getDefinition(): RectorDefinition
|
||||
{
|
||||
return new RectorDefinition('Turns fluent interface calls to classic ones.', [
|
||||
new CodeSample(
|
||||
<<<'CODE_SAMPLE'
|
||||
return (new SomeClass())->someFunction()
|
||||
->otherFunction();
|
||||
CODE_SAMPLE
|
||||
,
|
||||
<<<'CODE_SAMPLE'
|
||||
$someClass = new SomeClass();
|
||||
$someClass->someFunction();
|
||||
$someClass->otherFunction();
|
||||
return $someClass;
|
||||
CODE_SAMPLE
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getNodeTypes(): array
|
||||
{
|
||||
return [Return_::class];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Return_ $node
|
||||
*/
|
||||
public function refactor(Node $node): ?Node
|
||||
{
|
||||
$methodCall = $this->matchReturnMethodCall($node);
|
||||
if ($methodCall === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($this->shouldSkipMethodCall($methodCall)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$assignAndRootExprAndNodesToAdd = $this->createStandaloneNodesToAddFromChainMethodCalls(
|
||||
$methodCall,
|
||||
FluentCallsKind::NORMAL
|
||||
);
|
||||
|
||||
if ($assignAndRootExprAndNodesToAdd === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$this->removeCurrentNode($node);
|
||||
$this->addNodesAfterNode($assignAndRootExprAndNodesToAdd->getNodesToAdd(), $node);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
143
rules/defluent/src/Skipper/FluentMethodCallSkipper.php
Normal file
143
rules/defluent/src/Skipper/FluentMethodCallSkipper.php
Normal file
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Skipper;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use Rector\Defluent\Contract\ValueObject\FirstCallFactoryAwareInterface;
|
||||
use Rector\Defluent\NodeAnalyzer\FluentCallStaticTypeResolver;
|
||||
use Rector\Defluent\NodeAnalyzer\FluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\Defluent\NodeAnalyzer\GetterMethodCallAnalyzer;
|
||||
use Rector\Defluent\NodeAnalyzer\SameClassMethodCallAnalyzer;
|
||||
use Rector\Defluent\ValueObject\AssignAndRootExpr;
|
||||
use Rector\Defluent\ValueObject\FirstAssignFluentCall;
|
||||
|
||||
final class FluentMethodCallSkipper
|
||||
{
|
||||
/**
|
||||
* Skip query and builder
|
||||
* @see https://ocramius.github.io/blog/fluent-interfaces-are-evil/ "When does a fluent interface make sense?
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
private const ALLOWED_FLUENT_TYPES = [
|
||||
'Symfony\Component\DependencyInjection\Loader\Configurator\AbstractConfigurator',
|
||||
'Nette\Forms\Controls\BaseControl',
|
||||
'Nette\DI\ContainerBuilder',
|
||||
'Nette\DI\Definitions\Definition',
|
||||
'Nette\DI\Definitions\ServiceDefinition',
|
||||
'PHPStan\Analyser\Scope',
|
||||
'DateTime',
|
||||
'Nette\Utils\DateTime',
|
||||
'DateTimeInterface',
|
||||
'*Finder',
|
||||
'*Builder',
|
||||
'*Query',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var FluentCallStaticTypeResolver
|
||||
*/
|
||||
private $fluentCallStaticTypeResolver;
|
||||
|
||||
/**
|
||||
* @var SameClassMethodCallAnalyzer
|
||||
*/
|
||||
private $sameClassMethodCallAnalyzer;
|
||||
|
||||
/**
|
||||
* @var FluentChainMethodCallNodeAnalyzer
|
||||
*/
|
||||
private $fluentChainMethodCallNodeAnalyzer;
|
||||
|
||||
/**
|
||||
* @var GetterMethodCallAnalyzer
|
||||
*/
|
||||
private $getterMethodCallAnalyzer;
|
||||
|
||||
public function __construct(
|
||||
FluentCallStaticTypeResolver $fluentCallStaticTypeResolver,
|
||||
SameClassMethodCallAnalyzer $sameClassMethodCallAnalyzer,
|
||||
FluentChainMethodCallNodeAnalyzer $fluentChainMethodCallNodeAnalyzer,
|
||||
GetterMethodCallAnalyzer $getterMethodCallAnalyzer
|
||||
) {
|
||||
$this->fluentCallStaticTypeResolver = $fluentCallStaticTypeResolver;
|
||||
$this->sameClassMethodCallAnalyzer = $sameClassMethodCallAnalyzer;
|
||||
$this->fluentChainMethodCallNodeAnalyzer = $fluentChainMethodCallNodeAnalyzer;
|
||||
$this->getterMethodCallAnalyzer = $getterMethodCallAnalyzer;
|
||||
}
|
||||
|
||||
public function shouldSkipRootMethodCall(MethodCall $methodCall): bool
|
||||
{
|
||||
if (! $this->fluentChainMethodCallNodeAnalyzer->isLastChainMethodCall($methodCall)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->getterMethodCallAnalyzer->isGetterMethodCall($methodCall);
|
||||
}
|
||||
|
||||
public function shouldSkipFirstAssignFluentCall(FirstAssignFluentCall $firstAssignFluentCall): bool
|
||||
{
|
||||
$calleeUniqueTypes = $this->fluentCallStaticTypeResolver->resolveCalleeUniqueTypes(
|
||||
$firstAssignFluentCall->getFluentMethodCalls()
|
||||
->getFluentMethodCalls()
|
||||
);
|
||||
|
||||
if (! $this->sameClassMethodCallAnalyzer->isCorrectTypeCount($calleeUniqueTypes, $firstAssignFluentCall)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$calleeUniqueType = $this->resolveCalleeUniqueType($firstAssignFluentCall, $calleeUniqueTypes);
|
||||
|
||||
return $this->isAllowedType($calleeUniqueType, self::ALLOWED_FLUENT_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall[] $fluentMethodCalls
|
||||
*/
|
||||
public function shouldSkipMethodCalls(AssignAndRootExpr $assignAndRootExpr, array $fluentMethodCalls): bool
|
||||
{
|
||||
$calleeUniqueTypes = $this->fluentCallStaticTypeResolver->resolveCalleeUniqueTypes($fluentMethodCalls);
|
||||
|
||||
if (! $this->sameClassMethodCallAnalyzer->isCorrectTypeCount($calleeUniqueTypes, $assignAndRootExpr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$calleeUniqueType = $this->resolveCalleeUniqueType($assignAndRootExpr, $calleeUniqueTypes);
|
||||
|
||||
return $this->isAllowedType($calleeUniqueType, self::ALLOWED_FLUENT_TYPES);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $calleeUniqueTypes
|
||||
*/
|
||||
private function resolveCalleeUniqueType(
|
||||
FirstCallFactoryAwareInterface $firstCallFactoryAware,
|
||||
array $calleeUniqueTypes
|
||||
): string {
|
||||
if (! $firstCallFactoryAware->isFirstCallFactory()) {
|
||||
return $calleeUniqueTypes[0];
|
||||
}
|
||||
|
||||
return $calleeUniqueTypes[1] ?? $calleeUniqueTypes[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $allowedTypes
|
||||
*/
|
||||
private function isAllowedType(string $currentType, array $allowedTypes): bool
|
||||
{
|
||||
foreach ($allowedTypes as $allowedType) {
|
||||
if (is_a($currentType, $allowedType, true)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (fnmatch($allowedType, $currentType, FNM_NOESCAPE)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\ValueObject;
|
||||
namespace Rector\Defluent\ValueObject;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
|
@ -11,9 +11,11 @@ use PhpParser\Node\Expr\Variable;
|
|||
use PhpParser\Node\Stmt\Expression;
|
||||
use PhpParser\Node\Stmt\Return_;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Defluent\Contract\ValueObject\FirstCallFactoryAwareInterface;
|
||||
use Rector\Defluent\Contract\ValueObject\RootExprAwareInterface;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class AssignAndRootExpr
|
||||
final class AssignAndRootExpr implements RootExprAwareInterface, FirstCallFactoryAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
|
@ -74,17 +76,10 @@ final class AssignAndRootExpr
|
|||
public function createFirstAssign(): Assign
|
||||
{
|
||||
if ($this->isFirstCallFactory && $this->getFirstAssign() !== null) {
|
||||
/** @var Assign $currentMethodCall */
|
||||
$currentMethodCall = $this->getFirstAssign()
|
||||
->expr;
|
||||
while ($currentMethodCall->var instanceof MethodCall) {
|
||||
$currentMethodCall = $currentMethodCall->var;
|
||||
}
|
||||
|
||||
return new Assign($this->getFirstAssign()->var, $currentMethodCall);
|
||||
return $this->createFactoryAssign();
|
||||
}
|
||||
|
||||
return new Assign($this->assignExpr, $this->rootExpr);
|
||||
return $this->createAssign($this->assignExpr, $this->rootExpr);
|
||||
}
|
||||
|
||||
public function getCallerExpr(): Expr
|
||||
|
@ -124,4 +119,41 @@ final class AssignAndRootExpr
|
|||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function createFactoryAssign(): Assign
|
||||
{
|
||||
/** @var Assign $firstAssign */
|
||||
$firstAssign = $this->getFirstAssign();
|
||||
$currentMethodCall = $firstAssign->expr;
|
||||
|
||||
if (! $currentMethodCall instanceof MethodCall) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$currentMethodCall = $this->resolveLastMethodCall($currentMethodCall);
|
||||
|
||||
// ensure var and expr are different
|
||||
$assignVar = $firstAssign->var;
|
||||
$assignExpr = $currentMethodCall;
|
||||
|
||||
return $this->createAssign($assignVar, $assignExpr);
|
||||
}
|
||||
|
||||
private function createAssign(Expr $assignVar, Expr $assignExpr): Assign
|
||||
{
|
||||
if ($assignVar === $assignExpr) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
return new Assign($assignVar, $assignExpr);
|
||||
}
|
||||
|
||||
private function resolveLastMethodCall(MethodCall $currentMethodCall): MethodCall
|
||||
{
|
||||
while ($currentMethodCall->var instanceof MethodCall) {
|
||||
$currentMethodCall = $currentMethodCall->var;
|
||||
}
|
||||
|
||||
return $currentMethodCall;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\ValueObject;
|
||||
namespace Rector\Defluent\ValueObject;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Stmt\Return_;
|
135
rules/defluent/src/ValueObject/FirstAssignFluentCall.php
Normal file
135
rules/defluent/src/ValueObject/FirstAssignFluentCall.php
Normal file
|
@ -0,0 +1,135 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\ValueObject;
|
||||
|
||||
use PhpParser\Node\Expr;
|
||||
use PhpParser\Node\Expr\Assign;
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Stmt\Expression;
|
||||
use Rector\Core\Exception\ShouldNotHappenException;
|
||||
use Rector\Defluent\Contract\ValueObject\FirstCallFactoryAwareInterface;
|
||||
use Rector\Defluent\Contract\ValueObject\RootExprAwareInterface;
|
||||
use Rector\NodeTypeResolver\Node\AttributeKey;
|
||||
|
||||
final class FirstAssignFluentCall implements RootExprAwareInterface, FirstCallFactoryAwareInterface
|
||||
{
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $isFirstCallFactory = false;
|
||||
|
||||
/**
|
||||
* @var Expr
|
||||
*/
|
||||
private $assignExpr;
|
||||
|
||||
/**
|
||||
* @var Expr
|
||||
*/
|
||||
private $rootExpr;
|
||||
|
||||
/**
|
||||
* @var FluentMethodCalls
|
||||
*/
|
||||
private $fluentMethodCalls;
|
||||
|
||||
public function __construct(
|
||||
Expr $assignExpr,
|
||||
Expr $rootExpr,
|
||||
bool $isFirstCallFactory,
|
||||
FluentMethodCalls $fluentMethodCalls
|
||||
) {
|
||||
$this->assignExpr = $assignExpr;
|
||||
$this->rootExpr = $rootExpr;
|
||||
$this->isFirstCallFactory = $isFirstCallFactory;
|
||||
$this->fluentMethodCalls = $fluentMethodCalls;
|
||||
}
|
||||
|
||||
public function getAssignExpr(): Expr
|
||||
{
|
||||
return $this->assignExpr;
|
||||
}
|
||||
|
||||
public function getRootExpr(): Expr
|
||||
{
|
||||
return $this->rootExpr;
|
||||
}
|
||||
|
||||
public function createFirstAssign(): Assign
|
||||
{
|
||||
if ($this->isFirstCallFactory && $this->getFirstAssign() !== null) {
|
||||
return $this->createFactoryAssign();
|
||||
}
|
||||
|
||||
return $this->createAssign($this->assignExpr, $this->rootExpr);
|
||||
}
|
||||
|
||||
public function getCallerExpr(): Expr
|
||||
{
|
||||
return $this->assignExpr;
|
||||
}
|
||||
|
||||
public function isFirstCallFactory(): bool
|
||||
{
|
||||
return $this->isFirstCallFactory;
|
||||
}
|
||||
|
||||
public function getFactoryAssignVariable(): Expr
|
||||
{
|
||||
$firstAssign = $this->getFirstAssign();
|
||||
if ($firstAssign === null) {
|
||||
return $this->assignExpr;
|
||||
}
|
||||
|
||||
return $firstAssign->var;
|
||||
}
|
||||
|
||||
public function getFluentMethodCalls(): FluentMethodCalls
|
||||
{
|
||||
return $this->fluentMethodCalls;
|
||||
}
|
||||
|
||||
private function getFirstAssign(): ?Assign
|
||||
{
|
||||
$currentStmt = $this->assignExpr->getAttribute(AttributeKey::CURRENT_STATEMENT);
|
||||
if (! $currentStmt instanceof Expression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($currentStmt->expr instanceof Assign) {
|
||||
return $currentStmt->expr;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function createFactoryAssign(): Assign
|
||||
{
|
||||
/** @var Assign $firstAssign */
|
||||
$firstAssign = $this->getFirstAssign();
|
||||
$currentMethodCall = $firstAssign->expr;
|
||||
|
||||
if (! $currentMethodCall instanceof MethodCall) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
$currentMethodCall = $this->fluentMethodCalls->getLastMethodCall();
|
||||
|
||||
// ensure var and expr are different
|
||||
$assignVar = $firstAssign->var;
|
||||
$assignExpr = $currentMethodCall;
|
||||
|
||||
return $this->createAssign($assignVar, $assignExpr);
|
||||
}
|
||||
|
||||
private function createAssign(Expr $assignVar, Expr $assignExpr): Assign
|
||||
{
|
||||
if ($assignVar === $assignExpr) {
|
||||
throw new ShouldNotHappenException();
|
||||
}
|
||||
|
||||
return new Assign($assignVar, $assignExpr);
|
||||
}
|
||||
}
|
18
rules/defluent/src/ValueObject/FluentCallsKind.php
Normal file
18
rules/defluent/src/ValueObject/FluentCallsKind.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\ValueObject;
|
||||
|
||||
final class FluentCallsKind
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const NORMAL = 'normal';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
public const IN_ARGS = 'in_args';
|
||||
}
|
53
rules/defluent/src/ValueObject/FluentMethodCalls.php
Normal file
53
rules/defluent/src/ValueObject/FluentMethodCalls.php
Normal file
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\ValueObject;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
|
||||
final class FluentMethodCalls
|
||||
{
|
||||
/**
|
||||
* @var MethodCall[]
|
||||
*/
|
||||
private $fluentMethodCalls = [];
|
||||
|
||||
/**
|
||||
* @var MethodCall
|
||||
*/
|
||||
private $rootMethodCall;
|
||||
|
||||
/**
|
||||
* @var MethodCall
|
||||
*/
|
||||
private $lastMethodCall;
|
||||
|
||||
/**
|
||||
* @param MethodCall[] $fluentMethodCalls
|
||||
*/
|
||||
public function __construct(MethodCall $rootMethodCall, array $fluentMethodCalls, MethodCall $lastMethodCall)
|
||||
{
|
||||
$this->rootMethodCall = $rootMethodCall;
|
||||
$this->fluentMethodCalls = $fluentMethodCalls;
|
||||
$this->lastMethodCall = $lastMethodCall;
|
||||
}
|
||||
|
||||
public function getRootMethodCall(): MethodCall
|
||||
{
|
||||
return $this->rootMethodCall;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return MethodCall[]
|
||||
*/
|
||||
public function getFluentMethodCalls(): array
|
||||
{
|
||||
return $this->fluentMethodCalls;
|
||||
}
|
||||
|
||||
public function getLastMethodCall(): MethodCall
|
||||
{
|
||||
return $this->lastMethodCall;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\ValueObjectFactory;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use Rector\Defluent\NodeAnalyzer\FluentChainMethodCallNodeAnalyzer;
|
||||
use Rector\Defluent\NodeAnalyzer\SameClassMethodCallAnalyzer;
|
||||
use Rector\Defluent\ValueObject\FluentMethodCalls;
|
||||
|
||||
final class FluentMethodCallsFactory
|
||||
{
|
||||
/**
|
||||
* @var FluentChainMethodCallNodeAnalyzer
|
||||
*/
|
||||
private $fluentChainMethodCallNodeAnalyzer;
|
||||
|
||||
/**
|
||||
* @var SameClassMethodCallAnalyzer
|
||||
*/
|
||||
private $sameClassMethodCallAnalyzer;
|
||||
|
||||
public function __construct(
|
||||
FluentChainMethodCallNodeAnalyzer $fluentChainMethodCallNodeAnalyzer,
|
||||
SameClassMethodCallAnalyzer $sameClassMethodCallAnalyzer
|
||||
) {
|
||||
$this->fluentChainMethodCallNodeAnalyzer = $fluentChainMethodCallNodeAnalyzer;
|
||||
$this->sameClassMethodCallAnalyzer = $sameClassMethodCallAnalyzer;
|
||||
}
|
||||
|
||||
public function createFromLastMethodCall(MethodCall $lastMethodCall): ?FluentMethodCalls
|
||||
{
|
||||
$chainMethodCalls = $this->fluentChainMethodCallNodeAnalyzer->collectAllMethodCallsInChain($lastMethodCall);
|
||||
if (! $this->sameClassMethodCallAnalyzer->haveSingleClass($chainMethodCalls)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// we need at least 2 method call for fluent
|
||||
if (count($chainMethodCalls) < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$rootMethodCall = $this->resolveRootMethodCall($chainMethodCalls);
|
||||
return new FluentMethodCalls($rootMethodCall, $chainMethodCalls, $lastMethodCall);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param MethodCall[] $chainMethodCalls
|
||||
*/
|
||||
private function resolveRootMethodCall(array $chainMethodCalls): MethodCall
|
||||
{
|
||||
$lastKey = array_key_last($chainMethodCalls);
|
||||
return $chainMethodCalls[$lastKey];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\Source\AnotherTypeFactory;
|
||||
|
||||
final class IsFactoryVariableDoubleMethodCall
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$mainVariable = new AnotherTypeFactory();
|
||||
$someClassWithFluentMethods = $mainVariable->createSomeClassWithFluentMethods()->one();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\Source\SomeClassWithFluentMethods;
|
||||
|
||||
final class ReturnNewDoubleMethodCall
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
return (new SomeClassWithFluentMethods())->one()->two();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\Fixture;
|
||||
|
||||
use Nette\DI\ContainerBuilder;
|
||||
|
||||
final class SkipNoNFluentNetteContainerBuilder
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$containerBuilder = new ContainerBuilder();
|
||||
$containerBuilder->addDefinition('someClass');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\Source\SomeClassWithFluentMethods;
|
||||
|
||||
final class VariableDoubleMethodCall
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$mainVariable = new SomeClassWithFluentMethods();
|
||||
$mainVariable->one()->two();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor;
|
||||
|
||||
use PhpParser\Node\Expr\MethodCall;
|
||||
use PhpParser\Node\Expr\Variable;
|
||||
use Rector\Core\HttpKernel\RectorKernel;
|
||||
use Rector\Core\Testing\TestingParser\TestingParser;
|
||||
use Rector\Defluent\NodeAnalyzer\FluentChainMethodCallRootExtractor;
|
||||
use Rector\Defluent\ValueObject\AssignAndRootExpr;
|
||||
use Rector\Defluent\ValueObject\FluentCallsKind;
|
||||
use Symplify\PackageBuilder\Tests\AbstractKernelTestCase;
|
||||
|
||||
final class FluentChainMethodCallRootExtractorTest extends AbstractKernelTestCase
|
||||
{
|
||||
/**
|
||||
* @var FluentChainMethodCallRootExtractor
|
||||
*/
|
||||
private $fluentChainMethodCallRootExtractor;
|
||||
|
||||
/**
|
||||
* @var TestingParser
|
||||
*/
|
||||
private $testingParser;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->bootKernel(RectorKernel::class);
|
||||
$this->fluentChainMethodCallRootExtractor = self::$container->get(FluentChainMethodCallRootExtractor::class);
|
||||
$this->testingParser = self::$container->get(TestingParser::class);
|
||||
}
|
||||
|
||||
public function test(): void
|
||||
{
|
||||
$assignAndRootExpr = $this->parseFileAndCreateAssignAndRootExprForSure(
|
||||
__DIR__ . '/Fixture/variable_double_method_call.php.inc'
|
||||
);
|
||||
|
||||
$this->assertFalse($assignAndRootExpr->isFirstCallFactory());
|
||||
|
||||
$this->assertNull($assignAndRootExpr->getSilentVariable());
|
||||
}
|
||||
|
||||
public function testFactory(): void
|
||||
{
|
||||
$assignAndRootExpr = $this->parseFileAndCreateAssignAndRootExprForSure(
|
||||
__DIR__ . '/Fixture/is_factory_variable_double_method_call.php.inc'
|
||||
);
|
||||
|
||||
$this->assertTrue($assignAndRootExpr->isFirstCallFactory());
|
||||
}
|
||||
|
||||
public function testNew(): void
|
||||
{
|
||||
$assignAndRootExpr = $this->parseFileAndCreateAssignAndRootExprForSure(
|
||||
__DIR__ . '/Fixture/return_new_double_method_call.php.inc'
|
||||
);
|
||||
|
||||
$this->assertFalse($assignAndRootExpr->isFirstCallFactory());
|
||||
|
||||
$silentVariable = $assignAndRootExpr->getSilentVariable();
|
||||
/** @var Variable $silentVariable */
|
||||
$this->assertInstanceOf(Variable::class, $silentVariable);
|
||||
|
||||
$this->assertIsString($silentVariable->name);
|
||||
$this->assertSame('someClassWithFluentMethods', $silentVariable->name);
|
||||
}
|
||||
|
||||
public function testSingleMethodCallNull(): void
|
||||
{
|
||||
$assignAndRootExpr = $this->parseFileAndCreateAssignAndRootExpr(
|
||||
__DIR__ . '/Fixture/skip_non_fluent_nette_container_builder.php.inc'
|
||||
);
|
||||
|
||||
$this->assertNull($assignAndRootExpr);
|
||||
}
|
||||
|
||||
private function parseFileAndCreateAssignAndRootExprForSure(string $filePath): AssignAndRootExpr
|
||||
{
|
||||
$assignAndRootExpr = $this->parseFileAndCreateAssignAndRootExpr($filePath);
|
||||
$this->assertInstanceOf(AssignAndRootExpr::class, $assignAndRootExpr);
|
||||
|
||||
/** @var AssignAndRootExpr $assignAndRootExpr */
|
||||
return $assignAndRootExpr;
|
||||
}
|
||||
|
||||
private function parseFileAndCreateAssignAndRootExpr(string $filePath): ?AssignAndRootExpr
|
||||
{
|
||||
/** @var MethodCall[] $methodCalls */
|
||||
$methodCalls = $this->testingParser->parseFileToDecoratedNodesAndFindNodesByType(
|
||||
$filePath,
|
||||
MethodCall::class
|
||||
);
|
||||
|
||||
return $this->fluentChainMethodCallRootExtractor->extractFromMethodCalls(
|
||||
$methodCalls,
|
||||
FluentCallsKind::NORMAL
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\Source;
|
||||
|
||||
final class AnotherTypeFactory
|
||||
{
|
||||
/**
|
||||
* @return SomeClassWithFluentMethods
|
||||
*/
|
||||
public function createSomeClassWithFluentMethods()
|
||||
{
|
||||
return new SomeClassWithFluentMethods();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Tests\NodeFactory\FluentChainMethodCallRootExtractor\Source;
|
||||
|
||||
final class SomeClassWithFluentMethods
|
||||
{
|
||||
/**
|
||||
* @return self
|
||||
*/
|
||||
public function one()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function two()
|
||||
{
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
|
||||
class ChildClassWithSameMethodName extends SomeParentClassWithSameMethod
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ class SomeParentClassWithSameMethod
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
|
||||
class ChildClassWithSameMethodName extends SomeParentClassWithSameMethod
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
|
||||
class AnyClass
|
||||
{
|
||||
|
@ -27,7 +27,7 @@ class AnyClass
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
|
||||
class AnyClass
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
|
||||
class SomeMultiNested
|
||||
{
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Source\ParentInVendor;
|
||||
use Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Source\ParentInVendor;
|
||||
|
||||
class SkipParentInVendor extends ParentInVendor
|
||||
{
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector;
|
||||
namespace Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\MagicDisclosure\Rector\ClassMethod\ReturnThisRemoveRector;
|
||||
use Rector\Defluent\Rector\ClassMethod\ReturnThisRemoveRector;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class ReturnThisRemoveRectorTest extends AbstractRectorTestCase
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Source;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture\SkipParentInVendor;
|
||||
use Rector\Defluent\Tests\Rector\ClassMethod\ReturnThisRemoveRector\Fixture\SkipParentInVendor;
|
||||
|
||||
class ParentInVendor
|
||||
{
|
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\Row;
|
||||
|
||||
final class AssignOfFluent
|
||||
{
|
||||
public function run(Row $row)
|
||||
{
|
||||
$cell = $row->addCell()->setName(2);
|
||||
return $cell;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\Row;
|
||||
|
||||
final class AssignOfFluent
|
||||
{
|
||||
public function run(Row $row)
|
||||
{
|
||||
$cell = $row->addCell();
|
||||
$cell->setName(2);
|
||||
return $cell;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Throwable;
|
||||
|
||||
|
@ -34,7 +34,7 @@ class SomeAjaxPresenter
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Throwable;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\FluentInterfaceClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\FluentInterfaceClass;
|
||||
|
||||
class ActionClass
|
||||
{
|
||||
|
@ -24,9 +24,9 @@ class ActionClass
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\FluentInterfaceClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\FluentInterfaceClass;
|
||||
|
||||
class ActionClass
|
||||
{
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\DifferentReturnValues;
|
||||
|
||||
class KeepLastDifferentType
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$differentReturnValues = new DifferentReturnValues();
|
||||
$differentReturnValues->someFunction()
|
||||
->otherFunction();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\DifferentReturnValues;
|
||||
|
||||
class KeepLastDifferentType
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$differentReturnValues = new DifferentReturnValues();
|
||||
$differentReturnValues->someFunction();
|
||||
$differentReturnValues->otherFunction();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\FluentInterfaceClass;
|
||||
|
||||
class LastNormalCallOnFluent
|
||||
{
|
||||
public function someMethod(FluentInterfaceClass $fluentInterfaceClass)
|
||||
{
|
||||
$fluentInterfaceClass->someFunction()
|
||||
->voidReturningMethod();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\FluentInterfaceClass;
|
||||
|
||||
class LastNormalCallOnFluent
|
||||
{
|
||||
public function someMethod(FluentInterfaceClass $fluentInterfaceClass)
|
||||
{
|
||||
$fluentInterfaceClass->someFunction();
|
||||
$fluentInterfaceClass->voidReturningMethod();
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
|
@ -18,7 +18,7 @@ class MultipleSomeCommand extends Command
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Rector\ClassMethod\ReturnThisRemoveRector;
|
||||
use Rector\Defluent\Rector\ClassMethod\ReturnThisRemoveRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
final class SkipContainerConfigurator
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use DateTime;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use DateTime;
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\DifferentReturnValues;
|
||||
|
||||
class SkipDifferentType
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$differentReturnValues = new DifferentReturnValues();
|
||||
$differentReturnValues->otherFunction()
|
||||
->someFunction();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
class SkipFactoryCall extends Command
|
||||
{
|
||||
public function go()
|
||||
{
|
||||
$this->getApplication()
|
||||
->setAutoExit(true);
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\SomeResponse;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\SomeResponse;
|
||||
|
||||
final class SkipGetterResponseHeader
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Nette\Forms\Controls\TextInput;
|
||||
use Nette\Forms\Form;
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Nette\DI\CompilerExtension;
|
||||
|
||||
final class SkipNetteDIBuilder extends CompilerExtension
|
||||
{
|
||||
public function build(): void
|
||||
{
|
||||
$containerBuilder = $this->getContainerBuilder();
|
||||
$containerBuilder->addDefinition('one')
|
||||
->setFactory('two');
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\FluentInterfaceClass;
|
||||
|
||||
class SkipNew
|
||||
{
|
||||
public function someFunction()
|
||||
{
|
||||
return (new FluentInterfaceClass())->someFunction()->otherFunction();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use PHPStan\Type\MixedType;
|
||||
|
||||
class SkipPhpStanTrinary
|
||||
{
|
||||
public function run(MixedType $variableType)
|
||||
{
|
||||
return $variableType->isSuperTypeOf($variableType)->yes();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\QueryBuilder;
|
||||
|
||||
class SkipQueryBuilder
|
||||
{
|
||||
public function someFunction()
|
||||
{
|
||||
$queryBuilder = new QueryBuilder();
|
||||
$queryBuilder->addQuery()
|
||||
->select();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Rector\ClassMethod\ReturnThisRemoveRector;
|
||||
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
|
||||
|
||||
final class SkipReturn
|
||||
{
|
||||
public function run(ContainerConfigurator $containerConfigurator)
|
||||
{
|
||||
$services = $containerConfigurator->services();
|
||||
return $services->set(ReturnThisRemoveRector::class)
|
||||
->arg('key', 'value');
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\FluentInterfaceClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source\FluentInterfaceClass;
|
||||
|
||||
class UsedAsParameter
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
||||
|
@ -18,7 +18,7 @@ class SomeCommand extends Command
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\MagicDisclosure\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector;
|
||||
use Rector\Defluent\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class FluentChainMethodCallToNormalMethodCallRectorTest extends AbstractRectorTestCase
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
|
||||
final class Cell
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
|
||||
final class DifferentReturnValues implements FluentInterfaceClassInterface
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
|
||||
final class FluentInterfaceClass extends InterFluentInterfaceClass
|
||||
{
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
|
||||
interface FluentInterfaceClassInterface
|
||||
{
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
|
||||
abstract class InterFluentInterfaceClass implements FluentInterfaceClassInterface
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
|
||||
final class QueryBuilder
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
|
||||
final class Row
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Source;
|
||||
|
||||
interface SomeResponse
|
||||
{
|
|
@ -1,9 +1,9 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\DummyUserProfile;
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\DummyUserProvider;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\DummyUserProfile;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\DummyUserProvider;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
|
@ -27,10 +27,10 @@ class SomeClass
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\DummyUserProfile;
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\DummyUserProvider;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\DummyUserProfile;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\DummyUserProvider;
|
||||
|
||||
class SomeClass
|
||||
{
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
|
||||
class NewInArg
|
||||
{
|
||||
|
@ -20,9 +20,9 @@ class NewInArg
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
|
||||
class NewInArg
|
||||
{
|
|
@ -1,10 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\SetGetDateTime;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\SetGetDateTime;
|
||||
use Nette\Utils\DateTime as NetteDateTime;
|
||||
|
||||
final class SelfSelf
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
|
||||
class SkipNonArg
|
||||
{
|
||||
public function someFunction()
|
||||
{
|
||||
(new FluentClass())->otherFunction()
|
||||
->someFunction();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\NonFluentClass;
|
||||
|
||||
class SkipNonFluentNewInArg
|
||||
{
|
||||
public function someFunction()
|
||||
{
|
||||
$this->processFluentClass((new NonFluentClass())->number());
|
||||
}
|
||||
|
||||
public function processFluentClass(int $number)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
|
||||
class SkipSingleClass
|
||||
{
|
||||
public function someFunction(FluentClass $someClass)
|
||||
{
|
||||
$this->processFluentClass($someClass->someFunction());
|
||||
}
|
||||
|
||||
public function processFluentClass(FluentClass $someClass)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
|
||||
class UsedAsParameter
|
||||
{
|
||||
|
@ -20,9 +20,9 @@ class UsedAsParameter
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
|
||||
class UsedAsParameter
|
||||
{
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
|
||||
class WithArgs
|
||||
{
|
||||
|
@ -20,9 +20,9 @@ class WithArgs
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source\FluentClass;
|
||||
|
||||
class WithArgs
|
||||
{
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\MagicDisclosure\Rector\MethodCall\InArgFluentChainMethodCallToStandaloneMethodCallRector;
|
||||
use Rector\Defluent\Rector\MethodCall\InArgFluentChainMethodCallToStandaloneMethodCallRector;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class InArgChainFluentMethodCallToStandaloneMethodCallRectorTest extends AbstractRectorTestCase
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
|
||||
final class DummyUser
|
||||
{
|
||||
public $id;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
|
||||
final class DummyUserProfile
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
|
||||
final class DummyUserProvider
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
|
||||
final class FluentClass
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
|
||||
final class NonFluentClass
|
||||
{
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\InArgChainFluentMethodCallToStandaloneMethodCallRectorTest\Source;
|
||||
|
||||
use Nette\Utils\DateTime;
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
|
||||
class SomeClass
|
||||
{
|
||||
|
@ -22,9 +22,9 @@ class SomeClass
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
|
||||
class SomeClass
|
||||
{
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
|
||||
class MultiChain
|
||||
{
|
||||
|
@ -23,9 +23,9 @@ class MultiChain
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
|
||||
class MultiChain
|
||||
{
|
|
@ -1,8 +1,8 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
|
||||
class WithArguments
|
||||
{
|
||||
|
@ -23,9 +23,9 @@ class WithArguments
|
|||
-----
|
||||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Fixture;
|
||||
|
||||
use Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source\AnotherClass;
|
||||
|
||||
class WithArguments
|
||||
{
|
|
@ -2,11 +2,11 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector;
|
||||
|
||||
use Iterator;
|
||||
use Rector\Core\Testing\PHPUnit\AbstractRectorTestCase;
|
||||
use Rector\MagicDisclosure\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector;
|
||||
use Rector\Defluent\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector;
|
||||
use Symplify\SmartFileSystem\SmartFileInfo;
|
||||
|
||||
final class MethodCallOnSetterMethodCallToStandaloneAssignRectorTest extends AbstractRectorTestCase
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\MethodCallOnSetterMethodCallToStandaloneAssignRector\Source;
|
||||
|
||||
final class AnotherClass
|
||||
{
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\MagicDisclosure\Tests\Rector\MethodCall\FluentChainMethodCallToNormalMethodCallRector\Fixture;
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\NewFluentChainMethodCallToNonFluentRector\Fixture;
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
namespace Rector\Defluent\Tests\Rector\MethodCall\NewFluentChainMethodCallToNonFluentRector\Fixture;
|
||||
|
||||
use Rector\Defluent\Tests\Rector\MethodCall\NewFluentChainMethodCallToNonFluentRector\Source\DifferentReturnValues;
|
||||
|
||||
class SkipGetterOnNew
|
||||
{
|
||||
public function run()
|
||||
{
|
||||
$differentReturnValues = (new DifferentReturnValues())->otherFunction();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user