diff --git a/config/level/cakephp/cakephp34.yml b/config/level/cakephp/cakephp34.yml new file mode 100644 index 00000000000..9ea32b4e5bf --- /dev/null +++ b/config/level/cakephp/cakephp34.yml @@ -0,0 +1,4 @@ +# source: https://book.cakephp.org/3.0/en/appendices/3-4-migration-guide.html + +services: + # ... diff --git a/config/level/cakephp/cakephp35.yml b/config/level/cakephp/cakephp35.yml new file mode 100644 index 00000000000..6823da1073f --- /dev/null +++ b/config/level/cakephp/cakephp35.yml @@ -0,0 +1,36 @@ +# source: https://book.cakephp.org/3.0/en/appendices/3-5-migration-guide.html + +services: + Rector\Rector\Property\PropertyToMethodRector: + $perClassPropertyToMethods: + 'Cake\Network\Request': + 'params': + 'get': + method: 'getAttribute' + arguments: + - 'params' + 'data': + 'get': 'getData' + 'query': + 'get': 'getQueryParams' + 'cookies': + 'get': 'getCookie' + 'base': + 'get': + method: 'getAttribute' + arguments: + - 'base' + 'webroot': + 'get': + method: 'getAttribute' + arguments: + - 'webroot' + + Rector\Rector\Class_\ClassReplacerRector: + $oldToNewClasses: + 'Cake\Http\Client\CookieCollection ': 'Cake\Http\Cookie\CookieCollection' + + Rector\Rector\Property\PropertyNameReplacerRector: + $perClassOldToNewProperties: + 'Cake\Network\Request': + '_session': 'session' diff --git a/src/Node/MethodCallNodeFactory.php b/src/Node/MethodCallNodeFactory.php index a9f5e26a44b..a4cfd8cad98 100644 --- a/src/Node/MethodCallNodeFactory.php +++ b/src/Node/MethodCallNodeFactory.php @@ -71,11 +71,11 @@ final class MethodCallNodeFactory * @param mixed[] $arguments */ public function createWithVariableMethodNameAndArguments( - Variable $variableNode, + Expr $exprNode, string $method, array $arguments ): MethodCall { - $methodCall = $this->createWithVariableAndMethodName($variableNode, $method); + $methodCall = $this->createWithVariableAndMethodName($exprNode, $method); $methodCall->args = $this->nodeFactory->createArgs($arguments); return $methodCall; diff --git a/src/Rector/Property/PropertyToMethodRector.php b/src/Rector/Property/PropertyToMethodRector.php index d8f5f98160d..81d86784afd 100644 --- a/src/Rector/Property/PropertyToMethodRector.php +++ b/src/Rector/Property/PropertyToMethodRector.php @@ -21,11 +21,6 @@ final class PropertyToMethodRector extends AbstractRector */ private $perClassPropertyToMethods = []; - /** - * @var string - */ - private $activeMethod; - /** * @var PropertyFetchAnalyzer */ @@ -73,7 +68,32 @@ CODE_SAMPLE [ '$perClassPropertyToMethods' => [ 'SomeObject' => [ - 'property' => ['getProperty', 'setProperty'], + 'property' => [ + 'get' => 'getProperty', + 'set' => 'setProperty', + ], + ], + ], + ] + ), + new ConfiguredCodeSample( + <<<'CODE_SAMPLE' +$result = $object->property; +CODE_SAMPLE + , + <<<'CODE_SAMPLE' +$result = $object->getProperty('someArg'); +CODE_SAMPLE + , + [ + '$perClassPropertyToMethods' => [ + 'SomeObject' => [ + 'property' => [ + 'get' => [ + 'method' => 'getConfig', + 'arguments' => ['someArg'], + ], + ], ], ], ] @@ -94,45 +114,80 @@ CODE_SAMPLE */ public function refactor(Node $assignNode): ?Node { - // setter if ($assignNode->var instanceof PropertyFetch) { - if ($this->processPropertyFetchCandidate($assignNode->var, 'set') === false) { - return null; - } + return $this->processSetter($assignNode); } - // getter + if ($assignNode->expr instanceof PropertyFetch) { - if ($this->processPropertyFetchCandidate($assignNode->expr, 'get') === false) { - return null; - } - } - - // setter - if ($assignNode->var instanceof PropertyFetch) { - $args = $this->nodeFactory->createArgs([$assignNode->expr]); - - /** @var Variable $variable */ - $variable = $assignNode->var->var; - - return $this->methodCallNodeFactory->createWithVariableMethodNameAndArguments( - $variable, - $this->activeMethod, - $args - ); - } - - // getter - if ($assignNode->expr instanceof PropertyFetch) { - $assignNode->expr = $this->methodCallNodeFactory->createWithVariableAndMethodName( - $assignNode->expr->var, - $this->activeMethod - ); + return $this->processGetter($assignNode); } return null; } - private function processPropertyFetchCandidate(PropertyFetch $propertyFetchNode, string $type): bool + private function processSetter(Assign $assignNode): ?Node + { + /** @var PropertyFetch $propertyFetchNode */ + $propertyFetchNode = $assignNode->var; + + $newMethodMatch = $this->matchPropertyFetchCandidate($propertyFetchNode); + if ($newMethodMatch === null) { + return null; + } + + $args = $this->nodeFactory->createArgs([$assignNode->expr]); + + /** @var Variable $variable */ + $variable = $propertyFetchNode->var; + + return $this->methodCallNodeFactory->createWithVariableMethodNameAndArguments( + $variable, + $newMethodMatch['set'], + $args + ); + } + + private function processGetter(Assign $assignNode): ?Node + { + /** @var PropertyFetch $propertyFetchNode */ + $propertyFetchNode = $assignNode->expr; + + $newMethodMatch = $this->matchPropertyFetchCandidate($propertyFetchNode); + if ($newMethodMatch === null) { + return null; + } + + // simple method name + if (is_string($newMethodMatch['get'])) { + $assignNode->expr = $this->methodCallNodeFactory->createWithVariableAndMethodName( + $propertyFetchNode->var, + $newMethodMatch['get'] + ); + + return $assignNode; + + // method with argument + } + + if (is_array($newMethodMatch['get'])) { + $args = $this->nodeFactory->createArgs($newMethodMatch['get']['arguments']); + + $assignNode->expr = $this->methodCallNodeFactory->createWithVariableMethodNameAndArguments( + $propertyFetchNode->var, + $newMethodMatch['get']['method'], + $args + ); + + return $assignNode; + } + + return $assignNode; + } + + /** + * @return mixed[]|null + */ + private function matchPropertyFetchCandidate(PropertyFetch $propertyFetchNode): ?array { foreach ($this->perClassPropertyToMethods as $class => $propertyToMethods) { $properties = array_keys($propertyToMethods); @@ -141,12 +196,10 @@ CODE_SAMPLE /** @var Identifier $identifierNode */ $identifierNode = $propertyFetchNode->name; - $this->activeMethod = $propertyToMethods[$identifierNode->toString()][$type]; - - return true; + return $propertyToMethods[$identifierNode->toString()]; //[$type]; } } - return false; + return null; } } diff --git a/tests/Rector/Property/PropertyNameReplacerRector/PropertyNameReplacerRectorTest.php b/tests/Rector/Property/PropertyNameReplacerRector/PropertyNameReplacerRectorTest.php index 3583b5c30a6..207f6ba6967 100644 --- a/tests/Rector/Property/PropertyNameReplacerRector/PropertyNameReplacerRectorTest.php +++ b/tests/Rector/Property/PropertyNameReplacerRector/PropertyNameReplacerRectorTest.php @@ -5,6 +5,9 @@ namespace Rector\Tests\Rector\Property\PropertyNameReplacerRector; use Iterator; use Rector\Testing\PHPUnit\AbstractRectorTestCase; +/** + * @covers \Rector\Rector\Property\PropertyNameReplacerRector + */ final class PropertyNameReplacerRectorTest extends AbstractRectorTestCase { /** diff --git a/tests/Rector/Property/PropertyToMethodRector/Correct/correct2.php.inc b/tests/Rector/Property/PropertyToMethodRector/Correct/correct2.php.inc new file mode 100644 index 00000000000..908f4ea776a --- /dev/null +++ b/tests/Rector/Property/PropertyToMethodRector/Correct/correct2.php.inc @@ -0,0 +1,13 @@ +getConfig('parameter'); + } +} diff --git a/tests/Rector/Property/PropertyToMethodRector/PropertyToMethodRectorTest.php b/tests/Rector/Property/PropertyToMethodRector/PropertyToMethodRectorTest.php index 66be1bea7a8..3402f17b0b6 100644 --- a/tests/Rector/Property/PropertyToMethodRector/PropertyToMethodRectorTest.php +++ b/tests/Rector/Property/PropertyToMethodRector/PropertyToMethodRectorTest.php @@ -21,6 +21,7 @@ final class PropertyToMethodRectorTest extends AbstractRectorTestCase public function provideWrongToFixedFiles(): Iterator { yield [__DIR__ . '/Wrong/wrong.php.inc', __DIR__ . '/Correct/correct.php.inc']; + yield [__DIR__ . '/Wrong/wrong2.php.inc', __DIR__ . '/Correct/correct2.php.inc']; } protected function provideConfig(): string diff --git a/tests/Rector/Property/PropertyToMethodRector/Wrong/wrong2.php.inc b/tests/Rector/Property/PropertyToMethodRector/Wrong/wrong2.php.inc new file mode 100644 index 00000000000..8606d83ffa8 --- /dev/null +++ b/tests/Rector/Property/PropertyToMethodRector/Wrong/wrong2.php.inc @@ -0,0 +1,13 @@ +parameter; + } +} diff --git a/tests/Rector/Property/PropertyToMethodRector/config.yml b/tests/Rector/Property/PropertyToMethodRector/config.yml index dfebd2cadee..ba2ab8bcb79 100644 --- a/tests/Rector/Property/PropertyToMethodRector/config.yml +++ b/tests/Rector/Property/PropertyToMethodRector/config.yml @@ -5,3 +5,10 @@ services: 'locale': 'get': 'getLocale' 'set': 'setLocale' + + 'Rector\Tests\Rector\Property\PropertyToMethodRector\Wrong\SomeClassWithParameters': + 'parameter': + 'get': + method: 'getConfig' + arguments: + - 'parameter'