From 17f227997bb24a8c794471d0d7e04f2494fc2fe5 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sat, 2 Sep 2017 15:30:40 +0200 Subject: [PATCH 01/10] fix cs --- src/Builder/Kernel/ServiceFromKernelResolver.php | 1 - src/Rector/AbstractRector.php | 10 +++++----- .../CommandToConstructorInjectionRector.php | 6 +++++- .../Contrib/SymfonyExtra/GetterToPropertyRector.php | 6 +++++- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/Builder/Kernel/ServiceFromKernelResolver.php b/src/Builder/Kernel/ServiceFromKernelResolver.php index 4fa5b3ae35f1..69fe10d63155 100644 --- a/src/Builder/Kernel/ServiceFromKernelResolver.php +++ b/src/Builder/Kernel/ServiceFromKernelResolver.php @@ -20,7 +20,6 @@ public function resolveServiceClassFromArgument(Arg $argNode, string $kernelClas return $serviceType; } - private function resolveServiceClassByNameFromKernel(string $serviceName, string $kernelClass): ?string { $container = $this->createContainerFromKernelClass($kernelClass); diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index a7dfb014db85..b3a4cd901149 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -34,11 +34,6 @@ public function beforeTraverse(array $nodes): ?array return null; } - protected function getClassName(): string - { - return $this->classNode->namespacedName->toString(); - } - /** * @return null|int|Node */ @@ -54,4 +49,9 @@ public function enterNode(Node $node) return null; } + + protected function getClassName(): string + { + return $this->classNode->namespacedName->toString(); + } } diff --git a/src/Rector/Contrib/SymfonyExtra/CommandToConstructorInjectionRector.php b/src/Rector/Contrib/SymfonyExtra/CommandToConstructorInjectionRector.php index db77452b5482..882baa36de52 100644 --- a/src/Rector/Contrib/SymfonyExtra/CommandToConstructorInjectionRector.php +++ b/src/Rector/Contrib/SymfonyExtra/CommandToConstructorInjectionRector.php @@ -113,7 +113,11 @@ public function refactor(Node $node): ?Node { $this->replaceParentContainerAwareCommandWithCommand(); - $serviceType = $this->serviceFromKernelResolver->resolveServiceClassFromArgument($node->args[0], LocalKernel::class); + $serviceType = $this->serviceFromKernelResolver->resolveServiceClassFromArgument( + $node->args[0], + LocalKernel::class + ); + if ($serviceType === null) { return null; } diff --git a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php index 737a0dcb086e..a9d35d59c057 100644 --- a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php +++ b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php @@ -127,7 +127,11 @@ private function isContainerGetCall(MethodCall $methodCall): bool private function processMethodCallNode(MethodCall $methodCall): ?PropertyFetch { - $serviceType = $this->serviceFromKernelResolver->resolveServiceClassFromArgument($methodCall->args[0], LocalKernel::class); + $serviceType = $this->serviceFromKernelResolver->resolveServiceClassFromArgument( + $methodCall->args[0], + LocalKernel::class + ); + if ($serviceType === null) { return null; } From b35e0e54e57334817d3baca510520635ad0a7dae Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sat, 2 Sep 2017 15:31:17 +0200 Subject: [PATCH 02/10] fix cs --- src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php index a9d35d59c057..27f14efe32cd 100644 --- a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php +++ b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php @@ -58,6 +58,13 @@ public function __construct( public function isCandidate(Node $node): bool { + if (! $node instanceof MethodCall) { + return false; + } + + dump($node); + die; + // finds $var = $this->get('some_service'); // finds $var = $this->get('some_service')->getData(); if ($node instanceof Assign && ($node->expr instanceof MethodCall || $node->var instanceof MethodCall)) { From f24adbb1034beee80b93ab1012b285b731fba6d5 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sat, 2 Sep 2017 15:35:53 +0200 Subject: [PATCH 03/10] [SymfonyExtra] simplify GetterToPropertyRector --- .../SymfonyExtra/GetterToPropertyRector.php | 51 ++++--------------- 1 file changed, 9 insertions(+), 42 deletions(-) diff --git a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php index 27f14efe32cd..40ea28db3924 100644 --- a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php +++ b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php @@ -3,7 +3,6 @@ namespace Rector\Rector\Contrib\SymfonyExtra; use PhpParser\Node; -use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Scalar\String_; @@ -62,44 +61,16 @@ public function isCandidate(Node $node): bool return false; } - dump($node); - die; - - // finds $var = $this->get('some_service'); - // finds $var = $this->get('some_service')->getData(); - if ($node instanceof Assign && ($node->expr instanceof MethodCall || $node->var instanceof MethodCall)) { - if ($this->isContainerGetCall($node->expr)) { - return true; - } - } - - // finds ['var => $this->get('some_service')->getData()] - if ($node instanceof MethodCall && $node->var instanceof MethodCall) { - if ($this->isContainerGetCall($node->var)) { - return true; - } - } - - return false; + return $this->isContainerGetCall($node); } - public function refactor(Node $assignOrMethodCallNode): ?Node + /** + * @param MethodCall $methodCallNode + * @return null|Node + */ + public function refactor(Node $methodCallNode): ?Node { - if ($assignOrMethodCallNode instanceof Assign) { - $refactoredMethodCall = $this->processMethodCallNode($assignOrMethodCallNode->expr); - if ($refactoredMethodCall) { - $assignOrMethodCallNode->expr = $refactoredMethodCall; - } - } - - if ($assignOrMethodCallNode instanceof MethodCall) { - $refactoredMethodCall = $this->processMethodCallNode($assignOrMethodCallNode->var); - if ($refactoredMethodCall) { - $assignOrMethodCallNode->var = $refactoredMethodCall; - } - } - - return $assignOrMethodCallNode; + return $this->processMethodCallNode($methodCallNode); } public function getSetName(): string @@ -117,15 +88,11 @@ public function sinceVersion(): float */ private function isContainerGetCall(MethodCall $methodCall): bool { - if ($methodCall->var->name !== 'this') { - return false; - } - - if ((string) $methodCall->name !== 'get') { + if ($methodCall->var->name !== 'this' || (string) $methodCall->name !== 'get') { return false; } - if (! $methodCall->args[0]->value instanceof String_) { + if (count($methodCall->args) !== 1 || ! $methodCall->args[0]->value instanceof String_) { return false; } From d5fc51f559cf37e702965ee1a77e87ca34965ad5 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sat, 2 Sep 2017 15:36:27 +0200 Subject: [PATCH 04/10] fix cs --- src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php index 40ea28db3924..75c20d29d135 100644 --- a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php +++ b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php @@ -66,7 +66,6 @@ public function isCandidate(Node $node): bool /** * @param MethodCall $methodCallNode - * @return null|Node */ public function refactor(Node $methodCallNode): ?Node { From c5b52323d9223b78ff33eb2636e176d4afafacde Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sat, 2 Sep 2017 15:42:04 +0200 Subject: [PATCH 05/10] drop unsued code [skip ci] --- .../SymfonyExtra/GetterToPropertyRector.php | 28 ++++++++----------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php index 75c20d29d135..9c12ef1fa3ee 100644 --- a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php +++ b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php @@ -61,7 +61,17 @@ public function isCandidate(Node $node): bool return false; } - return $this->isContainerGetCall($node); + // finds **$this->get**('string') + if ($node->var->name !== 'this' || (string) $node->name !== 'get') { + return false; + } + + // finds $this->get(**'string'**) + if (count($node->args) !== 1 || ! $node->args[0]->value instanceof String_) { + return false; + } + + return true; } /** @@ -82,22 +92,6 @@ public function sinceVersion(): float return 3.3; } - /** - * Is "$this->get('string')" statements? - */ - private function isContainerGetCall(MethodCall $methodCall): bool - { - if ($methodCall->var->name !== 'this' || (string) $methodCall->name !== 'get') { - return false; - } - - if (count($methodCall->args) !== 1 || ! $methodCall->args[0]->value instanceof String_) { - return false; - } - - return true; - } - private function processMethodCallNode(MethodCall $methodCall): ?PropertyFetch { $serviceType = $this->serviceFromKernelResolver->resolveServiceClassFromArgument( From 338dcdb339139cf33fc1ebd02d08bcb15b9b0ff2 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sat, 2 Sep 2017 15:50:47 +0200 Subject: [PATCH 06/10] misc --- easy-coding-standard.neon | 2 +- src/NodeFactory/NodeFactory.php | 23 ++++++++++++++++++ .../Contrib/Symfony/FormIsValidRector.php | 24 +++++++++++-------- .../Symfony/StringFormTypeToClassRector.php | 15 +++++++++--- .../VarDumperTestTraitMethodArgsRector.php | 18 +++++++------- 5 files changed, 59 insertions(+), 23 deletions(-) diff --git a/easy-coding-standard.neon b/easy-coding-standard.neon index e8f8e5f0c5f1..01f3968c67bd 100644 --- a/easy-coding-standard.neon +++ b/easy-coding-standard.neon @@ -28,7 +28,7 @@ checkers: Symplify\CodingStandard\Sniffs\DependencyInjection\NoClassInstantiationSniff: extraAllowedClasses: - - 'PhpParser\Node\*' +# - 'PhpParser\Node\*' - 'PhpParser\Comment\Doc' parameters: diff --git a/src/NodeFactory/NodeFactory.php b/src/NodeFactory/NodeFactory.php index ea4175537755..16e89bfd0c53 100644 --- a/src/NodeFactory/NodeFactory.php +++ b/src/NodeFactory/NodeFactory.php @@ -2,8 +2,12 @@ namespace Rector\NodeFactory; +use PhpParser\Node\Expr\ClassConstFetch; +use PhpParser\Node\Expr\ConstFetch; +use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\Variable; +use PhpParser\Node\Name; final class NodeFactory { @@ -19,4 +23,23 @@ public function createLocalPropertyFetch(string $propertyName): PropertyFetch $propertyName ); } + + public function createNullConstant(): ConstFetch + { + return new ConstFetch(new Name('null')); + } + + public function createClassConstantReference(string $className): ClassConstFetch + { + $nameNode = new Name('\\' . $className); + + return new ClassConstFetch($nameNode, 'class'); + } + + public function createMethodCall(string $variableName, string $methodName): MethodCall + { + $varNode = new Variable($variableName); + + return new MethodCall($varNode, $methodName); + } } diff --git a/src/Rector/Contrib/Symfony/FormIsValidRector.php b/src/Rector/Contrib/Symfony/FormIsValidRector.php index f3c52080a6a7..a4629548a003 100644 --- a/src/Rector/Contrib/Symfony/FormIsValidRector.php +++ b/src/Rector/Contrib/Symfony/FormIsValidRector.php @@ -7,6 +7,7 @@ use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\Variable; use Rector\Deprecation\SetNames; +use Rector\NodeFactory\NodeFactory; use Rector\Rector\AbstractRector; /** @@ -18,6 +19,16 @@ */ final class FormIsValidRector extends AbstractRector { + /** + * @var NodeFactory + */ + private $nodeFactory; + + public function __construct(NodeFactory $nodeFactory) + { + $this->nodeFactory = $nodeFactory; + } + public function getSetName(): string { return SetNames::SYMFONY; @@ -54,18 +65,11 @@ public function isCandidate(Node $node): bool */ public function refactor(Node $node): ?Node { - $varName = $node->var->name; + $variableName = $node->var->name; return new BooleanAnd( - $this->createMethodCall($varName, 'isSubmitted'), - $this->createMethodCall($varName, 'isValid') + $this->nodeFactory->createMethodCall($variableName, 'isSubmitted'), + $this->nodeFactory->createMethodCall($variableName, 'isValid') ); } - - private function createMethodCall(string $varName, string $methodName): MethodCall - { - $varNode = new Variable($varName); - - return new MethodCall($varNode, $methodName); - } } diff --git a/src/Rector/Contrib/Symfony/StringFormTypeToClassRector.php b/src/Rector/Contrib/Symfony/StringFormTypeToClassRector.php index cd03e287f365..5e675b2b44d8 100644 --- a/src/Rector/Contrib/Symfony/StringFormTypeToClassRector.php +++ b/src/Rector/Contrib/Symfony/StringFormTypeToClassRector.php @@ -3,10 +3,10 @@ namespace Rector\Rector\Contrib\Symfony; use PhpParser\Node; -use PhpParser\Node\Expr\ClassConstFetch; use PhpParser\Node\Name; use PhpParser\Node\Scalar\String_; use Rector\Deprecation\SetNames; +use Rector\NodeFactory\NodeFactory; use Rector\Rector\AbstractRector; /** @@ -55,6 +55,16 @@ final class StringFormTypeToClassRector extends AbstractRector 'form.type.reset' => 'Symfony\Component\Form\Extension\Core\Type\ResetType', ]; + /** + * @var NodeFactory + */ + private $nodeFactory; + + public function __construct(NodeFactory $nodeFactory) + { + $this->nodeFactory = $nodeFactory; + } + public function getSetName(): string { return SetNames::SYMFONY; @@ -76,8 +86,7 @@ public function isCandidate(Node $node): bool public function refactor(Node $node): ?Node { $class = $this->nameToClassMap[$node->value]; - $nameNode = new Name('\\' . $class); - return new ClassConstFetch($nameNode, 'class'); + return $this->nodeFactory->createClassConstantReference($class); } } diff --git a/src/Rector/Contrib/Symfony/VarDumperTestTraitMethodArgsRector.php b/src/Rector/Contrib/Symfony/VarDumperTestTraitMethodArgsRector.php index b35d590482b8..48463f33855b 100644 --- a/src/Rector/Contrib/Symfony/VarDumperTestTraitMethodArgsRector.php +++ b/src/Rector/Contrib/Symfony/VarDumperTestTraitMethodArgsRector.php @@ -3,12 +3,11 @@ namespace Rector\Rector\Contrib\Symfony; use PhpParser\Node; -use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\StaticCall; -use PhpParser\Node\Name; use PhpParser\Node\Scalar\String_; use Rector\Deprecation\SetNames; use Rector\NodeAnalyzer\MethodCallAnalyzer; +use Rector\NodeFactory\NodeFactory; use Rector\Rector\AbstractRector; /** @@ -32,9 +31,15 @@ final class VarDumperTestTraitMethodArgsRector extends AbstractRector */ private $methodCallAnalyzer; - public function __construct(MethodCallAnalyzer $methodCallAnalyzer) + /** + * @var NodeFactory + */ + private $nodeFactory; + + public function __construct(MethodCallAnalyzer $methodCallAnalyzer, NodeFactory $nodeFactory) { $this->methodCallAnalyzer = $methodCallAnalyzer; + $this->nodeFactory = $nodeFactory; } public function getSetName(): string @@ -74,7 +79,7 @@ public function refactor(Node $node): ?Node if ($methodArguments[2]->value instanceof String_) { $methodArguments[3] = $methodArguments[2]; - $methodArguments[2] = $this->createNullConstant(); + $methodArguments[2] = $this->nodeFactory->createNullConstant(); $node->args = $methodArguments; @@ -83,9 +88,4 @@ public function refactor(Node $node): ?Node return null; } - - private function createNullConstant(): ConstFetch - { - return new ConstFetch(new Name('null')); - } } From 748e8218febf5bb16e1cdb07877d7da6882e74a7 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sun, 3 Sep 2017 14:08:17 +0200 Subject: [PATCH 07/10] misc --- src/NodeFactory/NodeFactory.php | 55 ++++++++++++++++--- .../AbstractChangeParentClassRector.php | 17 +----- src/Rector/AbstractRector.php | 18 ++++++ .../Contrib/Nette/FormCallbackRector.php | 45 ++++++--------- .../Nette/NetteObjectToSmartTraitRector.php | 54 +++++++----------- .../Symfony/ConstraintUrlOptionRector.php | 20 ++++--- .../Contrib/Symfony/FormIsValidRector.php | 1 - .../SymfonyExtra/GetterToPropertyRector.php | 28 ++++------ .../Correct/correct.php.inc | 2 +- 9 files changed, 130 insertions(+), 110 deletions(-) diff --git a/src/NodeFactory/NodeFactory.php b/src/NodeFactory/NodeFactory.php index 16e89bfd0c53..59e7d68f6ca4 100644 --- a/src/NodeFactory/NodeFactory.php +++ b/src/NodeFactory/NodeFactory.php @@ -2,12 +2,19 @@ namespace Rector\NodeFactory; +use PhpParser\Node; +use PhpParser\Node\Expr\Array_; +use PhpParser\Node\Expr\ArrayItem; use PhpParser\Node\Expr\ClassConstFetch; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Expr\Variable; +use PhpParser\Node\Identifier; use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; +use PhpParser\Node\Scalar\String_; +use PhpParser\Node\Stmt\TraitUse; final class NodeFactory { @@ -16,12 +23,11 @@ final class NodeFactory */ public function createLocalPropertyFetch(string $propertyName): PropertyFetch { - return new PropertyFetch( - new Variable('this', [ - 'name' => $propertyName, - ]), - $propertyName - ); + $localVariable = new Variable('this', [ + 'name' => $propertyName, + ]); + + return new PropertyFetch($localVariable, $propertyName); } public function createNullConstant(): ConstFetch @@ -29,9 +35,16 @@ public function createNullConstant(): ConstFetch return new ConstFetch(new Name('null')); } + public function createClassConstant(string $className, string $constantName): ClassConstFetch + { + $classNameNode = new FullyQualified($className); + + return new ClassConstFetch($classNameNode, $constantName); + } + public function createClassConstantReference(string $className): ClassConstFetch { - $nameNode = new Name('\\' . $className); + $nameNode = new FullyQualified($className); return new ClassConstFetch($nameNode, 'class'); } @@ -42,4 +55,32 @@ public function createMethodCall(string $variableName, string $methodName): Meth return new MethodCall($varNode, $methodName); } + + public function createTraitUse(string $traitName): TraitUse + { + $traitNameNode = new FullyQualified($traitName); + + return new TraitUse([$traitNameNode]); + } + + /** + * @param mixed|Node[] ...$items + */ + public function createArray(...$items): Array_ + { + $arrayItems = []; + + foreach ($items as $item) { + if ($item instanceof Variable) { + $arrayItems[] = new ArrayItem($item); + } elseif ($item instanceof Identifier) { + $string = new String_((string) $item); + $arrayItems[] = new ArrayItem($string); + } + } + + return new Array_($arrayItems, [ + 'kind' => Array_::KIND_SHORT, + ]); + } } diff --git a/src/Rector/AbstractChangeParentClassRector.php b/src/Rector/AbstractChangeParentClassRector.php index b4afe768e6b5..6d95a40651bc 100644 --- a/src/Rector/AbstractChangeParentClassRector.php +++ b/src/Rector/AbstractChangeParentClassRector.php @@ -14,7 +14,7 @@ public function isCandidate(Node $node): bool return false; } - return $this->getParentClassName($node) === $this->getOldClassName(); + return $this->getParentClassName() === $this->getOldClassName(); } /** @@ -30,19 +30,4 @@ public function refactor(Node $node): ?Node abstract protected function getOldClassName(): string; abstract protected function getNewClassName(): string; - - private function getParentClassName(Class_ $classNode): string - { - if (! $classNode->extends) { - return ''; - } - - /** @var Name $parentClassName */ - $parentClassNameNode = $classNode->extends; - - /** @var Node\Name\FullyQualified $fsqName */ - $fsqName = $parentClassNameNode->getAttribute('resolvedName'); - - return $fsqName->toString(); - } } diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index b3a4cd901149..3fbf985d2097 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -52,6 +52,24 @@ public function enterNode(Node $node) protected function getClassName(): string { + if ($this->classNode === null) { + return ''; + } + return $this->classNode->namespacedName->toString(); } + + protected function getParentClassName(): string + { + if ($this->classNode === null) { + return ''; + } + + $parentClass = $this->classNode->extends; + + /** @var Node\Name\FullyQualified $fqnParentClassName */ + $fqnParentClassName = $parentClass->getAttribute('resolvedName'); + + return $fqnParentClassName->toString(); + } } diff --git a/src/Rector/Contrib/Nette/FormCallbackRector.php b/src/Rector/Contrib/Nette/FormCallbackRector.php index c73403f65cfb..92e770c9416a 100644 --- a/src/Rector/Contrib/Nette/FormCallbackRector.php +++ b/src/Rector/Contrib/Nette/FormCallbackRector.php @@ -3,26 +3,39 @@ namespace Rector\Rector\Contrib\Nette; use PhpParser\Node; -use PhpParser\Node\Expr\Array_; -use PhpParser\Node\Expr\ArrayItem; use PhpParser\Node\Expr\PropertyFetch; -use PhpParser\Node\Scalar\String_; use PhpParser\NodeTraverser; use PhpParser\NodeVisitorAbstract; use Rector\Contract\Deprecation\DeprecationInterface; use Rector\Contract\Rector\RectorInterface; use Rector\Deprecation\SetNames; +use Rector\NodeFactory\NodeFactory; /** * Covers https://doc.nette.org/en/2.4/migration-2-4#toc-nette-smartobject. */ final class FormCallbackRector extends NodeVisitorAbstract implements DeprecationInterface, RectorInterface { + /** + * @var string + */ + public const FORM_CLASS = 'Nette\Application\UI\Form'; + /** * @var Node */ private $previousNode; + /** + * @var NodeFactory + */ + private $nodeFactory; + + public function __construct(NodeFactory $nodeFactory) + { + $this->nodeFactory = $nodeFactory; + } + public function getSetName(): string { return SetNames::NETTE; @@ -43,7 +56,7 @@ public function enterNode(Node $node) return null; } - return $this->createShortArray($node); + return $this->nodeFactory->createArray($node->var, $node->name); } $this->previousNode = $node; @@ -71,7 +84,7 @@ private function isFormEventAssign(Node $node): bool return false; } - if ($node->var->getAttribute('type') !== $this->getDesiredClass()) { + if ($node->var->getAttribute('type') !== self::FORM_CLASS) { return false; } @@ -82,26 +95,4 @@ private function isFormEventAssign(Node $node): bool return true; } - - /** - * [$this, 'something'] - */ - private function createShortArray(Node $node): Array_ - { - return new Array_([ - new ArrayItem($node->var), - new ArrayItem( - new String_( - (string) $node->name - ) - ), - ], [ - 'kind' => Array_::KIND_SHORT, - ]); - } - - private function getDesiredClass(): string - { - return 'Nette\Application\UI\Form'; - } } diff --git a/src/Rector/Contrib/Nette/NetteObjectToSmartTraitRector.php b/src/Rector/Contrib/Nette/NetteObjectToSmartTraitRector.php index 2de3802e59ea..c01ca49af4e4 100644 --- a/src/Rector/Contrib/Nette/NetteObjectToSmartTraitRector.php +++ b/src/Rector/Contrib/Nette/NetteObjectToSmartTraitRector.php @@ -3,11 +3,10 @@ namespace Rector\Rector\Contrib\Nette; use PhpParser\Node; -use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Stmt\Class_; -use PhpParser\Node\Stmt\TraitUse; use Rector\Builder\StatementGlue; use Rector\Deprecation\SetNames; +use Rector\NodeFactory\NodeFactory; use Rector\Rector\AbstractRector; /** @@ -15,14 +14,30 @@ */ final class NetteObjectToSmartTraitRector extends AbstractRector { + /** + * @var string + */ + private const PARENT_CLASS = 'Nette\Object'; + + /** + * @var string + */ + private const TRAIT_NAME = 'Nette\SmartObject'; + /** * @var StatementGlue */ private $statementGlue; - public function __construct(StatementGlue $statementGlue) + /** + * @var NodeFactory + */ + private $nodeFactory; + + public function __construct(StatementGlue $statementGlue, NodeFactory $nodeFactory) { $this->statementGlue = $statementGlue; + $this->nodeFactory = $nodeFactory; } public function getSetName(): string @@ -45,9 +60,7 @@ public function isCandidate(Node $node): bool return false; } - $parentClassName = $this->getParentClassName($node); - - return $parentClassName === $this->getParentClass(); + return $this->getParentClassName() === self::PARENT_CLASS; } /** @@ -55,7 +68,7 @@ public function isCandidate(Node $node): bool */ public function refactor(Node $classNode): ?Node { - $traitUseNode = $this->createTraitUse($this->getTraitName()); + $traitUseNode = $this->nodeFactory->createTraitUse(self::TRAIT_NAME); $this->statementGlue->addAsFirstTrait($classNode, $traitUseNode); $this->removeParentClass($classNode); @@ -63,33 +76,6 @@ public function refactor(Node $classNode): ?Node return $classNode; } - private function createTraitUse(string $traitName): TraitUse - { - return new TraitUse([ - new FullyQualified($traitName), - ]); - } - - private function getParentClass(): string - { - return 'Nette\Object'; - } - - private function getTraitName(): string - { - return 'Nette\SmartObject'; - } - - private function getParentClassName(Class_ $classNode): string - { - $parentClass = $classNode->extends; - - /** @var FullyQualified $fqnParentClassName */ - $fqnParentClassName = $parentClass->getAttribute('resolvedName'); - - return $fqnParentClassName->toString(); - } - private function removeParentClass(Class_ $classNode): void { $classNode->extends = null; diff --git a/src/Rector/Contrib/Symfony/ConstraintUrlOptionRector.php b/src/Rector/Contrib/Symfony/ConstraintUrlOptionRector.php index 91862eeba935..38bb3328aff5 100644 --- a/src/Rector/Contrib/Symfony/ConstraintUrlOptionRector.php +++ b/src/Rector/Contrib/Symfony/ConstraintUrlOptionRector.php @@ -3,11 +3,10 @@ namespace Rector\Rector\Contrib\Symfony; use PhpParser\Node; -use PhpParser\Node\Expr\ClassConstFetch; use PhpParser\Node\Expr\ConstFetch; -use PhpParser\Node\Name; use PhpParser\Node\Scalar\String_; use Rector\Deprecation\SetNames; +use Rector\NodeFactory\NodeFactory; use Rector\Rector\AbstractRector; /** @@ -22,10 +21,19 @@ final class ConstraintUrlOptionRector extends AbstractRector { /** - * @todo complete FQN * @var string */ - private const URL_CONSTRAINT_CLASS = 'Url'; + private const URL_CONSTRAINT_CLASS = 'Symfony\Component\Validator\Constraints\Url'; + + /** + * @var NodeFactory + */ + private $nodeFactory; + + public function __construct(NodeFactory $nodeFactory) + { + $this->nodeFactory = $nodeFactory; + } public function getSetName(): string { @@ -60,8 +68,6 @@ public function isCandidate(Node $node): bool */ public function refactor(Node $node): ?Node { - $classNameNode = new Name(self::URL_CONSTRAINT_CLASS); - - return new ClassConstFetch($classNameNode, 'CHECK_DNS_TYPE_ANY'); + return $this->nodeFactory->createClassConstant(self::URL_CONSTRAINT_CLASS, 'CHECK_DNS_TYPE_ANY'); } } diff --git a/src/Rector/Contrib/Symfony/FormIsValidRector.php b/src/Rector/Contrib/Symfony/FormIsValidRector.php index a4629548a003..9852682724bb 100644 --- a/src/Rector/Contrib/Symfony/FormIsValidRector.php +++ b/src/Rector/Contrib/Symfony/FormIsValidRector.php @@ -5,7 +5,6 @@ use PhpParser\Node; use PhpParser\Node\Expr\BinaryOp\BooleanAnd; use PhpParser\Node\Expr\MethodCall; -use PhpParser\Node\Expr\Variable; use Rector\Deprecation\SetNames; use Rector\NodeFactory\NodeFactory; use Rector\Rector\AbstractRector; diff --git a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php index 9c12ef1fa3ee..8cbb19d1b88f 100644 --- a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php +++ b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php @@ -4,7 +4,6 @@ use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; -use PhpParser\Node\Expr\PropertyFetch; use PhpParser\Node\Scalar\String_; use Rector\Builder\Class_\ClassPropertyCollector; use Rector\Builder\Kernel\ServiceFromKernelResolver; @@ -78,24 +77,9 @@ public function isCandidate(Node $node): bool * @param MethodCall $methodCallNode */ public function refactor(Node $methodCallNode): ?Node - { - return $this->processMethodCallNode($methodCallNode); - } - - public function getSetName(): string - { - return SetNames::SYMFONY_EXTRA; - } - - public function sinceVersion(): float - { - return 3.3; - } - - private function processMethodCallNode(MethodCall $methodCall): ?PropertyFetch { $serviceType = $this->serviceFromKernelResolver->resolveServiceClassFromArgument( - $methodCall->args[0], + $methodCallNode->args[0], LocalKernel::class ); @@ -109,4 +93,14 @@ private function processMethodCallNode(MethodCall $methodCall): ?PropertyFetch return $this->nodeFactory->createLocalPropertyFetch($propertyName); } + + public function getSetName(): string + { + return SetNames::SYMFONY_EXTRA; + } + + public function sinceVersion(): float + { + return 3.3; + } } diff --git a/tests/Rector/Contrib/Symfony/ConstraintUrlOptionRector/Correct/correct.php.inc b/tests/Rector/Contrib/Symfony/ConstraintUrlOptionRector/Correct/correct.php.inc index 61657febf88a..e0673611a8cb 100644 --- a/tests/Rector/Contrib/Symfony/ConstraintUrlOptionRector/Correct/correct.php.inc +++ b/tests/Rector/Contrib/Symfony/ConstraintUrlOptionRector/Correct/correct.php.inc @@ -1,3 +1,3 @@ Url::CHECK_DNS_TYPE_ANY]); +$containt = new Url(['checkDNS' => \Symfony\Component\Validator\Constraints\Url::CHECK_DNS_TYPE_ANY]); From 3611715075a3ccb5453de0fca3b3b5c8075b1b32 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sun, 3 Sep 2017 14:17:04 +0200 Subject: [PATCH 08/10] misc --- .../AbstractChangeParentClassRector.php | 2 +- .../RemoveConfiguratorConstantsRector.php | 23 ++++++++----------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/Rector/AbstractChangeParentClassRector.php b/src/Rector/AbstractChangeParentClassRector.php index 6d95a40651bc..bc74609f2ffa 100644 --- a/src/Rector/AbstractChangeParentClassRector.php +++ b/src/Rector/AbstractChangeParentClassRector.php @@ -22,7 +22,7 @@ public function isCandidate(Node $node): bool */ public function refactor(Node $node): ?Node { - $node->extends = new Name('\\' . $this->getNewClassName()); + $node->extends = new Name\FullyQualified($this->getNewClassName()); return $node; } diff --git a/src/Rector/Contrib/Nette/RemoveConfiguratorConstantsRector.php b/src/Rector/Contrib/Nette/RemoveConfiguratorConstantsRector.php index 4baa99757182..e1aadea20cb2 100644 --- a/src/Rector/Contrib/Nette/RemoveConfiguratorConstantsRector.php +++ b/src/Rector/Contrib/Nette/RemoveConfiguratorConstantsRector.php @@ -12,21 +12,17 @@ final class RemoveConfiguratorConstantsRector extends AbstractRector { public function isCandidate(Node $node): bool { - if ($node instanceof ClassConstFetch) { - $className = $this->getClassNameFromClassConstFetch($node); - - if ($className !== $this->getDesiredClass()) { - return false; - } + if (! $node instanceof ClassConstFetch) { + return false; + } - if (! in_array((string) $node->name, ['DEVELOPMENT', 'PRODUCTION'], true)) { - return false; - } + $className = $this->getClassNameFromClassConstFetch($node); - return true; + if ($className !== $this->getDesiredClass()) { + return false; } - return false; + return in_array((string) $node->name, ['DEVELOPMENT', 'PRODUCTION'], true); } /** @@ -35,9 +31,10 @@ public function isCandidate(Node $node): bool public function refactor(Node $classConstFetchNode): ?Node { $constantName = (string) $classConstFetchNode->name; - $string = strtolower($constantName); - return new String_($string); + $originalConstantValue = strtolower($constantName); + + return new String_($originalConstantValue); } public function getSetName(): string From 57d57843a7d31db62d8c86c9fa81a04b68899530 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sun, 3 Sep 2017 14:37:36 +0200 Subject: [PATCH 09/10] add SymfonyContainerClassAnalyzer --- easy-coding-standard.neon | 2 +- .../SymfonyContainerCallsAnalyzer.php | 45 +++++++++++++++++++ .../AbstractChangeParentClassRector.php | 4 +- .../CommandToConstructorInjectionRector.php | 25 +++++------ .../SymfonyExtra/GetterToPropertyRector.php | 22 ++++----- 5 files changed, 67 insertions(+), 31 deletions(-) create mode 100644 src/NodeAnalyzer/SymfonyContainerCallsAnalyzer.php diff --git a/easy-coding-standard.neon b/easy-coding-standard.neon index 01f3968c67bd..e8f8e5f0c5f1 100644 --- a/easy-coding-standard.neon +++ b/easy-coding-standard.neon @@ -28,7 +28,7 @@ checkers: Symplify\CodingStandard\Sniffs\DependencyInjection\NoClassInstantiationSniff: extraAllowedClasses: -# - 'PhpParser\Node\*' + - 'PhpParser\Node\*' - 'PhpParser\Comment\Doc' parameters: diff --git a/src/NodeAnalyzer/SymfonyContainerCallsAnalyzer.php b/src/NodeAnalyzer/SymfonyContainerCallsAnalyzer.php new file mode 100644 index 000000000000..01083d7dde92 --- /dev/null +++ b/src/NodeAnalyzer/SymfonyContainerCallsAnalyzer.php @@ -0,0 +1,45 @@ +get(...); + */ + public function isThisCall(MethodCall $methodCall): bool + { + if ($methodCall->var->name !== 'this' || (string) $methodCall->name !== 'get') { + return false; + } + + return $this->hasOneStringArgument($methodCall); + } + + /** + * Finds $this->getContainer()->get(...); + */ + public function isGetContainerCall(MethodCall $methodCall): bool + { + if (! $methodCall->var instanceof MethodCall) { + return false; + } + + if ((string) $methodCall->var->var->name !== 'this' || (string) $methodCall->name !== 'get') { + return false; + } + + return $this->hasOneStringArgument($methodCall); + } + + /** + * Finds ('some_service') + */ + private function hasOneStringArgument(MethodCall $methodCall): bool + { + return count($methodCall->args) === 1 && $methodCall->args[0]->value instanceof String_; + } +} diff --git a/src/Rector/AbstractChangeParentClassRector.php b/src/Rector/AbstractChangeParentClassRector.php index bc74609f2ffa..9b6dd359d2b1 100644 --- a/src/Rector/AbstractChangeParentClassRector.php +++ b/src/Rector/AbstractChangeParentClassRector.php @@ -3,7 +3,7 @@ namespace Rector\Rector; use PhpParser\Node; -use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\Stmt\Class_; abstract class AbstractChangeParentClassRector extends AbstractRector @@ -22,7 +22,7 @@ public function isCandidate(Node $node): bool */ public function refactor(Node $node): ?Node { - $node->extends = new Name\FullyQualified($this->getNewClassName()); + $node->extends = new FullyQualified($this->getNewClassName()); return $node; } diff --git a/src/Rector/Contrib/SymfonyExtra/CommandToConstructorInjectionRector.php b/src/Rector/Contrib/SymfonyExtra/CommandToConstructorInjectionRector.php index 882baa36de52..709540aa74db 100644 --- a/src/Rector/Contrib/SymfonyExtra/CommandToConstructorInjectionRector.php +++ b/src/Rector/Contrib/SymfonyExtra/CommandToConstructorInjectionRector.php @@ -6,11 +6,11 @@ use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Name; -use PhpParser\Node\Scalar\String_; use Rector\Builder\Class_\ClassPropertyCollector; use Rector\Builder\Kernel\ServiceFromKernelResolver; use Rector\Builder\Naming\NameResolver; use Rector\Deprecation\SetNames; +use Rector\NodeAnalyzer\SymfonyContainerCallsAnalyzer; use Rector\NodeFactory\NodeFactory; use Rector\Rector\AbstractRector; use Rector\Tests\Rector\Contrib\SymfonyExtra\GetterToPropertyRector\Source\LocalKernel; @@ -59,17 +59,23 @@ final class CommandToConstructorInjectionRector extends AbstractRector * @var NodeFactory */ private $nodeFactory; + /** + * @var SymfonyContainerCallsAnalyzer + */ + private $symfonyContainerCallsAnalyzer; public function __construct( ServiceFromKernelResolver $serviceFromKernelResolver, ClassPropertyCollector $classPropertyCollector, NameResolver $nameResolver, - NodeFactory $nodeFactory + NodeFactory $nodeFactory, + SymfonyContainerCallsAnalyzer $symfonyContainerCallsAnalyzer ) { $this->serviceFromKernelResolver = $serviceFromKernelResolver; $this->classPropertyCollector = $classPropertyCollector; $this->nameResolver = $nameResolver; $this->nodeFactory = $nodeFactory; + $this->symfonyContainerCallsAnalyzer = $symfonyContainerCallsAnalyzer; } public function getSetName(): string @@ -88,22 +94,11 @@ public function isCandidate(Node $node): bool return false; } - // finds **$this->getContainer()->get**('some_service'); - if (! $node instanceof MethodCall || ! $node->var instanceof MethodCall) { - return false; - } - - // finds **$this**->getContainer()->**get**('some_service'); - if ((string) $node->var->var->name !== 'this' || (string) $node->name !== 'get') { - return false; - } - - // finds $this->getContainer()->get**('some_service')**; - if (count($node->args) !== 1 || ! $node->args[0]->value instanceof String_) { + if (! $node instanceof MethodCall) { return false; } - return true; + return $this->symfonyContainerCallsAnalyzer->isGetContainerCall($node); } /** diff --git a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php index 8cbb19d1b88f..739fd4078451 100644 --- a/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php +++ b/src/Rector/Contrib/SymfonyExtra/GetterToPropertyRector.php @@ -4,11 +4,11 @@ use PhpParser\Node; use PhpParser\Node\Expr\MethodCall; -use PhpParser\Node\Scalar\String_; use Rector\Builder\Class_\ClassPropertyCollector; use Rector\Builder\Kernel\ServiceFromKernelResolver; use Rector\Builder\Naming\NameResolver; use Rector\Deprecation\SetNames; +use Rector\NodeAnalyzer\SymfonyContainerCallsAnalyzer; use Rector\NodeFactory\NodeFactory; use Rector\Rector\AbstractRector; use Rector\Tests\Rector\Contrib\SymfonyExtra\GetterToPropertyRector\Source\LocalKernel; @@ -41,17 +41,23 @@ final class GetterToPropertyRector extends AbstractRector * @var NodeFactory */ private $nodeFactory; + /** + * @var SymfonyContainerCallsAnalyzer + */ + private $symfonyContainerCallsAnalyzer; public function __construct( NameResolver $nameResolver, ServiceFromKernelResolver $serviceFromKernelResolver, ClassPropertyCollector $classPropertyCollector, - NodeFactory $nodeFactory + NodeFactory $nodeFactory, + SymfonyContainerCallsAnalyzer $symfonyContainerCallsAnalyzer ) { $this->nameResolver = $nameResolver; $this->serviceFromKernelResolver = $serviceFromKernelResolver; $this->classPropertyCollector = $classPropertyCollector; $this->nodeFactory = $nodeFactory; + $this->symfonyContainerCallsAnalyzer = $symfonyContainerCallsAnalyzer; } public function isCandidate(Node $node): bool @@ -60,17 +66,7 @@ public function isCandidate(Node $node): bool return false; } - // finds **$this->get**('string') - if ($node->var->name !== 'this' || (string) $node->name !== 'get') { - return false; - } - - // finds $this->get(**'string'**) - if (count($node->args) !== 1 || ! $node->args[0]->value instanceof String_) { - return false; - } - - return true; + return $this->symfonyContainerCallsAnalyzer->isThisCall($node); } /** From 3b7528662a77112e5e4b19878cffc886bac68510 Mon Sep 17 00:00:00 2001 From: TomasVotruba Date: Sun, 3 Sep 2017 14:38:21 +0200 Subject: [PATCH 10/10] ecs: cleanup unreported error skip --- easy-coding-standard.neon | 4 ---- 1 file changed, 4 deletions(-) diff --git a/easy-coding-standard.neon b/easy-coding-standard.neon index e8f8e5f0c5f1..7fa3888a0002 100644 --- a/easy-coding-standard.neon +++ b/easy-coding-standard.neon @@ -44,13 +44,9 @@ parameters: Symplify\CodingStandard\Fixer\Php\ClassStringToClassConstantFixer: # classes might not exist - */src/Rector/Contrib/*/*Rector.php - Symplify\CodingStandard\Sniffs\Debug\CommentedOutCodeSniff: - # examples of code to be found - - src/Rector/Contrib/SymfonyExtra/CommandToConstructorInjectionRector.php SlevomatCodingStandard\Sniffs\Classes\UnusedPrivateElementsSniff: # will be used soon - packages/NodeTypeResolver/src/TypeContext.php - PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff: # long FQN classes that might not exist - src/Rector/Contrib/Symfony/FrameworkBundleClassReplacementsRector.php