[ECS] Remove cognitive complexity ignores

This commit is contained in:
TomasVotruba 2020-02-09 12:31:31 +01:00
parent 4b3d5b477f
commit c52f03a019
126 changed files with 2470 additions and 1701 deletions

View File

@ -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

View File

@ -18,7 +18,7 @@ $stubFinder->files()->name('*.php')
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;
}

View File

@ -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",

View File

@ -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);
+}
}
```
<br>

View File

@ -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'
# 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/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'
- "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

View File

@ -112,22 +112,13 @@ PHP
{
$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 @@ PHP
$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 @@ PHP
$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;
}
}

View File

@ -10,7 +10,7 @@ use PHPStan\Type\ObjectType;
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 @@ final class ClassAnalyzer
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 @@ final class ClassAnalyzer
$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 @@ final class ClassAnalyzer
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;
}
}

View File

@ -9,7 +9,7 @@ use Doctrine\Common\Annotations\Reader;
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 @@ final class NodeAnnotationReader
$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 @@ final class NodeAnnotationReader
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 @@ final class NodeAnnotationReader
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);

View File

@ -113,20 +113,20 @@ final class ColumnTagValueNode extends AbstractDoctrineTagValueNode
$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);

View File

@ -119,17 +119,6 @@ final class JoinColumnTagValueNode extends AbstractDoctrineTagValueNode implemen
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;

View File

@ -11,18 +11,18 @@ use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagValueNode;
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 @@ final class JMSInjectPhpDocNodeFactory extends AbstractPhpDocNodeFactory
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);

View File

@ -6,7 +6,6 @@ namespace Rector\BetterPhpDocParser\PhpDocParser;
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 @@ final class AnnotationContentResolver
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;
}
$start = $this->tryStartWithKey($name, $start, $tokenIterator);
if (! $start) {
$tokenIterator->next();
continue;
}
$tokenContents[] = $tokenIterator->currentTokenValue();
// opening bracket {
if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET)) {
++$openedCurlyBracketCount;
}
// closing bracket }
if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
--$openedCurlyBracketCount;
// the final one
if ($openedCurlyBracketCount === 0) {
break;
}
}
$tokenIterator->next();
while (true) {
// the end
if (in_array($tokenIterator->currentTokenType(), [Lexer::TOKEN_CLOSE_PHPDOC, Lexer::TOKEN_END], true)) {
break;
}
return implode('', $tokenContents);
} catch (ParserException $parserException) {
throw $parserException;
$start = $this->tryStartWithKey($name, $start, $tokenIterator);
if (! $start) {
$tokenIterator->next();
continue;
}
$tokenContents[] = $tokenIterator->currentTokenValue();
// opening bracket {
if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_OPEN_CURLY_BRACKET)) {
++$openedCurlyBracketCount;
}
// closing bracket }
if ($tokenIterator->isCurrentTokenType(Lexer::TOKEN_CLOSE_CURLY_BRACKET)) {
--$openedCurlyBracketCount;
// the final one
if ($openedCurlyBracketCount === 0) {
break;
}
}
$tokenIterator->next();
}
return implode('', $tokenContents);
}
private function cleanMultilineAnnotationContent(string $annotationContent): string

View File

@ -43,16 +43,7 @@ final class ClassAnnotationMatcher
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 @@ final class ClassAnnotationMatcher
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;
}
}

View File

@ -9,7 +9,7 @@ use PhpParser\Node\Expr\MethodCall;
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 @@ final class DoctrineRepositoryClassMethodManipulator
return null;
}
if (! $this->nameResolver->isName($node->name, 'find')) {
if (! $this->nodeNameResolver->isName($node->name, 'find')) {
return null;
}

View File

@ -12,7 +12,7 @@ use PhpParser\Node\Stmt\ClassMethod;
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 @@ final class TemplateMethodCallManipulator
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');
}
}

View File

@ -75,28 +75,42 @@ PHP
private function processBoolTypeToNotBool(Node $node, Expr $leftExpr, Expr $rightExpr): ?Expr
{
if ($node instanceof Identical) {
if ($this->isTrue($rightExpr)) {
return $leftExpr;
}
if ($this->isFalse($rightExpr)) {
// prevent !!
if ($leftExpr instanceof BooleanNot) {
return $leftExpr->expr;
}
return new BooleanNot($leftExpr);
}
return $this->refactorIdentical($leftExpr, $rightExpr);
}
if ($node instanceof NotIdentical) {
if ($this->isFalse($rightExpr)) {
return $leftExpr;
return $this->refactorNotIdentical($leftExpr, $rightExpr);
}
return null;
}
private function refactorIdentical(Expr $leftExpr, Expr $rightExpr): ?Expr
{
if ($this->isTrue($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;

View File

@ -8,24 +8,24 @@ use PhpParser\Node;
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 @@ final class UseImportsTraverser
}
foreach ($node->uses as $useUse) {
$name = $this->nameResolver->getName($useUse);
$name = $this->nodeNameResolver->getName($useUse);
$callable($useUse, $name);
}
}
@ -84,7 +84,7 @@ final class UseImportsTraverser
continue;
}
$name = $prefixName . '\\' . $this->nameResolver->getName($useUse);
$name = $prefixName . '\\' . $this->nodeNameResolver->getName($useUse);
$callable($useUse, $name);
}
}

View File

@ -10,7 +10,7 @@ use PhpParser\Node\Stmt\Class_;
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 @@ final class UsedImportsResolver
// add class itself
if ($class !== null) {
$className = $this->nameResolver->getName($class);
$className = $this->nodeNameResolver->getName($class);
if ($className !== null) {
$usedImports[] = new FullyQualifiedObjectType($className);
}

View File

@ -8,18 +8,18 @@ use Nette\Utils\Strings;
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 @@ final class ClassNaming
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();
}

View File

@ -13,7 +13,7 @@ use Rector\CodingStyle\Application\UseAddingCommander;
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 @@ final class NameImporter
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 @@ final class NameImporter
$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;
}

View File

@ -81,11 +81,12 @@ PHP
{
$this->reset();
$hasChanged = false;
if ($node->stmts === null) {
return null;
}
$hasChanged = false;
foreach ($node->stmts as $key => $stmt) {
$currentStmtVariableName = null;

View File

@ -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 @@ PHP
$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 @@ PHP
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 @@ PHP
$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 @@ PHP
continue;
}
$useNamesAliasToName[$shortName][] = $alias;
$this->useNamesAliasToName[$shortName][] = $alias;
}
return $useNamesAliasToName;
}
private function shouldSkip(string $lastName, string $aliasName): bool
@ -184,81 +175,42 @@ PHP
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 @@ PHP
}
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;
}
}

View File

@ -16,7 +16,7 @@ use Rector\BetterPhpDocParser\Contract\Doctrine\MappedByNodeInterface;
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 @@ use Rector\NodeTypeResolver\NodeTypeResolver;
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 @@ final class DoctrineEntityManipulator
return false;
}
if (! $this->nameResolver->isName($node->name, $methodName)) {
if (! $this->nodeNameResolver->isName($node->name, $methodName)) {
return false;
}

View File

@ -0,0 +1,128 @@
<?php
declare(strict_types=1);
namespace Rector\DeadCode\NodeManipulator;
use PhpParser\Node;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\ArrayDimFetch;
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\PropertyFetch;
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;
final class LivingCodeManipulator
{
/**
* @param Node|int|string|null $expr
* @return Expr[]
*/
public 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 ($this->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_;
}
}

View File

@ -22,6 +22,7 @@ use Rector\Core\RectorDefinition\RectorDefinition;
use Rector\NodeTypeResolver\Node\AttributeKey;
use ReflectionClass;
use ReflectionMethod;
use ReflectionParameter;
/**
* @see \Rector\DeadCode\Tests\Rector\ClassMethod\RemoveDelegatingParentCallRector\RemoveDelegatingParentCallRectorTest
@ -223,17 +224,8 @@ PHP
/** @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 @@ PHP
}
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());
}
}

View File

@ -17,7 +17,7 @@ use Rector\Core\Rector\AbstractRector;
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

View File

@ -58,7 +58,7 @@ PHP
*/
public function refactor(Node $node): ?Node
{
$livingCode = $this->keepLivingCodeFromExpr($node->expr);
$livingCode = $this->livingCodeManipulator->keepLivingCodeFromExpr($node->expr);
if ($livingCode === []) {
return $this->removeNodeAndKeepComments($node);
}

View File

@ -8,15 +8,15 @@ use Nette\Utils\Strings;
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 @@ final class ClassUnusedPrivateClassMethodResolver
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 @@ final class ClassUnusedPrivateClassMethodResolver
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);

View File

@ -14,7 +14,7 @@ use PhpParser\Node\Param;
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 @@ final class UnusedClassResolver
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 @@ final class UnusedClassResolver
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 @@ final class UnusedClassResolver
/** @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 @@ final class UnusedClassResolver
/** @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 @@ final class UnusedClassResolver
$classNames = [];
foreach ($classConstFetches as $classConstFetch) {
$className = $this->nameResolver->getName($classConstFetch->class);
$className = $this->nodeNameResolver->getName($classConstFetch->class);
if (! is_string($className)) {
continue;
}

View File

@ -12,7 +12,7 @@ use Rector\BetterPhpDocParser\PhpDocNode\Doctrine\Property_\ColumnTagValueNode;
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 @@ final class EntityWithMissingUuidProvider
continue;
}
if (! $this->nameResolver->isName($classStmt, 'id')) {
if (! $this->nodeNameResolver->isName($classStmt, 'id')) {
continue;
}

View File

@ -7,6 +7,7 @@ namespace Rector\Laravel\Rector\FuncCall;
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 @@ PHP
}
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 @@ PHP
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;
}
}

View File

@ -128,24 +128,31 @@ PHP
continue;
}
if (! $property->isPublic()) {
// 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)) {
if ($property->isPublic()) {
continue;
}
$this->removeNodeFromStatements($node, $property);
// remove non-public empty
if ($property->stmts === []) {
$this->removeNodeFromStatements($node, $property);
} else {
$this->makePublic($property);
}
}
$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($class, $property);
}
}
}

View File

@ -221,42 +221,10 @@ PHP
}
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 @@ PHP
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;
}
}

View File

@ -20,7 +20,7 @@ use Prophecy\Doubler\Generator\Node\MethodNode;
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 @@ final class AssertManipulator
*/
public function processStaticCall(StaticCall $staticCall): Node
{
if ($this->nameResolver->isNames($staticCall, ['contains', 'notContains'])) {
$this->processContainsCall($staticCall);
} elseif ($this->nameResolver->isNames($staticCall, ['exception', 'throws'])) {
$this->processExceptionCall($staticCall);
} elseif ($this->nameResolver->isName($staticCall, 'type')) {
$this->processTypeCall($staticCall);
} elseif ($this->nameResolver->isName($staticCall, 'noError')) {
$this->processNoErrorCall($staticCall);
} elseif ($this->nameResolver->isNames($staticCall, ['truthy', 'falsey'])) {
if ($this->nodeNameResolver->isNames($staticCall, ['truthy', 'falsey'])) {
return $this->processTruthyOrFalseyCall($staticCall);
}
if ($this->nodeNameResolver->isNames($staticCall, ['contains', 'notContains'])) {
$this->processContainsCall($staticCall);
} elseif ($this->nodeNameResolver->isNames($staticCall, ['exception', 'throws'])) {
$this->processExceptionCall($staticCall);
} elseif ($this->nodeNameResolver->isName($staticCall, 'type')) {
$this->processTypeCall($staticCall);
} elseif ($this->nodeNameResolver->isName($staticCall, 'noError')) {
$this->processNoErrorCall($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 @@ final class AssertManipulator
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 @@ final class AssertManipulator
// 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 @@ final class AssertManipulator
*/
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 @@ final class AssertManipulator
{
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);
}
}
}

View File

@ -11,16 +11,16 @@ use PhpParser\Node\Expr\New_;
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 @@ final class RouteInfoFactory
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,65 +95,12 @@ final class RouteInfoFactory
$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;
}
[$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->nameResolver->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, []);
return $this->createForString($targetNode, $routePath);
}
return null;
@ -163,4 +110,73 @@ final class RouteInfoFactory
{
return str_replace(['<', '>'], ['{', '}'], $routePath);
}
/**
* @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;
// SomePresenter::class
if ($this->nodeNameResolver->isName($controllerMethodNode->name, 'class')) {
$presenterClass = $this->nodeNameResolver->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 null;
}
private function createForString(String_ $string, string $routePath): ?RouteInfo
{
$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, []);
}
}

View File

@ -16,7 +16,7 @@ use PhpParser\Node\Scalar\String_;
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 @@ final class SymfonyFormAbstractTypeFactory
// 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);

View File

@ -11,7 +11,7 @@ use PhpParser\Node\Expr\MethodCall;
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 @@ final class TemplatePropertyAssignCollector
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 @@ final class TemplatePropertyAssignCollector
$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 @@ final class TemplatePropertyAssignCollector
{
// $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 @@ final class TemplatePropertyAssignCollector
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');
}
}

View File

@ -12,7 +12,7 @@ use PHPStan\Type\ArrayType;
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 @@ final class PregMatchTypeCorrector
continue;
}
if (! $this->nameResolver->isNames($funcCallNode, ['preg_match', 'preg_match_all'])) {
if (! $this->nodeNameResolver->isNames($funcCallNode, ['preg_match', 'preg_match_all'])) {
continue;
}

View File

@ -32,7 +32,7 @@ use PHPStan\Type\UnionType;
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 @@ final class NodeTypeResolver
ObjectTypeSpecifier $objectTypeSpecifier,
array $perNodeTypeResolvers
) {
$this->nameResolver = $nameResolver;
$this->nodeNameResolver = $nodeNameResolver;
foreach ($perNodeTypeResolvers as $perNodeTypeResolver) {
$this->addPerNodeTypeResolver($perNodeTypeResolver);
@ -162,15 +162,7 @@ final class NodeTypeResolver
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 @@ final class NodeTypeResolver
}
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 @@ final class NodeTypeResolver
/** @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 @@ final class NodeTypeResolver
return false;
}
$className = $this->nameResolver->getName($node);
$className = $this->nodeNameResolver->getName($node);
return $className === null || Strings::contains($className, 'AnonymousClass');
}
@ -460,7 +444,7 @@ final class NodeTypeResolver
}
// 3rd party code
$propertyName = $this->nameResolver->getName($propertyFetch->name);
$propertyName = $this->nodeNameResolver->getName($propertyFetch->name);
if ($propertyName === null) {
return null;
}
@ -500,4 +484,30 @@ final class NodeTypeResolver
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();
}
}

View File

@ -50,17 +50,7 @@ final class StaticTypeAnalyzer
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 @@ final class StaticTypeAnalyzer
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;
}
}

View File

@ -14,7 +14,7 @@ use PHPStan\Type\MixedType;
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 @@ use Rector\NodeTypeResolver\NodeTypeResolver;
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 @@ final class ParamTypeResolver implements PerNodeTypeResolverInterface
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 @@ final class ParamTypeResolver implements PerNodeTypeResolverInterface
}
/** @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 @@ final class ParamTypeResolver implements PerNodeTypeResolverInterface
return null;
}
if (! $this->nameResolver->isName($node, $paramName)) {
if (! $this->nodeNameResolver->isName($node, $paramName)) {
return null;
}
@ -131,7 +131,7 @@ final class ParamTypeResolver implements PerNodeTypeResolverInterface
$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);

View File

@ -9,7 +9,7 @@ use PhpParser\Node\Expr\StaticCall;
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 @@ final class StaticCallTypeResolver implements PerNodeTypeResolverInterface
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. <ClassType>::$method()
if (! is_string($methodName)) {

View File

@ -12,7 +12,7 @@ use PHPStan\Analyser\Scope;
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 @@ use Rector\NodeTypeResolver\PHPStan\Collector\TraitNodeScopeCollector;
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 @@ final class VariableTypeResolver implements PerNodeTypeResolverInterface
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 @@ final class VariableTypeResolver implements PerNodeTypeResolverInterface
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);
}
// get nearest variable scope
$method = $node->getAttribute(AttributeKey::METHOD_NODE);
if ($method instanceof Node) {
$methodNodeScope = $method->getAttribute(AttributeKey::SCOPE);
if ($methodNodeScope !== null) {
return $methodNodeScope;
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;
}
$parentNodeScope = $parentNode->getAttribute(AttributeKey::SCOPE);
if ($parentNodeScope === null) {
continue;
}
return $parentNodeScope;
}
return null;

View File

@ -14,7 +14,7 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
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 @@ final class DocBlockNameImporter
PhpDocNodeTraverser $phpDocNodeTraverser,
StaticTypeMapper $staticTypeMapper,
UseAddingCommander $useAddingCommander,
NameResolver $nameResolver,
NodeNameResolver $nodeNameResolver,
BetterStandardPrinter $betterStandardPrinter,
ImportSkipper $importSkipper,
ParameterProvider $parameterProvider
@ -82,7 +82,7 @@ final class DocBlockNameImporter
$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 @@ final class DocBlockNameImporter
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()];

View File

@ -10,6 +10,7 @@ use PhpParser\Node\Identifier;
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\PhpDocParser\Ast\Type\TypeNode;
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 @@ final class StaticTypeMapper
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;
}
}

View File

@ -20,7 +20,7 @@ use PHPStan\Type\ThisType;
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 @@ final class ArrayTypeAnalyzer
return false;
}
$propertyName = $this->nameResolver->getName($node->name);
$propertyName = $this->nodeNameResolver->getName($node->name);
if ($propertyName === null) {
return false;
}

View File

@ -9,7 +9,7 @@ use PhpParser\Node;
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;

View File

@ -11,23 +11,23 @@ use PhpParser\Node\Expr\Instanceof_;
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 @@ final class IsArrayAndDualCheckToAble
}
/** @var FuncCall $funcCallNode */
if ($this->nameResolver->getName($funcCallNode) !== 'is_array') {
if ($this->nodeNameResolver->getName($funcCallNode) !== 'is_array') {
return null;
}

View File

@ -16,7 +16,7 @@ use Rector\Core\RectorDefinition\RectorDefinition;
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

View File

@ -8,7 +8,7 @@ use PhpParser\Node;
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 @@ final class LetManipulator
return null;
}
return $this->nameResolver->isName($node->name, 'beConstructedThrough');
return $this->nodeNameResolver->isName($node->name, 'beConstructedThrough');
}
);

View File

@ -13,7 +13,7 @@ use PhpParser\Node\Stmt\Class_;
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;
}

View File

@ -10,7 +10,7 @@ use PhpParser\Node\Param;
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 @@ final class PhpSpecMockCollector
*/
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 @@ final class PhpSpecMockCollector
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 @@ final class PhpSpecMockCollector
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 @@ final class PhpSpecMockCollector
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);

View File

@ -32,28 +32,13 @@ use Rector\PhpSpecToPHPUnit\Rector\AbstractPhpSpecToPHPUnitRector;
*/
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 @@ final class PhpSpecPromisesToPHPUnitAssertRector extends AbstractPhpSpecToPHPUni
$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 @@ final class PhpSpecPromisesToPHPUnitAssertRector extends AbstractPhpSpecToPHPUni
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');
}
}

View File

@ -32,6 +32,24 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
*/
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 @@ PHP
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;
}
}

View File

@ -11,7 +11,7 @@ use PhpParser\Node\Expr\PropertyFetch;
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 @@ use Rector\SymfonyPHPUnit\Node\KernelTestCaseNodeAnalyzer;
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 @@ final class OnContainerGetCallManipulator
return null;
}
$variableName = $this->nameResolver->getName($node);
$variableName = $this->nodeNameResolver->getName($node);
if ($variableName === null) {
return null;
}
@ -151,7 +151,7 @@ final class OnContainerGetCallManipulator
string $type,
array &$formerVariablesByMethods
): void {
$variableName = $this->nameResolver->getName($assign->var);
$variableName = $this->nodeNameResolver->getName($assign->var);
if ($variableName === null) {
return;
}

View File

@ -77,7 +77,9 @@ final class ArrayArgumentInTestToDataProviderRector extends AbstractPHPUnitRecto
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 @@ class SomeServiceTest extends \PHPUnit\Framework\TestCase
PHP
,
<<<'PHP'
class SomeServiceTest extends \PHPUnit\Framework\TestCase
use PHPUnit\Framework\TestCase;
class SomeServiceTest extends TestCase
{
/**
* @dataProvider provideData()
@ -134,12 +138,12 @@ PHP
*/
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 @@ PHP
}
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 @@ PHP
*/
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 @@ PHP
{
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;
}
}

View File

@ -12,7 +12,7 @@ use PhpParser\Node\Expr\BinaryOp\NotEqual;
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 @@ use Rector\Polyfill\ValueObject\VersionCompareCondition;
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 @@ final class ConditionResolver
return false;
}
return $this->nameResolver->isName($node, 'version_compare');
return $this->nodeNameResolver->isName($node, 'version_compare');
}
private function resolveVersionCompareConditionForFuncCall(FuncCall $funcCall)

View File

@ -9,7 +9,7 @@ use PhpParser\Node;
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 @@ use Symplify\SmartFileSystem\SmartFileInfo;
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 @@ final class FactoryClassPrinter
}
$directoryPath = Strings::before($classFileInfo->getRealPath(), DIRECTORY_SEPARATOR, -1);
$resolvedOldClass = $this->nameResolver->getName($oldClass);
$resolvedOldClass = $this->nodeNameResolver->getName($oldClass);
if ($resolvedOldClass === null) {
throw new ShouldNotHappenException();
}

View File

@ -22,16 +22,16 @@ use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
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 @@ final class UniqueObjectFactoryFactory
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 @@ final class UniqueObjectFactoryFactory
}
foreach ($properties as $property) {
$propertyName = $this->nameResolver->getName($property);
$propertyName = $this->nodeNameResolver->getName($property);
if (! is_string($propertyName)) {
throw new ShouldNotHappenException();
}

View File

@ -7,7 +7,7 @@ namespace Rector\Sensio\Helper;
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 @@ use Rector\NodeTypeResolver\Node\AttributeKey;
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 @@ final class TemplateGuesser
throw new ShouldNotHappenException();
}
$method = $this->nameResolver->getName($classMethod);
$method = $this->nodeNameResolver->getName($classMethod);
if ($method === null) {
throw new ShouldNotHappenException();
}

View File

@ -9,7 +9,7 @@ use PHPStan\Type\ObjectType;
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 @@ final class ClassConstantFetchAnalyzer
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 @@ final class ClassConstantFetchAnalyzer
}
foreach ($classOrInterface->getConstants() as $classConstant) {
if ($this->nameResolver->isName($classConstant, $constant)) {
if ($this->nodeNameResolver->isName($classConstant, $constant)) {
return $className;
}
}

View File

@ -6,7 +6,7 @@ namespace Rector\SymfonyPHPUnit\Node;
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 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
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 @@ final class KernelTestCaseNodeAnalyzer
return false;
}
if (! $this->nameResolver->isName($node->name, 'get')) {
if (! $this->nodeNameResolver->isName($node->name, 'get')) {
return false;
}

View File

@ -19,6 +19,7 @@ use Symfony\Component\Console\Command\Command;
/**
* @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 @@ PHP
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 @@ PHP
$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;
}
}

View File

@ -7,24 +7,24 @@ namespace Rector\TypeDeclaration\PhpDocParser;
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 @@ final class ParamPhpDocNodeFactory
return new AttributeAwareParamTagValueNode(
$typeNode,
$param->variadic,
'$' . $this->nameResolver->getName($param),
'$' . $this->nodeNameResolver->getName($param),
'',
$param->byRef
);

View File

@ -34,25 +34,14 @@ final class PhpParserTypeAnalyzer
}
// unwrap nullable types
if ($possibleParentType instanceof NullableType) {
$possibleParentType = $possibleParentType->type;
}
$possibleParentType = $this->unwrapNullableAndToString($possibleParentType);
$possibleSubtype = $this->unwrapNullableAndToString($possibleSubtype);
if ($possibleSubtype instanceof NullableType) {
$possibleSubtype = $possibleSubtype->type;
}
$possibleSubtype = $possibleSubtype->toString();
$possibleParentType = $possibleParentType->toString();
if (is_a($possibleSubtype, $possibleParentType, true)) {
return true;
}
if (in_array($possibleSubtype, ['array', 'Traversable'], true) && $possibleParentType === 'iterable') {
return true;
}
if (in_array($possibleSubtype, ['array', 'ArrayIterator'], true) && $possibleParentType === 'countable') {
if ($this->isTraversableOrIterableSubtype($possibleSubtype, $possibleParentType)) {
return true;
}
@ -62,4 +51,25 @@ final class PhpParserTypeAnalyzer
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 in_array($possibleSubtype, ['array', 'ArrayIterator'], true) && $possibleParentType === 'countable';
}
}

View File

@ -20,7 +20,7 @@ use Rector\Core\Rector\AbstractRector;
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

View File

@ -143,7 +143,7 @@ PHP
}
$position = (int) $position;
if ($node instanceof ClassMethod && $this->vendorLockResolver->isParameterChangeVendorLockedIn(
if ($node instanceof ClassMethod && $this->vendorLockResolver->isParamChangeVendorLockedIn(
$node,
$position
)) {

View File

@ -4,7 +4,7 @@ declare(strict_types=1);
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;

View File

@ -59,7 +59,7 @@ final class AssignToPropertyTypeInferer extends AbstractTypeInferer
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 @@ final class AssignToPropertyTypeInferer extends AbstractTypeInferer
}
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;
}

View File

@ -42,7 +42,7 @@ final class GetterNodeParamTypeInferer extends AbstractTypeInferer implements Pa
$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 === []) {

View File

@ -37,7 +37,7 @@ final class PropertyNodeParamTypeInferer extends AbstractTypeInferer implements
return new MixedType();
}
$paramName = $this->nameResolver->getName($param);
$paramName = $this->nodeNameResolver->getName($param);
if (! is_string($paramName)) {
throw new ShouldNotHappenException();
}

View File

@ -35,7 +35,7 @@ final class AllAssignNodePropertyTypeInferer extends AbstractTypeInferer impleme
return new MixedType();
}
$propertyName = $this->nameResolver->getName($property);
$propertyName = $this->nodeNameResolver->getName($property);
if (! is_string($propertyName)) {
throw new ShouldNotHappenException();
}

View File

@ -53,7 +53,7 @@ final class ConstructorPropertyTypeInferer extends AbstractTypeInferer implement
return new MixedType();
}
$propertyName = $this->nameResolver->getName($property);
$propertyName = $this->nodeNameResolver->getName($property);
if (! is_string($propertyName)) {
throw new ShouldNotHappenException();
}
@ -65,25 +65,7 @@ final class ConstructorPropertyTypeInferer extends AbstractTypeInferer implement
// 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 @@ final class ConstructorPropertyTypeInferer extends AbstractTypeInferer implement
return null;
}
if (! $this->nameResolver->isName($node, $propertyName)) {
if (! $this->nodeNameResolver->isName($node, $propertyName)) {
return null;
}
@ -165,7 +147,7 @@ final class ConstructorPropertyTypeInferer extends AbstractTypeInferer implement
return null;
}
$fullyQualifiedName = $this->nameResolver->getName($param->type);
$fullyQualifiedName = $this->nodeNameResolver->getName($param->type);
if (! $fullyQualifiedName) {
return null;
}
@ -189,4 +171,27 @@ final class ConstructorPropertyTypeInferer extends AbstractTypeInferer implement
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);
}
}

View File

@ -55,7 +55,7 @@ final class GetterPropertyTypeInferer extends AbstractTypeInferer implements Pro
}
/** @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 @@ final class GetterPropertyTypeInferer extends AbstractTypeInferer implements Pro
return false;
}
return $this->nameResolver->isName($return->expr, $propertyName);
return $this->nodeNameResolver->isName($return->expr, $propertyName);
}
private function inferClassMethodReturnType(ClassMethod $classMethod): Type

View File

@ -39,7 +39,7 @@ final class GetterTypeDeclarationPropertyTypeInferer extends AbstractTypeInferer
}
/** @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 @@ final class GetterTypeDeclarationPropertyTypeInferer extends AbstractTypeInferer
return false;
}
return $this->nameResolver->isName($return->expr, $propertyName);
return $this->nodeNameResolver->isName($return->expr, $propertyName);
}
}

View File

@ -33,7 +33,7 @@ final class SingleMethodAssignedNodePropertyTypeInferer extends AbstractTypeInfe
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 @@ final class SingleMethodAssignedNodePropertyTypeInferer extends AbstractTypeInfe
return null;
}
if (! $this->nameResolver->isName($node->var, $propertyName)) {
if (! $this->nodeNameResolver->isName($node->var, $propertyName)) {
return null;
}

View File

@ -30,7 +30,7 @@ final class ReturnTypeDeclarationReturnTypeInferer extends AbstractTypeInferer i
}
// 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();
}

View File

@ -595,7 +595,7 @@ class Command
*/
private $processTitle;
/**
* @var \Symfony\Component\Console\Input\InputDefinition
* @var InputDefinition
*/
private $definition;
/**

View File

@ -0,0 +1,7 @@
services:
_defaults:
public: true
autowire: true
Rector\VendorLocker\:
resource: '../src'

View File

@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace Rector\VendorLocker\Contract;
use PhpParser\Node;
interface NodeVendorLockerInterface
{
public function resolve(Node $node): bool;
}

View File

@ -0,0 +1,138 @@
<?php
declare(strict_types=1);
namespace Rector\VendorLocker;
use PhpParser\Node\Stmt\Class_;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\ClassMethod;
use PhpParser\Node\Stmt\Interface_;
use Rector\Core\NodeContainer\NodeCollector\ParsedNodeCollector;
use Rector\Core\PhpParser\Node\Manipulator\ClassManipulator;
use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
/**
* @todo decouple to standalone package "packages/vendor-locker"
*/
final class ReturnNodeVendorLockResolver
{
/**
* @var NodeNameResolver
*/
private $nodeNameResolver;
/**
* @var ClassManipulator
*/
private $classManipulator;
/**
* @var ParsedNodeCollector
*/
private $parsedNodeCollector;
public function __construct(
NodeNameResolver $nodeNameResolver,
ParsedNodeCollector $parsedNodeCollector,
ClassManipulator $classManipulator
) {
$this->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;
}
}

View File

@ -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\ClassLike;
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 @@ final class VendorLockResolver
return false;
}
$methodName = $this->nameResolver->getName($classMethod);
$methodName = $this->nodeNameResolver->getName($classMethod);
if (! is_string($methodName)) {
throw new ShouldNotHappenException();
}
@ -66,25 +76,9 @@ final class VendorLockResolver
$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 @@ final class VendorLockResolver
}
$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 @@ final class VendorLockResolver
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 @@ final class VendorLockResolver
$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 @@ final class VendorLockResolver
*/
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 @@ final class VendorLockResolver
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 @@ final class VendorLockResolver
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;
}
}

View File

@ -7,7 +7,7 @@ namespace Rector\ZendToSymfony\Detector;
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 @@ final class ZendDetector
return false;
}
return $this->nameResolver->isName($classMethod, '*Action');
return $this->nodeNameResolver->isName($classMethod, '*Action');
}
}

View File

@ -58,9 +58,9 @@ public function someAction()
{
$templateData = [];
$templateData['value']; = 5;
return $this->render("...", $templateData);
}
}
PHP
)]
);

View File

@ -10,7 +10,7 @@ use PhpParser\Node\Scalar\String_;
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 @@ final class ControllerMethodParamResolver
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;
}

View File

@ -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#'

View File

@ -19,7 +19,7 @@ use PhpParser\Node\Stmt\Namespace_;
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 @@ final class ScreenFileCommand extends AbstractCommand
SymfonyStyle $symfonyStyle,
FileInfoParser $fileInfoParser,
CallableNodeTraverser $callableNodeTraverser,
NameResolver $nameResolver,
NodeNameResolver $nodeNameResolver,
NodeTypeResolver $nodeTypeResolver,
BetterStandardPrinter $betterStandardPrinter,
StaticTypeMapper $staticTypeMapper
@ -87,7 +87,7 @@ final class ScreenFileCommand extends AbstractCommand
$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 @@ final class ScreenFileCommand extends AbstractCommand
$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 @@ final class ScreenFileCommand extends AbstractCommand
*/
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 @@ final class ScreenFileCommand extends AbstractCommand
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;
}
}

View File

@ -0,0 +1,14 @@
<?php
declare(strict_types=1);
namespace Rector\Core\Contract\NameResolver;
use PhpParser\Node;
interface NodeNameResolverInterface
{
public function getNode(): string;
public function resolve(Node $node): ?string;
}

View File

@ -18,7 +18,7 @@ use PHPStan\Type\MixedType;
use PHPStan\Type\ObjectType;
use PHPStan\Type\Type;
use PHPStan\Type\UnionType;
use Rector\Core\PhpParser\Node\Resolver\NameResolver;
use Rector\Core\PhpParser\Node\Resolver\NodeNameResolver;
use Rector\NodeTypeResolver\Node\AttributeKey;
use Rector\NodeTypeResolver\NodeTypeResolver;
@ -49,18 +49,18 @@ final class ParsedFunctionLikeNodeCollector
private $arrayCallablesByTypeAndMethod = [];
/**
* @var NameResolver
* @var NodeNameResolver
*/
private $nameResolver;
private $nodeNameResolver;
/**
* @var NodeTypeResolver
*/
private $nodeTypeResolver;
public function __construct(NameResolver $nameResolver)
public function __construct(NodeNameResolver $nodeNameResolver)
{
$this->nameResolver = $nameResolver;
$this->nodeNameResolver = $nodeNameResolver;
}
/**
@ -100,7 +100,7 @@ final class ParsedFunctionLikeNodeCollector
}
if ($node instanceof Function_) {
$functionName = $this->nameResolver->getName($node);
$functionName = $this->nodeNameResolver->getName($node);
if ($functionName === null) {
return;
}
@ -153,7 +153,7 @@ final class ParsedFunctionLikeNodeCollector
return;
}
$methodName = $this->nameResolver->getName($classMethod);
$methodName = $this->nodeNameResolver->getName($classMethod);
$this->methodsByType[$className][$methodName] = $classMethod;
}
@ -204,17 +204,9 @@ final class ParsedFunctionLikeNodeCollector
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 @@ final class ParsedFunctionLikeNodeCollector
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 @@ final class ParsedFunctionLikeNodeCollector
return false;
}
return $this->nameResolver->isName($node->class, $className);
return $this->nodeNameResolver->isName($node->class, $className);
}
return false;
@ -287,4 +279,20 @@ final class ParsedFunctionLikeNodeCollector
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);
}
}

View File

@ -20,7 +20,7 @@ use PhpParser\Node\Stmt\Interface_;
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 @@ final class ParsedNodeCollector
}
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 @@ final class ParsedNodeCollector
$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 @@ final class ParsedNodeCollector
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 @@ final class ParsedNodeCollector
}
/** @var string $constantName */
$constantName = $this->nameResolver->getName($classConstFetch->name);
$constantName = $this->nodeNameResolver->getName($classConstFetch->name);
return $this->findClassConstant($class, $constantName);
}
@ -270,7 +270,7 @@ final class ParsedNodeCollector
return;
}
$constantName = $this->nameResolver->getName($classConst);
$constantName = $this->nodeNameResolver->getName($classConst);
$this->constantsByType[$className][$constantName] = $classConst;
}

View File

@ -10,7 +10,7 @@ use PhpParser\Node\Stmt\ClassLike;
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 @@ final class ClassLikeParsedNodesFinder
foreach ($classLike->getTraitUses() as $traitUse) {
foreach ($traitUse->traits as $trait) {
$traitName = $this->nameResolver->getName($trait);
$traitName = $this->nodeNameResolver->getName($trait);
if ($traitName === null) {
continue;
}

View File

@ -12,7 +12,7 @@ use PhpParser\Node\Stmt\ClassMethod;
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 @@ use ReflectionClass;
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 @@ final class FunctionLikeParsedNodesFinder
return null;
}
$methodName = $this->nameResolver->getName($methodCall->name);
$methodName = $this->nodeNameResolver->getName($methodCall->name);
if ($methodName === null) {
return null;
}
@ -62,7 +62,7 @@ final class FunctionLikeParsedNodesFinder
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 @@ final class FunctionLikeParsedNodesFinder
}
/** @var string|null $methodName */
$methodName = $this->nameResolver->getName($classMethod);
$methodName = $this->nodeNameResolver->getName($classMethod);
if ($methodName === null) {
return [];
}

View File

@ -25,7 +25,7 @@ use PHPStan\Type\Constant\ConstantIntegerType;
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 @@ final class CallReflectionResolver
}
$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;

View File

@ -15,7 +15,7 @@ use PhpParser\Node\Expr\Variable;
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 @@ final class RegexPatternArgumentManipulator
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 @@ final class RegexPatternArgumentManipulator
}
foreach ($methodNamesToArgumentPosition as $methodName => $argumentPosition) {
if (! $this->nameResolver->isName($staticCall, $methodName)) {
if (! $this->nodeNameResolver->isName($staticCall, $methodName)) {
continue;
}

View File

@ -10,24 +10,24 @@ use PhpParser\Node\Expr\ArrayDimFetch;
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 @@ final class AssignManipulator
return false;
}
return $this->nameResolver->isNames($propertyFetch, $propertyNames);
return $this->nodeNameResolver->isNames($propertyFetch, $propertyNames);
}
/**
@ -95,7 +95,7 @@ final class AssignManipulator
return false;
}
return $this->nameResolver->isName($assign->expr, 'each');
return $this->nodeNameResolver->isName($assign->expr, 'each');
}
public function isNodeLeftPartOfAssign(Node $node): bool

View File

@ -8,7 +8,7 @@ use PhpParser\Node;
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 @@ final class ChainMethodCallManipulator
$methods = array_reverse($methods);
foreach ($methods as $method) {
$activeMethodName = $this->nameResolver->getName($node);
$activeMethodName = $this->nodeNameResolver->getName($node);
if ($activeMethodName !== $method) {
return false;
}

View File

@ -10,7 +10,7 @@ use PhpParser\Node\Stmt\Expression;
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 @@ final class ChildAndParentClassManipulator
public function completeChildConstructors(Class_ $classNode, ClassMethod $constructorClassMethod): void
{
$className = $this->nameResolver->getName($classNode);
$className = $this->nodeNameResolver->getName($classNode);
if ($className === null) {
return;
}

View File

@ -10,16 +10,16 @@ use PhpParser\Node\Stmt\Class_;
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 @@ final class ClassConstManipulator
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);
}
}

View File

@ -26,7 +26,7 @@ use PHPStan\Type\Type;
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 @@ use Rector\NodeTypeResolver\NodeTypeResolver;
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 @@ final class ClassManipulator
NodeTypeResolver $nodeTypeResolver
) {
$this->nodeFactory = $nodeFactory;
$this->nameResolver = $nameResolver;
$this->nodeNameResolver = $nodeNameResolver;
$this->childAndParentClassManipulator = $childAndParentClassManipulator;
$this->callableNodeTraverser = $callableNodeTraverser;
$this->nodeRemovingCommander = $nodeRemovingCommander;
@ -190,7 +190,7 @@ final class ClassManipulator
$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 @@ final class ClassManipulator
throw new ShouldNotHappenException();
}
if ($this->nameResolver->isName($property, $name)) {
if ($this->nodeNameResolver->isName($property, $name)) {
return $property;
}
}
@ -254,7 +254,7 @@ final class ClassManipulator
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 @@ final class ClassManipulator
}
/** @var string $propertyName */
$propertyName = $this->nameResolver->getName($property);
$propertyName = $this->nodeNameResolver->getName($property);
$privatePropertyNames[] = $propertyName;
}
@ -299,7 +299,7 @@ final class ClassManipulator
}
/** @var string $methodName */
$methodName = $this->nameResolver->getName($method);
$methodName = $this->nodeNameResolver->getName($method);
$publicMethodNames[] = $methodName;
}
@ -316,7 +316,7 @@ final class ClassManipulator
return null;
}
if (! $this->nameResolver->isNames($node, $propertyNames)) {
if (! $this->nodeNameResolver->isNames($node, $propertyNames)) {
return null;
}
@ -376,7 +376,7 @@ final class ClassManipulator
$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 @@ final class ClassManipulator
{
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 @@ final class ClassManipulator
{
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 @@ final class ClassManipulator
{
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 @@ final class ClassManipulator
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 @@ final class ClassManipulator
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 @@ final class ClassManipulator
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 @@ final class ClassManipulator
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 @@ final class ClassManipulator
{
$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 @@ final class ClassManipulator
$interfaceNames = [];
foreach ($class->implements as $implementNode) {
$interfaceName = $this->nameResolver->getName($implementNode);
$interfaceName = $this->nodeNameResolver->getName($implementNode);
if ($interfaceName === null) {
continue;
}
@ -656,7 +656,7 @@ final class ClassManipulator
$interfaceNames = [];
foreach ($interface->extends as $extendNode) {
$interfaceName = $this->nameResolver->getName($extendNode);
$interfaceName = $this->nodeNameResolver->getName($extendNode);
if ($interfaceName === null) {
continue;
}
@ -670,7 +670,7 @@ final class ClassManipulator
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;
}
}

View File

@ -13,7 +13,7 @@ use PhpParser\Node\Stmt\Class_;
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 @@ final class ClassMethodManipulator
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 @@ final class ClassMethodManipulator
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 @@ final class ClassMethodManipulator
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 @@ final class ClassMethodManipulator
return false;
}
return $this->nameResolver->isName($node, 'this');
return $this->nodeNameResolver->isName($node, 'this');
});
}
@ -161,7 +161,7 @@ final class ClassMethodManipulator
continue;
}
$paramName = $this->nameResolver->getName($paramNode);
$paramName = $this->nodeNameResolver->getName($paramNode);
if (! is_string($paramName)) {
throw new ShouldNotHappenException();
}
@ -178,7 +178,7 @@ final class ClassMethodManipulator
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 @@ final class ClassMethodManipulator
{
foreach ($possibleNames as $possibleName) {
foreach ($classMethod->params as $paramNode) {
if ($this->nameResolver->isName($paramNode, $possibleName)) {
if ($this->nodeNameResolver->isName($paramNode, $possibleName)) {
continue 2;
}
}

Some files were not shown because too many files have changed in this diff Show More