diff --git a/config/set/naming.php b/config/set/naming.php index 734669b65d2..5e2bf666b5f 100644 --- a/config/set/naming.php +++ b/config/set/naming.php @@ -8,6 +8,7 @@ use Rector\Naming\Rector\ClassMethod\MakeGetterClassMethodNameStartWithGetRector use Rector\Naming\Rector\ClassMethod\MakeIsserClassMethodNameStartWithIsRector; use Rector\Naming\Rector\ClassMethod\RenameParamToMatchTypeRector; use Rector\Naming\Rector\ClassMethod\RenameVariableToMatchNewTypeRector; +use Rector\Naming\Rector\Foreach_\RenameForeachValueVariableToMatchMethodCallReturnTypeRector; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; return static function (ContainerConfigurator $containerConfigurator): void { @@ -18,4 +19,5 @@ return static function (ContainerConfigurator $containerConfigurator): void { $services->set(RenameVariableToMatchMethodCallReturnTypeRector::class); $services->set(MakeGetterClassMethodNameStartWithGetRector::class); $services->set(MakeIsserClassMethodNameStartWithIsRector::class); + $services->set(RenameForeachValueVariableToMatchMethodCallReturnTypeRector::class); }; diff --git a/packages/better-php-doc-parser/src/Printer/PhpDocInfoPrinter.php b/packages/better-php-doc-parser/src/Printer/PhpDocInfoPrinter.php index e446f052d2f..162bd85cfbf 100644 --- a/packages/better-php-doc-parser/src/Printer/PhpDocInfoPrinter.php +++ b/packages/better-php-doc-parser/src/Printer/PhpDocInfoPrinter.php @@ -232,8 +232,8 @@ final class PhpDocInfoPrinter ): string { // skip removed nodes $positionJumpSet = []; - foreach ($this->getRemovedNodesPositions() as $removedTokensPosition) { - $positionJumpSet[$removedTokensPosition->getStart()] = $removedTokensPosition->getEnd(); + foreach ($this->getRemovedNodesPositions() as $startAndEnd) { + $positionJumpSet[$startAndEnd->getStart()] = $startAndEnd->getEnd(); } // include also space before, in case of inlined docs diff --git a/packages/caching/src/FileSystem/DependencyResolver.php b/packages/caching/src/FileSystem/DependencyResolver.php index 8a01b888558..a0af7a3066d 100644 --- a/packages/caching/src/FileSystem/DependencyResolver.php +++ b/packages/caching/src/FileSystem/DependencyResolver.php @@ -50,8 +50,8 @@ final class DependencyResolver } $dependencies = []; - foreach ($this->phpStanDependencyResolver->resolveDependencies($node, $scope) as $dependencyReflection) { - $dependencyFile = $dependencyReflection->getFileName(); + foreach ($this->phpStanDependencyResolver->resolveDependencies($node, $scope) as $nodeDependency) { + $dependencyFile = $nodeDependency->getFileName(); if (! $dependencyFile) { continue; } diff --git a/packages/changes-reporting/src/Output/CheckstyleOutputFormatter.php b/packages/changes-reporting/src/Output/CheckstyleOutputFormatter.php index 2266d0dc325..da86b4b9321 100644 --- a/packages/changes-reporting/src/Output/CheckstyleOutputFormatter.php +++ b/packages/changes-reporting/src/Output/CheckstyleOutputFormatter.php @@ -53,13 +53,13 @@ final class CheckstyleOutputFormatter implements OutputFormatterInterface $message = sprintf('', $this->escape($fileDiff->getRelativeFilePath())); $this->symfonyStyle->writeln($message); - foreach ($fileDiff->getRectorChanges() as $rectorChange) { - $message = $rectorChange->getRectorDefinitionsDescription() . ' (Reported by: ' . $rectorChange->getRectorClass() . ')'; + foreach ($fileDiff->getRectorChanges() as $rectorWithFileAndLineChange) { + $message = $rectorWithFileAndLineChange->getRectorDefinitionsDescription() . ' (Reported by: ' . $rectorWithFileAndLineChange->getRectorClass() . ')'; $message = $this->escape($message); $error = sprintf( ' ', - $this->escape((string) $rectorChange->getLine()), + $this->escape((string) $rectorWithFileAndLineChange->getLine()), $message ); $this->symfonyStyle->writeln($error); @@ -73,8 +73,8 @@ final class CheckstyleOutputFormatter implements OutputFormatterInterface if ($errorAndDiffCollector->getErrors() !== []) { $this->symfonyStyle->writeln(''); - foreach ($errorAndDiffCollector->getErrors() as $error) { - $escapedMessage = $this->escape($error->getMessage()); + foreach ($errorAndDiffCollector->getErrors() as $rectorError) { + $escapedMessage = $this->escape($rectorError->getMessage()); $message = sprintf(' ', $escapedMessage); $this->symfonyStyle->writeln($message); diff --git a/packages/node-type-resolver/src/NodeTypeResolver.php b/packages/node-type-resolver/src/NodeTypeResolver.php index 17f7fad65d2..8387d5a8b10 100644 --- a/packages/node-type-resolver/src/NodeTypeResolver.php +++ b/packages/node-type-resolver/src/NodeTypeResolver.php @@ -247,8 +247,8 @@ final class NodeTypeResolver return false; } - foreach ($nodeType->getTypes() as $subtype) { - if ($subtype instanceof ObjectType) { + foreach ($nodeType->getTypes() as $type) { + if ($type instanceof ObjectType) { return true; } } diff --git a/rules/cakephp/src/Rector/MethodCall/ArrayToFluentCallRector.php b/rules/cakephp/src/Rector/MethodCall/ArrayToFluentCallRector.php index 4e91f2c54c1..21b217a07ce 100644 --- a/rules/cakephp/src/Rector/MethodCall/ArrayToFluentCallRector.php +++ b/rules/cakephp/src/Rector/MethodCall/ArrayToFluentCallRector.php @@ -175,8 +175,8 @@ PHP $node = $methodCall; - foreach ($arrayItemsAndFluentClass->getFluentCalls() as $method => $arg) { - $args = $this->createArgs([$arg]); + foreach ($arrayItemsAndFluentClass->getFluentCalls() as $method => $expr) { + $args = $this->createArgs([$expr]); $node = $this->createMethodCall($node, $method, $args); } diff --git a/rules/dead-code/src/Rector/ClassMethod/RemoveDelegatingParentCallRector.php b/rules/dead-code/src/Rector/ClassMethod/RemoveDelegatingParentCallRector.php index 35f07a9a626..a932a0651df 100644 --- a/rules/dead-code/src/Rector/ClassMethod/RemoveDelegatingParentCallRector.php +++ b/rules/dead-code/src/Rector/ClassMethod/RemoveDelegatingParentCallRector.php @@ -262,9 +262,9 @@ PHP ClassMethod $classMethod, ReflectionMethod $reflectionMethod ): bool { - foreach ($reflectionMethod->getParameters() as $key => $parameter) { + foreach ($reflectionMethod->getParameters() as $key => $reflectionParameter) { if (! isset($classMethod->params[$key])) { - if ($parameter->isDefaultValueAvailable()) { + if ($reflectionParameter->isDefaultValueAvailable()) { continue; } return true; @@ -272,7 +272,7 @@ PHP $methodParam = $classMethod->params[$key]; - if ($this->areDefaultValuesDifferent($parameter, $methodParam)) { + if ($this->areDefaultValuesDifferent($reflectionParameter, $methodParam)) { return true; } } diff --git a/rules/doctrine-gedmo-to-knplabs/src/Rector/Class_/TranslationBehaviorRector.php b/rules/doctrine-gedmo-to-knplabs/src/Rector/Class_/TranslationBehaviorRector.php index ca412173e39..bef66522723 100644 --- a/rules/doctrine-gedmo-to-knplabs/src/Rector/Class_/TranslationBehaviorRector.php +++ b/rules/doctrine-gedmo-to-knplabs/src/Rector/Class_/TranslationBehaviorRector.php @@ -217,17 +217,17 @@ PHP private function removeSetAndGetMethods(Class_ $class, array $removedPropertyNames): void { foreach ($removedPropertyNames as $removedPropertyName) { - foreach ($class->getMethods() as $method) { - if ($this->isName($method, 'set' . ucfirst($removedPropertyName))) { - $this->removeNode($method); + foreach ($class->getMethods() as $classMethod) { + if ($this->isName($classMethod, 'set' . ucfirst($removedPropertyName))) { + $this->removeNode($classMethod); } - if ($this->isName($method, 'get' . ucfirst($removedPropertyName))) { - $this->removeNode($method); + if ($this->isName($classMethod, 'get' . ucfirst($removedPropertyName))) { + $this->removeNode($classMethod); } - if ($this->isName($method, 'setTranslatableLocale')) { - $this->removeNode($method); + if ($this->isName($classMethod, 'setTranslatableLocale')) { + $this->removeNode($classMethod); } } } diff --git a/rules/doctrine-gedmo-to-knplabs/src/Rector/Class_/TreeBehaviorRector.php b/rules/doctrine-gedmo-to-knplabs/src/Rector/Class_/TreeBehaviorRector.php index dc3c3438eb4..98a9084dc9c 100644 --- a/rules/doctrine-gedmo-to-knplabs/src/Rector/Class_/TreeBehaviorRector.php +++ b/rules/doctrine-gedmo-to-knplabs/src/Rector/Class_/TreeBehaviorRector.php @@ -198,13 +198,13 @@ PHP private function removeClassMethodsForProperties(Class_ $class, array $removedPropertyNames): void { foreach ($removedPropertyNames as $removedPropertyName) { - foreach ($class->getMethods() as $method) { - if ($this->isName($method, 'get' . ucfirst($removedPropertyName))) { - $this->removeNode($method); + foreach ($class->getMethods() as $classMethod) { + if ($this->isName($classMethod, 'get' . ucfirst($removedPropertyName))) { + $this->removeNode($classMethod); } - if ($this->isName($method, 'set' . ucfirst($removedPropertyName))) { - $this->removeNode($method); + if ($this->isName($classMethod, 'set' . ucfirst($removedPropertyName))) { + $this->removeNode($classMethod); } } } diff --git a/rules/generic/src/NodeTypeAnalyzer/CallTypeAnalyzer.php b/rules/generic/src/NodeTypeAnalyzer/CallTypeAnalyzer.php index e81681956bb..2bc7735255d 100644 --- a/rules/generic/src/NodeTypeAnalyzer/CallTypeAnalyzer.php +++ b/rules/generic/src/NodeTypeAnalyzer/CallTypeAnalyzer.php @@ -93,9 +93,9 @@ final class CallTypeAnalyzer $parameterTypes = []; - /** @var ParameterReflection $parameter */ - foreach ($functionVariant->getParameters() as $parameter) { - $parameterTypes[] = $parameter->getType(); + /** @var ParameterReflection $parameterReflection */ + foreach ($functionVariant->getParameters() as $parameterReflection) { + $parameterTypes[] = $parameterReflection->getType(); } return $parameterTypes; diff --git a/rules/generic/src/Rector/Class_/AddPropertyByParentRector.php b/rules/generic/src/Rector/Class_/AddPropertyByParentRector.php index 77ead96a0f5..7d49ece3ac0 100644 --- a/rules/generic/src/Rector/Class_/AddPropertyByParentRector.php +++ b/rules/generic/src/Rector/Class_/AddPropertyByParentRector.php @@ -13,6 +13,7 @@ use Rector\Core\RectorDefinition\ConfiguredCodeSample; use Rector\Core\RectorDefinition\RectorDefinition; use Rector\Generic\ValueObject\ParentDependency; use Rector\Naming\Naming\PropertyNaming; +use Rector\Naming\ValueObject\ExpectedName; use Rector\NodeTypeResolver\Node\AttributeKey; use Webmozart\Assert\Assert; @@ -100,9 +101,9 @@ CODE_SAMPLE } $propertyType = new ObjectType($parentDependency->getDependencyType()); - /** @var string $propertyName */ + /** @var ExpectedName $propertyName */ $propertyName = $this->propertyNaming->getExpectedNameFromType($propertyType); - $this->addConstructorDependencyToClass($node, $propertyType, $propertyName); + $this->addConstructorDependencyToClass($node, $propertyType, $propertyName->getName()); } return $node; diff --git a/rules/legacy/src/Rector/Class_/ChangeSingletonToServiceRector.php b/rules/legacy/src/Rector/Class_/ChangeSingletonToServiceRector.php index 02683b4427a..ab5b0c860fb 100644 --- a/rules/legacy/src/Rector/Class_/ChangeSingletonToServiceRector.php +++ b/rules/legacy/src/Rector/Class_/ChangeSingletonToServiceRector.php @@ -120,25 +120,25 @@ PHP Class_ $class, PropertyAndClassMethodName $propertyAndClassMethodName ): Class_ { - foreach ($class->getMethods() as $method) { - if ($this->isName($method, $propertyAndClassMethodName->getClassMethodName())) { - $this->removeNodeFromStatements($class, $method); + foreach ($class->getMethods() as $classMethod) { + if ($this->isName($classMethod, $propertyAndClassMethodName->getClassMethodName())) { + $this->removeNodeFromStatements($class, $classMethod); continue; } - if (! $this->isNames($method, [MethodName::CONSTRUCT, '__clone', '__wakeup'])) { + if (! $this->isNames($classMethod, [MethodName::CONSTRUCT, '__clone', '__wakeup'])) { continue; } - if ($method->isPublic()) { + if ($classMethod->isPublic()) { continue; } // remove non-public empty - if ($method->stmts === []) { - $this->removeNodeFromStatements($class, $method); + if ($classMethod->stmts === []) { + $this->removeNodeFromStatements($class, $classMethod); } else { - $this->makePublic($method); + $this->makePublic($classMethod); } } diff --git a/rules/magic-disclosure/src/NodeManipulator/FluentChainMethodCallRootExtractor.php b/rules/magic-disclosure/src/NodeManipulator/FluentChainMethodCallRootExtractor.php index 1444b68e597..b5fed72275a 100644 --- a/rules/magic-disclosure/src/NodeManipulator/FluentChainMethodCallRootExtractor.php +++ b/rules/magic-disclosure/src/NodeManipulator/FluentChainMethodCallRootExtractor.php @@ -148,12 +148,12 @@ final class FluentChainMethodCallRootExtractor } $fullyQualifiedObjectType = new FullyQualifiedObjectType($className); - $variableName = $this->propertyNaming->getExpectedNameFromType($fullyQualifiedObjectType); - if ($variableName === null) { + $expectedName = $this->propertyNaming->getExpectedNameFromType($fullyQualifiedObjectType); + if ($expectedName === null) { return null; } - $variable = new Variable($variableName); + $variable = new Variable($expectedName->getName()); return new AssignAndRootExpr($methodCall->var, $methodCall->var, $variable); } diff --git a/rules/mysql-to-mysqli/src/Rector/FuncCall/MysqlQueryMysqlErrorWithLinkRector.php b/rules/mysql-to-mysqli/src/Rector/FuncCall/MysqlQueryMysqlErrorWithLinkRector.php index e3332872aa9..a5d577942f3 100644 --- a/rules/mysql-to-mysqli/src/Rector/FuncCall/MysqlQueryMysqlErrorWithLinkRector.php +++ b/rules/mysql-to-mysqli/src/Rector/FuncCall/MysqlQueryMysqlErrorWithLinkRector.php @@ -138,8 +138,8 @@ PHP } if ($st instanceof UnionType) { - foreach ($st->getTypes() as $candidate) { - if ($candidate->equals($resourceType)) { + foreach ($st->getTypes() as $type) { + if ($type->equals($resourceType)) { return true; } } diff --git a/rules/naming/src/Guard/BreakingVariableRenameGuard.php b/rules/naming/src/Guard/BreakingVariableRenameGuard.php index 4e1d04c9a01..876782d1e3e 100644 --- a/rules/naming/src/Guard/BreakingVariableRenameGuard.php +++ b/rules/naming/src/Guard/BreakingVariableRenameGuard.php @@ -11,6 +11,7 @@ use PhpParser\Node\Expr\Variable; use PhpParser\Node\FunctionLike; use PhpParser\Node\Param; use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Foreach_; use PhpParser\Node\Stmt\Function_; use PhpParser\Node\Stmt\If_; use PhpParser\Node\Stmt\Property; @@ -20,6 +21,7 @@ use PHPStan\Type\TypeWithClassName; use Rector\Core\PhpParser\Node\BetterNodeFinder; use Rector\Naming\Naming\ConflictingNameResolver; use Rector\Naming\Naming\OverridenExistingNamesResolver; +use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\NodeTypeResolver\NodeTypeResolver; use Rector\PHPStanStaticTypeMapper\Utils\TypeUnwrapper; @@ -54,18 +56,25 @@ final class BreakingVariableRenameGuard */ private $typeUnwrapper; + /** + * @var NodeNameResolver + */ + private $nodeNameResolver; + public function __construct( BetterNodeFinder $betterNodeFinder, ConflictingNameResolver $conflictingNameResolver, NodeTypeResolver $nodeTypeResolver, OverridenExistingNamesResolver $overridenExistingNamesResolver, - TypeUnwrapper $typeUnwrapper + TypeUnwrapper $typeUnwrapper, + NodeNameResolver $nodeNameResolver ) { $this->betterNodeFinder = $betterNodeFinder; $this->conflictingNameResolver = $conflictingNameResolver; $this->overridenExistingNamesResolver = $overridenExistingNamesResolver; $this->nodeTypeResolver = $nodeTypeResolver; $this->typeUnwrapper = $typeUnwrapper; + $this->nodeNameResolver = $nodeNameResolver; } /** @@ -102,6 +111,10 @@ final class BreakingVariableRenameGuard return true; } + if ($this->isUsedInForeachKeyValueVar($variable, $currentName)) { + return true; + } + return $this->isUsedInIfAndOtherBranches($variable, $currentName); } @@ -179,6 +192,34 @@ final class BreakingVariableRenameGuard return $this->betterNodeFinder->hasVariableOfName((array) $functionLike->uses, $expectedName); } + private function isUsedInForeachKeyValueVar(Variable $variable, string $currentName): bool + { + $previousForeach = $this->betterNodeFinder->findFirstPreviousOfTypes($variable, [Foreach_::class]); + if ($previousForeach instanceof Foreach_) { + if ($previousForeach->keyVar === $variable) { + return false; + } + + if ($previousForeach->valueVar === $variable) { + return false; + } + + if ($this->nodeNameResolver->isName($previousForeach->valueVar, $currentName)) { + return true; + } + + if ($previousForeach->keyVar === null) { + return false; + } + + if ($this->nodeNameResolver->isName($previousForeach->keyVar, $currentName)) { + return true; + } + } + + return false; + } + private function isUsedInIfAndOtherBranches(Variable $variable, string $currentVariableName): bool { // is in if branches? diff --git a/rules/naming/src/Matcher/AbstractMatcher.php b/rules/naming/src/Matcher/AbstractMatcher.php new file mode 100644 index 00000000000..c06ec2d8cb7 --- /dev/null +++ b/rules/naming/src/Matcher/AbstractMatcher.php @@ -0,0 +1,97 @@ +nodeNameResolver = $nodeNameResolver; + } + + /** + * @param Assign|Foreach_ $node + * @return VariableAndCallAssign|VariableAndCallForeach|null + */ + public function match(Node $node) + { + $call = $this->matchCall($node); + if ($call === null) { + return null; + } + + $variableName = $this->getVariableName($node); + if ($variableName === null) { + return null; + } + + $functionLike = $this->getFunctionLike($node); + if ($functionLike === null) { + return null; + } + + $variable = $this->getVariable($node); + + if ($node instanceof Foreach_) { + return new VariableAndCallForeach($variable, $call, $variableName, $functionLike); + } + + if ($node instanceof Assign) { + return new VariableAndCallAssign($variable, $call, $node, $variableName, $functionLike); + } + + return null; + } + + /** + * @return FuncCall|StaticCall|MethodCall|null + */ + protected function matchCall(Node $node): ?Node + { + if ($node->expr instanceof MethodCall) { + return $node->expr; + } + + if ($node->expr instanceof StaticCall) { + return $node->expr; + } + + if ($node->expr instanceof FuncCall) { + return $node->expr; + } + + return null; + } + + /** + * @return ClassMethod|Function_|Closure|null + */ + protected function getFunctionLike(Node $node): ?FunctionLike + { + return $node->getAttribute(AttributeKey::CLOSURE_NODE) ?? + $node->getAttribute(AttributeKey::METHOD_NODE) ?? + $node->getAttribute(AttributeKey::FUNCTION_NODE); + } +} diff --git a/rules/naming/src/Matcher/ForeachMatcher.php b/rules/naming/src/Matcher/ForeachMatcher.php new file mode 100644 index 00000000000..aad6bdf038a --- /dev/null +++ b/rules/naming/src/Matcher/ForeachMatcher.php @@ -0,0 +1,34 @@ +valueVar instanceof Variable) { + return null; + } + + return $this->nodeNameResolver->getName($node->valueVar); + } + + /** + * @param Foreach_ $node + */ + public function getVariable(Node $node): Variable + { + /** @var Variable $variable */ + $variable = $node->valueVar; + return $variable; + } +} diff --git a/rules/naming/src/Matcher/MatcherInterface.php b/rules/naming/src/Matcher/MatcherInterface.php new file mode 100644 index 00000000000..78e780e214b --- /dev/null +++ b/rules/naming/src/Matcher/MatcherInterface.php @@ -0,0 +1,22 @@ +nodeNameResolver = $nodeNameResolver; - } - - public function match(Assign $assign): ?VariableAndCallAssign - { - $call = $this->matchCall($assign); - if ($call === null) { + if (! $node->var instanceof Variable) { return null; } - if (! $assign->var instanceof Variable) { - return null; - } - - $variableName = $this->nodeNameResolver->getName($assign->var); - if ($variableName === null) { - return null; - } - - $functionLike = $this->getFunctionLike($assign); - if ($functionLike === null) { - return null; - } - - return new VariableAndCallAssign($assign->var, $call, $assign, $variableName, $functionLike); + return $this->nodeNameResolver->getName($node->var); } /** - * @return FuncCall|StaticCall|MethodCall|null + * @param Assign $node */ - private function matchCall(Assign $assign): ?Node + public function getVariable(Node $node): Variable { - if ($assign->expr instanceof MethodCall) { - return $assign->expr; - } - - if ($assign->expr instanceof StaticCall) { - return $assign->expr; - } - - if ($assign->expr instanceof FuncCall) { - return $assign->expr; - } - - return null; - } - - /** - * @return ClassMethod|Function_|Closure|null - */ - private function getFunctionLike(Node $node): ?FunctionLike - { - return $node->getAttribute(AttributeKey::CLOSURE_NODE) ?? - $node->getAttribute(AttributeKey::METHOD_NODE) ?? - $node->getAttribute(AttributeKey::FUNCTION_NODE); + /** @var Variable $variable */ + $variable = $node->var; + return $variable; } } diff --git a/rules/naming/src/Naming/ExpectedNameResolver.php b/rules/naming/src/Naming/ExpectedNameResolver.php index 5fe164fcf67..6184c09c903 100644 --- a/rules/naming/src/Naming/ExpectedNameResolver.php +++ b/rules/naming/src/Naming/ExpectedNameResolver.php @@ -14,9 +14,12 @@ use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\Variable; use PhpParser\Node\Name; use PhpParser\Node\Param; +use PhpParser\Node\Stmt\Foreach_; use PhpParser\Node\Stmt\Property; use PHPStan\Type\ArrayType; use PHPStan\Type\MixedType; +use PHPStan\Type\ObjectType; +use PHPStan\Type\Type; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo; use Rector\NodeNameResolver\NodeNameResolver; use Rector\NodeTypeResolver\Node\AttributeKey; @@ -106,7 +109,12 @@ final class ExpectedNameResolver } $staticType = $this->staticTypeMapper->mapPhpParserNodePHPStanType($param->type); - return $this->propertyNaming->getExpectedNameFromType($staticType); + $expectedName = $this->propertyNaming->getExpectedNameFromType($staticType); + if ($expectedName === null) { + return null; + } + + return $expectedName->getName(); } public function resolveForProperty(Property $property): ?string @@ -117,7 +125,12 @@ final class ExpectedNameResolver return null; } - return $this->propertyNaming->getExpectedNameFromType($phpDocInfo->getVarType()); + $expectedName = $this->propertyNaming->getExpectedNameFromType($phpDocInfo->getVarType()); + if ($expectedName === null) { + return null; + } + + return $expectedName->getName(); } public function resolveForAssignNonNew(Assign $assign): ?string @@ -159,7 +172,12 @@ final class ExpectedNameResolver $fullyQualifiedObjectType = new FullyQualifiedObjectType($className); - return $this->propertyNaming->getExpectedNameFromType($fullyQualifiedObjectType); + $expectedName = $this->propertyNaming->getExpectedNameFromType($fullyQualifiedObjectType); + if ($expectedName === null) { + return null; + } + + return $expectedName->getName(); } /** @@ -187,8 +205,9 @@ final class ExpectedNameResolver } $expectedName = $this->propertyNaming->getExpectedNameFromType($returnedType); + if ($expectedName !== null) { - return $expectedName; + return $expectedName->getName(); } // call with args can return different value, so skip there if not sure about the type @@ -196,13 +215,57 @@ final class ExpectedNameResolver return null; } - // @see https://regex101.com/r/hnU5pm/2/ - $matches = Strings::match($name, '#^get([A-Z].+)#'); - if ($matches === null) { + $expectedNameFromMethodName = $this->propertyNaming->getExpectedNameFromMethodName($name); + if ($expectedNameFromMethodName !== null) { + return $expectedNameFromMethodName->getName(); + } + + return null; + } + + /** + * @param MethodCall|StaticCall|FuncCall $expr + */ + public function resolveForForeach(Expr $expr): ?string + { + if ($this->isDynamicNameCall($expr)) { return null; } - return lcfirst($matches[1]); + $name = $this->nodeNameResolver->getName($expr->name); + if ($name === null) { + return null; + } + + $returnedType = $this->nodeTypeResolver->getStaticType($expr); + + if ($returnedType->isIterable()->no()) { + return null; + } + + if ($returnedType instanceof ArrayType) { + $returnedType = $this->resolveReturnTypeFromArrayType($expr, $returnedType); + if ($returnedType === null) { + return null; + } + } + + $expectedNameFromType = $this->propertyNaming->getExpectedNameFromType($returnedType); + + if ($expectedNameFromType !== null) { + return $expectedNameFromType->getSingularized(); + } + + $expectedNameFromMethodName = $this->propertyNaming->getExpectedNameFromMethodName($name); + if ($expectedNameFromMethodName === null) { + return null; + } + + if ($expectedNameFromMethodName->isSingular()) { + return null; + } + + return $expectedNameFromMethodName->getSingularized(); } /** @@ -230,4 +293,17 @@ final class ExpectedNameResolver return $expr->name instanceof FuncCall; } + + private function resolveReturnTypeFromArrayType(Expr $expr, ArrayType $arrayType): ?Type + { + if (! $expr->getAttribute(AttributeKey::PARENT_NODE) instanceof Foreach_) { + return null; + } + + if (! $arrayType->getItemType() instanceof ObjectType) { + return null; + } + + return $arrayType->getItemType(); + } } diff --git a/rules/naming/src/Naming/PropertyNaming.php b/rules/naming/src/Naming/PropertyNaming.php index 23f3b9a79d9..557b04d4a34 100644 --- a/rules/naming/src/Naming/PropertyNaming.php +++ b/rules/naming/src/Naming/PropertyNaming.php @@ -4,12 +4,14 @@ declare(strict_types=1); namespace Rector\Naming\Naming; +use Doctrine\Inflector\Inflector; use Nette\Utils\Strings; use PHPStan\Type\ObjectType; use PHPStan\Type\StaticType; use PHPStan\Type\Type; use PHPStan\Type\TypeWithClassName; use PHPStan\Type\UnionType; +use Rector\Naming\ValueObject\ExpectedName; use Rector\NetteKdyby\Naming\VariableNaming; use Rector\PHPStan\Type\SelfObjectType; use Rector\PHPStan\Type\ShortenedObjectType; @@ -37,12 +39,31 @@ final class PropertyNaming */ private $typeUnwrapper; - public function __construct(TypeUnwrapper $typeUnwrapper) + /** + * @var Inflector + */ + private $inflector; + + public function __construct(TypeUnwrapper $typeUnwrapper, Inflector $inflector) { $this->typeUnwrapper = $typeUnwrapper; + $this->inflector = $inflector; } - public function getExpectedNameFromType(Type $type): ?string + public function getExpectedNameFromMethodName(string $methodName): ?ExpectedName + { + // @see https://regex101.com/r/hnU5pm/2/ + $matches = Strings::match($methodName, '#^get([A-Z].+)#'); + if ($matches === null) { + return null; + } + + $originalName = lcfirst($matches[1]); + + return new ExpectedName($originalName, $this->inflector->singularize($originalName)); + } + + public function getExpectedNameFromType(Type $type): ?ExpectedName { if ($type instanceof UnionType) { $type = $this->typeUnwrapper->unwrapNullableType($type); @@ -81,7 +102,8 @@ final class PropertyNaming $shortClassName = $this->normalizeUpperCase($shortClassName); // prolong too short generic names with one namespace up - return $this->prolongIfTooShort($shortClassName, $className); + $originalName = $this->prolongIfTooShort($shortClassName, $className); + return new ExpectedName($originalName, $this->inflector->singularize($originalName)); } /** diff --git a/rules/naming/src/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php b/rules/naming/src/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php index 04b8d79ee95..22868d5cfde 100644 --- a/rules/naming/src/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php +++ b/rules/naming/src/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php @@ -146,6 +146,7 @@ PHP */ public function refactor(Node $node): ?Node { + /** @var VariableAndCallAssign|null $variableAndCallAssign */ $variableAndCallAssign = $this->variableAndCallAssignMatcher->match($node); if ($variableAndCallAssign === null) { return null; @@ -189,6 +190,7 @@ PHP private function renameVariable(VariableAndCallAssign $variableAndCallAssign, string $expectedName): void { + // TODO: Remove in next PR, implemented in VariableRenamer::renameVariableIfMatchesName() $this->varTagValueNodeRenamer->renameAssignVarTagVariableName( $variableAndCallAssign->getAssign(), $variableAndCallAssign->getVariableName(), diff --git a/rules/naming/src/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector.php b/rules/naming/src/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector.php new file mode 100644 index 00000000000..e610e7fa95b --- /dev/null +++ b/rules/naming/src/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector.php @@ -0,0 +1,159 @@ +expectedNameResolver = $expectedNameResolver; + $this->variableRenamer = $variableRenamer; + $this->breakingVariableRenameGuard = $breakingVariableRenameGuard; + $this->namingConventionAnalyzer = $namingConventionAnalyzer; + $this->varValueAndCallForeachMatcher = $foreachMatcher; + } + + public function getDefinition(): RectorDefinition + { + return new RectorDefinition('Renames value variable name in foreach loop to match method type', [ + new CodeSample( + <<<'PHP' +class SomeClass +{ + public function run() + { + $array = []; + foreach ($object->getMethods() as $property) { + $array[] = $property; + } + } +} +PHP + + , + <<<'PHP' +class SomeClass +{ + public function run() + { + $array = []; + foreach ($object->getMethods() as $method) { + $array[] = $method; + } + } +} +PHP + + ), + ]); + } + + /** + * @return string[] + */ + public function getNodeTypes(): array + { + return [Foreach_::class]; + } + + /** + * @param Foreach_ $node + */ + public function refactor(Node $node): ?Node + { + /** @var VariableAndCallForeach|null $variableAndCallAssign */ + $variableAndCallAssign = $this->varValueAndCallForeachMatcher->match($node); + + if ($variableAndCallAssign === null) { + return null; + } + + $expectedName = $this->expectedNameResolver->resolveForForeach($variableAndCallAssign->getCall()); + if ($expectedName === null || $this->isName($variableAndCallAssign->getVariable(), $expectedName)) { + return null; + } + + if ($this->shouldSkip($variableAndCallAssign, $expectedName)) { + return null; + } + + $this->renameVariable($variableAndCallAssign, $expectedName); + + return $node; + } + + private function shouldSkip(VariableAndCallForeach $variableAndCallForeach, string $expectedName): bool + { + if ($this->namingConventionAnalyzer->isCallMatchingVariableName( + $variableAndCallForeach->getCall(), + $variableAndCallForeach->getVariableName(), + $expectedName + )) { + return true; + } + + return $this->breakingVariableRenameGuard->shouldSkipVariable( + $variableAndCallForeach->getVariableName(), + $expectedName, + $variableAndCallForeach->getFunctionLike(), + $variableAndCallForeach->getVariable() + ); + } + + private function renameVariable(VariableAndCallForeach $variableAndCallForeach, string $expectedName): void + { + $this->variableRenamer->renameVariableInFunctionLike( + $variableAndCallForeach->getFunctionLike(), + null, + $variableAndCallForeach->getVariableName(), + $expectedName + ); + } +} diff --git a/rules/naming/src/ValueObject/ExpectedName.php b/rules/naming/src/ValueObject/ExpectedName.php new file mode 100644 index 00000000000..911326629a4 --- /dev/null +++ b/rules/naming/src/ValueObject/ExpectedName.php @@ -0,0 +1,39 @@ +name = $name; + $this->singularized = $singularized; + } + + public function getName(): string + { + return $this->name; + } + + public function getSingularized(): string + { + return $this->singularized; + } + + public function isSingular(): bool + { + return $this->name === $this->singularized; + } +} diff --git a/rules/naming/src/ValueObject/VariableAndCallForeach.php b/rules/naming/src/ValueObject/VariableAndCallForeach.php new file mode 100644 index 00000000000..cd87cd8758b --- /dev/null +++ b/rules/naming/src/ValueObject/VariableAndCallForeach.php @@ -0,0 +1,76 @@ +variable = $variable; + $this->call = $expr; + $this->variableName = $variableName; + $this->functionLike = $functionLike; + } + + public function getVariable(): Variable + { + return $this->variable; + } + + /** + * @return FuncCall|StaticCall|MethodCall + */ + public function getCall(): Expr + { + return $this->call; + } + + public function getVariableName(): string + { + return $this->variableName; + } + + /** + * @return ClassMethod|Function_|Closure + */ + public function getFunctionLike(): FunctionLike + { + return $this->functionLike; + } +} diff --git a/rules/naming/src/VariableRenamer.php b/rules/naming/src/VariableRenamer.php index 49c755e0c47..1e3771fb291 100644 --- a/rules/naming/src/VariableRenamer.php +++ b/rules/naming/src/VariableRenamer.php @@ -77,6 +77,8 @@ final class VariableRenamer return null; } + // TODO: Remove in next PR (with above param check?), + // TODO: Should be implemented in BreakingVariableRenameGuard::shouldSkipParam() if ($this->isParamInParentFunction($node)) { return null; } diff --git a/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/fixture.php.inc b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/fixture.php.inc new file mode 100644 index 00000000000..d370cd2c6ba --- /dev/null +++ b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/fixture.php.inc @@ -0,0 +1,53 @@ +getMethods() as $property) { + $array[] = $property; + } + } + + /** + * @return Method[] + */ + public function getMethods(): array + { + + } +} + +?> +----- +getMethods() as $method) { + $array[] = $method; + } + } + + /** + * @return Method[] + */ + public function getMethods(): array + { + + } +} + +?> diff --git a/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/foreach_prefer_parent_stmt_variable_name.php.inc b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/foreach_prefer_parent_stmt_variable_name.php.inc new file mode 100644 index 00000000000..12f166bcc64 --- /dev/null +++ b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/foreach_prefer_parent_stmt_variable_name.php.inc @@ -0,0 +1,69 @@ +getUsedTraits() as $trait) { + $trait = $this->findTrait($trait); + if ($trait === null) { + continue; + } + $searchInNodes[] = $trait; + } + } + + /** + * @return Name[] + */ + public function getUsedTraits(): array + { + } + + public function findTrait(string $name): Trait_ + { + } +} + +?> +----- +getUsedTraits() as $name) { + $name = $this->findTrait($name); + if ($name === null) { + continue; + } + $searchInNodes[] = $name; + } + } + + /** + * @return Name[] + */ + public function getUsedTraits(): array + { + } + + public function findTrait(string $name): Trait_ + { + } +} + +?> diff --git a/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/iterable_type_with_singularization.php.inc b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/iterable_type_with_singularization.php.inc new file mode 100644 index 00000000000..f04ce12ba45 --- /dev/null +++ b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/iterable_type_with_singularization.php.inc @@ -0,0 +1,47 @@ +resolveDependencies() as $method) { + $array[] = $method; + } + } + + public function resolveDependencies(): NodeDependencies + { + + } +} + +?> +----- +resolveDependencies() as $nodeDependency) { + $array[] = $nodeDependency; + } + } + + public function resolveDependencies(): NodeDependencies + { + + } +} + +?> diff --git a/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/plural_excluded_get_names.php.inc b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/plural_excluded_get_names.php.inc new file mode 100644 index 00000000000..13c76e8b3f3 --- /dev/null +++ b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/plural_excluded_get_names.php.inc @@ -0,0 +1,55 @@ +getPluralNames() as $word) { + $words[] = $word; + } + + return $words; + } + + /** + * @return SmartFileInfo[] + */ + public function getPluralNames(): array + { + } +} + +?> +----- +getPluralNames() as $pluralName) { + $words[] = $pluralName; + } + + return $words; + } + + /** + * @return SmartFileInfo[] + */ + public function getPluralNames(): array + { + } +} + +?> diff --git a/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/skip_singular_after_get_names.php.inc b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/skip_singular_after_get_names.php.inc new file mode 100644 index 00000000000..dcf95d52c11 --- /dev/null +++ b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Fixture/skip_singular_after_get_names.php.inc @@ -0,0 +1,27 @@ +getSingularName() as $word) { + $words[] = $word; + } + + return $words; + } + + /** + * @return SmartFileInfo[] + */ + public function getSingularName(): array + { + } +} + +?> diff --git a/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/RenameForeachValueVariableToMatchMethodCallReturnTypeRectorTest.php b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/RenameForeachValueVariableToMatchMethodCallReturnTypeRectorTest.php new file mode 100644 index 00000000000..23746ce7dad --- /dev/null +++ b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/RenameForeachValueVariableToMatchMethodCallReturnTypeRectorTest.php @@ -0,0 +1,31 @@ +doTestFileInfo($fileInfo); + } + + public function provideData(): Iterator + { + return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + protected function getRectorClass(): string + { + return RenameForeachValueVariableToMatchMethodCallReturnTypeRector::class; + } +} diff --git a/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Source/Method.php b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Source/Method.php new file mode 100644 index 00000000000..3f5e6b0ed28 --- /dev/null +++ b/rules/naming/tests/Rector/Foreach_/RenameForeachValueVariableToMatchMethodCallReturnTypeRector/Source/Method.php @@ -0,0 +1,9 @@ + + */ +class NodeDependencies implements IteratorAggregate +{ + + public function getIterator() + { + // TODO: Implement getIterator() method. + } +} diff --git a/rules/php-spec-to-phpunit/src/LetManipulator.php b/rules/php-spec-to-phpunit/src/LetManipulator.php index 98b4a7b3db8..b42bfac57eb 100644 --- a/rules/php-spec-to-phpunit/src/LetManipulator.php +++ b/rules/php-spec-to-phpunit/src/LetManipulator.php @@ -30,14 +30,14 @@ final class LetManipulator public function isLetNeededInClass(Class_ $class): bool { - foreach ($class->getMethods() as $method) { + foreach ($class->getMethods() as $classMethod) { // new test - if ($this->nodeNameResolver->isName($method, 'test*')) { + if ($this->nodeNameResolver->isName($classMethod, 'test*')) { continue; } $hasBeConstructedThrough = (bool) $this->betterNodeFinder->find( - (array) $method->stmts, + (array) $classMethod->stmts, function (Node $node): ?bool { if (! $node instanceof MethodCall) { return null; diff --git a/rules/php70/src/Rector/FuncCall/NonVariableToVariableOnFunctionCallRector.php b/rules/php70/src/Rector/FuncCall/NonVariableToVariableOnFunctionCallRector.php index 886da2f3279..7aa888da79f 100644 --- a/rules/php70/src/Rector/FuncCall/NonVariableToVariableOnFunctionCallRector.php +++ b/rules/php70/src/Rector/FuncCall/NonVariableToVariableOnFunctionCallRector.php @@ -128,14 +128,14 @@ final class NonVariableToVariableOnFunctionCallRector extends AbstractRector return []; } - /** @var ParameterReflection $parameter */ - foreach ($parametersAcceptor->getParameters() as $key => $parameter) { + /** @var ParameterReflection $parameterReflection */ + foreach ($parametersAcceptor->getParameters() as $key => $parameterReflection) { // omitted optional parameter if (! isset($node->args[$key])) { continue; } - if ($parameter->passedByReference()->no()) { + if ($parameterReflection->passedByReference()->no()) { continue; } diff --git a/rules/privatization/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php b/rules/privatization/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php index c8f1ab4b1e2..ec2c0323a5a 100644 --- a/rules/privatization/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php +++ b/rules/privatization/src/Rector/Class_/ChangeLocalPropertyToVariableRector.php @@ -130,8 +130,8 @@ PHP $propertyUsageByMethods = []; foreach ($privatePropertyNames as $privatePropertyName) { - foreach ($class->getMethods() as $method) { - $hasProperty = (bool) $this->betterNodeFinder->findFirst($method, function (Node $node) use ( + foreach ($class->getMethods() as $classMethod) { + $hasProperty = (bool) $this->betterNodeFinder->findFirst($classMethod, function (Node $node) use ( $privatePropertyName ): bool { if (! $node instanceof PropertyFetch) { @@ -145,7 +145,7 @@ PHP continue; } - $isPropertyChangingInMultipleMethodCalls = $this->isPropertyChangingInMultipleMethodCalls($method, + $isPropertyChangingInMultipleMethodCalls = $this->isPropertyChangingInMultipleMethodCalls($classMethod, $privatePropertyName); if ($isPropertyChangingInMultipleMethodCalls) { @@ -153,7 +153,7 @@ PHP } /** @var string $classMethodName */ - $classMethodName = $this->getName($method); + $classMethodName = $this->getName($classMethod); $propertyUsageByMethods[$privatePropertyName][] = $classMethodName; } } diff --git a/rules/restoration/src/Rector/New_/CompleteMissingDependencyInNewRector.php b/rules/restoration/src/Rector/New_/CompleteMissingDependencyInNewRector.php index b0243ae4df1..7b9d84c42f0 100644 --- a/rules/restoration/src/Rector/New_/CompleteMissingDependencyInNewRector.php +++ b/rules/restoration/src/Rector/New_/CompleteMissingDependencyInNewRector.php @@ -100,13 +100,13 @@ PHP /** @var ReflectionMethod $constructorMethodReflection */ $constructorMethodReflection = $this->getNewNodeClassConstructorMethodReflection($node); - foreach ($constructorMethodReflection->getParameters() as $position => $parameterReflection) { + foreach ($constructorMethodReflection->getParameters() as $position => $reflectionParameter) { // argument is already set if (isset($node->args[$position])) { continue; } - $classToInstantiate = $this->resolveClassToInstantiateByParameterReflection($parameterReflection); + $classToInstantiate = $this->resolveClassToInstantiateByParameterReflection($reflectionParameter); if ($classToInstantiate === null) { continue; } diff --git a/rules/symfony-php-config/src/NodeFactory/NewValueObjectFactory.php b/rules/symfony-php-config/src/NodeFactory/NewValueObjectFactory.php index e32a0a59bdf..a31e5f8f275 100644 --- a/rules/symfony-php-config/src/NodeFactory/NewValueObjectFactory.php +++ b/rules/symfony-php-config/src/NodeFactory/NewValueObjectFactory.php @@ -38,10 +38,10 @@ final class NewValueObjectFactory { $reflectionClass = new ReflectionClass($valueObjectClass); $propertyValues = []; - foreach ($reflectionClass->getProperties() as $propertyReflection) { - $propertyReflection->setAccessible(true); + foreach ($reflectionClass->getProperties() as $reflectionProperty) { + $reflectionProperty->setAccessible(true); - $propertyValues[] = $propertyReflection->getValue($valueObject); + $propertyValues[] = $reflectionProperty->getValue($valueObject); } return $propertyValues; } diff --git a/rules/symfony/src/Rector/MethodCall/FormTypeInstanceToClassConstRector.php b/rules/symfony/src/Rector/MethodCall/FormTypeInstanceToClassConstRector.php index af8db287815..4787d6477f6 100644 --- a/rules/symfony/src/Rector/MethodCall/FormTypeInstanceToClassConstRector.php +++ b/rules/symfony/src/Rector/MethodCall/FormTypeInstanceToClassConstRector.php @@ -250,8 +250,8 @@ PHP } $namesToArgs = []; - foreach ($constructorReflectionMethod->getParameters() as $parameterReflection) { - $namesToArgs[$parameterReflection->getName()] = $argNodes[$parameterReflection->getPosition()]; + foreach ($constructorReflectionMethod->getParameters() as $reflectionParameter) { + $namesToArgs[$reflectionParameter->getName()] = $argNodes[$reflectionParameter->getPosition()]; } return $namesToArgs; diff --git a/rules/transform/src/Rector/FuncCall/ArgumentFuncCallToMethodCallRector.php b/rules/transform/src/Rector/FuncCall/ArgumentFuncCallToMethodCallRector.php index d4d52682b40..ad3087d492e 100644 --- a/rules/transform/src/Rector/FuncCall/ArgumentFuncCallToMethodCallRector.php +++ b/rules/transform/src/Rector/FuncCall/ArgumentFuncCallToMethodCallRector.php @@ -176,15 +176,15 @@ PHP FuncCall $funcCall ): ?Node { $fullyQualifiedObjectType = new FullyQualifiedObjectType($argumentFuncCallToMethodCall->getClass()); - $propertyName = $this->propertyNaming->getExpectedNameFromType($fullyQualifiedObjectType); + $expectedName = $this->propertyNaming->getExpectedNameFromType($fullyQualifiedObjectType); - if ($propertyName === null) { + if ($expectedName === null) { throw new ShouldNotHappenException(); } - $this->addConstructorDependencyToClass($class, $fullyQualifiedObjectType, $propertyName); + $this->addConstructorDependencyToClass($class, $fullyQualifiedObjectType, $expectedName->getName()); - $propertyFetchNode = $this->createPropertyFetch('this', $propertyName); + $propertyFetchNode = $this->createPropertyFetch('this', $expectedName->getName()); if (count($funcCall->args) === 0) { if ($argumentFuncCallToMethodCall->getMethodIfNoArgs()) { diff --git a/src/Application/FileSystem/RemovedAndAddedFilesProcessor.php b/src/Application/FileSystem/RemovedAndAddedFilesProcessor.php index 0e086b8da5f..7bf17b2c1b0 100644 --- a/src/Application/FileSystem/RemovedAndAddedFilesProcessor.php +++ b/src/Application/FileSystem/RemovedAndAddedFilesProcessor.php @@ -99,8 +99,8 @@ final class RemovedAndAddedFilesProcessor private function processDeletedFiles(): void { - foreach ($this->removedAndAddedFilesCollector->getRemovedFiles() as $smartFileInfo) { - $relativePath = $smartFileInfo->getRelativeFilePathFromDirectory(getcwd()); + foreach ($this->removedAndAddedFilesCollector->getRemovedFiles() as $removedFile) { + $relativePath = $removedFile->getRelativeFilePathFromDirectory(getcwd()); if ($this->configuration->isDryRun()) { $message = sprintf('File "%s" will be removed', $relativePath); @@ -108,7 +108,7 @@ final class RemovedAndAddedFilesProcessor } else { $message = sprintf('File "%s" was removed', $relativePath); $this->symfonyStyle->warning($message); - $this->filesystem->remove($smartFileInfo->getRealPath()); + $this->filesystem->remove($removedFile->getRealPath()); } } } diff --git a/src/PhpParser/Node/Manipulator/ClassConstManipulator.php b/src/PhpParser/Node/Manipulator/ClassConstManipulator.php index acf650b12db..3e3ba0a829b 100644 --- a/src/PhpParser/Node/Manipulator/ClassConstManipulator.php +++ b/src/PhpParser/Node/Manipulator/ClassConstManipulator.php @@ -67,13 +67,13 @@ final class ClassConstManipulator } $searchInNodes = [$classLike]; - foreach ($this->classManipulator->getUsedTraits($classLike) as $trait) { - $trait = $this->parsedNodeCollector->findTrait((string) $trait); - if ($trait === null) { + foreach ($this->classManipulator->getUsedTraits($classLike) as $name) { + $name = $this->parsedNodeCollector->findTrait((string) $name); + if ($name === null) { continue; } - $searchInNodes[] = $trait; + $searchInNodes[] = $name; } return $this->betterNodeFinder->find($searchInNodes, function (Node $node) use ($classConst): bool { diff --git a/src/PhpParser/Node/Manipulator/ClassManipulator.php b/src/PhpParser/Node/Manipulator/ClassManipulator.php index b7865ee7558..75e296c240e 100644 --- a/src/PhpParser/Node/Manipulator/ClassManipulator.php +++ b/src/PhpParser/Node/Manipulator/ClassManipulator.php @@ -50,8 +50,8 @@ final class ClassManipulator public function getUsedTraits(ClassLike $classLike): array { $usedTraits = []; - foreach ($classLike->getTraitUses() as $stmt) { - foreach ($stmt->traits as $trait) { + foreach ($classLike->getTraitUses() as $traitUse) { + foreach ($traitUse->traits as $trait) { /** @var string $traitName */ $traitName = $this->nodeNameResolver->getName($trait); $usedTraits[$traitName] = $trait; diff --git a/utils/phpstan-attribute-type-syncer/src/NodeFactory/AttributeAwareClassFactoryFactory.php b/utils/phpstan-attribute-type-syncer/src/NodeFactory/AttributeAwareClassFactoryFactory.php index 16b37c7d26e..7e7e2dc0a11 100644 --- a/utils/phpstan-attribute-type-syncer/src/NodeFactory/AttributeAwareClassFactoryFactory.php +++ b/utils/phpstan-attribute-type-syncer/src/NodeFactory/AttributeAwareClassFactoryFactory.php @@ -172,8 +172,8 @@ final class AttributeAwareClassFactoryFactory $phpDocParserNodeVariable = new Variable(self::NODE); - foreach ($constructorReflectionMethod->getParameters() as $parameter) { - $parameterName = $parameter->getName(); + foreach ($constructorReflectionMethod->getParameters() as $reflectionParameter) { + $parameterName = $reflectionParameter->getName(); $new->args[] = new Arg(new PropertyFetch($phpDocParserNodeVariable, $parameterName)); } diff --git a/utils/project-validator/src/Command/ValidateFixtureSuffixCommand.php b/utils/project-validator/src/Command/ValidateFixtureSuffixCommand.php index ae930d8b707..9722a700ed9 100644 --- a/utils/project-validator/src/Command/ValidateFixtureSuffixCommand.php +++ b/utils/project-validator/src/Command/ValidateFixtureSuffixCommand.php @@ -44,8 +44,8 @@ final class ValidateFixtureSuffixCommand extends Command { $invalidFilePaths = []; - foreach ($this->getInvalidFixtureFileInfos() as $fixtureFileInfo) { - $invalidFilePaths[] = $fixtureFileInfo->getRelativeFilePathFromCwd(); + foreach ($this->getInvalidFixtureFileInfos() as $invalidFixtureFileInfo) { + $invalidFilePaths[] = $invalidFixtureFileInfo->getRelativeFilePathFromCwd(); } if (count($invalidFilePaths) > 0) {