diff --git a/.github/workflows/phpstan.yaml b/.github/workflows/phpstan.yaml
index 3872a57941f4..699d4e70e02b 100644
--- a/.github/workflows/phpstan.yaml
+++ b/.github/workflows/phpstan.yaml
@@ -18,4 +18,4 @@ jobs:
tools: cs2pr
- run: composer install --no-progress
# turn the phpstan errors (formatted in checkstyle-format) into github pull request check annotations
- - run: composer phpstan -- --error-format=checkstyle | cs2pr
+ - run: composer phpstan # -- --error-format=checkstyle | cs2pr
diff --git a/compiler/build/scoper.inc.php b/compiler/build/scoper.inc.php
index b33814df1648..145f30a58df0 100644
--- a/compiler/build/scoper.inc.php
+++ b/compiler/build/scoper.inc.php
@@ -18,7 +18,7 @@
foreach ($stubFinder->getIterator() as $fileInfo) {
// mirrors https://github.com/phpstan/phpstan-src/commit/04f777bc4445725d17dac65c989400485454b145
- if ($file->getPathName() === '../../vendor/jetbrains/phpstorm-stubs/PhpStormStubsMap.php') {
+ if ($fileInfo->getPathName() === '../../vendor/jetbrains/phpstorm-stubs/PhpStormStubsMap.php') {
continue;
}
diff --git a/composer.json b/composer.json
index 07958d6ba50c..e34a1687b035 100644
--- a/composer.json
+++ b/composer.json
@@ -102,6 +102,7 @@
"Rector\\Symfony\\": "packages/symfony/src",
"Rector\\Twig\\": "packages/twig/src",
"Rector\\TypeDeclaration\\": "packages/type-declaration/src",
+ "Rector\\VendorLocker\\": "packages/vendor-locker/src",
"Rector\\ZendToSymfony\\": "packages/zend-to-symfony/src",
"Rector\\RectorGenerator\\": "packages/rector-generator/src",
"Rector\\StrictCodeQuality\\": "packages/strict-code-quality/src",
diff --git a/docs/AllRectorsOverview.md b/docs/AllRectorsOverview.md
index 1d4c4f3b6778..cfe3c619b21f 100644
--- a/docs/AllRectorsOverview.md
+++ b/docs/AllRectorsOverview.md
@@ -4512,7 +4512,9 @@ services:
↓
```diff
- class SomeServiceTest extends \PHPUnit\Framework\TestCase
+ use PHPUnit\Framework\TestCase;
+
+ class SomeServiceTest extends TestCase
{
- public function test()
+ /**
@@ -8781,12 +8783,11 @@ Change $this->_view->assign = 5; to $this->render("...", $templateData);
public function someAction()
{
- $this->_view->value = 5;
--}
+ $templateData = [];
+ $templateData['value']; = 5;
+
+ return $this->render("...", $templateData);
-+}
+ }
```
diff --git a/ecs.yaml b/ecs.yaml
index 1212ba0260c5..039d02d5b67a 100644
--- a/ecs.yaml
+++ b/ecs.yaml
@@ -73,61 +73,19 @@ parameters:
# hidden API
- 'src/Rector/AbstractRector.php'
- # @todo resolve!!!
Symplify\CodingStandard\Sniffs\CleanCode\CognitiveComplexitySniff:
- - 'src/NodeContainer/NodeCollector/ParsedFunctionLikeNodesByType.php'
- - 'src/NodeContainer/NodeCollector/ParsedFunctionLikeNodeCollector.php'
- - 'packages/solid/src/Rector/ClassConst/PrivatizeLocalClassConstantRector.php'
- - 'packages/type-declaration/src/TypeInferer/PropertyTypeInferer/ConstructorPropertyTypeInferer.php'
- - 'packages/node-type-resolver/src/PhpDoc/NodeAnalyzer/DocBlockManipulator.php'
- - 'packages/minimal-scope/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php'
- - 'packages/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php'
- # solve later
- - 'src/Console/Command/ScreenFileCommand.php'
- - 'packages/doctrine/src/Rector/ClassMethod/AddMethodCallBasedParamTypeRector.php'
- - 'packages/type-declaration/src/TypeInferer/ReturnTypeInferer/ReturnedNodesReturnTypeInferer.php'
- - 'packages/node-type-resolver/src/NodeTypeResolver.php'
- - 'packages/node-type-resolver/src/PerNodeTypeResolver/VariableTypeResolver.php'
- - 'packages/php-71/src/Rector/FuncCall/RemoveExtraParametersRector.php'
- - 'packages/solid/src/Analyzer/ClassConstantFetchAnalyzer.php'
- # tough logic
- - 'packages/autodiscovery/src/Analyzer/ClassAnalyzer.php'
- - 'packages/coding-style/src/Imports/ImportSkipper.php'
- - 'packages/phpunit/src/Rector/Class_/ArrayArgumentInTestToDataProviderRector.php'
- - 'packages/better-php-doc-parser/src/Ast/PhpDoc/*/*TagValueNode.php'
- - 'packages/node-type-resolver/src/PhpDoc/NodeAnalyzer/FqnNamePhpDocNodeDecorator.php'
- - 'packages/node-type-resolver/src/PHPStan/Type/StaticTypeAnalyzer.php'
- - 'src/NodeContainer/ParsedNodesByType.php'
-
- - 'packages/phpstan-static-type-mapper/src/PHPStanStaticTypeMapper.php'
- - 'packages/node-type-resolver/src/StaticTypeMapper.php'
-
- - 'packages/phpstan/src/Rector/Node/RemoveNonExistingVarAnnotationRector.php'
- - 'packages/architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php'
- - 'src/PhpParser/Node/Commander/NodeRemovingCommander.php'
- - 'packages/better-php-doc-parser/src/*'
- - 'packages/symfony/src/Rector/Class_/MakeCommandLazyRector.php'
- - 'packages/legacy/src/Rector/ClassMethod/ChangeSingletonToServiceRector.php'
- - 'packages/coding-style/src/Rector/Use_/RemoveUnusedAliasRector.php'
- - 'packages/nette-to-symfony/src/Route/RouteInfoFactory.php'
- - 'utils/*/DumpNodesCommand.php'
- - 'packages/code-quality/src/Rector/Identical/SimplifyBoolIdenticalTrueRector.php'
- - 'packages/better-php-doc-parser/src/Attributes/Ast/AttributeAwareNodeFactory.php'
- - 'packages/laravel/src/Rector/FuncCall/HelperFunctionToConstructorInjectionRector.php'
- - 'packages/php-spec-to-phpunit/src/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php'
- - 'packages/nette-tester-to-phpunit/src/AssertManipulator.php'
- - 'packages/legacy/src/NodeAnalyzer/SingletonClassMethodAnalyzer.php'
- - 'src/Rector/Psr4/MultipleClassFileToPsr4ClassesRector.php'
- - 'src/PhpParser/Node/Resolver/NameResolver.php'
- - 'src/Rector/MethodBody/NormalToFluentRector.php'
- - 'src/Rector/AbstractRector/ComplexRemovalTrait.php'
- - 'src/PhpParser/Node/Manipulator/IfManipulator.php'
- - 'packages/type-declaration/src/VendorLock/VendorLockResolver.php'
- - 'packages/type-declaration/src/PhpParserTypeAnalyzer.php'
- - 'packages/dead-code/src/Rector/ClassMethod/RemoveDelegatingParentCallRector.php'
- # aliases
- - 'packages/coding-style/src/Rector/Namespace_/ImportFullyQualifiedNamesRector.php'
-
+ # todo
+ - "packages/node-type-resolver/src/NodeTypeResolver.php"
+ - "packages/better-php-doc-parser/src/Printer/OriginalSpacingRestorer.php"
+ # @todo split to multiple rectors
+ - "packages/php-spec-to-phpunit/src/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php"
+
+ - "packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ColumnTagValueNode.php"
+ - "packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinColumnTagValueNode.php"
+ - "packages/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php"
+
+ # per node logic
+ - 'utils/DocumentationGenerator/src/Command/DumpNodesCommand.php'
# copied 3rd party logic
- 'packages/php-70/src/EregToPcreTransformer.php'
# dev
diff --git a/packages/architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php b/packages/architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php
index d48fc8c8df78..38bc413d27e2 100644
--- a/packages/architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php
+++ b/packages/architecture/src/Rector/Class_/ConstructorInjectionToActionInjectionRector.php
@@ -112,22 +112,13 @@ public function refactor(Node $node): ?Node
{
$this->reset();
- // only in controllers
- if (! $this->isName($node, '*Controller')) {
- return null;
- }
-
- if ($node->isAbstract()) {
- return null;
- }
-
- $constructMethod = $node->getMethod('__construct');
- // no constructor, nothing to do
- if ($constructMethod === null) {
+ if ($this->shouldSkip($node)) {
return null;
}
// traverse constructor dependencies and names of their properties
+ /** @var ClassMethod $constructMethod */
+ $constructMethod = $node->getMethod('__construct');
$this->collectPropertyFetchToParams($constructMethod);
// replace them in property fetches with particular class methods and use variable instead
@@ -220,23 +211,20 @@ private function changePropertyUsageToParameter(ClassMethod $classMethod, string
$param,
&$currentlyAddedLocalVariables
): ?Variable {
- if (! $node instanceof PropertyFetch) {
+ if ($this->shouldSkipClassMethod($node)) {
return null;
}
- if (! $this->isName($node->var, 'this')) {
+ /** @var PropertyFetch $node */
+ if (! $this->isName($node, $propertyName)) {
return null;
}
- if ($this->isName($node, $propertyName)) {
- $currentlyAddedLocalVariables[] = $param;
+ $currentlyAddedLocalVariables[] = $param;
- /** @var string $paramName */
- $paramName = $this->getName($param);
- return new Variable($paramName);
- }
-
- return null;
+ /** @var string $paramName */
+ $paramName = $this->getName($param);
+ return new Variable($paramName);
});
foreach ($currentlyAddedLocalVariables as $param) {
@@ -330,4 +318,30 @@ private function removeConstructIfEmpty(Class_ $class, ClassMethod $constructCla
$this->removeNodeFromStatements($class, $constructClassMethod);
}
+
+ private function shouldSkipClassMethod(Node $node): bool
+ {
+ if (! $node instanceof PropertyFetch) {
+ return true;
+ }
+
+ return ! $this->isName($node->var, 'this');
+ }
+
+ private function shouldSkip(Class_ $class): bool
+ {
+ // only in controllers
+ if (! $this->isName($class, '*Controller')) {
+ return true;
+ }
+
+ if ($class->isAbstract()) {
+ return true;
+ }
+
+ $constructMethod = $class->getMethod('__construct');
+ // no constructor, nothing to do
+
+ return $constructMethod === null;
+ }
}
diff --git a/packages/autodiscovery/src/Analyzer/ClassAnalyzer.php b/packages/autodiscovery/src/Analyzer/ClassAnalyzer.php
index 1486111e1950..34b9111ce1f5 100644
--- a/packages/autodiscovery/src/Analyzer/ClassAnalyzer.php
+++ b/packages/autodiscovery/src/Analyzer/ClassAnalyzer.php
@@ -10,7 +10,7 @@
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocNode\JMS\SerializerTypeTagValueNode;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -22,9 +22,9 @@ final class ClassAnalyzer
private $valueObjectStatusByClassName = [];
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var NodeTypeResolver
@@ -37,11 +37,11 @@ final class ClassAnalyzer
private $parsedNodeCollector;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector,
NodeTypeResolver $nodeTypeResolver
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeTypeResolver = $nodeTypeResolver;
}
@@ -52,7 +52,8 @@ public function isValueObjectClass(Class_ $class): bool
return false;
}
- $className = $this->nameResolver->getName($class);
+ /** @var string $className */
+ $className = $this->nodeNameResolver->getName($class);
if (isset($this->valueObjectStatusByClassName[$className])) {
return $this->valueObjectStatusByClassName[$className];
@@ -61,15 +62,7 @@ public function isValueObjectClass(Class_ $class): bool
$constructClassMethod = $class->getMethod('__construct');
if ($constructClassMethod === null) {
- // A. has all properties with serialize?
- if ($this->hasAllPropertiesWithSerialize($class)) {
- $this->valueObjectStatusByClassName[$className] = true;
- return true;
- }
-
- // probably not a value object
- $this->valueObjectStatusByClassName[$className] = false;
- return false;
+ return $this->analyseWithoutConstructor($class, $className);
}
// resolve constructor types
@@ -116,4 +109,17 @@ private function hasAllPropertiesWithSerialize(Class_ $class)
return true;
}
+
+ private function analyseWithoutConstructor(Class_ $class, ?string $className): bool
+ {
+ // A. has all properties with serialize?
+ if ($this->hasAllPropertiesWithSerialize($class)) {
+ $this->valueObjectStatusByClassName[$className] = true;
+ return true;
+ }
+
+ // probably not a value object
+ $this->valueObjectStatusByClassName[$className] = false;
+ return false;
+ }
}
diff --git a/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php b/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php
index 206f4e09d30f..38a22be40b32 100644
--- a/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php
+++ b/packages/better-php-doc-parser/src/AnnotationReader/NodeAnnotationReader.php
@@ -9,7 +9,7 @@
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Property;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\ClassExistenceStaticHelper;
use Rector\NodeTypeResolver\Node\AttributeKey;
use ReflectionClass;
@@ -25,14 +25,14 @@ final class NodeAnnotationReader
private $reader;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(Reader $reader, NameResolver $nameResolver)
+ public function __construct(Reader $reader, NodeNameResolver $nodeNameResolver)
{
$this->reader = $reader;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -44,7 +44,7 @@ public function readMethodAnnotation(ClassMethod $classMethod, string $annotatio
$className = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
/** @var string $methodName */
- $methodName = $this->nameResolver->getName($classMethod);
+ $methodName = $this->nodeNameResolver->getName($classMethod);
$reflectionMethod = new ReflectionMethod($className, $methodName);
@@ -82,7 +82,7 @@ public function readPropertyAnnotation(Property $property, string $annotationCla
private function createClassReflectionFromNode(Class_ $class): ReflectionClass
{
/** @var string $className */
- $className = $this->nameResolver->getName($class);
+ $className = $this->nodeNameResolver->getName($class);
return new ReflectionClass($className);
}
@@ -90,7 +90,7 @@ private function createClassReflectionFromNode(Class_ $class): ReflectionClass
private function createPropertyReflectionFromPropertyNode(Property $property): ?ReflectionProperty
{
/** @var string $propertyName */
- $propertyName = $this->nameResolver->getName($property);
+ $propertyName = $this->nodeNameResolver->getName($property);
/** @var string|null $className */
$className = $property->getAttribute(AttributeKey::CLASS_NAME);
diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ColumnTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ColumnTagValueNode.php
index 633981d520b0..ed1891351492 100644
--- a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ColumnTagValueNode.php
+++ b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/ColumnTagValueNode.php
@@ -113,20 +113,20 @@ public function __toString(): string
$contentItems['scale'] = sprintf('scale=%s', $this->scale);
}
- if ($this->unique !== null) {
- $contentItems['unique'] = sprintf('unique=%s', $this->unique ? 'true' : 'false');
- }
-
- if ($this->nullable !== null) {
- $contentItems['nullable'] = sprintf('nullable=%s', $this->nullable ? 'true' : 'false');
+ if ($this->columnDefinition !== null) {
+ $contentItems['columnDefinition'] = sprintf('columnDefinition="%s"', $this->columnDefinition);
}
if ($this->options) {
$contentItems['options'] = $this->printArrayItem($this->options, 'options');
}
- if ($this->columnDefinition !== null) {
- $contentItems['columnDefinition'] = sprintf('columnDefinition="%s"', $this->columnDefinition);
+ if ($this->unique !== null) {
+ $contentItems['unique'] = sprintf('unique=%s', $this->unique ? 'true' : 'false');
+ }
+
+ if ($this->nullable !== null) {
+ $contentItems['nullable'] = sprintf('nullable=%s', $this->nullable ? 'true' : 'false');
}
return $this->printContentItems($contentItems);
diff --git a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinColumnTagValueNode.php b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinColumnTagValueNode.php
index 69d68b749dc6..3a920da9cf97 100644
--- a/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinColumnTagValueNode.php
+++ b/packages/better-php-doc-parser/src/PhpDocNode/Doctrine/Property_/JoinColumnTagValueNode.php
@@ -119,17 +119,6 @@ public function __toString(): string
return $this->printContentItems($contentItems);
}
- public function changeNullable(bool $nullable): void
- {
- $this->nullable = $nullable;
- }
-
- public function changeReferencedColumnName(string $referencedColumnName): void
- {
- $this->orderedVisibleItems[] = 'referencedColumnName';
- $this->referencedColumnName = $referencedColumnName;
- }
-
public function isNullable(): ?bool
{
return $this->nullable;
diff --git a/packages/better-php-doc-parser/src/PhpDocNodeFactory/JMS/JMSInjectPhpDocNodeFactory.php b/packages/better-php-doc-parser/src/PhpDocNodeFactory/JMS/JMSInjectPhpDocNodeFactory.php
index 8f34f284aeb7..5ed4fb23fea4 100644
--- a/packages/better-php-doc-parser/src/PhpDocNodeFactory/JMS/JMSInjectPhpDocNodeFactory.php
+++ b/packages/better-php-doc-parser/src/PhpDocNodeFactory/JMS/JMSInjectPhpDocNodeFactory.php
@@ -11,18 +11,18 @@
use PHPStan\PhpDocParser\Parser\TokenIterator;
use Rector\BetterPhpDocParser\PhpDocNode\JMS\JMSInjectTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNodeFactory\AbstractPhpDocNodeFactory;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
final class JMSInjectPhpDocNodeFactory extends AbstractPhpDocNodeFactory
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(NameResolver $nameResolver)
+ public function __construct(NodeNameResolver $nodeNameResolver)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
public function getClass(): string
@@ -45,7 +45,7 @@ public function createFromNodeAndTokens(Node $node, TokenIterator $tokenIterator
return null;
}
- $serviceName = $inject->value === null ? $this->nameResolver->getName($node) : $inject->value;
+ $serviceName = $inject->value === null ? $this->nodeNameResolver->getName($node) : $inject->value;
// needed for proper doc block formatting
$this->resolveContentFromTokenIterator($tokenIterator);
diff --git a/packages/better-php-doc-parser/src/PhpDocParser/AnnotationContentResolver.php b/packages/better-php-doc-parser/src/PhpDocParser/AnnotationContentResolver.php
index 3ce643f8879c..0a0da54fb19f 100644
--- a/packages/better-php-doc-parser/src/PhpDocParser/AnnotationContentResolver.php
+++ b/packages/better-php-doc-parser/src/PhpDocParser/AnnotationContentResolver.php
@@ -6,7 +6,6 @@
use Nette\Utils\Strings;
use PHPStan\PhpDocParser\Lexer\Lexer;
-use PHPStan\PhpDocParser\Parser\ParserException;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use Rector\BetterPhpDocParser\PhpDocInfo\TokenIteratorFactory;
@@ -65,49 +64,45 @@ public function resolveFromTokenIterator(TokenIterator $tokenIterator): string
public function resolveNestedKey(string $annotationContent, string $name): string
{
- try {
- $start = false;
- $openedCurlyBracketCount = 0;
- $tokenContents = [];
+ $start = false;
+ $openedCurlyBracketCount = 0;
+ $tokenContents = [];
- $tokenIterator = $this->tokenIteratorFactory->create($annotationContent);
+ $tokenIterator = $this->tokenIteratorFactory->create($annotationContent);
- while (true) {
- // the end
- if (in_array($tokenIterator->currentTokenType(), [Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END], true)) {
- break;
- }
+ while (true) {
+ // the end
+ if (in_array($tokenIterator->currentTokenType(), [Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END], true)) {
+ break;
+ }
- $start = $this->tryStartWithKey($name, $start, $tokenIterator);
- if (! $start) {
- $tokenIterator->next();
- continue;
- }
+ $start = $this->tryStartWithKey($name, $start, $tokenIterator);
+ if (! $start) {
+ $tokenIterator->next();
+ continue;
+ }
- $tokenContents[] = $tokenIterator->currentTokenValue();
+ $tokenContents[] = $tokenIterator->currentTokenValue();
- // opening bracket {
- if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET)) {
- ++$openedCurlyBracketCount;
- }
+ // opening bracket {
+ if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET)) {
+ ++$openedCurlyBracketCount;
+ }
- // closing bracket }
- if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
- --$openedCurlyBracketCount;
+ // closing bracket }
+ if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
+ --$openedCurlyBracketCount;
- // the final one
- if ($openedCurlyBracketCount === 0) {
- break;
- }
+ // the final one
+ if ($openedCurlyBracketCount === 0) {
+ break;
}
-
- $tokenIterator->next();
}
- return implode('', $tokenContents);
- } catch (ParserException $parserException) {
- throw $parserException;
+ $tokenIterator->next();
}
+
+ return implode('', $tokenContents);
}
private function cleanMultilineAnnotationContent(string $annotationContent): string
diff --git a/packages/better-php-doc-parser/src/PhpDocParser/ClassAnnotationMatcher.php b/packages/better-php-doc-parser/src/PhpDocParser/ClassAnnotationMatcher.php
index e460c3bb0e16..12491e7dba49 100644
--- a/packages/better-php-doc-parser/src/PhpDocParser/ClassAnnotationMatcher.php
+++ b/packages/better-php-doc-parser/src/PhpDocParser/ClassAnnotationMatcher.php
@@ -43,16 +43,7 @@ private function matchFullAnnotationClassWithUses(string $tag, array $uses): ?st
continue;
}
- if ($useUse->alias !== null) {
- $unaliasedShortClass = Strings::substring($tag, Strings::length($useUse->alias->toString()));
- if (Strings::startsWith($unaliasedShortClass, '\\')) {
- return $useUse->name . $unaliasedShortClass;
- }
-
- return $useUse->name . '\\' . $unaliasedShortClass;
- }
-
- return $useUse->name->toString();
+ return $this->resolveName($tag, $useUse);
}
}
@@ -66,4 +57,18 @@ private function isUseMatchingName(string $tag, UseUse $useUse): bool
return (bool) Strings::match($tag, '#' . $shortNamePattern . '(\\\\[\w]+)?#i');
}
+
+ private function resolveName(string $tag, UseUse $useUse): string
+ {
+ if ($useUse->alias === null) {
+ return $useUse->name->toString();
+ }
+
+ $unaliasedShortClass = Strings::substring($tag, Strings::length($useUse->alias->toString()));
+ if (Strings::startsWith($unaliasedShortClass, '\\')) {
+ return $useUse->name . $unaliasedShortClass;
+ }
+
+ return $useUse->name . '\\' . $unaliasedShortClass;
+ }
}
diff --git a/packages/cakephp-to-symfony/src/NodeManipulator/DoctrineRepositoryClassMethodManipulator.php b/packages/cakephp-to-symfony/src/NodeManipulator/DoctrineRepositoryClassMethodManipulator.php
index a271f05d8d24..a78068bae6fd 100644
--- a/packages/cakephp-to-symfony/src/NodeManipulator/DoctrineRepositoryClassMethodManipulator.php
+++ b/packages/cakephp-to-symfony/src/NodeManipulator/DoctrineRepositoryClassMethodManipulator.php
@@ -9,7 +9,7 @@
use PhpParser\Node\Stmt\ClassMethod;
use Rector\CakePHPToSymfony\Contract\NodeManipulator\RepositoryFindMethodCallManipulatorInterface;
use Rector\Core\Exception\NotImplementedException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
@@ -26,9 +26,9 @@ final class DoctrineRepositoryClassMethodManipulator
private $callableNodeTraverser;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ValueResolver
@@ -40,12 +40,12 @@ final class DoctrineRepositoryClassMethodManipulator
*/
public function __construct(
CallableNodeTraverser $callableNodeTraverser,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ValueResolver $valueResolver,
array $repositoryFindMethodCallManipulators
) {
$this->callableNodeTraverser = $callableNodeTraverser;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->valueResolver = $valueResolver;
$this->repositoryFindMethodCallManipulators = $repositoryFindMethodCallManipulators;
}
@@ -59,7 +59,7 @@ function (Node $node) use ($entityClass) {
return null;
}
- if (! $this->nameResolver->isName($node->name, 'find')) {
+ if (! $this->nodeNameResolver->isName($node->name, 'find')) {
return null;
}
diff --git a/packages/cakephp-to-symfony/src/Template/TemplateMethodCallManipulator.php b/packages/cakephp-to-symfony/src/Template/TemplateMethodCallManipulator.php
index d3e5f6a27b07..20e86e442e00 100644
--- a/packages/cakephp-to-symfony/src/Template/TemplateMethodCallManipulator.php
+++ b/packages/cakephp-to-symfony/src/Template/TemplateMethodCallManipulator.php
@@ -12,7 +12,7 @@
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Return_;
use Rector\CakePHPToSymfony\TemplatePathResolver;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
@@ -34,20 +34,20 @@ final class TemplateMethodCallManipulator
private $callableNodeTraverser;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
public function __construct(
ValueResolver $valueResolver,
TemplatePathResolver $templatePathResolver,
CallableNodeTraverser $callableNodeTraverser,
- NameResolver $nameResolver
+ NodeNameResolver $nodeNameResolver
) {
$this->valueResolver = $valueResolver;
$this->templatePathResolver = $templatePathResolver;
$this->callableNodeTraverser = $callableNodeTraverser;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
public function refactorExistingRenderMethodCall(ClassMethod $classMethod): void
@@ -121,10 +121,10 @@ private function isThisRenderMethodCall(Node $node): bool
return false;
}
- if (! $this->nameResolver->isName($node->var, 'this')) {
+ if (! $this->nodeNameResolver->isName($node->var, 'this')) {
return false;
}
- return $this->nameResolver->isName($node->name, 'render');
+ return $this->nodeNameResolver->isName($node->name, 'render');
}
}
diff --git a/packages/code-quality/src/Rector/Identical/SimplifyBoolIdenticalTrueRector.php b/packages/code-quality/src/Rector/Identical/SimplifyBoolIdenticalTrueRector.php
index d0d2b7d7e9b9..77233ce225f7 100644
--- a/packages/code-quality/src/Rector/Identical/SimplifyBoolIdenticalTrueRector.php
+++ b/packages/code-quality/src/Rector/Identical/SimplifyBoolIdenticalTrueRector.php
@@ -75,28 +75,42 @@ public function refactor(Node $node): ?Node
private function processBoolTypeToNotBool(Node $node, Expr $leftExpr, Expr $rightExpr): ?Expr
{
if ($node instanceof Identical) {
- if ($this->isTrue($rightExpr)) {
- return $leftExpr;
- }
+ return $this->refactorIdentical($leftExpr, $rightExpr);
+ }
- if ($this->isFalse($rightExpr)) {
- // prevent !!
- if ($leftExpr instanceof BooleanNot) {
- return $leftExpr->expr;
- }
+ if ($node instanceof NotIdentical) {
+ return $this->refactorNotIdentical($leftExpr, $rightExpr);
+ }
- return new BooleanNot($leftExpr);
- }
+ return null;
+ }
+
+ private function refactorIdentical(Expr $leftExpr, Expr $rightExpr): ?Expr
+ {
+ if ($this->isTrue($rightExpr)) {
+ return $leftExpr;
}
- if ($node instanceof NotIdentical) {
- if ($this->isFalse($rightExpr)) {
- return $leftExpr;
+ if ($this->isFalse($rightExpr)) {
+ // prevent !!
+ if ($leftExpr instanceof BooleanNot) {
+ return $leftExpr->expr;
}
- if ($this->isTrue($rightExpr)) {
- return new BooleanNot($leftExpr);
- }
+ return new BooleanNot($leftExpr);
+ }
+
+ return null;
+ }
+
+ private function refactorNotIdentical(Expr $leftExpr, Expr $rightExpr): ?Expr
+ {
+ if ($this->isFalse($rightExpr)) {
+ return $leftExpr;
+ }
+
+ if ($this->isTrue($rightExpr)) {
+ return new BooleanNot($leftExpr);
}
return null;
diff --git a/packages/coding-style/src/Imports/UseImportsTraverser.php b/packages/coding-style/src/Imports/UseImportsTraverser.php
index cf127044c931..f245ea831c27 100644
--- a/packages/coding-style/src/Imports/UseImportsTraverser.php
+++ b/packages/coding-style/src/Imports/UseImportsTraverser.php
@@ -8,24 +8,24 @@
use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\GroupUse;
use PhpParser\Node\Stmt\Use_;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
final class UseImportsTraverser
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var CallableNodeTraverser
*/
private $callableNodeTraverser;
- public function __construct(NameResolver $nameResolver, CallableNodeTraverser $callableNodeTraverser)
+ public function __construct(NodeNameResolver $nodeNameResolver, CallableNodeTraverser $callableNodeTraverser)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->callableNodeTraverser = $callableNodeTraverser;
}
@@ -58,7 +58,7 @@ private function traverseForType(array $stmts, callable $callable, int $desiredT
}
foreach ($node->uses as $useUse) {
- $name = $this->nameResolver->getName($useUse);
+ $name = $this->nodeNameResolver->getName($useUse);
$callable($useUse, $name);
}
}
@@ -84,7 +84,7 @@ private function processGroupUse(GroupUse $groupUse, int $desiredType, callable
continue;
}
- $name = $prefixName . '\\' . $this->nameResolver->getName($useUse);
+ $name = $prefixName . '\\' . $this->nodeNameResolver->getName($useUse);
$callable($useUse, $name);
}
}
diff --git a/packages/coding-style/src/Imports/UsedImportsResolver.php b/packages/coding-style/src/Imports/UsedImportsResolver.php
index 27983ae337e7..134b2b71207d 100644
--- a/packages/coding-style/src/Imports/UsedImportsResolver.php
+++ b/packages/coding-style/src/Imports/UsedImportsResolver.php
@@ -10,7 +10,7 @@
use PhpParser\Node\Stmt\Namespace_;
use PhpParser\Node\Stmt\UseUse;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\PHPStan\Type\FullyQualifiedObjectType;
@@ -22,9 +22,9 @@ final class UsedImportsResolver
private $betterNodeFinder;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var UseImportsTraverser
@@ -33,11 +33,11 @@ final class UsedImportsResolver
public function __construct(
BetterNodeFinder $betterNodeFinder,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
UseImportsTraverser $useImportsTraverser
) {
$this->betterNodeFinder = $betterNodeFinder;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->useImportsTraverser = $useImportsTraverser;
}
@@ -67,7 +67,7 @@ public function resolveForStmts(array $stmts): array
// add class itself
if ($class !== null) {
- $className = $this->nameResolver->getName($class);
+ $className = $this->nodeNameResolver->getName($class);
if ($className !== null) {
$usedImports[] = new FullyQualifiedObjectType($className);
}
diff --git a/packages/coding-style/src/Naming/ClassNaming.php b/packages/coding-style/src/Naming/ClassNaming.php
index 447258dccf52..c9d42e053dfb 100644
--- a/packages/coding-style/src/Naming/ClassNaming.php
+++ b/packages/coding-style/src/Naming/ClassNaming.php
@@ -8,18 +8,18 @@
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
final class ClassNaming
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(NameResolver $nameResolver)
+ public function __construct(NodeNameResolver $nodeNameResolver)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -28,7 +28,7 @@ public function __construct(NameResolver $nameResolver)
public function getShortName($name): string
{
if ($name instanceof Name || $name instanceof Identifier) {
- $name = $this->nameResolver->getName($name);
+ $name = $this->nodeNameResolver->getName($name);
if ($name === null) {
throw new ShouldNotHappenException();
}
diff --git a/packages/coding-style/src/Node/NameImporter.php b/packages/coding-style/src/Node/NameImporter.php
index 3ff957d0e401..ca7b281e74e0 100644
--- a/packages/coding-style/src/Node/NameImporter.php
+++ b/packages/coding-style/src/Node/NameImporter.php
@@ -13,7 +13,7 @@
use Rector\CodingStyle\Imports\AliasUsesResolver;
use Rector\CodingStyle\Imports\ImportSkipper;
use Rector\Core\Configuration\Option;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\StaticTypeMapper;
use Rector\PHPStan\Type\FullyQualifiedObjectType;
@@ -47,9 +47,9 @@ final class NameImporter
private $importSkipper;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ParameterProvider
@@ -61,14 +61,14 @@ public function __construct(
AliasUsesResolver $aliasUsesResolver,
UseAddingCommander $useAddingCommander,
ImportSkipper $importSkipper,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ParameterProvider $parameterProvider
) {
$this->staticTypeMapper = $staticTypeMapper;
$this->aliasUsesResolver = $aliasUsesResolver;
$this->useAddingCommander = $useAddingCommander;
$this->importSkipper = $importSkipper;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->parameterProvider = $parameterProvider;
}
@@ -111,7 +111,7 @@ private function shouldSkipName(Name $name): bool
$importShortClasses = $this->parameterProvider->provideParameter(Option::IMPORT_SHORT_CLASSES_PARAMETER);
if (! $importShortClasses) {
- $name = $this->nameResolver->getName($name);
+ $name = $this->nodeNameResolver->getName($name);
if ($name !== null && substr_count($name, '\\') === 0) {
return true;
}
diff --git a/packages/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php b/packages/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php
index 74365ebb0772..e3720e2830e2 100644
--- a/packages/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php
+++ b/packages/coding-style/src/Rector/ClassMethod/NewlineBeforeNewAssignSetRector.php
@@ -81,11 +81,12 @@ public function refactor(Node $node): ?Node
{
$this->reset();
+ $hasChanged = false;
+
if ($node->stmts === null) {
return null;
}
- $hasChanged = false;
foreach ($node->stmts as $key => $stmt) {
$currentStmtVariableName = null;
diff --git a/packages/coding-style/src/Rector/Use_/RemoveUnusedAliasRector.php b/packages/coding-style/src/Rector/Use_/RemoveUnusedAliasRector.php
index 6572025cbe23..dcf9eec80714 100644
--- a/packages/coding-style/src/Rector/Use_/RemoveUnusedAliasRector.php
+++ b/packages/coding-style/src/Rector/Use_/RemoveUnusedAliasRector.php
@@ -49,6 +49,11 @@ final class RemoveUnusedAliasRector extends AbstractRector
*/
private $shortNameResolver;
+ /**
+ * @var string[][]
+ */
+ private $useNamesAliasToName = [];
+
public function __construct(ShortNameResolver $shortNameResolver)
{
$this->shortNameResolver = $shortNameResolver;
@@ -96,7 +101,7 @@ public function refactor(Node $node): ?Node
$this->resolvedNodeNames = [];
$this->resolveUsedNameNodes($node);
- $useNamesAliasToName = $this->collectUseNamesAliasToName($node);
+ $this->collectUseNamesAliasToName($node);
foreach ($node->uses as $use) {
if ($use->alias === null) {
@@ -118,16 +123,7 @@ public function refactor(Node $node): ?Node
continue;
}
- // only alias name is used → use last name directly
- if (isset($this->resolvedNodeNames[$aliasName])) {
- // keep to differentiate 2 aliases classes
- if (isset($useNamesAliasToName[$lastName]) && count($useNamesAliasToName[$lastName]) > 1) {
- continue;
- }
-
- $this->renameNameNode($this->resolvedNodeNames[$aliasName], $lastName);
- $use->alias = null;
- }
+ $this->refactorAliasName($aliasName, $lastName, $use);
}
return $node;
@@ -147,12 +143,9 @@ private function resolveUsedNameNodes(Use_ $node): void
$this->resolvedDocPossibleAliases = $this->resolveDocPossibleAliases($searchNode);
}
- /**
- * @return string[][]
- */
- private function collectUseNamesAliasToName(Use_ $use): array
+ private function collectUseNamesAliasToName(Use_ $use): void
{
- $useNamesAliasToName = [];
+ $this->useNamesAliasToName = [];
$shortNames = $this->shortNameResolver->resolveForNode($use);
foreach ($shortNames as $alias => $useImport) {
@@ -161,10 +154,8 @@ private function collectUseNamesAliasToName(Use_ $use): array
continue;
}
- $useNamesAliasToName[$shortName][] = $alias;
+ $this->useNamesAliasToName[$shortName][] = $alias;
}
-
- return $useNamesAliasToName;
}
private function shouldSkip(string $lastName, string $aliasName): bool
@@ -184,81 +175,42 @@ private function shouldSkip(string $lastName, string $aliasName): bool
private function renameNameNode(array $usedNameNodes, string $lastName): void
{
/** @var Identifier|Name $usedName */
+ // @todo value objects
foreach ($usedNameNodes as [$usedName, $parentNode]) {
if ($parentNode instanceof TraitUse) {
- foreach ($parentNode->traits as $key => $traitName) {
- if (! $this->areNamesEqual($traitName, $usedName)) {
- continue;
- }
-
- $parentNode->traits[$key] = new Name($lastName);
- }
-
- continue;
+ $this->renameTraitUse($lastName, $parentNode, $usedName);
}
if ($parentNode instanceof Class_) {
- if ($parentNode->name !== null && $this->areNamesEqual($parentNode->name, $usedName)) {
- $parentNode->name = new Identifier($lastName);
- }
-
- if ($parentNode->extends !== null && $this->areNamesEqual($parentNode->extends, $usedName)) {
- $parentNode->extends = new Name($lastName);
- }
-
- foreach ($parentNode->implements as $key => $implementNode) {
- if ($this->areNamesEqual($implementNode, $usedName)) {
- $parentNode->implements[$key] = new Name($lastName);
- }
- }
-
- continue;
+ $this->renameClass($lastName, $parentNode, $usedName);
}
if ($parentNode instanceof Param) {
- if ($parentNode->type !== null && $this->areNamesEqual($parentNode->type, $usedName)) {
- $parentNode->type = new Name($lastName);
- }
-
- continue;
+ $this->renameParam($lastName, $parentNode, $usedName);
}
if ($parentNode instanceof New_) {
- if ($this->areNamesEqual($parentNode->class, $usedName)) {
- $parentNode->class = new Name($lastName);
- }
-
- continue;
+ $this->renameNew($lastName, $parentNode, $usedName);
}
if ($parentNode instanceof ClassMethod) {
- if ($parentNode->returnType !== null && $this->areNamesEqual($parentNode->returnType, $usedName)) {
- $parentNode->returnType = new Name($lastName);
- }
-
- continue;
+ $this->renameClassMethod($lastName, $parentNode, $usedName);
}
if ($parentNode instanceof Interface_) {
- foreach ($parentNode->extends as $key => $extendInterfaceName) {
- if ($this->areNamesEqual($extendInterfaceName, $usedName)) {
- $parentNode->extends[$key] = new Name($lastName);
- }
- }
-
- continue;
+ $this->renameInterface($lastName, $parentNode, $usedName);
}
}
}
- private function resolveSearchNode(Use_ $node): ?Node
+ private function resolveSearchNode(Use_ $use): ?Node
{
- $searchNode = $node->getAttribute(AttributeKey::PARENT_NODE);
+ $searchNode = $use->getAttribute(AttributeKey::PARENT_NODE);
if ($searchNode !== null) {
return $searchNode;
}
- return $node->getAttribute(AttributeKey::NEXT_NODE);
+ return $use->getAttribute(AttributeKey::NEXT_NODE);
}
private function resolveUsedNames(Node $searchNode): void
@@ -357,4 +309,79 @@ private function appendPossibleAliases(Type $varType, array $possibleDocAliases)
}
return $possibleDocAliases;
}
+
+ private function renameClass(string $lastName, Class_ $class, $usedName): void
+ {
+ if ($class->name !== null && $this->areNamesEqual($class->name, $usedName)) {
+ $class->name = new Identifier($lastName);
+ }
+
+ if ($class->extends !== null && $this->areNamesEqual($class->extends, $usedName)) {
+ $class->extends = new Name($lastName);
+ }
+
+ foreach ($class->implements as $key => $implementNode) {
+ if ($this->areNamesEqual($implementNode, $usedName)) {
+ $class->implements[$key] = new Name($lastName);
+ }
+ }
+ }
+
+ private function renameTraitUse(string $lastName, TraitUse $traitUse, $usedName): void
+ {
+ foreach ($traitUse->traits as $key => $traitName) {
+ if (! $this->areNamesEqual($traitName, $usedName)) {
+ continue;
+ }
+
+ $traitUse->traits[$key] = new Name($lastName);
+ }
+ }
+
+ private function renameParam(string $lastName, $parentNode, $usedName): void
+ {
+ if ($parentNode->type !== null && $this->areNamesEqual($parentNode->type, $usedName)) {
+ $parentNode->type = new Name($lastName);
+ }
+ }
+
+ private function renameNew(string $lastName, $parentNode, $usedName): void
+ {
+ if ($this->areNamesEqual($parentNode->class, $usedName)) {
+ $parentNode->class = new Name($lastName);
+ }
+ }
+
+ private function renameClassMethod(string $lastName, ClassMethod $classMethod, $usedName): void
+ {
+ if ($classMethod->returnType !== null && $this->areNamesEqual($classMethod->returnType, $usedName)) {
+ $classMethod->returnType = new Name($lastName);
+ }
+ }
+
+ private function renameInterface(string $lastName, Interface_ $parentNode, $usedName): void
+ {
+ foreach ($parentNode->extends as $key => $extendInterfaceName) {
+ if ($this->areNamesEqual($extendInterfaceName, $usedName)) {
+ $parentNode->extends[$key] = new Name($lastName);
+ }
+ }
+ }
+
+ private function refactorAliasName(string $aliasName, string $lastName, UseUse $useUse): void
+ {
+ // only alias name is used → use last name directly
+
+ if (! isset($this->resolvedNodeNames[$aliasName])) {
+ return;
+ }
+
+ // keep to differentiate 2 aliases classes
+ if (isset($this->useNamesAliasToName[$lastName]) && count($this->useNamesAliasToName[$lastName]) > 1) {
+ return;
+ }
+
+ $this->renameNameNode($this->resolvedNodeNames[$aliasName], $lastName);
+ $useUse->alias = null;
+ }
}
diff --git a/packages/dead-code/src/Doctrine/DoctrineEntityManipulator.php b/packages/dead-code/src/Doctrine/DoctrineEntityManipulator.php
index b6c3358c6eda..f172756eeebf 100644
--- a/packages/dead-code/src/Doctrine/DoctrineEntityManipulator.php
+++ b/packages/dead-code/src/Doctrine/DoctrineEntityManipulator.php
@@ -16,7 +16,7 @@
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\EntityTagValueNode;
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Class_\InheritanceTypeTagValueNode;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -24,9 +24,9 @@
final class DoctrineEntityManipulator
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var DoctrineDocBlockResolver
@@ -39,11 +39,11 @@ final class DoctrineEntityManipulator
private $nodeTypeResolver;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
DoctrineDocBlockResolver $doctrineDocBlockResolver,
NodeTypeResolver $nodeTypeResolver
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
$this->nodeTypeResolver = $nodeTypeResolver;
}
@@ -123,7 +123,7 @@ public function isMethodCallOnDoctrineEntity(Node $node, string $methodName): bo
return false;
}
- if (! $this->nameResolver->isName($node->name, $methodName)) {
+ if (! $this->nodeNameResolver->isName($node->name, $methodName)) {
return false;
}
diff --git a/packages/dead-code/src/NodeManipulator/LivingCodeManipulator.php b/packages/dead-code/src/NodeManipulator/LivingCodeManipulator.php
new file mode 100644
index 000000000000..bbd6a871a98c
--- /dev/null
+++ b/packages/dead-code/src/NodeManipulator/LivingCodeManipulator.php
@@ -0,0 +1,128 @@
+isNestedExpr($expr)) {
+ return $this->keepLivingCodeFromExpr($expr->expr);
+ }
+
+ if ($expr instanceof Variable) {
+ return $this->keepLivingCodeFromExpr($expr->name);
+ }
+
+ if ($expr instanceof PropertyFetch) {
+ return array_merge(
+ $this->keepLivingCodeFromExpr($expr->var),
+ $this->keepLivingCodeFromExpr($expr->name)
+ );
+ }
+
+ if ($expr instanceof ArrayDimFetch) {
+ return array_merge(
+ $this->keepLivingCodeFromExpr($expr->var),
+ $this->keepLivingCodeFromExpr($expr->dim)
+ );
+ }
+
+ if ($expr instanceof ClassConstFetch ||
+ $expr instanceof StaticPropertyFetch) {
+ return array_merge(
+ $this->keepLivingCodeFromExpr($expr->class),
+ $this->keepLivingCodeFromExpr($expr->name)
+ );
+ }
+
+ if ($this->isBinaryOpWithoutChange($expr)) {
+ return array_merge(
+ $this->keepLivingCodeFromExpr($expr->left),
+ $this->keepLivingCodeFromExpr($expr->right)
+ );
+ }
+
+ if ($expr instanceof Instanceof_) {
+ return array_merge(
+ $this->keepLivingCodeFromExpr($expr->expr),
+ $this->keepLivingCodeFromExpr($expr->class)
+ );
+ }
+
+ if ($expr instanceof Isset_) {
+ return array_merge(...array_map(function (Expr $expr): array {
+ return $this->keepLivingCodeFromExpr($expr);
+ }, $expr->vars));
+ }
+
+ return [$expr];
+ }
+
+ private function isBinaryOpWithoutChange($expr): bool
+ {
+ return $expr instanceof BinaryOp
+ && ! (
+ $expr instanceof LogicalAnd ||
+ $expr instanceof BooleanAnd ||
+ $expr instanceof LogicalOr ||
+ $expr instanceof BooleanOr ||
+ $expr instanceof Coalesce
+ );
+ }
+
+ private function isNestedExpr($expr): bool
+ {
+ return $expr instanceof Cast ||
+ $expr instanceof Empty_ ||
+ $expr instanceof UnaryMinus ||
+ $expr instanceof UnaryPlus ||
+ $expr instanceof BitwiseNot ||
+ $expr instanceof BooleanNot ||
+ $expr instanceof Clone_;
+ }
+}
diff --git a/packages/dead-code/src/Rector/ClassMethod/RemoveDelegatingParentCallRector.php b/packages/dead-code/src/Rector/ClassMethod/RemoveDelegatingParentCallRector.php
index 9123baf57dd5..81a664bfda98 100644
--- a/packages/dead-code/src/Rector/ClassMethod/RemoveDelegatingParentCallRector.php
+++ b/packages/dead-code/src/Rector/ClassMethod/RemoveDelegatingParentCallRector.php
@@ -22,6 +22,7 @@
use Rector\NodeTypeResolver\Node\AttributeKey;
use ReflectionClass;
use ReflectionMethod;
+use ReflectionParameter;
/**
* @see \Rector\DeadCode\Tests\Rector\ClassMethod\RemoveDelegatingParentCallRector\RemoveDelegatingParentCallRectorTest
@@ -223,17 +224,8 @@ private function isParentClassMethodVisibilityOrDefaultOverride(
/** @var string $methodName */
$methodName = $this->getName($staticCall);
$parentClassMethod = $this->functionLikeParsedNodesFinder->findMethod($methodName, $parentClassName);
- if ($parentClassMethod !== null) {
- if ($parentClassMethod->isProtected() && $classMethod->isPublic()) {
- return true;
- }
-
- foreach ($parentClassMethod->params as $key => $parentParam) {
- if (! isset($classMethod->params[$key]) && $parentParam->default !== null) {
- continue;
- }
- $this->areNodesEqual($parentParam, $classMethod->params[$key]);
- }
+ if ($parentClassMethod !== null && $parentClassMethod->isProtected() && $classMethod->isPublic()) {
+ return true;
}
return $this->checkOverrideUsingReflection($classMethod, $parentClassName, $methodName);
@@ -285,17 +277,23 @@ private function areParameterDefaultsDifferent(
}
return true;
}
+
$methodParam = $classMethod->params[$key];
- if ($parameter->isDefaultValueAvailable() !== isset($methodParam->default)) {
- return true;
- }
- if ($parameter->isDefaultValueAvailable() && $methodParam->default !== null &&
- ! $this->valueResolver->isValue($methodParam->default, $parameter->getDefaultValue())
- ) {
+ if ($this->areDefaultValuesDifferent($parameter, $methodParam)) {
return true;
}
}
return false;
}
+
+ private function areDefaultValuesDifferent(ReflectionParameter $reflectionParameter, Param $methodParam): bool
+ {
+ if ($reflectionParameter->isDefaultValueAvailable() !== isset($methodParam->default)) {
+ return true;
+ }
+
+ return $reflectionParameter->isDefaultValueAvailable() && $methodParam->default !== null &&
+ ! $this->valueResolver->isValue($methodParam->default, $reflectionParameter->getDefaultValue());
+ }
}
diff --git a/packages/dead-code/src/Rector/Class_/RemoveSetterOnlyPropertyAndMethodCallRector.php b/packages/dead-code/src/Rector/Class_/RemoveSetterOnlyPropertyAndMethodCallRector.php
index e4953cda21f0..441d9f649837 100644
--- a/packages/dead-code/src/Rector/Class_/RemoveSetterOnlyPropertyAndMethodCallRector.php
+++ b/packages/dead-code/src/Rector/Class_/RemoveSetterOnlyPropertyAndMethodCallRector.php
@@ -17,7 +17,7 @@
use Rector\Core\RectorDefinition\CodeSample;
use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NodeTypeResolver\Node\AttributeKey;
-use Rector\TypeDeclaration\VendorLock\VendorLockResolver;
+use Rector\VendorLocker\VendorLockResolver;
/**
* @sponsor Thanks https://spaceflow.io/ for sponsoring this rule - visit them on https://github.com/SpaceFlow-app
diff --git a/packages/dead-code/src/Rector/Stmt/RemoveDeadStmtRector.php b/packages/dead-code/src/Rector/Stmt/RemoveDeadStmtRector.php
index 324ef10e0982..509f5369116f 100644
--- a/packages/dead-code/src/Rector/Stmt/RemoveDeadStmtRector.php
+++ b/packages/dead-code/src/Rector/Stmt/RemoveDeadStmtRector.php
@@ -58,7 +58,7 @@ public function getNodeTypes(): array
*/
public function refactor(Node $node): ?Node
{
- $livingCode = $this->keepLivingCodeFromExpr($node->expr);
+ $livingCode = $this->livingCodeManipulator->keepLivingCodeFromExpr($node->expr);
if ($livingCode === []) {
return $this->removeNodeAndKeepComments($node);
}
diff --git a/packages/dead-code/src/UnusedNodeResolver/ClassUnusedPrivateClassMethodResolver.php b/packages/dead-code/src/UnusedNodeResolver/ClassUnusedPrivateClassMethodResolver.php
index 72d90655dd25..0b004acdc601 100644
--- a/packages/dead-code/src/UnusedNodeResolver/ClassUnusedPrivateClassMethodResolver.php
+++ b/packages/dead-code/src/UnusedNodeResolver/ClassUnusedPrivateClassMethodResolver.php
@@ -8,15 +8,15 @@
use PhpParser\Node\Stmt\Class_;
use Rector\Core\NodeContainer\NodeFinder\FunctionLikeParsedNodesFinder;
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use ReflectionMethod;
final class ClassUnusedPrivateClassMethodResolver
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ClassManipulator
@@ -29,11 +29,11 @@ final class ClassUnusedPrivateClassMethodResolver
private $functionLikeParsedNodesFinder;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ClassManipulator $classManipulator,
FunctionLikeParsedNodesFinder $functionLikeParsedNodesFinder
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->classManipulator = $classManipulator;
$this->functionLikeParsedNodesFinder = $functionLikeParsedNodesFinder;
}
@@ -44,7 +44,7 @@ public function __construct(
public function getClassUnusedMethodNames(Class_ $class): array
{
/** @var string $className */
- $className = $this->nameResolver->getName($class);
+ $className = $this->nodeNameResolver->getName($class);
$classMethodCalls = $this->functionLikeParsedNodesFinder->findMethodCallsOnClass($className);
@@ -98,7 +98,7 @@ private function filterOutSystemMethods(array $unusedMethods): array
private function filterOutInterfaceRequiredMethods(Class_ $class, array $unusedMethods): array
{
/** @var string $className */
- $className = $this->nameResolver->getName($class);
+ $className = $this->nodeNameResolver->getName($class);
$interfaces = class_implements($className);
diff --git a/packages/dead-code/src/UnusedNodeResolver/UnusedClassResolver.php b/packages/dead-code/src/UnusedNodeResolver/UnusedClassResolver.php
index d5b26e2cadee..dfb4dbe7214e 100644
--- a/packages/dead-code/src/UnusedNodeResolver/UnusedClassResolver.php
+++ b/packages/dead-code/src/UnusedNodeResolver/UnusedClassResolver.php
@@ -14,7 +14,7 @@
use PhpParser\Node\Stmt\Class_;
use Rector\Core\Exception\NotImplementedException;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\Testing\PHPUnit\PHPUnitEnvironment;
final class UnusedClassResolver
@@ -25,18 +25,18 @@ final class UnusedClassResolver
private $cachedUsedClassNames = [];
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ParsedNodeCollector
*/
private $parsedNodeCollector;
- public function __construct(NameResolver $nameResolver, ParsedNodeCollector $parsedNodeCollector)
+ public function __construct(NodeNameResolver $nodeNameResolver, ParsedNodeCollector $parsedNodeCollector)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
}
@@ -71,15 +71,15 @@ public function isClassWithoutInterfaceAndNotController(Class_ $class): bool
return false;
}
- if ($this->nameResolver->isNames($class, ['*Controller', '*Presenter'])) {
+ if ($this->nodeNameResolver->isNames($class, ['*Controller', '*Presenter'])) {
return false;
}
- return ! $this->nameResolver->isName($class, '*Test');
+ return ! $this->nodeNameResolver->isName($class, '*Test');
}
public function isClassUsed(Class_ $class): bool
{
- return $this->nameResolver->isNames($class, $this->getUsedClassNames());
+ return $this->nodeNameResolver->isNames($class, $this->getUsedClassNames());
}
/**
@@ -106,7 +106,7 @@ private function getParamNodesClassNames(): array
if ($paramNode->type instanceof Name) {
/** @var string $paramTypeName */
- $paramTypeName = $this->nameResolver->getName($paramNode->type);
+ $paramTypeName = $this->nodeNameResolver->getName($paramNode->type);
$classNames[] = $paramTypeName;
} else {
throw new NotImplementedException();
@@ -126,7 +126,7 @@ private function getNewNodesClassNames(): array
/** @var New_[] $newNodes */
$newNodes = $this->parsedNodeCollector->getNodesByType(New_::class);
foreach ($newNodes as $newNode) {
- $newNodeClassName = $this->nameResolver->getName($newNode->class);
+ $newNodeClassName = $this->nodeNameResolver->getName($newNode->class);
if (! is_string($newNodeClassName)) {
continue;
}
@@ -147,7 +147,7 @@ private function getStaticCallClassNames(): array
/** @var StaticCall[] $staticCallNodes */
$staticCallNodes = $this->parsedNodeCollector->getNodesByType(StaticCall::class);
foreach ($staticCallNodes as $staticCallNode) {
- $staticClassName = $this->nameResolver->getName($staticCallNode->class);
+ $staticClassName = $this->nodeNameResolver->getName($staticCallNode->class);
if (! is_string($staticClassName)) {
continue;
}
@@ -167,7 +167,7 @@ private function getClassConstantFetchNames(): array
$classNames = [];
foreach ($classConstFetches as $classConstFetch) {
- $className = $this->nameResolver->getName($classConstFetch->class);
+ $className = $this->nodeNameResolver->getName($classConstFetch->class);
if (! is_string($className)) {
continue;
}
diff --git a/packages/doctrine/src/Provider/EntityWithMissingUuidProvider.php b/packages/doctrine/src/Provider/EntityWithMissingUuidProvider.php
index 89e1df334ed3..85e4bd62db6c 100644
--- a/packages/doctrine/src/Provider/EntityWithMissingUuidProvider.php
+++ b/packages/doctrine/src/Provider/EntityWithMissingUuidProvider.php
@@ -12,7 +12,7 @@
use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_\IdTagValueNode;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Doctrine\PhpDocParser\DoctrineDocBlockResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -39,20 +39,20 @@ final class EntityWithMissingUuidProvider
private $classManipulator;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
public function __construct(
ParsedNodeCollector $parsedNodeCollector,
DoctrineDocBlockResolver $doctrineDocBlockResolver,
ClassManipulator $classManipulator,
- NameResolver $nameResolver
+ NodeNameResolver $nodeNameResolver
) {
$this->parsedNodeCollector = $parsedNodeCollector;
$this->doctrineDocBlockResolver = $doctrineDocBlockResolver;
$this->classManipulator = $classManipulator;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -94,7 +94,7 @@ private function hasClassIdPropertyWithUuidType(Class_ $class): bool
continue;
}
- if (! $this->nameResolver->isName($classStmt, 'id')) {
+ if (! $this->nodeNameResolver->isName($classStmt, 'id')) {
continue;
}
diff --git a/packages/laravel/src/Rector/FuncCall/HelperFunctionToConstructorInjectionRector.php b/packages/laravel/src/Rector/FuncCall/HelperFunctionToConstructorInjectionRector.php
index be4a594bebc3..80cc915e5527 100644
--- a/packages/laravel/src/Rector/FuncCall/HelperFunctionToConstructorInjectionRector.php
+++ b/packages/laravel/src/Rector/FuncCall/HelperFunctionToConstructorInjectionRector.php
@@ -7,6 +7,7 @@
use PhpParser\Node;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\MethodCall;
+use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Exception\ShouldNotHappenException;
@@ -125,13 +126,7 @@ public function refactor(Node $node): ?Node
}
if ($functionChange instanceof ArrayFunctionToMethodCall) {
- if ($functionChange->getArrayMethod() && $this->isArrayType($node->args[0]->value)) {
- return new MethodCall($propertyFetchNode, $functionChange->getArrayMethod(), $node->args);
- }
-
- if ($functionChange->getNonArrayMethod() && ! $this->isArrayType($node->args[0]->value)) {
- return new MethodCall($propertyFetchNode, $functionChange->getNonArrayMethod(), $node->args);
- }
+ return $this->createMethodCallArrayFunctionToMethodCall($node, $functionChange, $propertyFetchNode);
}
throw new ShouldNotHappenException();
@@ -169,4 +164,20 @@ private function isFunctionToMethodCallWithArgs(Node $node, $functionChange): bo
return count($node->args) >= 1;
}
+
+ private function createMethodCallArrayFunctionToMethodCall(
+ FuncCall $funcCall,
+ ArrayFunctionToMethodCall $arrayFunctionToMethodCall,
+ PropertyFetch $propertyFetch
+ ) {
+ if ($arrayFunctionToMethodCall->getArrayMethod() && $this->isArrayType($funcCall->args[0]->value)) {
+ return new MethodCall($propertyFetch, $arrayFunctionToMethodCall->getArrayMethod(), $funcCall->args);
+ }
+
+ if ($arrayFunctionToMethodCall->getNonArrayMethod() && ! $this->isArrayType($funcCall->args[0]->value)) {
+ return new MethodCall($propertyFetch, $arrayFunctionToMethodCall->getNonArrayMethod(), $funcCall->args);
+ }
+
+ return null;
+ }
}
diff --git a/packages/legacy/src/Rector/ClassMethod/ChangeSingletonToServiceRector.php b/packages/legacy/src/Rector/ClassMethod/ChangeSingletonToServiceRector.php
index 8e40bcd3621c..593611e1c9e1 100644
--- a/packages/legacy/src/Rector/ClassMethod/ChangeSingletonToServiceRector.php
+++ b/packages/legacy/src/Rector/ClassMethod/ChangeSingletonToServiceRector.php
@@ -128,24 +128,31 @@ private function refactorClassStmts(
continue;
}
- if (! $property->isPublic()) {
- // remove non-public empty
- if ($property->stmts === []) {
- $this->removeNodeFromStatements($node, $property);
- } else {
- $this->makePublic($property);
- }
+ if ($property->isPublic()) {
+ continue;
+ }
+
+ // remove non-public empty
+ if ($property->stmts === []) {
+ $this->removeNodeFromStatements($node, $property);
+ } else {
+ $this->makePublic($property);
}
}
- foreach ($node->getProperties() as $property) {
- if (! $this->isName($property, $singletonPropertyName)) {
+ $this->removePropertyByName($node, $singletonPropertyName);
+
+ return $node;
+ }
+
+ private function removePropertyByName(Class_ $class, string $propertyName): void
+ {
+ foreach ($class->getProperties() as $property) {
+ if (! $this->isName($property, $propertyName)) {
continue;
}
- $this->removeNodeFromStatements($node, $property);
+ $this->removeNodeFromStatements($class, $property);
}
-
- return $node;
}
}
diff --git a/packages/minimal-scope/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php b/packages/minimal-scope/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php
index 4ca2a4c5bc77..daa5fc0dcdae 100644
--- a/packages/minimal-scope/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php
+++ b/packages/minimal-scope/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php
@@ -221,42 +221,10 @@ private function isPropertyChangingInMultipleMethodCalls(
}
if ($node instanceof If_) {
- $this->traverseNodesWithCallable($node->cond, function (Node $node) use (
- $privatePropertyName,
- &$isPropertyReadInIf
- ) {
- if (! $this->propertyFetchManipulator->isLocalPropertyOfNames($node, [$privatePropertyName])) {
- return null;
- }
-
- $isPropertyReadInIf = true;
-
- return NodeTraverser::STOP_TRAVERSAL;
- });
+ $isPropertyReadInIf = $this->refactorIf($node, $privatePropertyName);
}
- // here cannot be any property assign
- $this->traverseNodesWithCallable($node, function (Node $node) use (
- &$isPropertyChanging,
- $privatePropertyName
- ) {
- if (! $node instanceof Assign) {
- return null;
- }
-
- if (! $node->var instanceof PropertyFetch) {
- return null;
- }
-
- if (! $this->isName($node->var->name, $privatePropertyName)) {
- return null;
- }
-
- $isPropertyChanging = true;
-
- return NodeTraverser::STOP_TRAVERSAL;
- });
-
+ $isPropertyChanging = $this->isPropertyChanging($node, $this, $privatePropertyName);
if (! $isPropertyChanging) {
return null;
}
@@ -279,4 +247,52 @@ private function isScopeChangingNode(Node $node): bool
return false;
}
+
+ /**
+ * @return bool|null
+ */
+ private function refactorIf(If_ $if, string $privatePropertyName)
+ {
+ $this->traverseNodesWithCallable($if->cond, function (Node $node) use (
+ $privatePropertyName,
+ &$isPropertyReadInIf
+ ) {
+ if (! $this->propertyFetchManipulator->isLocalPropertyOfNames($node, [$privatePropertyName])) {
+ return null;
+ }
+
+ $isPropertyReadInIf = true;
+
+ return NodeTraverser::STOP_TRAVERSAL;
+ });
+
+ return $isPropertyReadInIf;
+ }
+
+ private function isPropertyChanging(Node $node, self $this__, string $privatePropertyName): bool
+ {
+ $isPropertyChanging = false;
+ // here cannot be any property assign
+ $this__->traverseNodesWithCallable($node, function (Node $node) use (
+ &$isPropertyChanging,
+ $privatePropertyName
+ ) {
+ if (! $node instanceof Assign) {
+ return null;
+ }
+
+ if (! $node->var instanceof PropertyFetch) {
+ return null;
+ }
+
+ if (! $this->isName($node->var->name, $privatePropertyName)) {
+ return null;
+ }
+
+ $isPropertyChanging = true;
+
+ return NodeTraverser::STOP_TRAVERSAL;
+ });
+ return $isPropertyChanging;
+ }
}
diff --git a/packages/nette-tester-to-phpunit/src/AssertManipulator.php b/packages/nette-tester-to-phpunit/src/AssertManipulator.php
index 7dc0976f2ac1..41e2d17d4a4c 100644
--- a/packages/nette-tester-to-phpunit/src/AssertManipulator.php
+++ b/packages/nette-tester-to-phpunit/src/AssertManipulator.php
@@ -20,7 +20,7 @@
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
use Rector\Core\PhpParser\Node\Commander\NodeAddingCommander;
use Rector\Core\PhpParser\Node\Commander\NodeRemovingCommander;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -50,9 +50,9 @@ final class AssertManipulator
];
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var NodeTypeResolver
@@ -80,14 +80,14 @@ final class AssertManipulator
private $stringTypeAnalyzer;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
ValueResolver $valueResolver,
NodeAddingCommander $nodeAddingCommander,
NodeRemovingCommander $nodeRemovingCommander,
StringTypeAnalyzer $stringTypeAnalyzer
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->valueResolver = $valueResolver;
$this->nodeAddingCommander = $nodeAddingCommander;
@@ -100,23 +100,20 @@ public function __construct(
*/
public function processStaticCall(StaticCall $staticCall): Node
{
- if ($this->nameResolver->isNames($staticCall, ['contains', 'notContains'])) {
+ if ($this->nodeNameResolver->isNames($staticCall, ['truthy', 'falsey'])) {
+ return $this->processTruthyOrFalseyCall($staticCall);
+ }
+
+ if ($this->nodeNameResolver->isNames($staticCall, ['contains', 'notContains'])) {
$this->processContainsCall($staticCall);
- } elseif ($this->nameResolver->isNames($staticCall, ['exception', 'throws'])) {
+ } elseif ($this->nodeNameResolver->isNames($staticCall, ['exception', 'throws'])) {
$this->processExceptionCall($staticCall);
- } elseif ($this->nameResolver->isName($staticCall, 'type')) {
+ } elseif ($this->nodeNameResolver->isName($staticCall, 'type')) {
$this->processTypeCall($staticCall);
- } elseif ($this->nameResolver->isName($staticCall, 'noError')) {
+ } elseif ($this->nodeNameResolver->isName($staticCall, 'noError')) {
$this->processNoErrorCall($staticCall);
- } elseif ($this->nameResolver->isNames($staticCall, ['truthy', 'falsey'])) {
- return $this->processTruthyOrFalseyCall($staticCall);
} else {
- foreach ($this->assertMethodsRemap as $oldMethod => $newMethod) {
- if ($this->nameResolver->isName($staticCall, $oldMethod)) {
- $staticCall->name = new Identifier($newMethod);
- continue;
- }
- }
+ $this->renameAssertMethod($staticCall);
}
// self or class, depending on the context
@@ -138,12 +135,12 @@ public function processStaticCall(StaticCall $staticCall): Node
private function processContainsCall(StaticCall $staticCall): void
{
if ($this->stringTypeAnalyzer->isStringOrUnionStringOnlyType($staticCall->args[1]->value)) {
- $name = $this->nameResolver->isName(
+ $name = $this->nodeNameResolver->isName(
$staticCall,
'contains'
) ? 'assertStringContainsString' : 'assertStringNotContainsString';
} else {
- $name = $this->nameResolver->isName($staticCall, 'contains') ? 'assertContains' : 'assertNotContains';
+ $name = $this->nodeNameResolver->isName($staticCall, 'contains') ? 'assertContains' : 'assertNotContains';
}
$staticCall->name = new Identifier($name);
@@ -165,30 +162,12 @@ private function processExceptionCall(StaticCall $staticCall): void
// expect message
if (isset($staticCall->args[2])) {
- $method = 'expectExceptionMessage';
-
- if ($this->sholdBeStaticCall($staticCall)) {
- $expectExceptionMessage = new StaticCall(new Name('self'), $method);
- } else {
- $expectExceptionMessage = new MethodCall(new Variable('this'), $method);
- }
-
- $expectExceptionMessage->args[] = $staticCall->args[2];
- $this->nodeAddingCommander->addNodeAfterNode($expectExceptionMessage, $staticCall);
+ $this->refactorExpectException($staticCall);
}
// expect code
if (isset($staticCall->args[3])) {
- $method = 'expectExceptionCode';
-
- if ($this->sholdBeStaticCall($staticCall)) {
- $expectExceptionCode = new StaticCall(new Name('self'), $method);
- } else {
- $expectExceptionCode = new MethodCall(new Variable('this'), $method);
- }
-
- $expectExceptionCode->args[] = $staticCall->args[3];
- $this->nodeAddingCommander->addNodeAfterNode($expectExceptionCode, $staticCall);
+ $this->refactorExpectExceptionCode($staticCall);
}
/** @var Closure $closure */
@@ -258,7 +237,7 @@ private function processNoErrorCall(StaticCall $staticCall): void
*/
private function processTruthyOrFalseyCall(StaticCall $staticCall): Expr
{
- $method = $this->nameResolver->isName($staticCall, 'truthy') ? 'assertTrue' : 'assertFalse';
+ $method = $this->nodeNameResolver->isName($staticCall, 'truthy') ? 'assertTrue' : 'assertFalse';
if (! $this->sholdBeStaticCall($staticCall)) {
$call = new MethodCall(new Variable('this'), $method);
@@ -281,4 +260,44 @@ private function sholdBeStaticCall(StaticCall $staticCall): bool
{
return ! (bool) $staticCall->getAttribute(AttributeKey::CLASS_NODE);
}
+
+ private function refactorExpectException(StaticCall $staticCall): string
+ {
+ $method = 'expectExceptionMessage';
+
+ if ($this->sholdBeStaticCall($staticCall)) {
+ $expectExceptionMessage = new StaticCall(new Name('self'), $method);
+ } else {
+ $expectExceptionMessage = new MethodCall(new Variable('this'), $method);
+ }
+
+ $expectExceptionMessage->args[] = $staticCall->args[2];
+ $this->nodeAddingCommander->addNodeAfterNode($expectExceptionMessage, $staticCall);
+ return $method;
+ }
+
+ private function refactorExpectExceptionCode(StaticCall $staticCall): void
+ {
+ $method = 'expectExceptionCode';
+
+ if ($this->sholdBeStaticCall($staticCall)) {
+ $expectExceptionCode = new StaticCall(new Name('self'), $method);
+ } else {
+ $expectExceptionCode = new MethodCall(new Variable('this'), $method);
+ }
+
+ $expectExceptionCode->args[] = $staticCall->args[3];
+ $this->nodeAddingCommander->addNodeAfterNode($expectExceptionCode, $staticCall);
+ }
+
+ private function renameAssertMethod(StaticCall $staticCall): void
+ {
+ foreach ($this->assertMethodsRemap as $oldMethod => $newMethod) {
+ if (! $this->nodeNameResolver->isName($staticCall, $oldMethod)) {
+ continue;
+ }
+
+ $staticCall->name = new Identifier($newMethod);
+ }
+ }
}
diff --git a/packages/nette-to-symfony/src/Route/RouteInfoFactory.php b/packages/nette-to-symfony/src/Route/RouteInfoFactory.php
index 31ac548443b1..c7e757fbb317 100644
--- a/packages/nette-to-symfony/src/Route/RouteInfoFactory.php
+++ b/packages/nette-to-symfony/src/Route/RouteInfoFactory.php
@@ -11,16 +11,16 @@
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\NetteToSymfony\ValueObject\RouteInfo;
final class RouteInfoFactory
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ValueResolver
@@ -33,11 +33,11 @@ final class RouteInfoFactory
private $parsedNodeCollector;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ValueResolver $valueResolver,
ParsedNodeCollector $parsedNodeCollector
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->valueResolver = $valueResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
}
@@ -58,12 +58,12 @@ public function createFromNode(Node $node): ?RouteInfo
return null;
}
- if (! $this->nameResolver->isNames($node, ['get', 'head', 'post', 'put', 'patch', 'delete'])) {
+ if (! $this->nodeNameResolver->isNames($node, ['get', 'head', 'post', 'put', 'patch', 'delete'])) {
return null;
}
/** @var string $methodName */
- $methodName = $this->nameResolver->getName($node);
+ $methodName = $this->nodeNameResolver->getName($node);
$uppercasedMethodName = strtoupper($methodName);
$methods = [];
@@ -95,72 +95,88 @@ private function createRouteInfoFromArgs(Node $node, array $methods = []): ?Rout
$targetNode = $node->args[1]->value;
if ($targetNode instanceof ClassConstFetch) {
- /** @var ClassConstFetch $controllerMethodNode */
- $controllerMethodNode = $node->args[1]->value;
-
- // SomePresenter::class
- if ($this->nameResolver->isName($controllerMethodNode->name, 'class')) {
- $presenterClass = $this->nameResolver->getName($controllerMethodNode->class);
- if ($presenterClass === null) {
- return null;
- }
-
- if (! class_exists($presenterClass)) {
- return null;
- }
-
- if (method_exists($presenterClass, 'run')) {
- return new RouteInfo($presenterClass, 'run', $routePath, null, $methods);
- }
- }
+ return $this->createForClassConstFetch($node, $methods, $routePath);
// @todo method specific route
}
if ($targetNode instanceof String_) {
- $targetValue = $targetNode->value;
- if (! Strings::contains($targetValue, ':')) {
- return null;
- }
+ return $this->createForString($targetNode, $routePath);
+ }
- [$controller, $method] = explode(':', $targetValue);
+ return null;
+ }
- // detect class by controller name?
- // foreach all instance and try to match a name $controller . 'Presenter/Controller'
+ private function normalizeArgumentWrappers(string $routePath): string
+ {
+ return str_replace(['<', '>'], ['{', '}'], $routePath);
+ }
- $classNode = $this->parsedNodeCollector->findByShortName($controller . 'Presenter');
- if ($classNode === null) {
- $classNode = $this->parsedNodeCollector->findByShortName($controller . 'Controller');
- }
+ /**
+ * @param New_|StaticCall $node
+ * @param string[] $methods
+ */
+ private function createForClassConstFetch(Node $node, array $methods, string $routePath): ?RouteInfo
+ {
+ /** @var ClassConstFetch $controllerMethodNode */
+ $controllerMethodNode = $node->args[1]->value;
- // unable to find here
- if ($classNode === null) {
+ // SomePresenter::class
+ if ($this->nodeNameResolver->isName($controllerMethodNode->name, 'class')) {
+ $presenterClass = $this->nodeNameResolver->getName($controllerMethodNode->class);
+ if ($presenterClass === null) {
return null;
}
- $controllerClass = $this->nameResolver->getName($classNode);
- if ($controllerClass === null) {
+ if (! class_exists($presenterClass)) {
return null;
}
- $methodName = null;
- if (method_exists($controllerClass, 'render' . ucfirst($method))) {
- $methodName = 'render' . ucfirst($method);
- } elseif (method_exists($controllerClass, 'action' . ucfirst($method))) {
- $methodName = 'action' . ucfirst($method);
+ if (method_exists($presenterClass, 'run')) {
+ return new RouteInfo($presenterClass, 'run', $routePath, null, $methods);
}
-
- if ($methodName === null) {
- return null;
- }
-
- return new RouteInfo($controllerClass, $methodName, $routePath, null, []);
}
return null;
}
- private function normalizeArgumentWrappers(string $routePath): string
+ private function createForString(String_ $string, string $routePath): ?RouteInfo
{
- return str_replace(['<', '>'], ['{', '}'], $routePath);
+ $targetValue = $string->value;
+ if (! Strings::contains($targetValue, ':')) {
+ return null;
+ }
+
+ [$controller, $method] = explode(':', $targetValue);
+
+ // detect class by controller name?
+ // foreach all instance and try to match a name $controller . 'Presenter/Controller'
+
+ $classNode = $this->parsedNodeCollector->findByShortName($controller . 'Presenter');
+ if ($classNode === null) {
+ $classNode = $this->parsedNodeCollector->findByShortName($controller . 'Controller');
+ }
+
+ // unable to find here
+ if ($classNode === null) {
+ return null;
+ }
+
+ $controllerClass = $this->nodeNameResolver->getName($classNode);
+ if ($controllerClass === null) {
+ return null;
+ }
+
+ $methodName = null;
+ if (method_exists($controllerClass, 'render' . ucfirst($method))) {
+ $methodName = 'render' . ucfirst($method);
+ } elseif (method_exists($controllerClass, 'action' . ucfirst($method))) {
+ $methodName = 'action' . ucfirst($method);
+ }
+
+ if ($methodName === null) {
+ return null;
+ }
+
+ return new RouteInfo($controllerClass, $methodName, $routePath, null, []);
}
}
diff --git a/packages/nette-to-symfony/src/SymfonyFormAbstractTypeFactory.php b/packages/nette-to-symfony/src/SymfonyFormAbstractTypeFactory.php
index c60e6da7bfba..96c5c3c0987f 100644
--- a/packages/nette-to-symfony/src/SymfonyFormAbstractTypeFactory.php
+++ b/packages/nette-to-symfony/src/SymfonyFormAbstractTypeFactory.php
@@ -16,7 +16,7 @@
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\PhpParser\Node\NodeFactory;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Symfony\Component\Form\Extension\Core\Type\TextType;
final class SymfonyFormAbstractTypeFactory
@@ -27,14 +27,14 @@ final class SymfonyFormAbstractTypeFactory
private $nodeFactory;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(NodeFactory $nodeFactory, NameResolver $nameResolver)
+ public function __construct(NodeFactory $nodeFactory, NodeNameResolver $nodeNameResolver)
{
$this->nodeFactory = $nodeFactory;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -69,7 +69,7 @@ private function createBuildFormMethodCalls(array $methodCalls, Variable $formBu
// create symfony form from nette form method calls
foreach ($methodCalls as $methodCall) {
- if ($this->nameResolver->isName($methodCall->name, 'addText')) {
+ if ($this->nodeNameResolver->isName($methodCall->name, 'addText')) {
$optionsArray = $this->createOptionsArray($methodCall);
$formTypeClassConstant = $this->nodeFactory->createClassConstantReference(TextType::class);
diff --git a/packages/nette/src/TemplatePropertyAssignCollector.php b/packages/nette/src/TemplatePropertyAssignCollector.php
index 827183522a16..485cad23fd05 100644
--- a/packages/nette/src/TemplatePropertyAssignCollector.php
+++ b/packages/nette/src/TemplatePropertyAssignCollector.php
@@ -11,7 +11,7 @@
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\ClassMethod;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\Nette\ValueObject\MagicTemplatePropertyCalls;
@@ -38,14 +38,14 @@ final class TemplatePropertyAssignCollector
private $callableNodeTraverser;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(CallableNodeTraverser $callableNodeTraverser, NameResolver $nameResolver)
+ public function __construct(CallableNodeTraverser $callableNodeTraverser, NodeNameResolver $nodeNameResolver)
{
$this->callableNodeTraverser = $callableNodeTraverser;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
public function collectTemplateFileNameVariablesAndNodesToRemove(
@@ -73,7 +73,7 @@ function (Node $node): void {
private function collectTemplateFileExpr(MethodCall $methodCall): void
{
- if ($this->nameResolver->isName($methodCall->name, 'render')) {
+ if ($this->nodeNameResolver->isName($methodCall->name, 'render')) {
if (isset($methodCall->args[0])) {
$this->templateFileExpr = $methodCall->args[0]->value;
}
@@ -81,7 +81,7 @@ private function collectTemplateFileExpr(MethodCall $methodCall): void
$this->nodesToRemove[] = $methodCall;
}
- if ($this->nameResolver->isName($methodCall->name, 'setFile')) {
+ if ($this->nodeNameResolver->isName($methodCall->name, 'setFile')) {
$this->templateFileExpr = $methodCall->args[0]->value;
$this->nodesToRemove[] = $methodCall;
}
@@ -91,11 +91,11 @@ private function collectVariableFromAssign(Assign $assign): void
{
// $this->template = x
if ($assign->var instanceof PropertyFetch) {
- if (! $this->nameResolver->isName($assign->var->var, 'template')) {
+ if (! $this->nodeNameResolver->isName($assign->var->var, 'template')) {
return;
}
- $variableName = $this->nameResolver->getName($assign->var);
+ $variableName = $this->nodeNameResolver->getName($assign->var);
$this->templateVariables[$variableName] = $assign->expr;
$this->nodesToRemove[] = $assign;
@@ -121,10 +121,10 @@ private function isTemplatePropertyFetch(Expr $expr): bool
return false;
}
- if (! $this->nameResolver->isName($expr->var, 'this')) {
+ if (! $this->nodeNameResolver->isName($expr->var, 'this')) {
return false;
}
- return $this->nameResolver->isName($expr->name, 'template');
+ return $this->nodeNameResolver->isName($expr->name, 'template');
}
}
diff --git a/packages/node-type-resolver/src/NodeTypeCorrector/PregMatchTypeCorrector.php b/packages/node-type-resolver/src/NodeTypeCorrector/PregMatchTypeCorrector.php
index d567dc1b3720..acc3b15ce4b1 100644
--- a/packages/node-type-resolver/src/NodeTypeCorrector/PregMatchTypeCorrector.php
+++ b/packages/node-type-resolver/src/NodeTypeCorrector/PregMatchTypeCorrector.php
@@ -12,7 +12,7 @@
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -24,9 +24,9 @@ final class PregMatchTypeCorrector
private $betterNodeFinder;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var BetterStandardPrinter
@@ -35,11 +35,11 @@ final class PregMatchTypeCorrector
public function __construct(
BetterNodeFinder $betterNodeFinder,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
BetterStandardPrinter $betterStandardPrinter
) {
$this->betterNodeFinder = $betterNodeFinder;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->betterStandardPrinter = $betterStandardPrinter;
}
@@ -69,7 +69,7 @@ public function correct(Node $node, Type $originalType): Type
continue;
}
- if (! $this->nameResolver->isNames($funcCallNode, ['preg_match', 'preg_match_all'])) {
+ if (! $this->nodeNameResolver->isNames($funcCallNode, ['preg_match', 'preg_match_all'])) {
continue;
}
diff --git a/packages/node-type-resolver/src/NodeTypeResolver.php b/packages/node-type-resolver/src/NodeTypeResolver.php
index f2edafbfe400..3823ca600ec0 100644
--- a/packages/node-type-resolver/src/NodeTypeResolver.php
+++ b/packages/node-type-resolver/src/NodeTypeResolver.php
@@ -32,7 +32,7 @@
use Rector\BetterPhpDocParser\PhpDocParser\BetterPhpDocParser;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
@@ -49,9 +49,9 @@ final class NodeTypeResolver
private $perNodeTypeResolvers = [];
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ClassReflectionTypesResolver
@@ -98,7 +98,7 @@ final class NodeTypeResolver
*/
public function __construct(
BetterPhpDocParser $betterPhpDocParser,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector,
ClassReflectionTypesResolver $classReflectionTypesResolver,
ReflectionProvider $reflectionProvider,
@@ -107,7 +107,7 @@ public function __construct(
ObjectTypeSpecifier $objectTypeSpecifier,
array $perNodeTypeResolvers
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
foreach ($perNodeTypeResolvers as $perNodeTypeResolver) {
$this->addPerNodeTypeResolver($perNodeTypeResolver);
@@ -162,15 +162,7 @@ public function isObjectType(Node $node, $requiredType): bool
return true;
}
- if ($resolvedType instanceof UnionType) {
- foreach ($resolvedType->getTypes() as $unionedType) {
- if ($unionedType->equals($requiredType)) {
- return true;
- }
- }
- }
-
- return false;
+ return $this->isMatchingUnionType($requiredType, $resolvedType);
}
public function resolve(Node $node): Type
@@ -231,11 +223,7 @@ public function getStaticType(Node $node): Type
}
if ($node instanceof PropertyFetch) {
- // compensate 3rd party non-analysed property reflection
- $vendorPropertyType = $this->getVendorPropertyFetchType($node);
- if ($vendorPropertyType !== null) {
- return $vendorPropertyType;
- }
+ return $this->resolvePropertyFetchType($node);
}
return $this->objectTypeSpecifier->narrowToFullyQualifiedOrAlaisedObjectType($node, $staticType);
@@ -369,11 +357,7 @@ private function resolveFirstType(Node $node): Type
/** @var Scope|null $nodeScope */
$nodeScope = $node->getAttribute(AttributeKey::SCOPE);
- if ($nodeScope === null) {
- return new MixedType();
- }
-
- if (! $node instanceof Expr) {
+ if ($nodeScope === null || ! $node instanceof Expr) {
return new MixedType();
}
@@ -443,7 +427,7 @@ private function isAnonymousClass(Node $node): bool
return false;
}
- $className = $this->nameResolver->getName($node);
+ $className = $this->nodeNameResolver->getName($node);
return $className === null || Strings::contains($className, 'AnonymousClass');
}
@@ -460,7 +444,7 @@ private function getVendorPropertyFetchType(PropertyFetch $propertyFetch): ?Type
}
// 3rd party code
- $propertyName = $this->nameResolver->getName($propertyFetch->name);
+ $propertyName = $this->nodeNameResolver->getName($propertyFetch->name);
if ($propertyName === null) {
return null;
}
@@ -500,4 +484,30 @@ private function getClassLikeTypesByClassName(string $className): array
return array_unique($classLikeTypes);
}
+
+ private function isMatchingUnionType(Type $requiredType, Type $resolvedType): bool
+ {
+ if (! $resolvedType instanceof UnionType) {
+ return false;
+ }
+ foreach ($resolvedType->getTypes() as $unionedType) {
+ if (! $unionedType->equals($requiredType)) {
+ continue;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+ private function resolvePropertyFetchType(PropertyFetch $propertyFetch)
+ {
+ // compensate 3rd party non-analysed property reflection
+ $vendorPropertyType = $this->getVendorPropertyFetchType($propertyFetch);
+ if ($vendorPropertyType !== null) {
+ return $vendorPropertyType;
+ }
+
+ return new MixedType();
+ }
}
diff --git a/packages/node-type-resolver/src/PHPStan/Type/StaticTypeAnalyzer.php b/packages/node-type-resolver/src/PHPStan/Type/StaticTypeAnalyzer.php
index e5f599bb2783..75594dcecc74 100644
--- a/packages/node-type-resolver/src/PHPStan/Type/StaticTypeAnalyzer.php
+++ b/packages/node-type-resolver/src/PHPStan/Type/StaticTypeAnalyzer.php
@@ -50,17 +50,7 @@ public function isAlwaysTruableType(Type $type): bool
return false;
}
- if ($type instanceof UnionType) {
- foreach ($type->getTypes() as $unionedType) {
- if (! $this->isAlwaysTruableType($unionedType)) {
- return false;
- }
- }
-
- return true;
- }
-
- return true;
+ return $this->isAlwaysTruableUnionType($type);
}
public function isNullable(Type $type): bool
@@ -86,4 +76,19 @@ private function isScalarType(Type $type): bool
return $type instanceof BooleanType || $type instanceof StringType || $type instanceof IntegerType || $type instanceof FloatType;
}
+
+ private function isAlwaysTruableUnionType(Type $type): bool
+ {
+ if (! $type instanceof UnionType) {
+ return false;
+ }
+
+ foreach ($type->getTypes() as $unionedType) {
+ if (! $this->isAlwaysTruableType($unionedType)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
diff --git a/packages/node-type-resolver/src/PerNodeTypeResolver/ParamTypeResolver.php b/packages/node-type-resolver/src/PerNodeTypeResolver/ParamTypeResolver.php
index 86ad6b05905a..e9df4f6e8631 100644
--- a/packages/node-type-resolver/src/PerNodeTypeResolver/ParamTypeResolver.php
+++ b/packages/node-type-resolver/src/PerNodeTypeResolver/ParamTypeResolver.php
@@ -14,7 +14,7 @@
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -26,9 +26,9 @@
final class ParamTypeResolver implements PerNodeTypeResolverInterface
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var CallableNodeTraverser
@@ -40,9 +40,9 @@ final class ParamTypeResolver implements PerNodeTypeResolverInterface
*/
private $nodeTypeResolver;
- public function __construct(NameResolver $nameResolver, CallableNodeTraverser $callableNodeTraverser)
+ public function __construct(NodeNameResolver $nodeNameResolver, CallableNodeTraverser $callableNodeTraverser)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->callableNodeTraverser = $callableNodeTraverser;
}
@@ -83,7 +83,7 @@ public function resolve(Node $node): Type
private function resolveFromType(Node $node)
{
if ($node->type !== null && ! $node->type instanceof Identifier) {
- $resolveTypeName = $this->nameResolver->getName($node->type);
+ $resolveTypeName = $this->nodeNameResolver->getName($node->type);
if ($resolveTypeName) {
// @todo map the other way every type :)
return new ObjectType($resolveTypeName);
@@ -101,7 +101,7 @@ private function resolveFromFirstVariableUse(Param $param): Type
}
/** @var string $paramName */
- $paramName = $this->nameResolver->getName($param);
+ $paramName = $this->nodeNameResolver->getName($param);
$paramStaticType = new MixedType();
// special case for param inside method/function
@@ -112,7 +112,7 @@ function (Node $node) use ($paramName, &$paramStaticType): ?int {
return null;
}
- if (! $this->nameResolver->isName($node, $paramName)) {
+ if (! $this->nodeNameResolver->isName($node, $paramName)) {
return null;
}
@@ -131,7 +131,7 @@ private function resolveFromFunctionDocBlock(Param $param): Type
$parentNode = $param->getAttribute(AttributeKey::PARENT_NODE);
/** @var string $paramName */
- $paramName = $this->nameResolver->getName($param);
+ $paramName = $this->nodeNameResolver->getName($param);
/** @var PhpDocInfo $phpDocInfo */
$phpDocInfo = $parentNode->getAttribute(AttributeKey::PHP_DOC_INFO);
diff --git a/packages/node-type-resolver/src/PerNodeTypeResolver/StaticCallTypeResolver.php b/packages/node-type-resolver/src/PerNodeTypeResolver/StaticCallTypeResolver.php
index a767d555326a..b2f076416cab 100644
--- a/packages/node-type-resolver/src/PerNodeTypeResolver/StaticCallTypeResolver.php
+++ b/packages/node-type-resolver/src/PerNodeTypeResolver/StaticCallTypeResolver.php
@@ -9,7 +9,7 @@
use PHPStan\Analyser\Scope;
use PHPStan\Type\Type;
use PHPStan\Type\TypeUtils;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -22,13 +22,13 @@ final class StaticCallTypeResolver implements PerNodeTypeResolverInterface
private $nodeTypeResolver;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(NameResolver $nameResolver)
+ public function __construct(NodeNameResolver $nodeNameResolver)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -53,7 +53,7 @@ public function getNodeClasses(): array
public function resolve(Node $node): Type
{
$classType = $this->nodeTypeResolver->resolve($node->class);
- $methodName = $this->nameResolver->getName($node->name);
+ $methodName = $this->nodeNameResolver->getName($node->name);
// no specific method found, return class types, e.g. ::$method()
if (! is_string($methodName)) {
diff --git a/packages/node-type-resolver/src/PerNodeTypeResolver/VariableTypeResolver.php b/packages/node-type-resolver/src/PerNodeTypeResolver/VariableTypeResolver.php
index 2b1b9a66c4e8..520835682d53 100644
--- a/packages/node-type-resolver/src/PerNodeTypeResolver/VariableTypeResolver.php
+++ b/packages/node-type-resolver/src/PerNodeTypeResolver/VariableTypeResolver.php
@@ -12,7 +12,7 @@
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Contract\PerNodeTypeResolver\PerNodeTypeResolverInterface;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -24,9 +24,9 @@
final class VariableTypeResolver implements PerNodeTypeResolverInterface
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var NodeTypeResolver
@@ -38,9 +38,9 @@ final class VariableTypeResolver implements PerNodeTypeResolverInterface
*/
private $traitNodeScopeCollector;
- public function __construct(NameResolver $nameResolver, TraitNodeScopeCollector $traitNodeScopeCollector)
+ public function __construct(NodeNameResolver $nodeNameResolver, TraitNodeScopeCollector $traitNodeScopeCollector)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->traitNodeScopeCollector = $traitNodeScopeCollector;
}
@@ -62,7 +62,7 @@ public function resolve(Node $variableNode): Type
return $this->nodeTypeResolver->resolve($parentNode);
}
- $variableName = $this->nameResolver->getName($variableNode);
+ $variableName = $this->nodeNameResolver->getName($variableNode);
if ($variableName === null) {
return new MixedType();
}
@@ -104,40 +104,44 @@ private function resolveTypesFromScope(Variable $variable, string $variableName)
return $nodeScope->getVariableType($variableName);
}
- private function resolveNodeScope(Node $node): ?Scope
+ private function resolveNodeScope(Variable $variable): ?Scope
{
/** @var Scope|null $nodeScope */
- $nodeScope = $node->getAttribute(AttributeKey::SCOPE);
+ $nodeScope = $variable->getAttribute(AttributeKey::SCOPE);
if ($nodeScope !== null) {
return $nodeScope;
}
// is node in trait
- $classNode = $node->getAttribute(AttributeKey::CLASS_NODE);
+ $classNode = $variable->getAttribute(AttributeKey::CLASS_NODE);
if ($classNode instanceof Trait_) {
/** @var string $traitName */
- $traitName = $node->getAttribute(AttributeKey::CLASS_NAME);
- $traitNodeScope = $this->traitNodeScopeCollector->getScopeForTraitAndNode($traitName, $node);
+ $traitName = $variable->getAttribute(AttributeKey::CLASS_NAME);
+ $traitNodeScope = $this->traitNodeScopeCollector->getScopeForTraitAndNode($traitName, $variable);
if ($traitNodeScope !== null) {
return $traitNodeScope;
}
}
- $parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
- if ($parentNode instanceof Node) {
- $parentNodeScope = $parentNode->getAttribute(AttributeKey::SCOPE);
- if ($parentNodeScope !== null) {
- return $parentNodeScope;
+ return $this->resolveFromParentNodes($variable);
+ }
+
+ private function resolveFromParentNodes(Variable $variable): ?Scope
+ {
+ $parentNodeAttributes = [AttributeKey::PARENT_NODE, AttributeKey::METHOD_NODE];
+
+ foreach ($parentNodeAttributes as $parentNodeAttribute) {
+ $parentNode = $variable->getAttribute($parentNodeAttribute);
+ if (! $parentNode instanceof Node) {
+ continue;
}
- }
- // get nearest variable scope
- $method = $node->getAttribute(AttributeKey::METHOD_NODE);
- if ($method instanceof Node) {
- $methodNodeScope = $method->getAttribute(AttributeKey::SCOPE);
- if ($methodNodeScope !== null) {
- return $methodNodeScope;
+ $parentNodeScope = $parentNode->getAttribute(AttributeKey::SCOPE);
+ if ($parentNodeScope === null) {
+ continue;
}
+
+ return $parentNodeScope;
}
return null;
diff --git a/packages/node-type-resolver/src/PhpDoc/NodeAnalyzer/DocBlockNameImporter.php b/packages/node-type-resolver/src/PhpDoc/NodeAnalyzer/DocBlockNameImporter.php
index 47b46be65397..bb7f84d4cb5c 100644
--- a/packages/node-type-resolver/src/PhpDoc/NodeAnalyzer/DocBlockNameImporter.php
+++ b/packages/node-type-resolver/src/PhpDoc/NodeAnalyzer/DocBlockNameImporter.php
@@ -14,7 +14,7 @@
use Rector\CodingStyle\Application\UseAddingCommander;
use Rector\CodingStyle\Imports\ImportSkipper;
use Rector\Core\Configuration\Option;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeTypeResolver\ClassExistenceStaticHelper;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -51,9 +51,9 @@ final class DocBlockNameImporter
private $useAddingCommander;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var BetterStandardPrinter
@@ -74,7 +74,7 @@ public function __construct(
PhpDocNodeTraverser $phpDocNodeTraverser,
StaticTypeMapper $staticTypeMapper,
UseAddingCommander $useAddingCommander,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
BetterStandardPrinter $betterStandardPrinter,
ImportSkipper $importSkipper,
ParameterProvider $parameterProvider
@@ -82,7 +82,7 @@ public function __construct(
$this->phpDocNodeTraverser = $phpDocNodeTraverser;
$this->staticTypeMapper = $staticTypeMapper;
$this->useAddingCommander = $useAddingCommander;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->betterStandardPrinter = $betterStandardPrinter;
$this->importSkipper = $importSkipper;
$this->parameterProvider = $parameterProvider;
@@ -192,7 +192,7 @@ private function isCurrentNamespaceSameShortClassAlreadyUsed(
return true;
}
- $className = $this->nameResolver->getName($classNode);
+ $className = $this->nodeNameResolver->getName($classNode);
if (isset($this->usedShortNameByClasses[$className][$shortenedObjectType->getShortName()])) {
return $this->usedShortNameByClasses[$className][$shortenedObjectType->getShortName()];
diff --git a/packages/node-type-resolver/src/StaticTypeMapper.php b/packages/node-type-resolver/src/StaticTypeMapper.php
index daf0fc2a446f..2eeb6f05fb06 100644
--- a/packages/node-type-resolver/src/StaticTypeMapper.php
+++ b/packages/node-type-resolver/src/StaticTypeMapper.php
@@ -10,6 +10,7 @@
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\NullableType;
+use PhpParser\Node\Stmt\Use_;
use PhpParser\Node\Stmt\UseUse;
use PhpParser\Node\UnionType as PhpParserUnionType;
use PHPStan\Analyser\NameScope;
@@ -21,7 +22,7 @@
use PHPStan\Type\Type;
use Rector\Core\Exception\NotImplementedException;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\PhpDoc\PhpDocTypeMapper;
use Rector\NodeTypeResolver\TypeMapper\PhpParserNodeMapper;
@@ -38,9 +39,9 @@ final class StaticTypeMapper
private $phpStanStaticTypeMapper;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var PhpParserNodeMapper
@@ -54,12 +55,12 @@ final class StaticTypeMapper
public function __construct(
PHPStanStaticTypeMapper $phpStanStaticTypeMapper,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
PhpParserNodeMapper $phpParserNodeMapper,
PhpDocTypeMapper $phpDocTypeMapper
) {
$this->phpStanStaticTypeMapper = $phpStanStaticTypeMapper;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->phpParserNodeMapper = $phpParserNodeMapper;
$this->phpDocTypeMapper = $phpDocTypeMapper;
}
@@ -160,26 +161,37 @@ public function mapPHPStanPhpDocTypeNodeToPHPStanType(TypeNode $typeNode, Node $
private function createNameScopeFromNode(Node $node): NameScope
{
$namespace = $node->getAttribute(AttributeKey::NAMESPACE_NAME);
- $useNodes = $node->getAttribute(AttributeKey::USE_NODES);
-
- $uses = [];
- if ($useNodes) {
- foreach ($useNodes as $useNode) {
- foreach ($useNode->uses as $useUse) {
- /** @var UseUse $useUse */
- $aliasName = $useUse->getAlias()->name;
- $useName = $this->nameResolver->getName($useUse->name);
- if (! is_string($useName)) {
- throw new ShouldNotHappenException();
- }
-
- $uses[$aliasName] = $useName;
- }
- }
- }
+ /** @var Use_[] $useNodes */
+ $useNodes = (array) $node->getAttribute(AttributeKey::USE_NODES);
+
+ $uses = $this->resolveUseNamesByAlias($useNodes);
$className = $node->getAttribute(AttributeKey::CLASS_NAME);
return new NameScope($namespace, $uses, $className);
}
+
+ /***
+ * @param Use_[] $useNodes
+ * @return string[]
+ */
+ private function resolveUseNamesByAlias(array $useNodes): array
+ {
+ $useNamesByAlias = [];
+
+ foreach ($useNodes as $useNode) {
+ foreach ($useNode->uses as $useUse) {
+ /** @var UseUse $useUse */
+ $aliasName = $useUse->getAlias()->name;
+ $useName = $this->nodeNameResolver->getName($useUse->name);
+ if (! is_string($useName)) {
+ throw new ShouldNotHappenException();
+ }
+
+ $useNamesByAlias[$aliasName] = $useName;
+ }
+ }
+
+ return $useNamesByAlias;
+ }
}
diff --git a/packages/node-type-resolver/src/TypeAnalyzer/ArrayTypeAnalyzer.php b/packages/node-type-resolver/src/TypeAnalyzer/ArrayTypeAnalyzer.php
index ddbb740be04b..bc5b2d6f0055 100644
--- a/packages/node-type-resolver/src/TypeAnalyzer/ArrayTypeAnalyzer.php
+++ b/packages/node-type-resolver/src/TypeAnalyzer/ArrayTypeAnalyzer.php
@@ -20,7 +20,7 @@
use PHPStan\Type\Type;
use PHPStan\Type\TypeWithClassName;
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeCorrector\PregMatchTypeCorrector;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -38,9 +38,9 @@ final class ArrayTypeAnalyzer
private $pregMatchTypeCorrector;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ClassManipulator
@@ -50,12 +50,12 @@ final class ArrayTypeAnalyzer
public function __construct(
NodeTypeResolver $nodeTypeResolver,
PregMatchTypeCorrector $pregMatchTypeCorrector,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ClassManipulator $classManipulator
) {
$this->nodeTypeResolver = $nodeTypeResolver;
$this->pregMatchTypeCorrector = $pregMatchTypeCorrector;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->classManipulator = $classManipulator;
}
@@ -120,7 +120,7 @@ private function isPropertyFetchWithArrayDefault(Node $node): bool
return false;
}
- $propertyName = $this->nameResolver->getName($node->name);
+ $propertyName = $this->nodeNameResolver->getName($node->name);
if ($propertyName === null) {
return false;
}
diff --git a/packages/node-type-resolver/tests/NodeVisitor/FunctionMethodAndClassNodeVisitor/FunctionMethodAndClassNodeVisitorTest.php b/packages/node-type-resolver/tests/NodeVisitor/FunctionMethodAndClassNodeVisitor/FunctionMethodAndClassNodeVisitorTest.php
index 145d1dde4187..903d6dfcd1e9 100644
--- a/packages/node-type-resolver/tests/NodeVisitor/FunctionMethodAndClassNodeVisitor/FunctionMethodAndClassNodeVisitorTest.php
+++ b/packages/node-type-resolver/tests/NodeVisitor/FunctionMethodAndClassNodeVisitor/FunctionMethodAndClassNodeVisitorTest.php
@@ -9,7 +9,7 @@
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor\NameResolver;
use Rector\CodingStyle\Naming\ClassNaming;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver as NodeNameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\Testing\PHPUnit\AbstractNodeVisitorTestCase;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeVisitor\FunctionMethodAndClassNodeVisitor;
diff --git a/packages/php-71/src/IsArrayAndDualCheckToAble.php b/packages/php-71/src/IsArrayAndDualCheckToAble.php
index 33f24ece6d23..cbc76c1ab73e 100644
--- a/packages/php-71/src/IsArrayAndDualCheckToAble.php
+++ b/packages/php-71/src/IsArrayAndDualCheckToAble.php
@@ -11,23 +11,23 @@
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Name;
use Rector\Core\PhpParser\Node\Manipulator\BinaryOpManipulator;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
final class IsArrayAndDualCheckToAble
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var BinaryOpManipulator
*/
private $binaryOpManipulator;
- public function __construct(NameResolver $nameResolver, BinaryOpManipulator $binaryOpManipulator)
+ public function __construct(NodeNameResolver $nodeNameResolver, BinaryOpManipulator $binaryOpManipulator)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->binaryOpManipulator = $binaryOpManipulator;
}
@@ -52,7 +52,7 @@ public function processBooleanOr(BooleanOr $booleanOr, string $type, string $new
}
/** @var FuncCall $funcCallNode */
- if ($this->nameResolver->getName($funcCallNode) !== 'is_array') {
+ if ($this->nodeNameResolver->getName($funcCallNode) !== 'is_array') {
return null;
}
diff --git a/packages/php-74/src/Rector/Property/TypedPropertyRector.php b/packages/php-74/src/Rector/Property/TypedPropertyRector.php
index 80425a4902fe..994a198d4b26 100644
--- a/packages/php-74/src/Rector/Property/TypedPropertyRector.php
+++ b/packages/php-74/src/Rector/Property/TypedPropertyRector.php
@@ -16,7 +16,7 @@
use Rector\Core\ValueObject\PhpVersionFeature;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\TypeDeclaration\TypeInferer\PropertyTypeInferer;
-use Rector\TypeDeclaration\VendorLock\VendorLockResolver;
+use Rector\VendorLocker\VendorLockResolver;
/**
* @source https://wiki.php.net/rfc/typed_properties_v2#proposal
diff --git a/packages/php-spec-to-phpunit/src/LetManipulator.php b/packages/php-spec-to-phpunit/src/LetManipulator.php
index a78a99249882..a530576b34fd 100644
--- a/packages/php-spec-to-phpunit/src/LetManipulator.php
+++ b/packages/php-spec-to-phpunit/src/LetManipulator.php
@@ -8,7 +8,7 @@
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
final class LetManipulator
{
@@ -18,21 +18,21 @@ final class LetManipulator
private $betterNodeFinder;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(BetterNodeFinder $betterNodeFinder, NameResolver $nameResolver)
+ public function __construct(BetterNodeFinder $betterNodeFinder, NodeNameResolver $nodeNameResolver)
{
$this->betterNodeFinder = $betterNodeFinder;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
public function isLetNeededInClass(Class_ $class): bool
{
foreach ($class->getMethods() as $method) {
// new test
- if ($this->nameResolver->isName($method, 'test*')) {
+ if ($this->nodeNameResolver->isName($method, 'test*')) {
continue;
}
@@ -43,7 +43,7 @@ function (Node $node): ?bool {
return null;
}
- return $this->nameResolver->isName($node->name, 'beConstructedThrough');
+ return $this->nodeNameResolver->isName($node->name, 'beConstructedThrough');
}
);
diff --git a/packages/php-spec-to-phpunit/src/Naming/PhpSpecRenaming.php b/packages/php-spec-to-phpunit/src/Naming/PhpSpecRenaming.php
index 62649c2a0427..9182b1bbd48c 100644
--- a/packages/php-spec-to-phpunit/src/Naming/PhpSpecRenaming.php
+++ b/packages/php-spec-to-phpunit/src/Naming/PhpSpecRenaming.php
@@ -13,7 +13,7 @@
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Namespace_;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\Util\RectorStrings;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symplify\PackageBuilder\Strings\StringFormatConverter;
@@ -26,19 +26,19 @@ final class PhpSpecRenaming
private $stringFormatConverter;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(StringFormatConverter $stringFormatConverter, NameResolver $nameResolver)
+ public function __construct(StringFormatConverter $stringFormatConverter, NodeNameResolver $nodeNameResolver)
{
$this->stringFormatConverter = $stringFormatConverter;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
public function renameMethod(ClassMethod $classMethod): void
{
- $name = $this->nameResolver->getName($classMethod);
+ $name = $this->nodeNameResolver->getName($classMethod);
if ($name === null) {
return;
}
diff --git a/packages/php-spec-to-phpunit/src/PhpSpecMockCollector.php b/packages/php-spec-to-phpunit/src/PhpSpecMockCollector.php
index c98a78408d1f..2f5590583617 100644
--- a/packages/php-spec-to-phpunit/src/PhpSpecMockCollector.php
+++ b/packages/php-spec-to-phpunit/src/PhpSpecMockCollector.php
@@ -10,7 +10,7 @@
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -32,18 +32,18 @@ final class PhpSpecMockCollector
private $propertyMocksByClass = [];
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var CallableNodeTraverser
*/
private $callableNodeTraverser;
- public function __construct(NameResolver $nameResolver, CallableNodeTraverser $callableNodeTraverser)
+ public function __construct(NodeNameResolver $nodeNameResolver, CallableNodeTraverser $callableNodeTraverser)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->callableNodeTraverser = $callableNodeTraverser;
}
@@ -52,7 +52,7 @@ public function __construct(NameResolver $nameResolver, CallableNodeTraverser $c
*/
public function resolveClassMocksFromParam(Class_ $class): array
{
- $className = $this->nameResolver->getName($class);
+ $className = $this->nodeNameResolver->getName($class);
if (isset($this->mocks[$className])) {
return $this->mocks[$className];
@@ -82,7 +82,7 @@ public function resolveClassMocksFromParam(Class_ $class): array
public function isVariableMockInProperty(Variable $variable): bool
{
- $variableName = $this->nameResolver->getName($variable);
+ $variableName = $this->nodeNameResolver->getName($variable);
$className = $variable->getAttribute(AttributeKey::CLASS_NAME);
return in_array($variableName, $this->propertyMocksByClass[$className] ?? [], true);
@@ -90,7 +90,7 @@ public function isVariableMockInProperty(Variable $variable): bool
public function getTypeForClassAndVariable(Class_ $node, string $variable): string
{
- $className = $this->nameResolver->getName($node);
+ $className = $this->nodeNameResolver->getName($node);
if (! isset($this->mocksWithsTypes[$className][$variable])) {
throw new ShouldNotHappenException();
@@ -106,7 +106,7 @@ public function addPropertyMock(string $class, string $property): void
private function addMockFromParam(Param $param): void
{
- $variable = $this->nameResolver->getName($param->var);
+ $variable = $this->nodeNameResolver->getName($param->var);
/** @var string $class */
$class = $param->getAttribute(AttributeKey::CLASS_NAME);
diff --git a/packages/php-spec-to-phpunit/src/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php b/packages/php-spec-to-phpunit/src/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php
index a42e8d2f2f4a..50c96a57520d 100644
--- a/packages/php-spec-to-phpunit/src/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php
+++ b/packages/php-spec-to-phpunit/src/Rector/MethodCall/PhpSpecPromisesToPHPUnitAssertRector.php
@@ -32,28 +32,13 @@
*/
final class PhpSpecPromisesToPHPUnitAssertRector extends AbstractPhpSpecToPHPUnitRector
{
- /**
- * @var string
- */
- private $testedClass;
-
- /**
- * @var bool
- */
- private $isBoolAssert = false;
-
- /**
- * @var bool
- */
- private $isPrepared = false;
-
/**
* @see https://github.com/phpspec/phpspec/blob/master/src/PhpSpec/Wrapper/Subject.php
* ↓
* @see https://phpunit.readthedocs.io/en/8.0/assertions.html
* @var string[][]
*/
- private $newMethodToOldMethods = [
+ private const NEW_METHOD_TO_OLD_METHODS = [
'assertInstanceOf' => ['shouldBeAnInstanceOf', 'shouldHaveType', 'shouldReturnAnInstanceOf'],
'assertSame' => ['shouldBe', 'shouldReturn'],
'assertNotSame' => ['shouldNotBe', 'shouldNotReturn'],
@@ -90,6 +75,21 @@ final class PhpSpecPromisesToPHPUnitAssertRector extends AbstractPhpSpecToPHPUni
'assertInfinite' => ['shouldBeInfinite', 'shouldNotBeInfinite'],
];
+ /**
+ * @var string
+ */
+ private $testedClass;
+
+ /**
+ * @var bool
+ */
+ private $isBoolAssert = false;
+
+ /**
+ * @var bool
+ */
+ private $isPrepared = false;
+
/**
* @var string[]
*/
@@ -163,22 +163,13 @@ public function refactor(Node $node): ?Node
$this->processMatchersKeys($node);
- foreach ($this->newMethodToOldMethods as $newMethod => $oldMethods) {
+ foreach (self::NEW_METHOD_TO_OLD_METHODS as $newMethod => $oldMethods) {
if ($this->isNames($node->name, $oldMethods)) {
return $this->createAssertMethod($newMethod, $node->var, $node->args[0]->value ?? null);
}
}
- if (! $node->var instanceof Variable) {
- return null;
- }
-
- if (! $this->isName($node->var, 'this')) {
- return null;
- }
-
- // skip "createMock" method
- if ($this->isName($node->name, 'createMock')) {
+ if ($this->shouldSkip($node)) {
return null;
}
@@ -391,4 +382,18 @@ private function thisToTestedObjectPropertyFetch(Expr $expr): Expr
return $this->testedObjectPropertyFetch;
}
+
+ private function shouldSkip(MethodCall $methodCall): bool
+ {
+ if (! $methodCall->var instanceof Variable) {
+ return true;
+ }
+
+ if (! $this->isName($methodCall->var, 'this')) {
+ return true;
+ }
+
+ // skip "createMock" method
+ return $this->isName($methodCall->name, 'createMock');
+ }
}
diff --git a/packages/phpstan/src/Rector/Node/RemoveNonExistingVarAnnotationRector.php b/packages/phpstan/src/Rector/Node/RemoveNonExistingVarAnnotationRector.php
index cf793aaf1975..3be84e3d17c2 100644
--- a/packages/phpstan/src/Rector/Node/RemoveNonExistingVarAnnotationRector.php
+++ b/packages/phpstan/src/Rector/Node/RemoveNonExistingVarAnnotationRector.php
@@ -32,6 +32,24 @@
*/
final class RemoveNonExistingVarAnnotationRector extends AbstractRector
{
+ /**
+ * @var class-string[]
+ */
+ private const NODES_TO_MATCH = [
+ Assign::class,
+ AssignRef::class,
+ Foreach_::class,
+ Static_::class,
+ Echo_::class,
+ Return_::class,
+ Expression::class,
+ Throw_::class,
+ If_::class,
+ While_::class,
+ Switch_::class,
+ Nop::class,
+ ];
+
public function getDefinition(): RectorDefinition
{
return new RectorDefinition('Removes non-existing @var annotations above the code', [
@@ -101,17 +119,14 @@ public function refactor(Node $node): ?Node
private function shouldSkip(Node $node): bool
{
- return ! $node instanceof Assign
- && ! $node instanceof AssignRef
- && ! $node instanceof Foreach_
- && ! $node instanceof Static_
- && ! $node instanceof Echo_
- && ! $node instanceof Return_
- && ! $node instanceof Expression
- && ! $node instanceof Throw_
- && ! $node instanceof If_
- && ! $node instanceof While_
- && ! $node instanceof Switch_
- && ! $node instanceof Nop;
+ foreach (self::NODES_TO_MATCH as $nodeToMatch) {
+ if (! is_a($node, $nodeToMatch, true)) {
+ continue;
+ }
+
+ return false;
+ }
+
+ return true;
}
}
diff --git a/packages/phpunit/src/Manipulator/OnContainerGetCallManipulator.php b/packages/phpunit/src/Manipulator/OnContainerGetCallManipulator.php
index aab0ebf42c4c..2a012c3b82e3 100644
--- a/packages/phpunit/src/Manipulator/OnContainerGetCallManipulator.php
+++ b/packages/phpunit/src/Manipulator/OnContainerGetCallManipulator.php
@@ -11,7 +11,7 @@
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\Class_;
use Rector\Core\PhpParser\Node\Commander\NodeRemovingCommander;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -21,9 +21,9 @@
final class OnContainerGetCallManipulator
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var CallableNodeTraverser
@@ -51,14 +51,14 @@ final class OnContainerGetCallManipulator
private $valueResolver;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
CallableNodeTraverser $callableNodeTraverser,
ServiceNaming $serviceNaming,
NodeRemovingCommander $nodeRemovingCommander,
KernelTestCaseNodeAnalyzer $kernelTestCaseNodeAnalyzer,
ValueResolver $valueResolver
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->callableNodeTraverser = $callableNodeTraverser;
$this->serviceNaming = $serviceNaming;
$this->nodeRemovingCommander = $nodeRemovingCommander;
@@ -81,7 +81,7 @@ public function replaceFormerVariablesWithPropertyFetch(Class_ $class, array $fo
return null;
}
- $variableName = $this->nameResolver->getName($node);
+ $variableName = $this->nodeNameResolver->getName($node);
if ($variableName === null) {
return null;
}
@@ -151,7 +151,7 @@ private function processAssign(
string $type,
array &$formerVariablesByMethods
): void {
- $variableName = $this->nameResolver->getName($assign->var);
+ $variableName = $this->nodeNameResolver->getName($assign->var);
if ($variableName === null) {
return;
}
diff --git a/packages/phpunit/src/Rector/Class_/ArrayArgumentInTestToDataProviderRector.php b/packages/phpunit/src/Rector/Class_/ArrayArgumentInTestToDataProviderRector.php
index 12c2f0d1e3ea..f5b451b2c9c7 100644
--- a/packages/phpunit/src/Rector/Class_/ArrayArgumentInTestToDataProviderRector.php
+++ b/packages/phpunit/src/Rector/Class_/ArrayArgumentInTestToDataProviderRector.php
@@ -77,7 +77,9 @@ public function getDefinition(): RectorDefinition
return new RectorDefinition('Move array argument from tests into data provider [configurable]', [
new ConfiguredCodeSample(
<<<'PHP'
-class SomeServiceTest extends \PHPUnit\Framework\TestCase
+use PHPUnit\Framework\TestCase;
+
+class SomeServiceTest extends TestCase
{
public function test()
{
@@ -87,7 +89,9 @@ public function test()
PHP
,
<<<'PHP'
-class SomeServiceTest extends \PHPUnit\Framework\TestCase
+use PHPUnit\Framework\TestCase;
+
+class SomeServiceTest extends TestCase
{
/**
* @dataProvider provideData()
@@ -134,12 +138,12 @@ public function getNodeTypes(): array
*/
public function refactor(Node $node): ?Node
{
- $this->ensureConfigurationIsSet($this->configuration);
-
if (! $this->isInTestClass($node)) {
return null;
}
+ $this->ensureConfigurationIsSet($this->configuration);
+
$this->dataProviderClassMethodRecipes = [];
$this->traverseNodesWithCallable($node->stmts, function (Node $node) {
@@ -148,53 +152,7 @@ public function refactor(Node $node): ?Node
}
foreach ($this->configuration as $singleConfiguration) {
- if (! $this->isMethodCallMatch($node, $singleConfiguration)) {
- continue;
- }
-
- if (count($node->args) !== 1) {
- throw new ShouldNotHappenException();
- }
-
- // resolve value types
- $firstArgumentValue = $node->args[0]->value;
- if (! $firstArgumentValue instanceof Array_) {
- // nothing we can do
- return null;
- }
-
- // rename method to new one handling non-array input
- $node->name = new Identifier($singleConfiguration['new_method']);
-
- $dataProviderMethodName = $this->createDataProviderMethodName($node);
-
- $this->dataProviderClassMethodRecipes[] = new DataProviderClassMethodRecipe(
- $dataProviderMethodName,
- $node->args,
- $this->resolveUniqueArrayStaticType($firstArgumentValue)
- );
-
- $node->args = [];
- $paramAndArgs = $this->collectParamAndArgsFromArray(
- $firstArgumentValue,
- $singleConfiguration['variable_name']
- );
- foreach ($paramAndArgs as $paramAndArg) {
- $node->args[] = new Arg($paramAndArg->getVariable());
- }
-
- /** @var ClassMethod $classMethod */
- $classMethod = $node->getAttribute(AttributeKey::METHOD_NODE);
- $this->refactorTestClassMethodParams($classMethod, $paramAndArgs);
-
- // add data provider annotation
- $dataProviderTagNode = $this->createDataProviderTagNode($dataProviderMethodName);
-
- /** @var PhpDocInfo $phpDocInfo */
- $phpDocInfo = $classMethod->getAttribute(AttributeKey::PHP_DOC_INFO);
- $phpDocInfo->addPhpDocTagNode($dataProviderTagNode);
-
- return null;
+ $this->refactorMethodCallWithConfiguration($node, $singleConfiguration);
}
return null;
@@ -266,41 +224,13 @@ private function resolveUniqueArrayStaticType(Array_ $array): Type
*/
private function collectParamAndArgsFromArray(Array_ $array, string $variableName): array
{
- // multiple arguments
- $i = 1;
-
- $paramAndArgs = [];
-
$isNestedArray = $this->isNestedArray($array);
-
- $itemsStaticType = $this->resolveItemStaticType($array, $isNestedArray);
-
- if (! $isNestedArray) {
- foreach ($array->items as $arrayItem) {
- $variable = new Variable($variableName . ($i === 1 ? '' : $i));
-
- $paramAndArgs[] = new ParamAndArgValueObject($variable, $itemsStaticType);
- ++$i;
-
- if (! $arrayItem->value instanceof Array_) {
- break;
- }
- }
- } else {
- foreach ($array->items as $arrayItem) {
- /** @var Array_ $nestedArray */
- $nestedArray = $arrayItem->value;
- foreach ($nestedArray->items as $nestedArrayItem) {
- $variable = new Variable($variableName . ($i === 1 ? '' : $i));
-
- $itemsStaticType = $this->getStaticType($nestedArrayItem->value);
- $paramAndArgs[] = new ParamAndArgValueObject($variable, $itemsStaticType);
- ++$i;
- }
- }
+ if ($isNestedArray) {
+ return $this->collectParamAndArgsFromNestedArray($array, $variableName);
}
- return $paramAndArgs;
+ $itemsStaticType = $this->resolveItemStaticType($array, $isNestedArray);
+ return $this->collectParamAndArgsFromNonNestedArray($array, $variableName, $itemsStaticType);
}
/**
@@ -422,4 +352,103 @@ private function createParamTagNode(string $name, TypeNode $typeNode): Attribute
{
return new AttributeAwareParamTagValueNode($typeNode, false, '$' . $name, '', false);
}
+
+ private function refactorMethodCallWithConfiguration(MethodCall $methodCall, array $singleConfiguration): void
+ {
+ if (! $this->isMethodCallMatch($methodCall, $singleConfiguration)) {
+ return;
+ }
+
+ if (count($methodCall->args) !== 1) {
+ throw new ShouldNotHappenException();
+ }
+
+ // resolve value types
+ $firstArgumentValue = $methodCall->args[0]->value;
+ if (! $firstArgumentValue instanceof Array_) {
+ // nothing we can do
+ return;
+ }
+
+ // rename method to new one handling non-array input
+ $methodCall->name = new Identifier($singleConfiguration['new_method']);
+
+ $dataProviderMethodName = $this->createDataProviderMethodName($methodCall);
+
+ $this->dataProviderClassMethodRecipes[] = new DataProviderClassMethodRecipe(
+ $dataProviderMethodName,
+ $methodCall->args,
+ $this->resolveUniqueArrayStaticType($firstArgumentValue)
+ );
+
+ $methodCall->args = [];
+
+ $paramAndArgs = $this->collectParamAndArgsFromArray(
+ $firstArgumentValue,
+ $singleConfiguration['variable_name']
+ );
+
+ foreach ($paramAndArgs as $paramAndArg) {
+ $methodCall->args[] = new Arg($paramAndArg->getVariable());
+ }
+
+ /** @var ClassMethod $classMethod */
+ $classMethod = $methodCall->getAttribute(AttributeKey::METHOD_NODE);
+
+ $this->refactorTestClassMethodParams($classMethod, $paramAndArgs);
+
+ // add data provider annotation
+ $dataProviderTagNode = $this->createDataProviderTagNode($dataProviderMethodName);
+
+ /** @var PhpDocInfo $phpDocInfo */
+ $phpDocInfo = $classMethod->getAttribute(AttributeKey::PHP_DOC_INFO);
+ $phpDocInfo->addPhpDocTagNode($dataProviderTagNode);
+ }
+
+ /**
+ * @return ParamAndArgValueObject[]
+ */
+ private function collectParamAndArgsFromNonNestedArray(
+ Array_ $array,
+ string $variableName,
+ Type $itemsStaticType
+ ): array {
+ $i = 1;
+ $paramAndArgs = [];
+
+ foreach ($array->items as $arrayItem) {
+ $variable = new Variable($variableName . ($i === 1 ? '' : $i));
+
+ $paramAndArgs[] = new ParamAndArgValueObject($variable, $itemsStaticType);
+ ++$i;
+
+ if (! $arrayItem->value instanceof Array_) {
+ break;
+ }
+ }
+
+ return $paramAndArgs;
+ }
+
+ /**
+ * @return ParamAndArgValueObject[]
+ */
+ private function collectParamAndArgsFromNestedArray(Array_ $array, string $variableName): array
+ {
+ $paramAndArgs = [];
+ $i = 1;
+
+ foreach ($array->items as $arrayItem) {
+ /** @var Array_ $nestedArray */
+ $nestedArray = $arrayItem->value;
+ foreach ($nestedArray->items as $nestedArrayItem) {
+ $variable = new Variable($variableName . ($i === 1 ? '' : $i));
+
+ $itemsStaticType = $this->getStaticType($nestedArrayItem->value);
+ $paramAndArgs[] = new ParamAndArgValueObject($variable, $itemsStaticType);
+ ++$i;
+ }
+ }
+ return $paramAndArgs;
+ }
}
diff --git a/packages/polyfill/src/ConditionResolver.php b/packages/polyfill/src/ConditionResolver.php
index 6688036df654..6c17fd47e299 100644
--- a/packages/polyfill/src/ConditionResolver.php
+++ b/packages/polyfill/src/ConditionResolver.php
@@ -12,7 +12,7 @@
use PhpParser\Node\Expr\BinaryOp\NotIdentical;
use PhpParser\Node\Expr\FuncCall;
use Rector\Core\Php\PhpVersionProvider;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\Polyfill\Contract\ConditionInterface;
use Rector\Polyfill\ValueObject\BinaryToVersionCompareCondition;
@@ -21,9 +21,9 @@
final class ConditionResolver
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ValueResolver
@@ -36,11 +36,11 @@ final class ConditionResolver
private $phpVersionProvider;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ValueResolver $valueResolver,
PhpVersionProvider $phpVersionProvider
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->valueResolver = $valueResolver;
$this->phpVersionProvider = $phpVersionProvider;
}
@@ -87,7 +87,7 @@ private function isVersionCompareFuncCall(Node $node): bool
return false;
}
- return $this->nameResolver->isName($node, 'version_compare');
+ return $this->nodeNameResolver->isName($node, 'version_compare');
}
private function resolveVersionCompareConditionForFuncCall(FuncCall $funcCall)
diff --git a/packages/removing-static/src/Printer/FactoryClassPrinter.php b/packages/removing-static/src/Printer/FactoryClassPrinter.php
index e915c2524553..fccdbb7fd77b 100644
--- a/packages/removing-static/src/Printer/FactoryClassPrinter.php
+++ b/packages/removing-static/src/Printer/FactoryClassPrinter.php
@@ -9,7 +9,7 @@
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\Namespace_;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Symfony\Component\Filesystem\Filesystem;
@@ -18,9 +18,9 @@
final class FactoryClassPrinter
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var BetterStandardPrinter
@@ -33,11 +33,11 @@ final class FactoryClassPrinter
private $filesystem;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
BetterStandardPrinter $betterStandardPrinter,
Filesystem $filesystem
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->betterStandardPrinter = $betterStandardPrinter;
$this->filesystem = $filesystem;
}
@@ -69,7 +69,7 @@ private function createFactoryClassFilePath(Class_ $oldClass): string
}
$directoryPath = Strings::before($classFileInfo->getRealPath(), DIRECTORY_SEPARATOR, -1);
- $resolvedOldClass = $this->nameResolver->getName($oldClass);
+ $resolvedOldClass = $this->nodeNameResolver->getName($oldClass);
if ($resolvedOldClass === null) {
throw new ShouldNotHappenException();
}
diff --git a/packages/removing-static/src/UniqueObjectFactoryFactory.php b/packages/removing-static/src/UniqueObjectFactoryFactory.php
index f568ce514f33..f8c5ca6216b7 100644
--- a/packages/removing-static/src/UniqueObjectFactoryFactory.php
+++ b/packages/removing-static/src/UniqueObjectFactoryFactory.php
@@ -22,16 +22,16 @@
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\Naming\PropertyNaming;
use Rector\Core\PhpParser\Node\NodeFactory;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\StaticTypeMapper;
final class UniqueObjectFactoryFactory
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var BuilderFactory
@@ -54,13 +54,13 @@ final class UniqueObjectFactoryFactory
private $nodeFactory;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
BuilderFactory $builderFactory,
PropertyNaming $propertyNaming,
StaticTypeMapper $staticTypeMapper,
NodeFactory $nodeFactory
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->builderFactory = $builderFactory;
$this->propertyNaming = $propertyNaming;
$this->staticTypeMapper = $staticTypeMapper;
@@ -69,7 +69,7 @@ public function __construct(
public function createFactoryClass(Class_ $class, ObjectType $objectType): Class_
{
- $className = $this->nameResolver->getName($class);
+ $className = $this->nodeNameResolver->getName($class);
if ($className === null) {
throw new ShouldNotHappenException();
}
@@ -163,7 +163,7 @@ private function createCreateMethod(Class_ $class, string $className, array $pro
}
foreach ($properties as $property) {
- $propertyName = $this->nameResolver->getName($property);
+ $propertyName = $this->nodeNameResolver->getName($property);
if (! is_string($propertyName)) {
throw new ShouldNotHappenException();
}
diff --git a/packages/sensio/src/Helper/TemplateGuesser.php b/packages/sensio/src/Helper/TemplateGuesser.php
index e0b9d46c72ab..e10b81815037 100644
--- a/packages/sensio/src/Helper/TemplateGuesser.php
+++ b/packages/sensio/src/Helper/TemplateGuesser.php
@@ -7,7 +7,7 @@
use Nette\Utils\Strings;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
@@ -17,13 +17,13 @@
final class TemplateGuesser
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(NameResolver $nameResolver)
+ public function __construct(NodeNameResolver $nodeNameResolver)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
public function resolveFromClassMethodNode(ClassMethod $classMethod, int $version = 5): string
@@ -38,7 +38,7 @@ public function resolveFromClassMethodNode(ClassMethod $classMethod, int $versio
throw new ShouldNotHappenException();
}
- $method = $this->nameResolver->getName($classMethod);
+ $method = $this->nodeNameResolver->getName($classMethod);
if ($method === null) {
throw new ShouldNotHappenException();
}
diff --git a/packages/solid/src/Analyzer/ClassConstantFetchAnalyzer.php b/packages/solid/src/Analyzer/ClassConstantFetchAnalyzer.php
index 0cd2676b942a..393f54946f61 100644
--- a/packages/solid/src/Analyzer/ClassConstantFetchAnalyzer.php
+++ b/packages/solid/src/Analyzer/ClassConstantFetchAnalyzer.php
@@ -9,7 +9,7 @@
use PHPStan\Type\Type;
use PHPStan\Type\TypeUtils;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\Testing\PHPUnit\PHPUnitEnvironment;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -22,9 +22,9 @@ final class ClassConstantFetchAnalyzer
private $classConstantFetchByClassAndName = [];
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var NodeTypeResolver
@@ -38,11 +38,11 @@ final class ClassConstantFetchAnalyzer
public function __construct(
NodeTypeResolver $nodeTypeResolver,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector
) {
$this->nodeTypeResolver = $nodeTypeResolver;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
}
@@ -66,7 +66,7 @@ public function provideClassConstantFetchByClassAndName(): array
private function addClassConstantFetch(ClassConstFetch $classConstFetch): void
{
- $constantName = $this->nameResolver->getName($classConstFetch->name);
+ $constantName = $this->nodeNameResolver->getName($classConstFetch->name);
if ($constantName === 'class' || $constantName === null) {
// this is not a manual constant
@@ -105,7 +105,7 @@ private function matchClassTypeThatContainsConstant(Type $type, string $constant
}
foreach ($classOrInterface->getConstants() as $classConstant) {
- if ($this->nameResolver->isName($classConstant, $constant)) {
+ if ($this->nodeNameResolver->isName($classConstant, $constant)) {
return $className;
}
}
diff --git a/packages/symfony-phpunit/src/Node/KernelTestCaseNodeAnalyzer.php b/packages/symfony-phpunit/src/Node/KernelTestCaseNodeAnalyzer.php
index d4867cc6e453..a75a23dea2b6 100644
--- a/packages/symfony-phpunit/src/Node/KernelTestCaseNodeAnalyzer.php
+++ b/packages/symfony-phpunit/src/Node/KernelTestCaseNodeAnalyzer.php
@@ -6,7 +6,7 @@
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -14,18 +14,18 @@
final class KernelTestCaseNodeAnalyzer
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var NodeTypeResolver
*/
private $nodeTypeResolver;
- public function __construct(NameResolver $nameResolver, NodeTypeResolver $nodeTypeResolver)
+ public function __construct(NodeNameResolver $nodeNameResolver, NodeTypeResolver $nodeTypeResolver)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->nodeTypeResolver = $nodeTypeResolver;
}
@@ -54,7 +54,7 @@ private function isSelfContainerGetMethodCall(Node $node): bool
return false;
}
- if (! $this->nameResolver->isName($node->name, 'get')) {
+ if (! $this->nodeNameResolver->isName($node->name, 'get')) {
return false;
}
diff --git a/packages/symfony/src/Rector/Class_/MakeCommandLazyRector.php b/packages/symfony/src/Rector/Class_/MakeCommandLazyRector.php
index 03e886ee893c..f5d1fdd86990 100644
--- a/packages/symfony/src/Rector/Class_/MakeCommandLazyRector.php
+++ b/packages/symfony/src/Rector/Class_/MakeCommandLazyRector.php
@@ -19,6 +19,7 @@
/**
* @see https://symfony.com/doc/current/console/commands_as_services.html
* @sponsor Thanks https://www.musement.com/ for sponsoring this rule; initiated by https://github.com/stloyd
+ *
* @see \Rector\Symfony\Tests\Rector\Class_\MakeCommandLazyRector\MakeCommandLazyRectorTest
*/
final class MakeCommandLazyRector extends AbstractRector
@@ -88,40 +89,10 @@ public function refactor(Node $node): ?Node
private function resolveCommandNameAndRemove(Class_ $class): ?Node
{
- $commandName = null;
-
- $this->traverseNodesWithCallable((array) $class->stmts, function (Node $node) use (&$commandName) {
- if ($node instanceof MethodCall) {
- if (! $this->isObjectType($node->var, Command::class)) {
- return null;
- }
-
- if (! $this->isName($node->name, 'setName')) {
- return null;
- }
-
- $commandName = $node->args[0]->value;
- $commandNameStaticType = $this->getStaticType($commandName);
- if (! $commandNameStaticType instanceof StringType) {
- return null;
- }
-
- $this->removeNode($node);
- }
-
- if ($node instanceof StaticCall) {
- if (! $this->isObjectType($node->class, Command::class)) {
- return null;
- }
-
- $commandName = $this->matchCommandNameNodeInConstruct($node);
- if ($commandName === null) {
- return null;
- }
-
- array_shift($node->args);
- }
- });
+ $commandName = $this->resolveCommandNameFromConstructor($class);
+ if ($commandName === null) {
+ $commandName = $this->resolveCommandNameFromSetName($class);
+ }
$this->removeConstructorIfHasOnlySetNameMethodCall($class);
@@ -181,4 +152,55 @@ private function removeConstructorIfHasOnlySetNameMethodCall(Class_ $class): voi
$this->removeNode($constructClassMethod);
}
+
+ private function resolveCommandNameFromConstructor(Class_ $class): ?Node
+ {
+ $commandName = null;
+
+ $this->traverseNodesWithCallable((array) $class->stmts, function (Node $node) use (&$commandName) {
+ if (! $node instanceof StaticCall) {
+ return null;
+ }
+ if (! $this->isObjectType($node->class, Command::class)) {
+ return null;
+ }
+
+ $commandName = $this->matchCommandNameNodeInConstruct($node);
+ if ($commandName === null) {
+ return null;
+ }
+
+ array_shift($node->args);
+ });
+
+ return $commandName;
+ }
+
+ private function resolveCommandNameFromSetName(Class_ $class): ?Node
+ {
+ $commandName = null;
+
+ $this->traverseNodesWithCallable((array) $class->stmts, function (Node $node) use (&$commandName) {
+ if (! $node instanceof MethodCall) {
+ return null;
+ }
+ if (! $this->isObjectType($node->var, Command::class)) {
+ return null;
+ }
+
+ if (! $this->isName($node->name, 'setName')) {
+ return null;
+ }
+
+ $commandName = $node->args[0]->value;
+ $commandNameStaticType = $this->getStaticType($commandName);
+ if (! $commandNameStaticType instanceof StringType) {
+ return null;
+ }
+
+ $this->removeNode($node);
+ });
+
+ return $commandName;
+ }
}
diff --git a/packages/type-declaration/src/PhpDocParser/ParamPhpDocNodeFactory.php b/packages/type-declaration/src/PhpDocParser/ParamPhpDocNodeFactory.php
index 7f7536416b16..a2bbb90d5dde 100644
--- a/packages/type-declaration/src/PhpDocParser/ParamPhpDocNodeFactory.php
+++ b/packages/type-declaration/src/PhpDocParser/ParamPhpDocNodeFactory.php
@@ -7,24 +7,24 @@
use PhpParser\Node\Param;
use PHPStan\Type\Type;
use Rector\AttributeAwarePhpDoc\Ast\PhpDoc\AttributeAwareParamTagValueNode;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\StaticTypeMapper;
final class ParamPhpDocNodeFactory
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var StaticTypeMapper
*/
private $staticTypeMapper;
- public function __construct(NameResolver $nameResolver, StaticTypeMapper $staticTypeMapper)
+ public function __construct(NodeNameResolver $nodeNameResolver, StaticTypeMapper $staticTypeMapper)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->staticTypeMapper = $staticTypeMapper;
}
@@ -35,7 +35,7 @@ public function create(Type $type, Param $param): AttributeAwareParamTagValueNod
return new AttributeAwareParamTagValueNode(
$typeNode,
$param->variadic,
- '$' . $this->nameResolver->getName($param),
+ '$' . $this->nodeNameResolver->getName($param),
'',
$param->byRef
);
diff --git a/packages/type-declaration/src/PhpParserTypeAnalyzer.php b/packages/type-declaration/src/PhpParserTypeAnalyzer.php
index 4ec6e74c187c..cf51aff43f2a 100644
--- a/packages/type-declaration/src/PhpParserTypeAnalyzer.php
+++ b/packages/type-declaration/src/PhpParserTypeAnalyzer.php
@@ -34,32 +34,42 @@ public function isSubtypeOf(Node $possibleSubtype, Node $possibleParentType): bo
}
// unwrap nullable types
- if ($possibleParentType instanceof NullableType) {
- $possibleParentType = $possibleParentType->type;
- }
-
- if ($possibleSubtype instanceof NullableType) {
- $possibleSubtype = $possibleSubtype->type;
- }
+ $possibleParentType = $this->unwrapNullableAndToString($possibleParentType);
+ $possibleSubtype = $this->unwrapNullableAndToString($possibleSubtype);
- $possibleSubtype = $possibleSubtype->toString();
- $possibleParentType = $possibleParentType->toString();
if (is_a($possibleSubtype, $possibleParentType, true)) {
return true;
}
- if (in_array($possibleSubtype, ['array', 'Traversable'], true) && $possibleParentType === 'iterable') {
+ if ($this->isTraversableOrIterableSubtype($possibleSubtype, $possibleParentType)) {
return true;
}
- if (in_array($possibleSubtype, ['array', 'ArrayIterator'], true) && $possibleParentType === 'countable') {
+ if ($possibleParentType === $possibleSubtype) {
return true;
}
- if ($possibleParentType === $possibleSubtype) {
+ return ctype_upper($possibleSubtype[0]) && $possibleParentType === 'object';
+ }
+
+ /**
+ * @param Name|NullableType|Identifier $node
+ */
+ private function unwrapNullableAndToString(Node $node): string
+ {
+ if (! $node instanceof NullableType) {
+ return $node->toString();
+ }
+
+ return $node->type->toString();
+ }
+
+ private function isTraversableOrIterableSubtype(string $possibleSubtype, string $possibleParentType): bool
+ {
+ if (in_array($possibleSubtype, ['array', 'Traversable'], true) && $possibleParentType === 'iterable') {
return true;
}
- return ctype_upper($possibleSubtype[0]) && $possibleParentType === 'object';
+ return in_array($possibleSubtype, ['array', 'ArrayIterator'], true) && $possibleParentType === 'countable';
}
}
diff --git a/packages/type-declaration/src/Rector/FunctionLike/AbstractTypeDeclarationRector.php b/packages/type-declaration/src/Rector/FunctionLike/AbstractTypeDeclarationRector.php
index ccf07d3aaeaf..aa80000a3500 100644
--- a/packages/type-declaration/src/Rector/FunctionLike/AbstractTypeDeclarationRector.php
+++ b/packages/type-declaration/src/Rector/FunctionLike/AbstractTypeDeclarationRector.php
@@ -20,7 +20,7 @@
use Rector\NodeTypeResolver\PhpDoc\NodeAnalyzer\DocBlockManipulator;
use Rector\PHPStan\Type\SelfObjectType;
use Rector\TypeDeclaration\PhpParserTypeAnalyzer;
-use Rector\TypeDeclaration\VendorLock\VendorLockResolver;
+use Rector\VendorLocker\VendorLockResolver;
/**
* @see https://wiki.php.net/rfc/scalar_type_hints_v5
diff --git a/packages/type-declaration/src/Rector/FunctionLike/ParamTypeDeclarationRector.php b/packages/type-declaration/src/Rector/FunctionLike/ParamTypeDeclarationRector.php
index 2edc08a6daf1..4380490147b1 100644
--- a/packages/type-declaration/src/Rector/FunctionLike/ParamTypeDeclarationRector.php
+++ b/packages/type-declaration/src/Rector/FunctionLike/ParamTypeDeclarationRector.php
@@ -143,7 +143,7 @@ public function refactor(Node $node): ?Node
}
$position = (int) $position;
- if ($node instanceof ClassMethod && $this->vendorLockResolver->isParameterChangeVendorLockedIn(
+ if ($node instanceof ClassMethod && $this->vendorLockResolver->isParamChangeVendorLockedIn(
$node,
$position
)) {
diff --git a/packages/type-declaration/src/TypeInferer/AbstractTypeInferer.php b/packages/type-declaration/src/TypeInferer/AbstractTypeInferer.php
index 8edca81f5061..caeeb853e65c 100644
--- a/packages/type-declaration/src/TypeInferer/AbstractTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/AbstractTypeInferer.php
@@ -4,7 +4,7 @@
namespace Rector\TypeDeclaration\TypeInferer;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory;
@@ -18,9 +18,9 @@ abstract class AbstractTypeInferer
protected $callableNodeTraverser;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- protected $nameResolver;
+ protected $nodeNameResolver;
/**
* @var NodeTypeResolver
@@ -42,13 +42,13 @@ abstract class AbstractTypeInferer
*/
public function autowireAbstractTypeInferer(
CallableNodeTraverser $callableNodeTraverser,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
StaticTypeMapper $staticTypeMapper,
TypeFactory $typeFactory
): void {
$this->callableNodeTraverser = $callableNodeTraverser;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->staticTypeMapper = $staticTypeMapper;
$this->typeFactory = $typeFactory;
diff --git a/packages/type-declaration/src/TypeInferer/AssignToPropertyTypeInferer.php b/packages/type-declaration/src/TypeInferer/AssignToPropertyTypeInferer.php
index 1293a951cd5e..c723bc32a3e2 100644
--- a/packages/type-declaration/src/TypeInferer/AssignToPropertyTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/AssignToPropertyTypeInferer.php
@@ -59,7 +59,7 @@ public function inferPropertyInClassLike(string $propertyName, ClassLike $classL
private function matchPropertyAssignExpr(Assign $assign, string $propertyName): ?Expr
{
if ($this->isPropertyFetch($assign->var)) {
- if (! $this->nameResolver->isName($assign->var, $propertyName)) {
+ if (! $this->nodeNameResolver->isName($assign->var, $propertyName)) {
return null;
}
@@ -67,7 +67,7 @@ private function matchPropertyAssignExpr(Assign $assign, string $propertyName):
}
if ($assign->var instanceof ArrayDimFetch && $this->isPropertyFetch($assign->var->var)) {
- if (! $this->nameResolver->isName($assign->var->var, $propertyName)) {
+ if (! $this->nodeNameResolver->isName($assign->var->var, $propertyName)) {
return null;
}
diff --git a/packages/type-declaration/src/TypeInferer/ParamTypeInferer/GetterNodeParamTypeInferer.php b/packages/type-declaration/src/TypeInferer/ParamTypeInferer/GetterNodeParamTypeInferer.php
index 7da7894d537a..6b168f2178af 100644
--- a/packages/type-declaration/src/TypeInferer/ParamTypeInferer/GetterNodeParamTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/ParamTypeInferer/GetterNodeParamTypeInferer.php
@@ -42,7 +42,7 @@ public function inferParam(Param $param): Type
$classMethod = $param->getAttribute(AttributeKey::PARENT_NODE);
/** @var string $paramName */
- $paramName = $this->nameResolver->getName($param);
+ $paramName = $this->nodeNameResolver->getName($param);
$propertyNames = $this->propertyFetchManipulator->getPropertyNamesOfAssignOfVariable($classMethod, $paramName);
if ($propertyNames === []) {
diff --git a/packages/type-declaration/src/TypeInferer/ParamTypeInferer/PropertyNodeParamTypeInferer.php b/packages/type-declaration/src/TypeInferer/ParamTypeInferer/PropertyNodeParamTypeInferer.php
index 3535290f5eba..f4c4d9aa9db9 100644
--- a/packages/type-declaration/src/TypeInferer/ParamTypeInferer/PropertyNodeParamTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/ParamTypeInferer/PropertyNodeParamTypeInferer.php
@@ -37,7 +37,7 @@ public function inferParam(Param $param): Type
return new MixedType();
}
- $paramName = $this->nameResolver->getName($param);
+ $paramName = $this->nodeNameResolver->getName($param);
if (! is_string($paramName)) {
throw new ShouldNotHappenException();
}
diff --git a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/AllAssignNodePropertyTypeInferer.php b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/AllAssignNodePropertyTypeInferer.php
index 1159348dbf31..daddaf41af88 100644
--- a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/AllAssignNodePropertyTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/AllAssignNodePropertyTypeInferer.php
@@ -35,7 +35,7 @@ public function inferProperty(Property $property): Type
return new MixedType();
}
- $propertyName = $this->nameResolver->getName($property);
+ $propertyName = $this->nodeNameResolver->getName($property);
if (! is_string($propertyName)) {
throw new ShouldNotHappenException();
}
diff --git a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/ConstructorPropertyTypeInferer.php b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/ConstructorPropertyTypeInferer.php
index c20c1732ca39..f8b21b839e29 100644
--- a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/ConstructorPropertyTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/ConstructorPropertyTypeInferer.php
@@ -53,7 +53,7 @@ public function inferProperty(Property $property): Type
return new MixedType();
}
- $propertyName = $this->nameResolver->getName($property);
+ $propertyName = $this->nodeNameResolver->getName($property);
if (! is_string($propertyName)) {
throw new ShouldNotHappenException();
}
@@ -65,25 +65,7 @@ public function inferProperty(Property $property): Type
// A. infer from type declaration of parameter
if ($param->type !== null) {
- $type = $this->resolveParamTypeToPHPStanType($param);
- if ($type instanceof MixedType) {
- return new MixedType();
- }
-
- $types = [];
-
- // it's an array - annotation → make type more precise, if possible
- if ($type instanceof ArrayType) {
- $types[] = $this->getResolveParamStaticTypeAsPHPStanType($classMethod, $propertyName);
- } else {
- $types[] = $type;
- }
-
- if ($this->isParamNullable($param)) {
- $types[] = new NullType();
- }
-
- return $this->typeFactory->createMixedPassedOrUnionType($types);
+ return $this->resolveFromParamType($param, $classMethod, $propertyName);
}
return new MixedType();
@@ -131,7 +113,7 @@ private function getResolveParamStaticTypeAsPHPStanType(ClassMethod $classMethod
return null;
}
- if (! $this->nameResolver->isName($node, $propertyName)) {
+ if (! $this->nodeNameResolver->isName($node, $propertyName)) {
return null;
}
@@ -165,7 +147,7 @@ private function resolveFullyQualifiedOrAliasedObjectType(Param $param): ?Type
return null;
}
- $fullyQualifiedName = $this->nameResolver->getName($param->type);
+ $fullyQualifiedName = $this->nodeNameResolver->getName($param->type);
if (! $fullyQualifiedName) {
return null;
}
@@ -189,4 +171,27 @@ private function resolveFullyQualifiedOrAliasedObjectType(Param $param): ?Type
return null;
}
+
+ private function resolveFromParamType(Param $param, ClassMethod $classMethod, string $propertyName): Type
+ {
+ $type = $this->resolveParamTypeToPHPStanType($param);
+ if ($type instanceof MixedType) {
+ return new MixedType();
+ }
+
+ $types = [];
+
+ // it's an array - annotation → make type more precise, if possible
+ if ($type instanceof ArrayType) {
+ $types[] = $this->getResolveParamStaticTypeAsPHPStanType($classMethod, $propertyName);
+ } else {
+ $types[] = $type;
+ }
+
+ if ($this->isParamNullable($param)) {
+ $types[] = new NullType();
+ }
+
+ return $this->typeFactory->createMixedPassedOrUnionType($types);
+ }
}
diff --git a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/GetterPropertyTypeInferer.php b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/GetterPropertyTypeInferer.php
index c8460fa4da9b..b734916c3f51 100644
--- a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/GetterPropertyTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/GetterPropertyTypeInferer.php
@@ -55,7 +55,7 @@ public function inferProperty(Property $property): Type
}
/** @var string $propertyName */
- $propertyName = $this->nameResolver->getName($property);
+ $propertyName = $this->nodeNameResolver->getName($property);
foreach ($class->getMethods() as $classMethod) {
if (! $this->hasClassMethodOnlyStatementReturnOfPropertyFetch($classMethod, $propertyName)) {
@@ -97,7 +97,7 @@ private function hasClassMethodOnlyStatementReturnOfPropertyFetch(
return false;
}
- return $this->nameResolver->isName($return->expr, $propertyName);
+ return $this->nodeNameResolver->isName($return->expr, $propertyName);
}
private function inferClassMethodReturnType(ClassMethod $classMethod): Type
diff --git a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/GetterTypeDeclarationPropertyTypeInferer.php b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/GetterTypeDeclarationPropertyTypeInferer.php
index 9ab6484d5968..98b126429b52 100644
--- a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/GetterTypeDeclarationPropertyTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/GetterTypeDeclarationPropertyTypeInferer.php
@@ -39,7 +39,7 @@ public function inferProperty(Property $property): Type
}
/** @var string $propertyName */
- $propertyName = $this->nameResolver->getName($property);
+ $propertyName = $this->nodeNameResolver->getName($property);
foreach ($class->getMethods() as $classMethod) {
if (! $this->hasClassMethodOnlyStatementReturnOfPropertyFetch($classMethod, $propertyName)) {
@@ -87,6 +87,6 @@ private function hasClassMethodOnlyStatementReturnOfPropertyFetch(
return false;
}
- return $this->nameResolver->isName($return->expr, $propertyName);
+ return $this->nodeNameResolver->isName($return->expr, $propertyName);
}
}
diff --git a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/SingleMethodAssignedNodePropertyTypeInferer.php b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/SingleMethodAssignedNodePropertyTypeInferer.php
index 4c3644e3d578..43841375a1d9 100644
--- a/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/SingleMethodAssignedNodePropertyTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/PropertyTypeInferer/SingleMethodAssignedNodePropertyTypeInferer.php
@@ -33,7 +33,7 @@ public function inferProperty(Property $property): Type
return new MixedType();
}
- $propertyName = $this->nameResolver->getName($property);
+ $propertyName = $this->nodeNameResolver->getName($property);
$assignedNode = $this->resolveAssignedNodeToProperty($classMethod, $propertyName);
if ($assignedNode === null) {
@@ -59,7 +59,7 @@ private function resolveAssignedNodeToProperty(ClassMethod $classMethod, string
return null;
}
- if (! $this->nameResolver->isName($node->var, $propertyName)) {
+ if (! $this->nodeNameResolver->isName($node->var, $propertyName)) {
return null;
}
diff --git a/packages/type-declaration/src/TypeInferer/ReturnTypeInferer/ReturnTypeDeclarationReturnTypeInferer.php b/packages/type-declaration/src/TypeInferer/ReturnTypeInferer/ReturnTypeDeclarationReturnTypeInferer.php
index 7449fc9dfeda..12e024438f44 100644
--- a/packages/type-declaration/src/TypeInferer/ReturnTypeInferer/ReturnTypeDeclarationReturnTypeInferer.php
+++ b/packages/type-declaration/src/TypeInferer/ReturnTypeInferer/ReturnTypeDeclarationReturnTypeInferer.php
@@ -30,7 +30,7 @@ public function inferFunctionLike(FunctionLike $functionLike): Type
}
// resolve later with more precise type, e.g. Type[]
- if ($this->nameResolver->isNames($functionLike->getReturnType(), ['array', 'iterable'])) {
+ if ($this->nodeNameResolver->isNames($functionLike->getReturnType(), ['array', 'iterable'])) {
return new MixedType();
}
diff --git a/packages/type-declaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Fixture/symfony_console_command.php.inc b/packages/type-declaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Fixture/symfony_console_command.php.inc
index 57e8b8c6b66f..7687984b57b3 100644
--- a/packages/type-declaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Fixture/symfony_console_command.php.inc
+++ b/packages/type-declaration/tests/Rector/Property/CompleteVarDocTypePropertyRector/Fixture/symfony_console_command.php.inc
@@ -595,7 +595,7 @@ class Command
*/
private $processTitle;
/**
- * @var \Symfony\Component\Console\Input\InputDefinition
+ * @var InputDefinition
*/
private $definition;
/**
diff --git a/packages/vendor-locker/config/config.yaml b/packages/vendor-locker/config/config.yaml
new file mode 100644
index 000000000000..f4b3af24beb3
--- /dev/null
+++ b/packages/vendor-locker/config/config.yaml
@@ -0,0 +1,7 @@
+services:
+ _defaults:
+ public: true
+ autowire: true
+
+ Rector\VendorLocker\:
+ resource: '../src'
diff --git a/packages/vendor-locker/src/Contract/NodeVendorLockerInterface.php b/packages/vendor-locker/src/Contract/NodeVendorLockerInterface.php
new file mode 100644
index 000000000000..8d48221b4268
--- /dev/null
+++ b/packages/vendor-locker/src/Contract/NodeVendorLockerInterface.php
@@ -0,0 +1,12 @@
+nodeNameResolver = $nodeNameResolver;
+ $this->parsedNodeCollector = $parsedNodeCollector;
+ $this->classManipulator = $classManipulator;
+ }
+
+ public function isVendorLocked(ClassMethod $classMethod): bool
+ {
+ $classNode = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
+ if ($classNode === null) {
+ return false;
+ }
+
+ if (! $this->hasParentClassOrImplementsInterface($classNode)) {
+ return false;
+ }
+
+ /** @var string $methodName */
+ $methodName = $this->nodeNameResolver->getName($classMethod);
+
+ // @todo extract to some "inherited parent method" service
+ /** @var string|null $parentClassName */
+ $parentClassName = $classMethod->getAttribute(AttributeKey::PARENT_CLASS_NAME);
+
+ if ($parentClassName !== null) {
+ return $this->isVendorLockedByParentClass($parentClassName, $methodName);
+ }
+
+ $classNode = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
+ if (! $classNode instanceof Class_ && ! $classNode instanceof Interface_) {
+ return false;
+ }
+
+ $interfaceNames = $this->classManipulator->getClassLikeNodeParentInterfaceNames($classNode);
+
+ return $this->isVendorLockedByInterface($interfaceNames, $methodName);
+ }
+
+ private function hasParentClassOrImplementsInterface(ClassLike $classLike): bool
+ {
+ if (($classLike instanceof Class_ || $classLike instanceof Interface_) && $classLike->extends) {
+ return true;
+ }
+
+ if ($classLike instanceof Class_) {
+ return (bool) $classLike->implements;
+ }
+
+ return false;
+ }
+
+ private function isVendorLockedByParentClass(string $parentClassName, string $methodName): bool
+ {
+ $parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
+ if ($parentClassNode !== null) {
+ $parentMethodNode = $parentClassNode->getMethod($methodName);
+ // @todo validate type is conflicting
+ // parent class method in local scope → it's ok
+ if ($parentMethodNode !== null) {
+ return $parentMethodNode->returnType !== null;
+ }
+
+ // if not, look for it's parent parent - @todo recursion
+ }
+
+ if (method_exists($parentClassName, $methodName)) {
+ // @todo validate type is conflicting
+ // parent class method in external scope → it's not ok
+ return true;
+
+ // if not, look for it's parent parent - @todo recursion
+ }
+
+ return false;
+ }
+
+ /**
+ * @param string[] $interfaceNames
+ */
+ private function isVendorLockedByInterface(array $interfaceNames, string $methodName): bool
+ {
+ foreach ($interfaceNames as $interfaceName) {
+ $interface = $this->parsedNodeCollector->findInterface($interfaceName);
+ // parent class method in local scope → it's ok
+ // @todo validate type is conflicting
+ if ($interface !== null && $interface->getMethod($methodName) !== null) {
+ return false;
+ }
+
+ if (method_exists($interfaceName, $methodName)) {
+ // parent class method in external scope → it's not ok
+ // @todo validate type is conflicting
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/packages/type-declaration/src/VendorLock/VendorLockResolver.php b/packages/vendor-locker/src/VendorLockResolver.php
similarity index 56%
rename from packages/type-declaration/src/VendorLock/VendorLockResolver.php
rename to packages/vendor-locker/src/VendorLockResolver.php
index 2c8d23a9c9d9..336215192f24 100644
--- a/packages/type-declaration/src/VendorLock/VendorLockResolver.php
+++ b/packages/vendor-locker/src/VendorLockResolver.php
@@ -2,7 +2,7 @@
declare(strict_types=1);
-namespace Rector\TypeDeclaration\VendorLock;
+namespace Rector\VendorLocker;
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
@@ -10,20 +10,22 @@
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Property;
-use PhpParser\Node\Stmt\PropertyProperty;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use ReflectionClass;
+/**
+ * @todo decouple to standalone package "packages/vendor-locker"
+ */
final class VendorLockResolver
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ClassManipulator
@@ -35,18 +37,26 @@ final class VendorLockResolver
*/
private $parsedNodeCollector;
+ /**
+ * @var ReturnNodeVendorLockResolver
+ */
+ private $returnNodeVendorLockResolver;
+
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector,
- ClassManipulator $classManipulator
+ ClassManipulator $classManipulator,
+ ReturnNodeVendorLockResolver $returnNodeVendorLockResolver
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->classManipulator = $classManipulator;
+ $this->returnNodeVendorLockResolver = $returnNodeVendorLockResolver;
}
- public function isParameterChangeVendorLockedIn(ClassMethod $classMethod, int $paramPosition): bool
+ public function isParamChangeVendorLockedIn(ClassMethod $classMethod, int $paramPosition): bool
{
+ /** @var Class_|null $classNode */
$classNode = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
if ($classNode === null) {
return false;
@@ -56,7 +66,7 @@ public function isParameterChangeVendorLockedIn(ClassMethod $classMethod, int $p
return false;
}
- $methodName = $this->nameResolver->getName($classMethod);
+ $methodName = $this->nodeNameResolver->getName($classMethod);
if (! is_string($methodName)) {
throw new ShouldNotHappenException();
}
@@ -66,25 +76,9 @@ public function isParameterChangeVendorLockedIn(ClassMethod $classMethod, int $p
$parentClassName = $classMethod->getAttribute(AttributeKey::PARENT_CLASS_NAME);
if ($parentClassName !== null) {
- $parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
- if ($parentClassNode !== null) {
- $parentMethodNode = $parentClassNode->getMethod($methodName);
- // @todo validate type is conflicting
- // parent class method in local scope → it's ok
- if ($parentMethodNode !== null) {
- // parent method has no type → we cannot change it here
- return isset($parentMethodNode->params[$paramPosition]) && $parentMethodNode->params[$paramPosition]->type === null;
- }
-
- // if not, look for it's parent parent - @todo recursion
- }
-
- if (method_exists($parentClassName, $methodName)) {
- // @todo validate type is conflicting
- // parent class method in external scope → it's not ok
- return true;
-
- // if not, look for it's parent parent - @todo recursion
+ $vendorLock = $this->isParentClassVendorLocking($paramPosition, $parentClassName, $methodName);
+ if ($vendorLock !== null) {
+ return $vendorLock;
}
}
@@ -94,92 +88,17 @@ public function isParameterChangeVendorLockedIn(ClassMethod $classMethod, int $p
}
$interfaceNames = $this->classManipulator->getClassLikeNodeParentInterfaceNames($classNode);
- foreach ($interfaceNames as $interfaceName) {
- $interface = $this->parsedNodeCollector->findInterface($interfaceName);
- // parent class method in local scope → it's ok
- // @todo validate type is conflicting
- if ($interface !== null && $interface->getMethod($methodName) !== null) {
- return false;
- }
-
- if (method_exists($interfaceName, $methodName)) {
- // parent class method in external scope → it's not ok
- // @todo validate type is conflicting
- return true;
- }
- }
-
- return false;
+ return $this->isInterfaceParamVendorLockin($interfaceNames, $methodName);
}
public function isReturnChangeVendorLockedIn(ClassMethod $classMethod): bool
{
- $classNode = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
- if ($classNode === null) {
- return false;
- }
-
- if (! $this->hasParentClassOrImplementsInterface($classNode)) {
- return false;
- }
-
- $methodName = $this->nameResolver->getName($classMethod);
- if (! is_string($methodName)) {
- throw new ShouldNotHappenException();
- }
-
- // @todo extract to some "inherited parent method" service
- /** @var string|null $parentClassName */
- $parentClassName = $classMethod->getAttribute(AttributeKey::PARENT_CLASS_NAME);
-
- if ($parentClassName !== null) {
- $parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
- if ($parentClassNode !== null) {
- $parentMethodNode = $parentClassNode->getMethod($methodName);
- // @todo validate type is conflicting
- // parent class method in local scope → it's ok
- if ($parentMethodNode !== null) {
- return $parentMethodNode->returnType !== null;
- }
-
- // if not, look for it's parent parent - @todo recursion
- }
-
- if (method_exists($parentClassName, $methodName)) {
- // @todo validate type is conflicting
- // parent class method in external scope → it's not ok
- return true;
-
- // if not, look for it's parent parent - @todo recursion
- }
- }
-
- $classNode = $classMethod->getAttribute(AttributeKey::CLASS_NODE);
- if (! $classNode instanceof Class_ && ! $classNode instanceof Interface_) {
- return false;
- }
-
- $interfaceNames = $this->classManipulator->getClassLikeNodeParentInterfaceNames($classNode);
- foreach ($interfaceNames as $interfaceName) {
- $interface = $this->parsedNodeCollector->findInterface($interfaceName);
- // parent class method in local scope → it's ok
- // @todo validate type is conflicting
- if ($interface !== null && $interface->getMethod($methodName) !== null) {
- return false;
- }
-
- if (method_exists($interfaceName, $methodName)) {
- // parent class method in external scope → it's not ok
- // @todo validate type is conflicting
- return true;
- }
- }
-
- return false;
+ return $this->returnNodeVendorLockResolver->isVendorLocked($classMethod);
}
public function isPropertyChangeVendorLockedIn(Property $property): bool
{
+ /** @var Class_|null $classNode */
$classNode = $property->getAttribute(AttributeKey::CLASS_NODE);
if ($classNode === null) {
return false;
@@ -189,7 +108,8 @@ public function isPropertyChangeVendorLockedIn(Property $property): bool
return false;
}
- $propertyName = $this->nameResolver->getName($property);
+ /** @var string|null $propertyName */
+ $propertyName = $this->nodeNameResolver->getName($property);
if (! is_string($propertyName)) {
throw new ShouldNotHappenException();
}
@@ -199,18 +119,16 @@ public function isPropertyChangeVendorLockedIn(Property $property): bool
$parentClassName = $classNode->getAttribute(AttributeKey::PARENT_CLASS_NAME);
if ($parentClassName !== null) {
- $parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
- if ($parentClassNode !== null) {
- $parentPropertyNode = $this->getProperty($parentClassNode, $propertyName);
- // @todo validate type is conflicting
- // parent class property in local scope → it's ok
- if ($parentPropertyNode !== null) {
- return $parentPropertyNode->type !== null;
- }
+ $parentClassProperty = $this->findParentProperty($parentClassName, $propertyName);
- // if not, look for it's parent parent - @todo recursion
+ // @todo validate type is conflicting
+ // parent class property in local scope → it's ok
+ if ($parentClassProperty !== null) {
+ return $parentClassProperty->type !== null;
}
+ // if not, look for it's parent parent - @todo recursion
+
if (property_exists($parentClassName, $propertyName)) {
// @todo validate type is conflicting
// parent class property in external scope → it's not ok
@@ -233,7 +151,7 @@ public function isPropertyChangeVendorLockedIn(Property $property): bool
*/
public function isClassMethodRemovalVendorLocked(ClassMethod $classMethod): bool
{
- $classMethodName = $this->nameResolver->getName($classMethod);
+ $classMethodName = $this->nodeNameResolver->getName($classMethod);
if (! is_string($classMethodName)) {
throw new ShouldNotHappenException();
}
@@ -244,22 +162,7 @@ public function isClassMethodRemovalVendorLocked(ClassMethod $classMethod): bool
return false;
}
- // required by interface?
- foreach ($class->implements as $implement) {
- $implementedInterfaceName = $this->nameResolver->getName($implement);
- if (! is_string($implementedInterfaceName)) {
- throw new ShouldNotHappenException();
- }
-
- if (! interface_exists($implementedInterfaceName)) {
- continue;
- }
-
- $interfaceMethods = get_class_methods($implementedInterfaceName);
- if (! in_array($classMethodName, $interfaceMethods, true)) {
- continue;
- }
-
+ if ($this->isVendorLockedByInterface($class, $classMethodName)) {
return true;
}
@@ -309,15 +212,97 @@ private function hasParentClassOrImplementsInterface(Node $classNode): bool
private function getProperty(ClassLike $classLike, string $name)
{
$lowerName = strtolower($name);
- foreach ($classLike->stmts as $stmt) {
- if ($stmt instanceof Property) {
- foreach ($stmt->props as $prop) {
- if ($prop instanceof PropertyProperty && $lowerName === $prop->name->toLowerString()) {
- return $stmt;
- }
+
+ foreach ($classLike->getProperties() as $property) {
+ foreach ($property->props as $propertyProperty) {
+ if ($lowerName !== $propertyProperty->name->toLowerString()) {
+ continue;
}
+
+ return $property;
+ }
+ }
+
+ return null;
+ }
+
+ private function findParentProperty(string $parentClassName, string $propertyName): ?Property
+ {
+ $parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
+ if ($parentClassNode === null) {
+ return null;
+ }
+
+ return $this->getProperty($parentClassNode, $propertyName);
+ }
+
+ private function isVendorLockedByInterface(Class_ $class, string $classMethodName): bool
+ {
+ // required by interface?
+ foreach ($class->implements as $implement) {
+ $implementedInterfaceName = $this->nodeNameResolver->getName($implement);
+ if (! is_string($implementedInterfaceName)) {
+ throw new ShouldNotHappenException();
+ }
+
+ if (! interface_exists($implementedInterfaceName)) {
+ continue;
}
+
+ $interfaceMethods = get_class_methods($implementedInterfaceName);
+ if (! in_array($classMethodName, $interfaceMethods, true)) {
+ continue;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ private function isParentClassVendorLocking(int $paramPosition, string $parentClassName, string $methodName): ?bool
+ {
+ $parentClassNode = $this->parsedNodeCollector->findClass($parentClassName);
+ if ($parentClassNode !== null) {
+ $parentMethodNode = $parentClassNode->getMethod($methodName);
+ // @todo validate type is conflicting
+ // parent class method in local scope → it's ok
+ if ($parentMethodNode !== null) {
+ // parent method has no type → we cannot change it here
+ return isset($parentMethodNode->params[$paramPosition]) && $parentMethodNode->params[$paramPosition]->type === null;
+ }
+ }
+
+ // if not, look for it's parent parent - @todo recursion
+
+ if (method_exists($parentClassName, $methodName)) {
+ // @todo validate type is conflicting
+ // parent class method in external scope → it's not ok
+ return true;
+
+ // if not, look for it's parent parent - @todo recursion
}
+
return null;
}
+
+ private function isInterfaceParamVendorLockin(array $interfaceNames, string $methodName): bool
+ {
+ foreach ($interfaceNames as $interfaceName) {
+ $interface = $this->parsedNodeCollector->findInterface($interfaceName);
+ // parent class method in local scope → it's ok
+ // @todo validate type is conflicting
+ if ($interface !== null && $interface->getMethod($methodName) !== null) {
+ return false;
+ }
+
+ if (method_exists($interfaceName, $methodName)) {
+ // parent class method in external scope → it's not ok
+ // @todo validate type is conflicting
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/packages/zend-to-symfony/src/Detector/ZendDetector.php b/packages/zend-to-symfony/src/Detector/ZendDetector.php
index a4171aaf6a91..8cbcf610079e 100644
--- a/packages/zend-to-symfony/src/Detector/ZendDetector.php
+++ b/packages/zend-to-symfony/src/Detector/ZendDetector.php
@@ -7,7 +7,7 @@
use PhpParser\Node;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassMethod;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Rector\ZendToSymfony\ValueObject\ZendClass;
@@ -20,14 +20,14 @@ final class ZendDetector
private $nodeTypeResolver;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(NodeTypeResolver $nodeTypeResolver, NameResolver $nameResolver)
+ public function __construct(NodeTypeResolver $nodeTypeResolver, NodeNameResolver $nodeNameResolver)
{
$this->nodeTypeResolver = $nodeTypeResolver;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
public function isInZendController(Node $node): bool
@@ -50,6 +50,6 @@ public function isZendActionMethod(ClassMethod $classMethod): bool
return false;
}
- return $this->nameResolver->isName($classMethod, '*Action');
+ return $this->nodeNameResolver->isName($classMethod, '*Action');
}
}
diff --git a/packages/zend-to-symfony/src/Rector/ClassMethod/ThisViewToThisRenderResponseRector.php b/packages/zend-to-symfony/src/Rector/ClassMethod/ThisViewToThisRenderResponseRector.php
index e4afd4b1488d..53dffca7ec24 100644
--- a/packages/zend-to-symfony/src/Rector/ClassMethod/ThisViewToThisRenderResponseRector.php
+++ b/packages/zend-to-symfony/src/Rector/ClassMethod/ThisViewToThisRenderResponseRector.php
@@ -58,9 +58,9 @@ public function someAction()
{
$templateData = [];
$templateData['value']; = 5;
-
+
return $this->render("...", $templateData);
-}
+}
PHP
)]
);
diff --git a/packages/zend-to-symfony/src/Resolver/ControllerMethodParamResolver.php b/packages/zend-to-symfony/src/Resolver/ControllerMethodParamResolver.php
index 403438e46485..b2df69471c7a 100644
--- a/packages/zend-to-symfony/src/Resolver/ControllerMethodParamResolver.php
+++ b/packages/zend-to-symfony/src/Resolver/ControllerMethodParamResolver.php
@@ -10,7 +10,7 @@
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Exception\NotImplementedException;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -22,14 +22,14 @@ final class ControllerMethodParamResolver
private $callableNodeTraverser;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(CallableNodeTraverser $callableNodeTraverser, NameResolver $nameResolver)
+ public function __construct(CallableNodeTraverser $callableNodeTraverser, NodeNameResolver $nodeNameResolver)
{
$this->callableNodeTraverser = $callableNodeTraverser;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -45,11 +45,11 @@ public function resolve(ClassMethod $classMethod): array
return null;
}
- if (! $this->nameResolver->isName($node->var, 'this')) {
+ if (! $this->nodeNameResolver->isName($node->var, 'this')) {
return null;
}
- if (! $this->nameResolver->isName($node->name, 'getParam')) {
+ if (! $this->nodeNameResolver->isName($node->name, 'getParam')) {
return null;
}
diff --git a/phpstan.neon b/phpstan.neon
index 8e1703cf66e1..40a5fef20916 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -240,3 +240,4 @@ parameters:
- '#Method Rector\\SOLID\\Reflection\\ParentConstantReflectionResolver\:\:(.*?)\(\) should return ReflectionClassConstant\|null but returns ReflectionClassConstant\|false#'
- '#Method Rector\\Core\\NodeContainer\\NodeCollector\\ParsedFunctionLikeNodesByType\:\:findFunction\(\) should return PhpParser\\Node\\Stmt\\Function_\|null but returns PhpParser\\Node\|null#'
+ - '#Parameter \#1 \$firstStmt of method Rector\\Core\\Rector\\MethodBody\\NormalToFluentRector\:\:isBothMethodCallMatch\(\) expects PhpParser\\Node\\Stmt\\Expression, PhpParser\\Node\\Stmt given#'
diff --git a/src/Console/Command/ScreenFileCommand.php b/src/Console/Command/ScreenFileCommand.php
index 41dc53263e93..dc4b923e0dc7 100644
--- a/src/Console/Command/ScreenFileCommand.php
+++ b/src/Console/Command/ScreenFileCommand.php
@@ -19,7 +19,7 @@
use PhpParser\Node\Stmt\Return_;
use PHPStan\Type\TypeUtils;
use Rector\Core\Console\Shell;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\FileSystemRector\Parser\FileInfoParser;
@@ -56,9 +56,9 @@ final class ScreenFileCommand extends AbstractCommand
private $callableNodeTraverser;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var NodeTypeResolver
@@ -79,7 +79,7 @@ public function __construct(
SymfonyStyle $symfonyStyle,
FileInfoParser $fileInfoParser,
CallableNodeTraverser $callableNodeTraverser,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
BetterStandardPrinter $betterStandardPrinter,
StaticTypeMapper $staticTypeMapper
@@ -87,7 +87,7 @@ public function __construct(
$this->symfonyStyle = $symfonyStyle;
$this->fileInfoParser = $fileInfoParser;
$this->callableNodeTraverser = $callableNodeTraverser;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->betterStandardPrinter = $betterStandardPrinter;
$this->staticTypeMapper = $staticTypeMapper;
@@ -172,34 +172,12 @@ private function decorateNodeData(Node $node, array $data = []): array
$data = $this->decorateClassLike($node, $data);
}
- if ($node instanceof Variable) {
- $data['name'] = $this->nameResolver->getName($node);
- }
-
if ($node instanceof Assign) {
$data = $this->decorateAssign($node, $data);
}
- if ($node instanceof Namespace_ && $node->name !== null) {
- $data['name'] = $this->nameResolver->getName($node->name);
- }
-
- if ($node instanceof FuncCall && $node->name !== null) {
- $data['name'] = $this->nameResolver->getName($node->name);
- }
-
- if ($node instanceof Variable) {
- $staticType = $this->nodeTypeResolver->getStaticType($node);
-
- $classNames = TypeUtils::getDirectClassNames($staticType);
- if ($classNames !== []) {
- $objectTypesAsString = implode(', ', $classNames);
- $data['variable_types'] = $objectTypesAsString;
- } else {
- $typeString = $this->staticTypeMapper->mapPHPStanTypeToDocString($staticType);
- $data['variable_types'] = $typeString;
- }
- }
+ $data = $this->addNameData($node, $data);
+ $data = $this->addVariableTypeData($node, $data);
if ($node instanceof Return_) {
$data = $this->decorateReturn($node, $data);
@@ -264,7 +242,7 @@ private function decorateWithNodeType(Node $node, array $data): array
*/
private function decorateClassLike(ClassLike $classLike, array $data): array
{
- $data['name'] = $this->nameResolver->getName($classLike);
+ $data['name'] = $this->nodeNameResolver->getName($classLike);
$parentClassName = $classLike->getAttribute(AttributeKey::PARENT_CLASS_NAME);
if ($parentClassName) {
@@ -318,8 +296,42 @@ private function getObjectShortClass($object): string
private function decorateMethodCall(MethodCall $methodCall, array $data): array
{
$data['method_call_variable'] = $this->decorateNodeData($methodCall->var);
- $data['method_call_name'] = $this->nameResolver->getName($methodCall->name);
+ $data['method_call_name'] = $this->nodeNameResolver->getName($methodCall->name);
+
+ return $data;
+ }
+
+ private function addNameData(Node $node, array $data): array
+ {
+ if ($node instanceof Variable) {
+ $data['name'] = $this->nodeNameResolver->getName($node);
+ }
+ if ($node instanceof Namespace_ && $node->name !== null) {
+ $data['name'] = $this->nodeNameResolver->getName($node->name);
+ }
+
+ if ($node instanceof FuncCall && $node->name !== null) {
+ $data['name'] = $this->nodeNameResolver->getName($node->name);
+ }
+
+ return $data;
+ }
+
+ private function addVariableTypeData(Node $node, array $data): array
+ {
+ if ($node instanceof Variable) {
+ $staticType = $this->nodeTypeResolver->getStaticType($node);
+
+ $classNames = TypeUtils::getDirectClassNames($staticType);
+ if ($classNames !== []) {
+ $objectTypesAsString = implode(', ', $classNames);
+ $data['variable_types'] = $objectTypesAsString;
+ } else {
+ $typeString = $this->staticTypeMapper->mapPHPStanTypeToDocString($staticType);
+ $data['variable_types'] = $typeString;
+ }
+ }
return $data;
}
}
diff --git a/src/Contract/NameResolver/NodeNameResolverInterface.php b/src/Contract/NameResolver/NodeNameResolverInterface.php
new file mode 100644
index 000000000000..f560b96a2167
--- /dev/null
+++ b/src/Contract/NameResolver/NodeNameResolverInterface.php
@@ -0,0 +1,14 @@
+nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -100,7 +100,7 @@ public function collect(Node $node): void
}
if ($node instanceof Function_) {
- $functionName = $this->nameResolver->getName($node);
+ $functionName = $this->nodeNameResolver->getName($node);
if ($functionName === null) {
return;
}
@@ -153,7 +153,7 @@ private function addMethod(ClassMethod $classMethod): void
return;
}
- $methodName = $this->nameResolver->getName($classMethod);
+ $methodName = $this->nodeNameResolver->getName($classMethod);
$this->methodsByType[$className][$methodName] = $classMethod;
}
@@ -204,17 +204,9 @@ private function matchArrayCallableClassAndMethod(Array_ $array): ?array
private function addCall(Node $node): void
{
// one node can be of multiple-class types
- if ($node instanceof MethodCall) {
- if ($node->var instanceof MethodCall) {
- $classType = $this->resolveNodeClassTypes($node);
- } else {
- $classType = $this->resolveNodeClassTypes($node->var);
- }
- } else {
- $classType = $this->resolveNodeClassTypes($node->class);
- }
+ $classType = $this->resolveClassType($node);
- $methodName = $this->nameResolver->getName($node);
+ $methodName = $this->nodeNameResolver->getName($node);
if ($classType instanceof MixedType) { // anonymous
return;
}
@@ -241,17 +233,17 @@ private function addCall(Node $node): void
private function isThisVariable(Node $node): bool
{
// $this
- if ($node instanceof Variable && $this->nameResolver->isName($node, 'this')) {
+ if ($node instanceof Variable && $this->nodeNameResolver->isName($node, 'this')) {
return true;
}
if ($node instanceof ClassConstFetch) {
- if (! $this->nameResolver->isName($node->name, 'class')) {
+ if (! $this->nodeNameResolver->isName($node->name, 'class')) {
return false;
}
// self::class, static::class
- if ($this->nameResolver->isNames($node->class, ['self', 'static'])) {
+ if ($this->nodeNameResolver->isNames($node->class, ['self', 'static'])) {
return true;
}
@@ -262,7 +254,7 @@ private function isThisVariable(Node $node): bool
return false;
}
- return $this->nameResolver->isName($node->class, $className);
+ return $this->nodeNameResolver->isName($node->class, $className);
}
return false;
@@ -287,4 +279,20 @@ private function resolveNodeClassTypes(Node $node): Type
return $this->nodeTypeResolver->resolve($node);
}
+
+ /**
+ * @param MethodCall|StaticCall $node
+ */
+ private function resolveClassType(Node $node): Type
+ {
+ if ($node instanceof MethodCall) {
+ if ($node->var instanceof MethodCall) {
+ return $this->resolveNodeClassTypes($node);
+ }
+
+ return $this->resolveNodeClassTypes($node->var);
+ }
+
+ return $this->resolveNodeClassTypes($node->class);
+ }
}
diff --git a/src/NodeContainer/NodeCollector/ParsedNodeCollector.php b/src/NodeContainer/NodeCollector/ParsedNodeCollector.php
index 29837adfdc91..b165e301abfa 100644
--- a/src/NodeContainer/NodeCollector/ParsedNodeCollector.php
+++ b/src/NodeContainer/NodeCollector/ParsedNodeCollector.php
@@ -20,7 +20,7 @@
use PhpParser\Node\Stmt\Trait_;
use Rector\Core\Exception\NotImplementedException;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
@@ -64,9 +64,9 @@ final class ParsedNodeCollector
private $simpleParsedNodesByType = [];
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var Interface_[]
@@ -78,9 +78,9 @@ final class ParsedNodeCollector
*/
private $traits = [];
- public function __construct(NameResolver $nameResolver)
+ public function __construct(NodeNameResolver $nodeNameResolver)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -182,7 +182,7 @@ public function collect(Node $node): void
}
if ($node instanceof Interface_ || $node instanceof Trait_) {
- $name = $this->nameResolver->getName($node);
+ $name = $this->nodeNameResolver->getName($node);
if ($name === null) {
throw new ShouldNotHappenException();
}
@@ -216,7 +216,7 @@ public function findNewNodesByClass(string $className): array
$news = $this->getNodesByType(New_::class);
foreach ($news as $new) {
- if (! $this->nameResolver->isName($new->class, $className)) {
+ if (! $this->nodeNameResolver->isName($new->class, $className)) {
continue;
}
@@ -228,7 +228,7 @@ public function findNewNodesByClass(string $className): array
public function findClassConstantByClassConstFetch(ClassConstFetch $classConstFetch): ?ClassConst
{
- $class = $this->nameResolver->getName($classConstFetch->class);
+ $class = $this->nodeNameResolver->getName($classConstFetch->class);
if ($class === 'self') {
/** @var string|null $class */
@@ -243,7 +243,7 @@ public function findClassConstantByClassConstFetch(ClassConstFetch $classConstFe
}
/** @var string $constantName */
- $constantName = $this->nameResolver->getName($classConstFetch->name);
+ $constantName = $this->nodeNameResolver->getName($classConstFetch->name);
return $this->findClassConstant($class, $constantName);
}
@@ -270,7 +270,7 @@ private function addClassConstant(ClassConst $classConst): void
return;
}
- $constantName = $this->nameResolver->getName($classConst);
+ $constantName = $this->nodeNameResolver->getName($classConst);
$this->constantsByType[$className][$constantName] = $classConst;
}
diff --git a/src/NodeContainer/NodeFinder/ClassLikeParsedNodesFinder.php b/src/NodeContainer/NodeFinder/ClassLikeParsedNodesFinder.php
index 2dd278096639..093b2c07ffbc 100644
--- a/src/NodeContainer/NodeFinder/ClassLikeParsedNodesFinder.php
+++ b/src/NodeContainer/NodeFinder/ClassLikeParsedNodesFinder.php
@@ -10,7 +10,7 @@
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\Trait_;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ClassLikeParsedNodesFinder
@@ -21,14 +21,14 @@ final class ClassLikeParsedNodesFinder
private $parsedNodeCollector;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(ParsedNodeCollector $parsedNodeCollector, NameResolver $nameResolver)
+ public function __construct(ParsedNodeCollector $parsedNodeCollector, NodeNameResolver $nodeNameResolver)
{
$this->parsedNodeCollector = $parsedNodeCollector;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -82,7 +82,7 @@ public function findUsedTraitsInClass(ClassLike $classLike): array
foreach ($classLike->getTraitUses() as $traitUse) {
foreach ($traitUse->traits as $trait) {
- $traitName = $this->nameResolver->getName($trait);
+ $traitName = $this->nodeNameResolver->getName($trait);
if ($traitName === null) {
continue;
}
diff --git a/src/NodeContainer/NodeFinder/FunctionLikeParsedNodesFinder.php b/src/NodeContainer/NodeFinder/FunctionLikeParsedNodesFinder.php
index fe4f61872d71..dd0438cfb017 100644
--- a/src/NodeContainer/NodeFinder/FunctionLikeParsedNodesFinder.php
+++ b/src/NodeContainer/NodeFinder/FunctionLikeParsedNodesFinder.php
@@ -12,7 +12,7 @@
use PhpParser\Node\Stmt\Function_;
use PHPStan\Type\TypeUtils;
use Rector\Core\NodeContainer\NodeCollector\ParsedFunctionLikeNodeCollector;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use ReflectionClass;
@@ -20,9 +20,9 @@
final class FunctionLikeParsedNodesFinder
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var NodeTypeResolver
@@ -35,11 +35,11 @@ final class FunctionLikeParsedNodesFinder
private $parsedFunctionLikeNodeCollector;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
ParsedFunctionLikeNodeCollector $parsedFunctionLikeNodeCollector
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->nodeTypeResolver = $nodeTypeResolver;
$this->parsedFunctionLikeNodeCollector = $parsedFunctionLikeNodeCollector;
}
@@ -52,7 +52,7 @@ public function findClassMethodByMethodCall(MethodCall $methodCall): ?ClassMetho
return null;
}
- $methodName = $this->nameResolver->getName($methodCall->name);
+ $methodName = $this->nodeNameResolver->getName($methodCall->name);
if ($methodName === null) {
return null;
}
@@ -62,7 +62,7 @@ public function findClassMethodByMethodCall(MethodCall $methodCall): ?ClassMetho
public function findClassMethodByStaticCall(StaticCall $staticCall): ?ClassMethod
{
- $methodName = $this->nameResolver->getName($staticCall->name);
+ $methodName = $this->nodeNameResolver->getName($staticCall->name);
if ($methodName === null) {
return null;
}
@@ -135,7 +135,7 @@ public function findClassMethodCalls(ClassMethod $classMethod): array
}
/** @var string|null $methodName */
- $methodName = $this->nameResolver->getName($classMethod);
+ $methodName = $this->nodeNameResolver->getName($classMethod);
if ($methodName === null) {
return [];
}
diff --git a/src/PHPStan/Reflection/CallReflectionResolver.php b/src/PHPStan/Reflection/CallReflectionResolver.php
index 046f52e256ef..952b8b684de2 100644
--- a/src/PHPStan/Reflection/CallReflectionResolver.php
+++ b/src/PHPStan/Reflection/CallReflectionResolver.php
@@ -25,7 +25,7 @@
use PHPStan\Type\Constant\ConstantStringType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\ObjectWithoutClassType;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -51,18 +51,18 @@ final class CallReflectionResolver
private $nodeTypeResolver;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
public function __construct(
ReflectionProvider $reflectionProvider,
NodeTypeResolver $nodeTypeResolver,
- NameResolver $nameResolver
+ NodeNameResolver $nodeNameResolver
) {
$this->reflectionProvider = $reflectionProvider;
$this->nodeTypeResolver = $nodeTypeResolver;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -132,7 +132,7 @@ public function resolveMethodCall(Node $node): ?MethodReflection
}
$classType = $this->nodeTypeResolver->resolve($node instanceof MethodCall ? $node->var : $node->class);
- $methodName = $this->nameResolver->getName($node->name);
+ $methodName = $this->nodeNameResolver->getName($node->name);
if ($methodName === null || ! $classType->hasMethod($methodName)->yes()) {
return null;
diff --git a/src/Php/Regex/RegexPatternArgumentManipulator.php b/src/Php/Regex/RegexPatternArgumentManipulator.php
index 10c0a704d5a0..3bbb56067c9d 100644
--- a/src/Php/Regex/RegexPatternArgumentManipulator.php
+++ b/src/Php/Regex/RegexPatternArgumentManipulator.php
@@ -15,7 +15,7 @@
use PhpParser\Node\Scalar\String_;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -53,9 +53,9 @@ final class RegexPatternArgumentManipulator
private $nodeTypeResolver;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var BetterNodeFinder
@@ -74,13 +74,13 @@ final class RegexPatternArgumentManipulator
public function __construct(
NodeTypeResolver $nodeTypeResolver,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector,
BetterNodeFinder $betterNodeFinder,
BetterStandardPrinter $betterStandardPrinter
) {
$this->nodeTypeResolver = $nodeTypeResolver;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->betterNodeFinder = $betterNodeFinder;
$this->betterStandardPrinter = $betterStandardPrinter;
@@ -108,7 +108,7 @@ public function matchCallArgumentWithRegexPattern(Expr $expr): array
private function processFuncCall(FuncCall $funcCall): array
{
foreach ($this->functionsWithPatternsToArgumentPosition as $functionName => $argumentPosition) {
- if (! $this->nameResolver->isName($funcCall, $functionName)) {
+ if (! $this->nodeNameResolver->isName($funcCall, $functionName)) {
continue;
}
@@ -133,7 +133,7 @@ private function processStaticCall(StaticCall $staticCall): array
}
foreach ($methodNamesToArgumentPosition as $methodName => $argumentPosition) {
- if (! $this->nameResolver->isName($staticCall, $methodName)) {
+ if (! $this->nodeNameResolver->isName($staticCall, $methodName)) {
continue;
}
diff --git a/src/PhpParser/Node/Manipulator/AssignManipulator.php b/src/PhpParser/Node/Manipulator/AssignManipulator.php
index 1978b056855d..98b42286e267 100644
--- a/src/PhpParser/Node/Manipulator/AssignManipulator.php
+++ b/src/PhpParser/Node/Manipulator/AssignManipulator.php
@@ -10,24 +10,24 @@
use PhpParser\Node\Expr\Assign;
use PhpParser\Node\Expr\FuncCall;
use PhpParser\Node\Expr\List_;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class AssignManipulator
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var PropertyFetchManipulator
*/
private $propertyFetchManipulator;
- public function __construct(NameResolver $nameResolver, PropertyFetchManipulator $propertyFetchManipulator)
+ public function __construct(NodeNameResolver $nodeNameResolver, PropertyFetchManipulator $propertyFetchManipulator)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->propertyFetchManipulator = $propertyFetchManipulator;
}
@@ -62,7 +62,7 @@ public function isLocalPropertyAssignWithPropertyNames(Node $node, array $proper
return false;
}
- return $this->nameResolver->isNames($propertyFetch, $propertyNames);
+ return $this->nodeNameResolver->isNames($propertyFetch, $propertyNames);
}
/**
@@ -95,7 +95,7 @@ public function isListToEachAssign(Assign $assign): bool
return false;
}
- return $this->nameResolver->isName($assign->expr, 'each');
+ return $this->nodeNameResolver->isName($assign->expr, 'each');
}
public function isNodeLeftPartOfAssign(Node $node): bool
diff --git a/src/PhpParser/Node/Manipulator/ChainMethodCallManipulator.php b/src/PhpParser/Node/Manipulator/ChainMethodCallManipulator.php
index d739b7deb8c0..139b5e9aed1f 100644
--- a/src/PhpParser/Node/Manipulator/ChainMethodCallManipulator.php
+++ b/src/PhpParser/Node/Manipulator/ChainMethodCallManipulator.php
@@ -8,7 +8,7 @@
use PhpParser\Node\Expr\MethodCall;
use PHPStan\Type\MixedType;
use PHPStan\Type\Type;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\NodeTypeResolver;
/**
@@ -23,14 +23,14 @@ final class ChainMethodCallManipulator
private $nodeTypeResolver;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(NodeTypeResolver $nodeTypeResolver, NameResolver $nameResolver)
+ public function __construct(NodeTypeResolver $nodeTypeResolver, NodeNameResolver $nodeNameResolver)
{
$this->nodeTypeResolver = $nodeTypeResolver;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -48,7 +48,7 @@ public function isTypeAndChainCalls(Node $node, Type $type, array $methods): boo
$methods = array_reverse($methods);
foreach ($methods as $method) {
- $activeMethodName = $this->nameResolver->getName($node);
+ $activeMethodName = $this->nodeNameResolver->getName($node);
if ($activeMethodName !== $method) {
return false;
}
diff --git a/src/PhpParser/Node/Manipulator/ChildAndParentClassManipulator.php b/src/PhpParser/Node/Manipulator/ChildAndParentClassManipulator.php
index f31e3c32128f..68beeaceb207 100644
--- a/src/PhpParser/Node/Manipulator/ChildAndParentClassManipulator.php
+++ b/src/PhpParser/Node/Manipulator/ChildAndParentClassManipulator.php
@@ -10,7 +10,7 @@
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
use Rector\Core\NodeContainer\NodeFinder\ClassLikeParsedNodesFinder;
use Rector\Core\PhpParser\Node\NodeFactory;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ChildAndParentClassManipulator
@@ -21,9 +21,9 @@ final class ChildAndParentClassManipulator
private $nodeFactory;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ClassLikeParsedNodesFinder
@@ -38,11 +38,11 @@ final class ChildAndParentClassManipulator
public function __construct(
ParsedNodeCollector $parsedNodeCollector,
NodeFactory $nodeFactory,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ClassLikeParsedNodesFinder $classLikeParsedNodesFinder
) {
$this->nodeFactory = $nodeFactory;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->classLikeParsedNodesFinder = $classLikeParsedNodesFinder;
$this->parsedNodeCollector = $parsedNodeCollector;
}
@@ -75,7 +75,7 @@ public function completeParentConstructor(Class_ $classNode, ClassMethod $classM
public function completeChildConstructors(Class_ $classNode, ClassMethod $constructorClassMethod): void
{
- $className = $this->nameResolver->getName($classNode);
+ $className = $this->nodeNameResolver->getName($classNode);
if ($className === null) {
return;
}
diff --git a/src/PhpParser/Node/Manipulator/ClassConstManipulator.php b/src/PhpParser/Node/Manipulator/ClassConstManipulator.php
index a8a93f5233c0..55073650d60c 100644
--- a/src/PhpParser/Node/Manipulator/ClassConstManipulator.php
+++ b/src/PhpParser/Node/Manipulator/ClassConstManipulator.php
@@ -10,16 +10,16 @@
use PhpParser\Node\Stmt\ClassConst;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class ClassConstManipulator
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var BetterNodeFinder
@@ -42,13 +42,13 @@ final class ClassConstManipulator
private $classManipulator;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
BetterNodeFinder $betterNodeFinder,
BetterStandardPrinter $betterStandardPrinter,
ParsedNodeCollector $parsedNodeCollector,
ClassManipulator $classManipulator
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->betterNodeFinder = $betterNodeFinder;
$this->betterStandardPrinter = $betterStandardPrinter;
$this->parsedNodeCollector = $parsedNodeCollector;
@@ -98,7 +98,7 @@ public function getAllClassConstFetch(ClassConst $classConst): array
private function isNameMatch(Node $node, ClassConst $classConst): bool
{
- return $this->nameResolver->getName($node) === 'self::' . $this->nameResolver->getName($classConst)
- || $this->nameResolver->getName($node) === 'static::' . $this->nameResolver->getName($classConst);
+ return $this->nodeNameResolver->getName($node) === 'self::' . $this->nodeNameResolver->getName($classConst)
+ || $this->nodeNameResolver->getName($node) === 'static::' . $this->nodeNameResolver->getName($classConst);
}
}
diff --git a/src/PhpParser/Node/Manipulator/ClassManipulator.php b/src/PhpParser/Node/Manipulator/ClassManipulator.php
index c27b00174439..a1bdd1e9ea83 100644
--- a/src/PhpParser/Node/Manipulator/ClassManipulator.php
+++ b/src/PhpParser/Node/Manipulator/ClassManipulator.php
@@ -26,7 +26,7 @@
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\Commander\NodeRemovingCommander;
use Rector\Core\PhpParser\Node\NodeFactory;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -35,9 +35,9 @@
final class ClassManipulator
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var NodeFactory
@@ -70,7 +70,7 @@ final class ClassManipulator
private $nodeTypeResolver;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
NodeFactory $nodeFactory,
ChildAndParentClassManipulator $childAndParentClassManipulator,
CallableNodeTraverser $callableNodeTraverser,
@@ -79,7 +79,7 @@ public function __construct(
NodeTypeResolver $nodeTypeResolver
) {
$this->nodeFactory = $nodeFactory;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->childAndParentClassManipulator = $childAndParentClassManipulator;
$this->callableNodeTraverser = $callableNodeTraverser;
$this->nodeRemovingCommander = $nodeRemovingCommander;
@@ -190,7 +190,7 @@ public function getUsedTraits(ClassLike $classLike): array
$usedTraits = [];
foreach ($classLike->getTraitUses() as $stmt) {
foreach ($stmt->traits as $trait) {
- $traitName = $this->nameResolver->getName($trait);
+ $traitName = $this->nodeNameResolver->getName($trait);
if ($traitName !== null) {
$usedTraits[$traitName] = $trait;
}
@@ -208,7 +208,7 @@ public function getProperty(ClassLike $classLike, string $name): ?Property
throw new ShouldNotHappenException();
}
- if ($this->nameResolver->isName($property, $name)) {
+ if ($this->nodeNameResolver->isName($property, $name)) {
return $property;
}
}
@@ -254,7 +254,7 @@ public function removeProperty(Class_ $class, string $propertyName): void
public function findMethodParamByName(ClassMethod $classMethod, string $name): ?Param
{
foreach ($classMethod->params as $param) {
- if (! $this->nameResolver->isName($param, $name)) {
+ if (! $this->nodeNameResolver->isName($param, $name)) {
continue;
}
@@ -276,7 +276,7 @@ public function getPrivatePropertyNames(Class_ $class): array
}
/** @var string $propertyName */
- $propertyName = $this->nameResolver->getName($property);
+ $propertyName = $this->nodeNameResolver->getName($property);
$privatePropertyNames[] = $propertyName;
}
@@ -299,7 +299,7 @@ public function getPublicMethodNames(Class_ $class): array
}
/** @var string $methodName */
- $methodName = $this->nameResolver->getName($method);
+ $methodName = $this->nodeNameResolver->getName($method);
$publicMethodNames[] = $methodName;
}
@@ -316,7 +316,7 @@ public function removeProperties(Class_ $class, array $propertyNames): void
return null;
}
- if (! $this->nameResolver->isNames($node, $propertyNames)) {
+ if (! $this->nodeNameResolver->isNames($node, $propertyNames)) {
return null;
}
@@ -376,7 +376,7 @@ public function getImplementedInterfaceNames(Class_ $class): array
$implementedInterfaceNames = [];
foreach ($class->implements as $implement) {
- $interfaceName = $this->nameResolver->getName($implement);
+ $interfaceName = $this->nodeNameResolver->getName($implement);
if (! is_string($interfaceName)) {
throw new ShouldNotHappenException();
}
@@ -391,7 +391,7 @@ public function hasPropertyName(Class_ $node, string $name): bool
{
foreach ($node->getProperties() as $property) {
foreach ($property->props as $propertyProperty) {
- if (! $this->nameResolver->isName($propertyProperty, $name)) {
+ if (! $this->nodeNameResolver->isName($propertyProperty, $name)) {
continue;
}
@@ -406,7 +406,7 @@ public function hasClassTrait(Class_ $class, string $desiredTrait): bool
{
foreach ($class->getTraitUses() as $traitUse) {
foreach ($traitUse->traits as $traitTrait) {
- if (! $this->nameResolver->isName($traitTrait, $desiredTrait)) {
+ if (! $this->nodeNameResolver->isName($traitTrait, $desiredTrait)) {
continue;
}
@@ -421,7 +421,7 @@ public function replaceTrait(Class_ $class, string $oldTrait, string $newTrait):
{
foreach ($class->getTraitUses() as $traitUse) {
foreach ($traitUse->traits as $key => $traitTrait) {
- if (! $this->nameResolver->isName($traitTrait, $oldTrait)) {
+ if (! $this->nodeNameResolver->isName($traitTrait, $oldTrait)) {
continue;
}
@@ -451,7 +451,7 @@ public function getClassLikeNodeParentInterfaceNames(ClassLike $classLike)
public function hasInterface(Class_ $class, string $desiredInterface): bool
{
foreach ($class->implements as $implement) {
- if (! $this->nameResolver->isName($implement, $desiredInterface)) {
+ if (! $this->nodeNameResolver->isName($implement, $desiredInterface)) {
continue;
}
@@ -464,7 +464,7 @@ public function hasInterface(Class_ $class, string $desiredInterface): bool
public function removeInterface(Class_ $class, string $desiredInterface): void
{
foreach ($class->implements as $implement) {
- if (! $this->nameResolver->isName($implement, $desiredInterface)) {
+ if (! $this->nodeNameResolver->isName($implement, $desiredInterface)) {
continue;
}
@@ -484,12 +484,12 @@ public function renamePropertyFetches(Class_ $class, array $oldToNewPropertyName
return null;
}
- if (! $this->nameResolver->isName($node->var, 'this')) {
+ if (! $this->nodeNameResolver->isName($node->var, 'this')) {
return null;
}
foreach ($oldToNewPropertyNames as $oldPropertyName => $newPropertyName) {
- if (! $this->nameResolver->isName($node->name, $oldPropertyName)) {
+ if (! $this->nodeNameResolver->isName($node->name, $oldPropertyName)) {
continue;
}
@@ -549,7 +549,7 @@ private function addStatementToClassBeforeTypes(Class_ $classNode, Stmt $stmt, s
private function hasClassProperty(Class_ $classNode, string $name): bool
{
foreach ($classNode->getProperties() as $property) {
- if ($this->nameResolver->isName($property, $name)) {
+ if ($this->nodeNameResolver->isName($property, $name)) {
return true;
}
}
@@ -578,7 +578,7 @@ private function getClassMethodNames(Class_ $classNode): array
{
$classMethodNames = [];
foreach ($classNode->getMethods() as $classMethod) {
- $methodName = $this->nameResolver->getName($classMethod);
+ $methodName = $this->nodeNameResolver->getName($classMethod);
if (! is_string($methodName)) {
throw new ShouldNotHappenException();
}
@@ -637,7 +637,7 @@ private function getClassImplementedInterfaceNames(Class_ $class): array
$interfaceNames = [];
foreach ($class->implements as $implementNode) {
- $interfaceName = $this->nameResolver->getName($implementNode);
+ $interfaceName = $this->nodeNameResolver->getName($implementNode);
if ($interfaceName === null) {
continue;
}
@@ -656,7 +656,7 @@ private function getInterfaceExtendedInterfacesNames(Interface_ $interface): arr
$interfaceNames = [];
foreach ($interface->extends as $extendNode) {
- $interfaceName = $this->nameResolver->getName($extendNode);
+ $interfaceName = $this->nodeNameResolver->getName($extendNode);
if ($interfaceName === null) {
continue;
}
@@ -670,7 +670,7 @@ private function getInterfaceExtendedInterfacesNames(Interface_ $interface): arr
private function hasMethodParameter(ClassMethod $classMethod, string $name): bool
{
foreach ($classMethod->params as $constructorParameter) {
- if ($this->nameResolver->isName($constructorParameter->var, $name)) {
+ if ($this->nodeNameResolver->isName($constructorParameter->var, $name)) {
return true;
}
}
diff --git a/src/PhpParser/Node/Manipulator/ClassMethodManipulator.php b/src/PhpParser/Node/Manipulator/ClassMethodManipulator.php
index 6a71596979c4..4cf1a2897b68 100644
--- a/src/PhpParser/Node/Manipulator/ClassMethodManipulator.php
+++ b/src/PhpParser/Node/Manipulator/ClassMethodManipulator.php
@@ -13,7 +13,7 @@
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Node\Value\ValueResolver;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -37,9 +37,9 @@ final class ClassMethodManipulator
private $nodeTypeResolver;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ValueResolver
@@ -50,13 +50,13 @@ public function __construct(
BetterNodeFinder $betterNodeFinder,
BetterStandardPrinter $betterStandardPrinter,
NodeTypeResolver $nodeTypeResolver,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
ValueResolver $valueResolver
) {
$this->betterNodeFinder = $betterNodeFinder;
$this->betterStandardPrinter = $betterStandardPrinter;
$this->nodeTypeResolver = $nodeTypeResolver;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->valueResolver = $valueResolver;
}
@@ -78,17 +78,17 @@ public function isParameterUsedMethod(Param $param, ClassMethod $classMethod): b
return false;
}
- return $this->nameResolver->isName($node, 'compact');
+ return $this->nodeNameResolver->isName($node, 'compact');
});
$arguments = $this->extractArgumentsFromCompactFuncCalls($compactFuncCalls);
- return $this->nameResolver->isNames($param, $arguments);
+ return $this->nodeNameResolver->isNames($param, $arguments);
}
public function isNamedConstructor(ClassMethod $classMethod): bool
{
- if (! $this->nameResolver->isName($classMethod, '__construct')) {
+ if (! $this->nodeNameResolver->isName($classMethod, '__construct')) {
return false;
}
@@ -102,7 +102,7 @@ public function isNamedConstructor(ClassMethod $classMethod): bool
public function hasParentMethodOrInterfaceMethod(ClassMethod $classMethod, ?string $methodName = null): bool
{
- $methodName = $methodName ?? $this->nameResolver->getName($classMethod->name);
+ $methodName = $methodName ?? $this->nodeNameResolver->getName($classMethod->name);
$class = $classMethod->getAttribute(AttributeKey::CLASS_NAME);
if (! is_string($class)) {
@@ -141,7 +141,7 @@ public function isStaticClassMethod(ClassMethod $classMethod): bool
return false;
}
- return $this->nameResolver->isName($node, 'this');
+ return $this->nodeNameResolver->isName($node, 'this');
});
}
@@ -161,7 +161,7 @@ public function addMethodParameterIfMissing(Node $node, string $type, array $pos
continue;
}
- $paramName = $this->nameResolver->getName($paramNode);
+ $paramName = $this->nodeNameResolver->getName($paramNode);
if (! is_string($paramName)) {
throw new ShouldNotHappenException();
}
@@ -178,7 +178,7 @@ public function addMethodParameterIfMissing(Node $node, string $type, array $pos
public function removeParameter(Param $param, ClassMethod $classMethod): void
{
foreach ($classMethod->params as $key => $constructorParam) {
- if (! $this->nameResolver->areNamesEqual($constructorParam, $param)) {
+ if (! $this->nodeNameResolver->areNamesEqual($constructorParam, $param)) {
continue;
}
@@ -233,7 +233,7 @@ private function resolveName(ClassMethod $classMethod, array $possibleNames): st
{
foreach ($possibleNames as $possibleName) {
foreach ($classMethod->params as $paramNode) {
- if ($this->nameResolver->isName($paramNode, $possibleName)) {
+ if ($this->nodeNameResolver->isName($paramNode, $possibleName)) {
continue 2;
}
}
diff --git a/src/PhpParser/Node/Manipulator/FunctionLikeManipulator.php b/src/PhpParser/Node/Manipulator/FunctionLikeManipulator.php
index a105d151874c..9450a92756d7 100644
--- a/src/PhpParser/Node/Manipulator/FunctionLikeManipulator.php
+++ b/src/PhpParser/Node/Manipulator/FunctionLikeManipulator.php
@@ -8,15 +8,15 @@
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\Function_;
use PhpParser\Node\Stmt\Return_;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
final class FunctionLikeManipulator
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var CallableNodeTraverser
@@ -29,11 +29,11 @@ final class FunctionLikeManipulator
private $propertyFetchManipulator;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
CallableNodeTraverser $callableNodeTraverser,
PropertyFetchManipulator $propertyFetchManipulator
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->callableNodeTraverser = $callableNodeTraverser;
$this->propertyFetchManipulator = $propertyFetchManipulator;
}
@@ -60,7 +60,7 @@ public function getReturnedLocalPropertyNames(FunctionLike $functionLike): array
return null;
}
- $propertyName = $this->nameResolver->getName($node->expr);
+ $propertyName = $this->nodeNameResolver->getName($node->expr);
if ($propertyName === null) {
return null;
}
diff --git a/src/PhpParser/Node/Manipulator/IdentifierManipulator.php b/src/PhpParser/Node/Manipulator/IdentifierManipulator.php
index e9ac124a8735..35ee599cffdb 100644
--- a/src/PhpParser/Node/Manipulator/IdentifierManipulator.php
+++ b/src/PhpParser/Node/Manipulator/IdentifierManipulator.php
@@ -13,7 +13,7 @@
use PhpParser\Node\Identifier;
use PhpParser\Node\Stmt\ClassMethod;
use Rector\Core\Exception\NodeChanger\NodeMissingIdentifierException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
/**
* This class renames node identifier, e.g. ClassMethod rename:
@@ -31,13 +31,13 @@ final class IdentifierManipulator
];
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(NameResolver $nameResolver)
+ public function __construct(NodeNameResolver $nodeNameResolver)
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -48,7 +48,7 @@ public function renameNodeWithMap(Node $node, array $renameMethodMap): void
{
$this->ensureNodeHasIdentifier($node);
- $oldNodeMethodName = $this->nameResolver->getName($node);
+ $oldNodeMethodName = $this->nodeNameResolver->getName($node);
if ($oldNodeMethodName === null) {
return;
}
@@ -63,7 +63,7 @@ public function removeSuffix(Node $node, string $suffixToRemove): void
{
$this->ensureNodeHasIdentifier($node);
- $name = $this->nameResolver->getName($node);
+ $name = $this->nodeNameResolver->getName($node);
if ($name === null) {
return;
}
diff --git a/src/PhpParser/Node/Manipulator/IfManipulator.php b/src/PhpParser/Node/Manipulator/IfManipulator.php
index 2e61010b0356..e39f88db3be4 100644
--- a/src/PhpParser/Node/Manipulator/IfManipulator.php
+++ b/src/PhpParser/Node/Manipulator/IfManipulator.php
@@ -13,7 +13,7 @@
use PhpParser\Node\Expr\Variable;
use PhpParser\Node\Stmt\If_;
use PhpParser\Node\Stmt\Return_;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
final class IfManipulator
@@ -34,20 +34,20 @@ final class IfManipulator
private $stmtsManipulator;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
public function __construct(
BetterStandardPrinter $betterStandardPrinter,
ConstFetchManipulator $constFetchManipulator,
StmtsManipulator $stmtsManipulator,
- NameResolver $nameResolver
+ NodeNameResolver $nodeNameResolver
) {
$this->betterStandardPrinter = $betterStandardPrinter;
$this->constFetchManipulator = $constFetchManipulator;
$this->stmtsManipulator = $stmtsManipulator;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -213,7 +213,7 @@ public function isIfOrIfElseWithFunctionCondition(If_ $if, string $functionName)
if (! $if->cond instanceof FuncCall) {
return false;
}
- return $this->nameResolver->isName($if->cond, $functionName);
+ return $this->nodeNameResolver->isName($if->cond, $functionName);
}
private function matchComparedAndReturnedNode(NotIdentical $notIdentical, Return_ $returnNode): ?Expr
diff --git a/src/PhpParser/Node/Manipulator/MethodCallManipulator.php b/src/PhpParser/Node/Manipulator/MethodCallManipulator.php
index d61f00fefd19..d4a9af51cafd 100644
--- a/src/PhpParser/Node/Manipulator/MethodCallManipulator.php
+++ b/src/PhpParser/Node/Manipulator/MethodCallManipulator.php
@@ -11,16 +11,16 @@
use PhpParser\Node\FunctionLike;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\NodeTypeResolver\Node\AttributeKey;
final class MethodCallManipulator
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var CallableNodeTraverser
@@ -33,11 +33,11 @@ final class MethodCallManipulator
private $betterNodeFinder;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
CallableNodeTraverser $callableNodeTraverser,
BetterNodeFinder $betterNodeFinder
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->callableNodeTraverser = $callableNodeTraverser;
$this->betterNodeFinder = $betterNodeFinder;
}
@@ -51,7 +51,7 @@ public function findMethodCallNamesOnVariable(Variable $variable): array
$methodCallNamesOnVariable = [];
foreach ($methodCallsOnVariable as $methodCallOnVariable) {
- $methodName = $this->nameResolver->getName($methodCallOnVariable);
+ $methodName = $this->nodeNameResolver->getName($methodCallOnVariable);
if ($methodName === null) {
continue;
}
@@ -95,7 +95,7 @@ public function findAssignToVariable(Variable $variable): ?Assign
return null;
}
- $variableName = $this->nameResolver->getName($variable);
+ $variableName = $this->nodeNameResolver->getName($variable);
if ($variableName === null) {
return null;
}
@@ -123,7 +123,7 @@ private function findMethodCallsOnVariable(Variable $variable): array
return [];
}
- $variableName = $this->nameResolver->getName($variable);
+ $variableName = $this->nodeNameResolver->getName($variable);
if ($variableName === null) {
return [];
}
@@ -176,7 +176,7 @@ private function findAssignToVariableName(Node $node, string $variableName): ?As
return false;
}
- return $this->nameResolver->isName($node->var, $variableName);
+ return $this->nodeNameResolver->isName($node->var, $variableName);
});
return $assign;
@@ -217,7 +217,7 @@ private function collectMethodCallsOnVariableName(Node $node, string $variableNa
return null;
}
- if (! $this->nameResolver->isName($node->var, $variableName)) {
+ if (! $this->nodeNameResolver->isName($node->var, $variableName)) {
return null;
}
diff --git a/src/PhpParser/Node/Manipulator/PropertyFetchManipulator.php b/src/PhpParser/Node/Manipulator/PropertyFetchManipulator.php
index 6c21c66693ff..31da5218cfc2 100644
--- a/src/PhpParser/Node/Manipulator/PropertyFetchManipulator.php
+++ b/src/PhpParser/Node/Manipulator/PropertyFetchManipulator.php
@@ -20,7 +20,7 @@
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use Rector\Core\Exception\ShouldNotHappenException;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\NodeTraverser\CallableNodeTraverser;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@@ -42,9 +42,9 @@ final class PropertyFetchManipulator
private $reflectionProvider;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var CallableNodeTraverser
@@ -54,18 +54,18 @@ final class PropertyFetchManipulator
public function __construct(
NodeTypeResolver $nodeTypeResolver,
ReflectionProvider $reflectionProvider,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
CallableNodeTraverser $callableNodeTraverser
) {
$this->nodeTypeResolver = $nodeTypeResolver;
$this->reflectionProvider = $reflectionProvider;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->callableNodeTraverser = $callableNodeTraverser;
}
public function isPropertyToSelf(PropertyFetch $propertyFetch): bool
{
- if (! $this->nameResolver->isName($propertyFetch->var, 'this')) {
+ if (! $this->nodeNameResolver->isName($propertyFetch->var, 'this')) {
return false;
}
@@ -75,12 +75,12 @@ public function isPropertyToSelf(PropertyFetch $propertyFetch): bool
return false;
}
- if (! $this->nameResolver->isName($propertyFetch->var, 'this')) {
+ if (! $this->nodeNameResolver->isName($propertyFetch->var, 'this')) {
return false;
}
foreach ($class->getProperties() as $property) {
- if ($this->nameResolver->areNamesEqual($property->props[0], $propertyFetch)) {
+ if ($this->nodeNameResolver->areNamesEqual($property->props[0], $propertyFetch)) {
return true;
}
}
@@ -108,7 +108,7 @@ public function isMagicOnType(Node $node, Type $type): bool
return false;
}
- $nodeName = $this->nameResolver->getName($node);
+ $nodeName = $this->nodeNameResolver->getName($node);
if ($nodeName === null) {
return false;
}
@@ -132,7 +132,7 @@ public function getPropertyNamesOfAssignOfVariable(Node $node, string $paramName
}
/** @var Assign $node */
- $propertyName = $this->nameResolver->getName($node->expr);
+ $propertyName = $this->nodeNameResolver->getName($node->expr);
if ($propertyName) {
$propertyNames[] = $propertyName;
}
@@ -157,7 +157,7 @@ public function isVariableAssignToThisPropertyFetch(Node $node, string $variable
return false;
}
- if (! $this->nameResolver->isName($node->expr, $variableName)) {
+ if (! $this->nodeNameResolver->isName($node->expr, $variableName)) {
return false;
}
@@ -165,7 +165,7 @@ public function isVariableAssignToThisPropertyFetch(Node $node, string $variable
return false;
}
// must be local property
- return $this->nameResolver->isName($node->var->var, 'this');
+ return $this->nodeNameResolver->isName($node->var->var, 'this');
}
/**
@@ -178,7 +178,7 @@ public function isLocalPropertyOfNames(Node $node, array $propertyNames): bool
}
/** @var PropertyFetch $node */
- return $this->nameResolver->isNames($node->name, $propertyNames);
+ return $this->nodeNameResolver->isNames($node->name, $propertyNames);
}
public function isLocalProperty(Node $node): bool
@@ -187,7 +187,7 @@ public function isLocalProperty(Node $node): bool
return false;
}
- return $this->nameResolver->isName($node->var, 'this');
+ return $this->nodeNameResolver->isName($node->var, 'this');
}
/**
@@ -211,11 +211,11 @@ public function resolveParamForPropertyFetch(ClassMethod $classMethod, string $p
return null;
}
- if (! $this->nameResolver->isName($node->var, $propertyName)) {
+ if (! $this->nodeNameResolver->isName($node->var, $propertyName)) {
return null;
}
- $assignedParamName = $this->nameResolver->getName($node->expr);
+ $assignedParamName = $this->nodeNameResolver->getName($node->expr);
return NodeTraverser::STOP_TRAVERSAL;
});
@@ -227,7 +227,7 @@ public function resolveParamForPropertyFetch(ClassMethod $classMethod, string $p
/** @var Param $param */
foreach ((array) $classMethod->params as $param) {
- if (! $this->nameResolver->isName($param, $assignedParamName)) {
+ if (! $this->nodeNameResolver->isName($param, $assignedParamName)) {
continue;
}
@@ -277,11 +277,11 @@ public function isToThisPropertyFetchOfSpecificNameAssign(Node $node, string $pr
return false;
}
- if (! $this->nameResolver->isName($node->var->var, 'this')) {
+ if (! $this->nodeNameResolver->isName($node->var->var, 'this')) {
return false;
}
- return $this->nameResolver->isName($node->var->name, $propertyName);
+ return $this->nodeNameResolver->isName($node->var->name, $propertyName);
}
private function hasPublicProperty(PropertyFetch $propertyFetch, string $propertyName): bool
diff --git a/src/PhpParser/Node/Manipulator/PropertyManipulator.php b/src/PhpParser/Node/Manipulator/PropertyManipulator.php
index 4f35f8ba253a..9f6adc0aafc8 100644
--- a/src/PhpParser/Node/Manipulator/PropertyManipulator.php
+++ b/src/PhpParser/Node/Manipulator/PropertyManipulator.php
@@ -17,7 +17,7 @@
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeContainer\NodeFinder\ClassLikeParsedNodesFinder;
use Rector\Core\PhpParser\Node\BetterNodeFinder;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\Core\PhpParser\Printer\BetterStandardPrinter;
use Rector\Doctrine\AbstractRector\DoctrineTrait;
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -40,9 +40,9 @@ final class PropertyManipulator
private $betterStandardPrinter;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var AssignManipulator
@@ -57,13 +57,13 @@ final class PropertyManipulator
public function __construct(
BetterNodeFinder $betterNodeFinder,
BetterStandardPrinter $betterStandardPrinter,
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
AssignManipulator $assignManipulator,
ClassLikeParsedNodesFinder $classLikeParsedNodesFinder
) {
$this->betterNodeFinder = $betterNodeFinder;
$this->betterStandardPrinter = $betterStandardPrinter;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->assignManipulator = $assignManipulator;
$this->classLikeParsedNodesFinder = $classLikeParsedNodesFinder;
}
@@ -98,7 +98,7 @@ public function getAllPropertyFetch(PropertyProperty $propertyProperty): array
}
// is it the name match?
- if (! $this->nameResolver->areNamesEqual($node, $propertyProperty)) {
+ if (! $this->nodeNameResolver->areNamesEqual($node, $propertyProperty)) {
return false;
}
return in_array($node->getAttribute(AttributeKey::CLASS_NODE), $nodesToSearch, true);
diff --git a/src/PhpParser/Node/NodeNameResolver/ClassConstFetchNameResolver.php b/src/PhpParser/Node/NodeNameResolver/ClassConstFetchNameResolver.php
new file mode 100644
index 000000000000..db4cea02a165
--- /dev/null
+++ b/src/PhpParser/Node/NodeNameResolver/ClassConstFetchNameResolver.php
@@ -0,0 +1,46 @@
+nodeNameResolver = $nodeNameResolver;
+ }
+
+ public function getNode(): string
+ {
+ return ClassConstFetch::class;
+ }
+
+ /**
+ * @param ClassConstFetch $node
+ */
+ public function resolve(Node $node): ?string
+ {
+ $class = $this->nodeNameResolver->getName($node->class);
+ $name = $this->nodeNameResolver->getName($node->name);
+
+ if ($class === null || $name === null) {
+ return null;
+ }
+
+ return $class . '::' . $name;
+ }
+}
diff --git a/src/PhpParser/Node/NodeNameResolver/ClassConstNameResolver.php b/src/PhpParser/Node/NodeNameResolver/ClassConstNameResolver.php
new file mode 100644
index 000000000000..aac470ca8791
--- /dev/null
+++ b/src/PhpParser/Node/NodeNameResolver/ClassConstNameResolver.php
@@ -0,0 +1,45 @@
+nodeNameResolver = $nodeNameResolver;
+ }
+
+ public function getNode(): string
+ {
+ return ClassConst::class;
+ }
+
+ /**
+ * @param ClassConst $node
+ */
+ public function resolve(Node $node): ?string
+ {
+ if (count($node->consts) === 0) {
+ return null;
+ }
+
+ $onlyConstant = $node->consts[0];
+
+ return $this->nodeNameResolver->getName($onlyConstant);
+ }
+}
diff --git a/src/PhpParser/Node/NodeNameResolver/ClassNameResolver.php b/src/PhpParser/Node/NodeNameResolver/ClassNameResolver.php
new file mode 100644
index 000000000000..52e520792795
--- /dev/null
+++ b/src/PhpParser/Node/NodeNameResolver/ClassNameResolver.php
@@ -0,0 +1,47 @@
+nodeNameResolver = $nodeNameResolver;
+ }
+
+ public function getNode(): string
+ {
+ return Class_::class;
+ }
+
+ /**
+ * @param Class_ $node
+ */
+ public function resolve(Node $node): ?string
+ {
+ if (isset($node->namespacedName)) {
+ return $node->namespacedName->toString();
+ }
+
+ if ($node->name === null) {
+ return null;
+ }
+
+ return $this->nodeNameResolver->getName($node->name);
+ }
+}
diff --git a/src/PhpParser/Node/NodeNameResolver/EmptyNameResolver.php b/src/PhpParser/Node/NodeNameResolver/EmptyNameResolver.php
new file mode 100644
index 000000000000..b559e5852ae5
--- /dev/null
+++ b/src/PhpParser/Node/NodeNameResolver/EmptyNameResolver.php
@@ -0,0 +1,25 @@
+name instanceof Expr) {
+ return null;
+ }
+
+ $functionName = $node->name;
+
+ if (! $functionName instanceof Name) {
+ return (string) $functionName;
+ }
+
+ $namespaceName = $functionName->getAttribute('namespacedName');
+ if ($namespaceName instanceof FullyQualified) {
+ $functionFqnName = $namespaceName->toString();
+ if (function_exists($functionFqnName)) {
+ return $functionFqnName;
+ }
+ }
+
+ return (string) $functionName;
+ }
+}
diff --git a/src/PhpParser/Node/NodeNameResolver/NameNameResolver.php b/src/PhpParser/Node/NodeNameResolver/NameNameResolver.php
new file mode 100644
index 000000000000..c492a135af6d
--- /dev/null
+++ b/src/PhpParser/Node/NodeNameResolver/NameNameResolver.php
@@ -0,0 +1,32 @@
+getAttribute(AttributeKey::RESOLVED_NAME);
+ if ($resolvedName instanceof FullyQualified) {
+ return $resolvedName->toString();
+ }
+
+ return $node->toString();
+ }
+}
diff --git a/src/PhpParser/Node/NodeNameResolver/ParamNameResolver.php b/src/PhpParser/Node/NodeNameResolver/ParamNameResolver.php
new file mode 100644
index 000000000000..0f6db0f7fe31
--- /dev/null
+++ b/src/PhpParser/Node/NodeNameResolver/ParamNameResolver.php
@@ -0,0 +1,39 @@
+nodeNameResolver = $nodeNameResolver;
+ }
+
+ public function getNode(): string
+ {
+ return Param::class;
+ }
+
+ /**
+ * @param Param $node
+ */
+ public function resolve(Node $node): ?string
+ {
+ return $this->nodeNameResolver->getName($node->var);
+ }
+}
diff --git a/src/PhpParser/Node/NodeNameResolver/PropertyNameResolver.php b/src/PhpParser/Node/NodeNameResolver/PropertyNameResolver.php
new file mode 100644
index 000000000000..21fc410b8a6b
--- /dev/null
+++ b/src/PhpParser/Node/NodeNameResolver/PropertyNameResolver.php
@@ -0,0 +1,45 @@
+nodeNameResolver = $nodeNameResolver;
+ }
+
+ public function getNode(): string
+ {
+ return Property::class;
+ }
+
+ /**
+ * @param Property $node
+ */
+ public function resolve(Node $node): ?string
+ {
+ if (count($node->props) === 0) {
+ return null;
+ }
+
+ $onlyProperty = $node->props[0];
+
+ return $this->nodeNameResolver->getName($onlyProperty);
+ }
+}
diff --git a/src/PhpParser/Node/NodeNameResolver/UseNameResolver.php b/src/PhpParser/Node/NodeNameResolver/UseNameResolver.php
new file mode 100644
index 000000000000..4218a5707e3e
--- /dev/null
+++ b/src/PhpParser/Node/NodeNameResolver/UseNameResolver.php
@@ -0,0 +1,45 @@
+nodeNameResolver = $nodeNameResolver;
+ }
+
+ public function getNode(): string
+ {
+ return Use_::class;
+ }
+
+ /**
+ * @param Use_ $node
+ */
+ public function resolve(Node $node): ?string
+ {
+ if (count($node->uses) === 0) {
+ return null;
+ }
+
+ $onlyUse = $node->uses[0];
+
+ return $this->nodeNameResolver->getName($onlyUse);
+ }
+}
diff --git a/src/PhpParser/Node/NodeNameResolver/VariableNameResolver.php b/src/PhpParser/Node/NodeNameResolver/VariableNameResolver.php
new file mode 100644
index 000000000000..3f2ab3ddaf61
--- /dev/null
+++ b/src/PhpParser/Node/NodeNameResolver/VariableNameResolver.php
@@ -0,0 +1,50 @@
+getAttribute(AttributeKey::PARENT_NODE);
+ // is $variable::method(), unable to resolve $variable->class name
+ if ($parentNode instanceof StaticCall) {
+ return null;
+ }
+
+ // skip $some->$dynamicMethodName()
+ if ($parentNode instanceof MethodCall && $node === $parentNode->name) {
+ return null;
+ }
+
+ // skip $some->$dynamicPropertyName
+ if ($parentNode instanceof PropertyFetch && $node === $parentNode->name) {
+ return null;
+ }
+
+ if ($node->name instanceof Expr) {
+ return null;
+ }
+
+ return (string) $node->name;
+ }
+}
diff --git a/src/PhpParser/Node/NodeVisitor/NodeRemovingNodeVisitor.php b/src/PhpParser/Node/NodeVisitor/NodeRemovingNodeVisitor.php
index 629b06747187..08256538bffb 100644
--- a/src/PhpParser/Node/NodeVisitor/NodeRemovingNodeVisitor.php
+++ b/src/PhpParser/Node/NodeVisitor/NodeRemovingNodeVisitor.php
@@ -11,7 +11,7 @@
use PhpParser\NodeTraverser;
use PhpParser\NodeVisitorAbstract;
use Rector\Core\PhpParser\Node\NodeFactory;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
final class NodeRemovingNodeVisitor extends NodeVisitorAbstract
{
@@ -26,18 +26,18 @@ final class NodeRemovingNodeVisitor extends NodeVisitorAbstract
private $nodeFactory;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @param Stmt[] $nodesToRemove
*/
- public function __construct(array $nodesToRemove, NodeFactory $nodeFactory, NameResolver $nameResolver)
+ public function __construct(array $nodesToRemove, NodeFactory $nodeFactory, NodeNameResolver $nodeNameResolver)
{
$this->nodesToRemove = $nodesToRemove;
$this->nodeFactory = $nodeFactory;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -59,7 +59,7 @@ public function enterNode(Node $node)
continue;
}
- $methodName = $this->nameResolver->getName($node->name);
+ $methodName = $this->nodeNameResolver->getName($node->name);
if ($methodName === null) {
continue;
}
diff --git a/src/PhpParser/Node/NodeVisitorFactory/NodeRemovingNodeVisitorFactory.php b/src/PhpParser/Node/NodeVisitorFactory/NodeRemovingNodeVisitorFactory.php
index e2be1205927b..d87d5e71022c 100644
--- a/src/PhpParser/Node/NodeVisitorFactory/NodeRemovingNodeVisitorFactory.php
+++ b/src/PhpParser/Node/NodeVisitorFactory/NodeRemovingNodeVisitorFactory.php
@@ -7,7 +7,7 @@
use PhpParser\Node;
use Rector\Core\PhpParser\Node\NodeFactory;
use Rector\Core\PhpParser\Node\NodeVisitor\NodeRemovingNodeVisitor;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
final class NodeRemovingNodeVisitorFactory
{
@@ -17,14 +17,14 @@ final class NodeRemovingNodeVisitorFactory
private $nodeFactory;
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
- public function __construct(NodeFactory $nodeFactory, NameResolver $nameResolver)
+ public function __construct(NodeFactory $nodeFactory, NodeNameResolver $nodeNameResolver)
{
$this->nodeFactory = $nodeFactory;
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
}
/**
@@ -32,6 +32,6 @@ public function __construct(NodeFactory $nodeFactory, NameResolver $nameResolver
*/
public function createFromNodesToRemove(array $nodesToRemove): NodeRemovingNodeVisitor
{
- return new NodeRemovingNodeVisitor($nodesToRemove, $this->nodeFactory, $this->nameResolver);
+ return new NodeRemovingNodeVisitor($nodesToRemove, $this->nodeFactory, $this->nodeNameResolver);
}
}
diff --git a/src/PhpParser/Node/Resolver/NameResolver.php b/src/PhpParser/Node/Resolver/NameResolver.php
deleted file mode 100644
index 688bc14450b7..000000000000
--- a/src/PhpParser/Node/Resolver/NameResolver.php
+++ /dev/null
@@ -1,241 +0,0 @@
-isName($node, $name)) {
- return true;
- }
- }
-
- return false;
- }
-
- public function isName(Node $node, string $name): bool
- {
- if ($node instanceof MethodCall) {
- // method call cannot have a name, only the variable or method name
- return false;
- }
-
- $resolvedName = $this->getName($node);
- if ($resolvedName === null) {
- return false;
- }
-
- if ($name === '') {
- return false;
- }
-
- // is probably regex pattern
- if ($this->isRegexPattern($name)) {
- return (bool) Strings::match($resolvedName, $name);
- }
-
- // is probably fnmatch
- if (Strings::contains($name, '*')) {
- return fnmatch($name, $resolvedName, FNM_NOESCAPE);
- }
-
- // special case
- if ($name === 'Object') {
- return $name === $resolvedName;
- }
-
- return strtolower($resolvedName) === strtolower($name);
- }
-
- public function getName(Node $node): ?string
- {
- if ($node instanceof Empty_) {
- return 'empty';
- }
-
- // more complex
- if ($node instanceof ClassConst) {
- if (count($node->consts) === 0) {
- return null;
- }
-
- return $this->getName($node->consts[0]);
- }
-
- if ($node instanceof Property) {
- if (count($node->props) === 0) {
- return null;
- }
-
- return $this->getName($node->props[0]);
- }
-
- if ($node instanceof Use_) {
- if (count($node->uses) === 0) {
- return null;
- }
-
- return $this->getName($node->uses[0]);
- }
-
- if ($node instanceof Param) {
- return $this->getName($node->var);
- }
-
- if ($node instanceof Name) {
- $resolvedName = $node->getAttribute(AttributeKey::RESOLVED_NAME);
- if ($resolvedName instanceof FullyQualified) {
- return $resolvedName->toString();
- }
-
- return $node->toString();
- }
-
- if ($node instanceof Class_) {
- if (isset($node->namespacedName)) {
- return $node->namespacedName->toString();
- }
- if ($node->name === null) {
- return null;
- }
-
- return $this->getName($node->name);
- }
-
- if ($node instanceof Interface_ || $node instanceof Trait_) {
- return $this->resolveNamespacedNameAwareNode($node);
- }
-
- if ($node instanceof ClassConstFetch) {
- $class = $this->getName($node->class);
- $name = $this->getName($node->name);
-
- if ($class === null || $name === null) {
- return null;
- }
-
- return $class . '::' . $name;
- }
-
- if (! property_exists($node, 'name')) {
- return null;
- }
-
- // unable to resolve
- if ($node->name instanceof Expr) {
- return null;
- }
-
- if ($node instanceof Variable) {
- $parentNode = $node->getAttribute(AttributeKey::PARENT_NODE);
- // is $variable::method(), unable to resolve $variable->class name
- if ($parentNode instanceof StaticCall) {
- return null;
- }
-
- // skip $some->$dynamicMethodName()
- if ($parentNode instanceof MethodCall && $node === $parentNode->name) {
- return null;
- }
-
- // skip $some->$dynamicPropertyName
- if ($parentNode instanceof PropertyFetch && $node === $parentNode->name) {
- return null;
- }
- }
-
- if ($node instanceof FuncCall) {
- return $this->resolveFuncCallName($node);
- }
-
- return (string) $node->name;
- }
-
- public function areNamesEqual(Node $firstNode, Node $secondNode): bool
- {
- return $this->getName($firstNode) === $this->getName($secondNode);
- }
-
- private function isRegexPattern(string $name): bool
- {
- if (Strings::length($name) <= 2) {
- return false;
- }
-
- $firstChar = $name[0];
- $lastChar = $name[strlen($name) - 1];
- if ($firstChar !== $lastChar) {
- return false;
- }
-
- // this prevents miss matching like "aMethoda"
- $possibleDelimiters = ['#', '~', '/'];
-
- return in_array($firstChar, $possibleDelimiters, true);
- }
-
- /**
- * @param Interface_|Trait_ $classLike
- */
- private function resolveNamespacedNameAwareNode(ClassLike $classLike): ?string
- {
- if (isset($classLike->namespacedName)) {
- return $classLike->namespacedName->toString();
- }
-
- if ($classLike->name === null) {
- return null;
- }
-
- return $this->getName($classLike->name);
- }
-
- /**
- * If some function is namespaced, it will be used over global one.
- * But only if it really exists.
- */
- private function resolveFuncCallName(Node $node): string
- {
- $functionName = $node->name;
- if ($functionName instanceof Name) {
- $namespaceName = $functionName->getAttribute('namespacedName');
- if ($namespaceName instanceof FullyQualified) {
- $functionFqnName = $namespaceName->toString();
- if (function_exists($functionFqnName)) {
- return $functionFqnName;
- }
- }
- }
-
- return (string) $functionName;
- }
-}
diff --git a/src/PhpParser/Node/Resolver/NodeNameResolver.php b/src/PhpParser/Node/Resolver/NodeNameResolver.php
new file mode 100644
index 000000000000..39003ddc967c
--- /dev/null
+++ b/src/PhpParser/Node/Resolver/NodeNameResolver.php
@@ -0,0 +1,150 @@
+nodeNameResolvers = $nodeNameResolvers;
+ }
+
+ /**
+ * @param string[] $names
+ */
+ public function isNames(Node $node, array $names): bool
+ {
+ foreach ($names as $name) {
+ if ($this->isName($node, $name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public function isName(Node $node, string $name): bool
+ {
+ if ($node instanceof MethodCall) {
+ // method call cannot have a name, only the variable or method name
+ return false;
+ }
+
+ $resolvedName = $this->getName($node);
+ if ($resolvedName === null) {
+ return false;
+ }
+
+ if ($name === '') {
+ return false;
+ }
+
+ // is probably regex pattern
+ if ($this->isRegexPattern($name)) {
+ return (bool) Strings::match($resolvedName, $name);
+ }
+
+ // is probably fnmatch
+ if (Strings::contains($name, '*')) {
+ return fnmatch($name, $resolvedName, FNM_NOESCAPE);
+ }
+
+ // special case
+ if ($name === 'Object') {
+ return $name === $resolvedName;
+ }
+
+ return strtolower($resolvedName) === strtolower($name);
+ }
+
+ public function getName(Node $node): ?string
+ {
+ foreach ($this->nodeNameResolvers as $nodeNameResolver) {
+ if (! is_a($node, $nodeNameResolver->getNode(), true)) {
+ continue;
+ }
+
+ return $nodeNameResolver->resolve($node);
+ }
+
+ // more complex
+ if ($node instanceof Interface_ || $node instanceof Trait_) {
+ return $this->resolveNamespacedNameAwareNode($node);
+ }
+
+ if (! property_exists($node, 'name')) {
+ return null;
+ }
+
+ // unable to resolve
+ if ($node->name instanceof Expr) {
+ return null;
+ }
+
+ return (string) $node->name;
+ }
+
+ public function areNamesEqual(Node $firstNode, Node $secondNode): bool
+ {
+ return $this->getName($firstNode) === $this->getName($secondNode);
+ }
+
+ private function isRegexPattern(string $name): bool
+ {
+ if (Strings::length($name) <= 2) {
+ return false;
+ }
+
+ $firstChar = $name[0];
+ $lastChar = $name[strlen($name) - 1];
+ if ($firstChar !== $lastChar) {
+ return false;
+ }
+
+ // this prevents miss matching like "aMethoda"
+ $possibleDelimiters = ['#', '~', '/'];
+
+ return in_array($firstChar, $possibleDelimiters, true);
+ }
+
+ /**
+ * @param Interface_|Trait_ $classLike
+ */
+ private function resolveNamespacedNameAwareNode(ClassLike $classLike): ?string
+ {
+ if (isset($classLike->namespacedName)) {
+ return $classLike->namespacedName->toString();
+ }
+
+ if ($classLike->name === null) {
+ return null;
+ }
+
+ return $this->getName($classLike->name);
+ }
+}
diff --git a/src/PhpParser/Node/Value/ValueResolver.php b/src/PhpParser/Node/Value/ValueResolver.php
index 78c25f66669a..3ad8fd2d6e2d 100644
--- a/src/PhpParser/Node/Value/ValueResolver.php
+++ b/src/PhpParser/Node/Value/ValueResolver.php
@@ -15,7 +15,7 @@
use PHPStan\Type\ConstantScalarType;
use Rector\Core\Exception\ShouldNotHappenException;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
use Symplify\SmartFileSystem\SmartFileInfo;
@@ -26,9 +26,9 @@
final class ValueResolver
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ConstExprEvaluator
@@ -46,11 +46,11 @@ final class ValueResolver
private $nodeTypeResolver;
public function __construct(
- NameResolver $nameResolver,
+ NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
ParsedNodeCollector $parsedNodeCollector
) {
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->parsedNodeCollector = $parsedNodeCollector;
$this->nodeTypeResolver = $nodeTypeResolver;
}
@@ -76,7 +76,7 @@ public function getValue(Expr $expr)
}
if ($expr instanceof ConstFetch) {
- return $this->nameResolver->getName($expr);
+ return $this->nodeNameResolver->getName($expr);
}
$nodeStaticType = $this->nodeTypeResolver->getStaticType($expr);
@@ -173,8 +173,8 @@ private function resolveFileConstant(File $file): string
private function resolveClassConstFetch(ClassConstFetch $classConstFetch)
{
- $class = $this->nameResolver->getName($classConstFetch->class);
- $constant = $this->nameResolver->getName($classConstFetch->name);
+ $class = $this->nodeNameResolver->getName($classConstFetch->class);
+ $constant = $this->nodeNameResolver->getName($classConstFetch->name);
if ($class === null) {
throw new ShouldNotHappenException();
diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php
index b35cda96c5cb..3efb299ea4ee 100644
--- a/src/Rector/AbstractRector.php
+++ b/src/Rector/AbstractRector.php
@@ -280,7 +280,7 @@ protected function isAnonymousClass(Node $node): bool
return false;
}
- $className = $this->nameResolver->getName($node);
+ $className = $this->nodeNameResolver->getName($node);
return $className === null || Strings::contains($className, 'AnonymousClass');
}
diff --git a/src/Rector/AbstractRector/ComplexRemovalTrait.php b/src/Rector/AbstractRector/ComplexRemovalTrait.php
index 602733745a66..0303f9892972 100644
--- a/src/Rector/AbstractRector/ComplexRemovalTrait.php
+++ b/src/Rector/AbstractRector/ComplexRemovalTrait.php
@@ -7,34 +7,11 @@
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
-use PhpParser\Node\Expr\ArrayDimFetch;
use PhpParser\Node\Expr\Assign;
-use PhpParser\Node\Expr\BinaryOp;
-use PhpParser\Node\Expr\BinaryOp\BooleanAnd;
-use PhpParser\Node\Expr\BinaryOp\BooleanOr;
-use PhpParser\Node\Expr\BinaryOp\Coalesce;
-use PhpParser\Node\Expr\BinaryOp\LogicalAnd;
-use PhpParser\Node\Expr\BinaryOp\LogicalOr;
-use PhpParser\Node\Expr\BitwiseNot;
-use PhpParser\Node\Expr\BooleanNot;
-use PhpParser\Node\Expr\Cast;
-use PhpParser\Node\Expr\ClassConstFetch;
-use PhpParser\Node\Expr\Clone_;
-use PhpParser\Node\Expr\Closure;
-use PhpParser\Node\Expr\ConstFetch;
-use PhpParser\Node\Expr\Empty_;
-use PhpParser\Node\Expr\Instanceof_;
-use PhpParser\Node\Expr\Isset_;
use PhpParser\Node\Expr\MethodCall;
use PhpParser\Node\Expr\PropertyFetch;
use PhpParser\Node\Expr\StaticCall;
use PhpParser\Node\Expr\StaticPropertyFetch;
-use PhpParser\Node\Expr\UnaryMinus;
-use PhpParser\Node\Expr\UnaryPlus;
-use PhpParser\Node\Expr\Variable;
-use PhpParser\Node\Identifier;
-use PhpParser\Node\Name;
-use PhpParser\Node\Scalar;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use PhpParser\Node\Stmt\Property;
@@ -44,10 +21,13 @@
use Rector\Core\NodeContainer\NodeFinder\FunctionLikeParsedNodesFinder;
use Rector\Core\PhpParser\Node\Commander\NodeRemovingCommander;
use Rector\Core\PhpParser\Node\Manipulator\PropertyManipulator;
+use Rector\DeadCode\NodeManipulator\LivingCodeManipulator;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
+ * Located in another trait ↓
* @property NodeRemovingCommander $nodeRemovingCommander
+ * @property FunctionLikeParsedNodesFinder $functionLikeParsedNodesFinder
*/
trait ComplexRemovalTrait
{
@@ -56,6 +36,11 @@ trait ComplexRemovalTrait
*/
protected $parsedNodeCollector;
+ /**
+ * @var LivingCodeManipulator
+ */
+ protected $livingCodeManipulator;
+
/**
* @var PropertyManipulator
*/
@@ -67,11 +52,11 @@ trait ComplexRemovalTrait
public function autowireComplextRemovalTrait(
PropertyManipulator $propertyManipulator,
ParsedNodeCollector $parsedNodeCollector,
- FunctionLikeParsedNodesFinder $functionLikeParsedNodesFinder
+ LivingCodeManipulator $livingCodeManipulator
): void {
$this->parsedNodeCollector = $parsedNodeCollector;
$this->propertyManipulator = $propertyManipulator;
- $this->functionLikeParsedNodesFinder = $functionLikeParsedNodesFinder;
+ $this->livingCodeManipulator = $livingCodeManipulator;
}
abstract protected function removeNode(Node $node): void;
@@ -106,15 +91,7 @@ protected function removePropertyAndUsages(
continue;
}
- $assign = $propertyFetch->getAttribute(AttributeKey::PARENT_NODE);
-
- while ($assign !== null && ! $assign instanceof Assign) {
- $assign = $assign->getAttribute(AttributeKey::PARENT_NODE);
- }
-
- if (! $assign instanceof Assign) {
- throw new ShouldNotHappenException("Can't handle this situation");
- }
+ $assign = $this->resolveAssign($propertyFetch);
$this->removeAssignNode($assign);
}
@@ -129,7 +106,7 @@ protected function removePropertyAndUsages(
foreach ($property->props as $prop) {
if (! $this->nodeRemovingCommander->isNodeRemoved($prop)) {
- //if the property has at least one node left -> return
+ // if the property has at least one node left -> return
return;
}
}
@@ -137,78 +114,6 @@ protected function removePropertyAndUsages(
$this->removeNode($property);
}
- /**
- * @param Node|int|string|null $expr
- * @return Expr[]
- */
- protected function keepLivingCodeFromExpr($expr): array
- {
- if (! $expr instanceof Node ||
- $expr instanceof Closure ||
- $expr instanceof Name ||
- $expr instanceof Identifier ||
- $expr instanceof Scalar ||
- $expr instanceof ConstFetch) {
- return [];
- }
- if ($expr instanceof Cast ||
- $expr instanceof Empty_ ||
- $expr instanceof UnaryMinus ||
- $expr instanceof UnaryPlus ||
- $expr instanceof BitwiseNot ||
- $expr instanceof BooleanNot ||
- $expr instanceof Clone_) {
- return $this->keepLivingCodeFromExpr($expr->expr);
- }
- if ($expr instanceof Variable) {
- return $this->keepLivingCodeFromExpr($expr->name);
- }
- if ($expr instanceof PropertyFetch) {
- return array_merge(
- $this->keepLivingCodeFromExpr($expr->var),
- $this->keepLivingCodeFromExpr($expr->name)
- );
- }
- if ($expr instanceof ArrayDimFetch) {
- return array_merge(
- $this->keepLivingCodeFromExpr($expr->var),
- $this->keepLivingCodeFromExpr($expr->dim)
- );
- }
- if ($expr instanceof ClassConstFetch ||
- $expr instanceof StaticPropertyFetch) {
- return array_merge(
- $this->keepLivingCodeFromExpr($expr->class),
- $this->keepLivingCodeFromExpr($expr->name)
- );
- }
- if ($expr instanceof BinaryOp
- && ! (
- $expr instanceof LogicalAnd ||
- $expr instanceof BooleanAnd ||
- $expr instanceof LogicalOr ||
- $expr instanceof BooleanOr ||
- $expr instanceof Coalesce
- )) {
- return array_merge(
- $this->keepLivingCodeFromExpr($expr->left),
- $this->keepLivingCodeFromExpr($expr->right)
- );
- }
- if ($expr instanceof Instanceof_) {
- return array_merge(
- $this->keepLivingCodeFromExpr($expr->expr),
- $this->keepLivingCodeFromExpr($expr->class)
- );
- }
-
- if ($expr instanceof Isset_) {
- return array_merge(...array_map([$this, 'keepLivingCodeFromExpr'], $expr->vars));
- }
-
- return [$expr];
- }
-
private function removeAssignNode(Assign $assign): void
{
$currentStatement = $assign->getAttribute(AttributeKey::CURRENT_STATEMENT);
@@ -226,7 +131,7 @@ private function removeAssignNode(Assign $assign): void
private function addLivingCodeBeforeNode(Expr $expr, Node $addBeforeThisNode): void
{
- foreach ($this->keepLivingCodeFromExpr($expr) as $expr) {
+ foreach ($this->livingCodeManipulator->keepLivingCodeFromExpr($expr) as $expr) {
$this->addNodeBeforeNode(new Expression($expr), $addBeforeThisNode);
}
}
@@ -262,4 +167,22 @@ private function shouldSkipPropertyForClassMethod(Expr $expr, array $classMethod
return in_array($classMethodName, $classMethodNamesToSkip, true);
}
+
+ /**
+ * @param PropertyFetch|StaticPropertyFetch $expr
+ */
+ private function resolveAssign(Expr $expr): Assign
+ {
+ $assign = $expr->getAttribute(AttributeKey::PARENT_NODE);
+
+ while ($assign !== null && ! $assign instanceof Assign) {
+ $assign = $assign->getAttribute(AttributeKey::PARENT_NODE);
+ }
+
+ if (! $assign instanceof Assign) {
+ throw new ShouldNotHappenException("Can't handle this situation");
+ }
+
+ return $assign;
+ }
}
diff --git a/src/Rector/AbstractRector/NameResolverTrait.php b/src/Rector/AbstractRector/NameResolverTrait.php
index 98533173be1a..8400079c0dc7 100644
--- a/src/Rector/AbstractRector/NameResolverTrait.php
+++ b/src/Rector/AbstractRector/NameResolverTrait.php
@@ -8,7 +8,7 @@
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use Rector\CodingStyle\Naming\ClassNaming;
-use Rector\Core\PhpParser\Node\Resolver\NameResolver;
+use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
/**
* This could be part of @see AbstractRector, but decopuling to trait
@@ -17,9 +17,9 @@
trait NameResolverTrait
{
/**
- * @var NameResolver
+ * @var NodeNameResolver
*/
- private $nameResolver;
+ private $nodeNameResolver;
/**
* @var ClassNaming
@@ -29,20 +29,20 @@ trait NameResolverTrait
/**
* @required
*/
- public function autowireNameResolverTrait(NameResolver $nameResolver, ClassNaming $classNaming): void
+ public function autowireNameResolverTrait(NodeNameResolver $nodeNameResolver, ClassNaming $classNaming): void
{
- $this->nameResolver = $nameResolver;
+ $this->nodeNameResolver = $nodeNameResolver;
$this->classNaming = $classNaming;
}
public function isName(Node $node, string $name): bool
{
- return $this->nameResolver->isName($node, $name);
+ return $this->nodeNameResolver->isName($node, $name);
}
public function areNamesEqual(Node $firstNode, Node $secondNode): bool
{
- return $this->nameResolver->areNamesEqual($firstNode, $secondNode);
+ return $this->nodeNameResolver->areNamesEqual($firstNode, $secondNode);
}
/**
@@ -50,12 +50,12 @@ public function areNamesEqual(Node $firstNode, Node $secondNode): bool
*/
public function isNames(Node $node, array $names): bool
{
- return $this->nameResolver->isNames($node, $names);
+ return $this->nodeNameResolver->isNames($node, $names);
}
public function getName(Node $node): ?string
{
- return $this->nameResolver->getName($node);
+ return $this->nodeNameResolver->getName($node);
}
/**
diff --git a/src/Rector/MethodBody/NormalToFluentRector.php b/src/Rector/MethodBody/NormalToFluentRector.php
index c10b4ed3903a..3a74af5b6ccf 100644
--- a/src/Rector/MethodBody/NormalToFluentRector.php
+++ b/src/Rector/MethodBody/NormalToFluentRector.php
@@ -6,6 +6,7 @@
use PhpParser\Node;
use PhpParser\Node\Expr\MethodCall;
+use PhpParser\Node\Stmt;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Expression;
use Rector\Core\Rector\AbstractRector;
@@ -81,21 +82,12 @@ public function refactor(Node $node): ?Node
// iterate from bottom to up, so we can merge
for ($i = $classMethodStatementCount - 1; $i >= 0; --$i) {
$stmt = $node->stmts[$i];
-
- // we look only for 2+ stmts
- if (! isset($node->stmts[$i - 1])) {
- continue;
- }
-
- // we look for 2 methods calls in a row
- if (! $stmt instanceof Expression) {
+ if ($this->shouldSkipPreviousStmt($node, $i, $stmt)) {
continue;
}
+ /** @var Expression $prevStmt */
$prevStmt = $node->stmts[$i - 1];
- if (! $prevStmt instanceof Expression) {
- continue;
- }
// here are 2 method calls statements in a row, while current one is first one
if (! $this->isBothMethodCallMatch($stmt, $prevStmt)) {
@@ -105,7 +97,6 @@ public function refactor(Node $node): ?Node
// reset for new type
$this->collectedMethodCalls = [];
-
continue;
}
@@ -193,4 +184,21 @@ private function matchMethodCall(MethodCall $methodCall): ?string
return null;
}
+
+ private function shouldSkipPreviousStmt(Node $node, int $i, Stmt $stmt): bool
+ {
+ // we look only for 2+ stmts
+ if (! isset($node->stmts[$i - 1])) {
+ return true;
+ }
+
+ // we look for 2 methods calls in a row
+ if (! $stmt instanceof Expression) {
+ return true;
+ }
+
+ $prevStmt = $node->stmts[$i - 1];
+
+ return ! $prevStmt instanceof Expression;
+ }
}
diff --git a/src/Rector/Psr4/MultipleClassFileToPsr4ClassesRector.php b/src/Rector/Psr4/MultipleClassFileToPsr4ClassesRector.php
index 50bada08e808..bf6d57066513 100644
--- a/src/Rector/Psr4/MultipleClassFileToPsr4ClassesRector.php
+++ b/src/Rector/Psr4/MultipleClassFileToPsr4ClassesRector.php
@@ -128,22 +128,8 @@ private function processNamespaceNodes(
/** @var ClassLike[] $classLikes */
$classLikes = $this->betterNodeFinder->findClassLikes($nodes);
- if (count($classLikes) <= 1) {
- continue;
- }
-
foreach ($classLikes as $classLikeNode) {
- $this->removeAllClassLikesFromNamespaceNode($newStmt);
- $newStmt->stmts[] = $classLikeNode;
-
- $fileDestination = $this->createClassLikeFileDestination($classLikeNode, $smartFileInfo);
-
- // has file changed?
- if ($shouldDeleteFile) {
- $this->printNewNodesToFilePath($newStmtsSet, $fileDestination);
- } else {
- $this->printNodesToFilePath($newStmtsSet, $fileDestination);
- }
+ $this->refactorClassLike($smartFileInfo, $shouldDeleteFile, $newStmt, $classLikeNode, $newStmtsSet);
}
}
}
@@ -214,4 +200,24 @@ private function createClassLikeFileDestination(ClassLike $classLike, SmartFileI
return $currentDirectory . DIRECTORY_SEPARATOR . $classLike->name . '.php';
}
+
+ private function refactorClassLike(
+ SmartFileInfo $smartFileInfo,
+ bool $shouldDeleteFile,
+ Namespace_ $newStmt,
+ ClassLike $classLike,
+ array $newStmtsSet
+ ): void {
+ $this->removeAllClassLikesFromNamespaceNode($newStmt);
+ $newStmt->stmts[] = $classLike;
+
+ $fileDestination = $this->createClassLikeFileDestination($classLike, $smartFileInfo);
+
+ // has file changed?
+ if ($shouldDeleteFile) {
+ $this->printNewNodesToFilePath($newStmtsSet, $fileDestination);
+ } else {
+ $this->printNodesToFilePath($newStmtsSet, $fileDestination);
+ }
+ }
}