From be3d0c61a9ff264b4b61c5050d1fe00fc6d2bf41 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 17:53:21 +0200 Subject: [PATCH 01/14] decopule ternary type method --- .../NodeTypeResolver/NodeTypeResolver.php | 43 +++++++++++-------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index 3542bdb2123..e6a1637d4f6 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -127,24 +127,7 @@ public function isObjectType(Node $node, ObjectType $requiredObjectType): bool public function resolve(Node $node): Type { if ($node instanceof Ternary) { - if ($node->if !== null) { - $first = $this->resolve($node->if); - $second = $this->resolve($node->else); - - if ($this->isUnionTypeable($first, $second)) { - return new UnionType([$first, $second]); - } - } - - $condType = $this->resolve($node->cond); - if ($this->isNullableType($node->cond) && $condType instanceof UnionType) { - $first = $condType->getTypes()[0]; - $second = $this->resolve($node->else); - - if ($this->isUnionTypeable($first, $second)) { - return new UnionType([$first, $second]); - } - } + return $this->resolveTernaryType($node); } if ($node instanceof Coalesce) { @@ -501,4 +484,28 @@ private function resolveObjectType(ObjectType $resolvedObjectType, ObjectType $r return true; } + + private function resolveTernaryType(Ternary $ternary): MixedType|UnionType + { + if ($ternary->if !== null) { + $first = $this->resolve($ternary->if); + $second = $this->resolve($ternary->else); + + if ($this->isUnionTypeable($first, $second)) { + return new UnionType([$first, $second]); + } + } + + $condType = $this->resolve($ternary->cond); + if ($this->isNullableType($ternary->cond) && $condType instanceof UnionType) { + $first = $condType->getTypes()[0]; + $second = $this->resolve($ternary->else); + + if ($this->isUnionTypeable($first, $second)) { + return new UnionType([$first, $second]); + } + } + + return new MixedType(); + } } From a0fbe152e68b2a484daedd74da66f6d69ac03218 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 17:58:23 +0200 Subject: [PATCH 02/14] use getType() over getObjectType() --- .../FlipTypeControlToUseExclusiveTypeRector.php | 2 +- ...IssetOnPropertyObjectToPropertyExistsRector.php | 2 +- .../ExplicitMethodCallOverMagicGetSetRector.php | 4 ++-- ...ActionInjectionToConstructorInjectionRector.php | 4 ++-- .../StaticCallOnNonStaticToInstanceCallRector.php | 2 +- ...sPropertyAssignToConstructorPromotionRector.php | 2 +- src/Rector/AbstractRector.php | 14 +++++++++++++- 7 files changed, 21 insertions(+), 9 deletions(-) diff --git a/rules/CodeQuality/Rector/Identical/FlipTypeControlToUseExclusiveTypeRector.php b/rules/CodeQuality/Rector/Identical/FlipTypeControlToUseExclusiveTypeRector.php index 1b21c18e52b..2ab099b423d 100644 --- a/rules/CodeQuality/Rector/Identical/FlipTypeControlToUseExclusiveTypeRector.php +++ b/rules/CodeQuality/Rector/Identical/FlipTypeControlToUseExclusiveTypeRector.php @@ -107,7 +107,7 @@ public function refactor(Node $node): ?Node $type = $phpDocInfo->getVarType(); if (! $type instanceof UnionType) { - $type = $this->getObjectType($assign->expr); + $type = $this->getType($assign->expr); } if (! $type instanceof UnionType) { diff --git a/rules/CodeQuality/Rector/Isset_/IssetOnPropertyObjectToPropertyExistsRector.php b/rules/CodeQuality/Rector/Isset_/IssetOnPropertyObjectToPropertyExistsRector.php index 0be54ec9fb2..2c069750a79 100644 --- a/rules/CodeQuality/Rector/Isset_/IssetOnPropertyObjectToPropertyExistsRector.php +++ b/rules/CodeQuality/Rector/Isset_/IssetOnPropertyObjectToPropertyExistsRector.php @@ -95,7 +95,7 @@ public function refactor(Node $node): ?Node continue; } - $propertyFetchVarType = $this->getObjectType($issetVar->var); + $propertyFetchVarType = $this->getType($issetVar->var); if ($propertyFetchVarType instanceof TypeWithClassName) { if (! $this->reflectionProvider->hasClass($propertyFetchVarType->getClassName())) { diff --git a/rules/CodeQuality/Rector/PropertyFetch/ExplicitMethodCallOverMagicGetSetRector.php b/rules/CodeQuality/Rector/PropertyFetch/ExplicitMethodCallOverMagicGetSetRector.php index acbec30f125..f35926e5b03 100644 --- a/rules/CodeQuality/Rector/PropertyFetch/ExplicitMethodCallOverMagicGetSetRector.php +++ b/rules/CodeQuality/Rector/PropertyFetch/ExplicitMethodCallOverMagicGetSetRector.php @@ -110,7 +110,7 @@ public function refactor(Node $node): ?Node private function refactorPropertyFetch(PropertyFetch $propertyFetch): MethodCall|null { - $callerType = $this->getObjectType($propertyFetch->var); + $callerType = $this->getType($propertyFetch->var); if (! $callerType instanceof TypeWithClassName) { return null; } @@ -143,7 +143,7 @@ private function refactorPropertyFetch(PropertyFetch $propertyFetch): MethodCall private function refactorMagicSet(Expr $expr, PropertyFetch $propertyFetch): MethodCall|null { - $propertyCallerType = $this->getObjectType($propertyFetch->var); + $propertyCallerType = $this->getType($propertyFetch->var); if (! $propertyCallerType instanceof ObjectType) { return null; } diff --git a/rules/DependencyInjection/Rector/Class_/ActionInjectionToConstructorInjectionRector.php b/rules/DependencyInjection/Rector/Class_/ActionInjectionToConstructorInjectionRector.php index cf4f4f6e71e..a739fcc30fa 100644 --- a/rules/DependencyInjection/Rector/Class_/ActionInjectionToConstructorInjectionRector.php +++ b/rules/DependencyInjection/Rector/Class_/ActionInjectionToConstructorInjectionRector.php @@ -99,7 +99,7 @@ private function processClassMethod(Class_ $class, ClassMethod $classMethod): vo continue; } - $paramType = $this->getObjectType($paramNode); + $paramType = $this->getType($paramNode); /** @var string $paramName */ $paramName = $this->getName($paramNode->var); @@ -124,7 +124,7 @@ private function isActionInjectedParamNode(Param $param): bool return false; } - $paramStaticType = $this->getObjectType($param); + $paramStaticType = $this->getType($param); if (! $paramStaticType instanceof ObjectType) { return false; } diff --git a/rules/Php70/Rector/StaticCall/StaticCallOnNonStaticToInstanceCallRector.php b/rules/Php70/Rector/StaticCall/StaticCallOnNonStaticToInstanceCallRector.php index 5b23ef07f71..6063edf813e 100644 --- a/rules/Php70/Rector/StaticCall/StaticCallOnNonStaticToInstanceCallRector.php +++ b/rules/Php70/Rector/StaticCall/StaticCallOnNonStaticToInstanceCallRector.php @@ -130,7 +130,7 @@ public function refactor(Node $node): ?Node private function resolveStaticCallClassName(StaticCall $staticCall): ?string { if ($staticCall->class instanceof PropertyFetch) { - $objectType = $this->getObjectType($staticCall->class); + $objectType = $this->getType($staticCall->class); if ($objectType instanceof ObjectType) { return $objectType->getClassName(); } diff --git a/rules/Php80/Rector/Class_/ClassPropertyAssignToConstructorPromotionRector.php b/rules/Php80/Rector/Class_/ClassPropertyAssignToConstructorPromotionRector.php index 597dc37ce09..28a2b47ed38 100644 --- a/rules/Php80/Rector/Class_/ClassPropertyAssignToConstructorPromotionRector.php +++ b/rules/Php80/Rector/Class_/ClassPropertyAssignToConstructorPromotionRector.php @@ -149,7 +149,7 @@ public function provideMinPhpVersion(): int private function processNullableType(Property $property, Param $param): void { if ($this->nodeTypeResolver->isNullableType($property)) { - $objectType = $this->getObjectType($property); + $objectType = $this->getType($property); $param->type = $this->staticTypeMapper->mapPHPStanTypeToPhpParserNode($objectType, TypeKind::PARAM()); } } diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index 31f1a2efd5d..2faf707d789 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -323,6 +323,10 @@ protected function isObjectType(Node $node, ObjectType $objectType): bool return $this->nodeTypeResolver->isObjectType($node, $objectType); } + /** + * @deprecated + * Use @see AbstractRector::getType() instead, as single method to get types + */ protected function getStaticType(Node $node): Type { return $this->nodeTypeResolver->getStaticType($node); @@ -330,9 +334,17 @@ protected function getStaticType(Node $node): Type /** * @deprecated - * Use getStaticType() instead, as single method to get types + * Use @see AbstractRector::getType() instead, as single method to get types */ protected function getObjectType(Node $node): Type + { + return $this->getType($node); + } + + /** + * Use this method for getting expr|node type + */ + protected function getType(Node $node): Type { return $this->nodeTypeResolver->resolve($node); } From 9abb77358019403bead18e8317403300b9ad77b1 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 18:11:29 +0200 Subject: [PATCH 03/14] rename use of getStaticType() to getType() --- packages/NodeTypeResolver/NodeTypeResolver.php | 5 ++++- .../Rector/Equal/UseIdenticalOverEqualWithSameTypeRector.php | 4 ++-- .../Rector/Expression/InlineIfToExplicitIfRector.php | 2 +- rules/CodeQuality/Rector/Foreach_/ForeachToInArrayRector.php | 2 +- .../Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php | 2 +- .../CodeQuality/Rector/FuncCall/CompactToVariablesRector.php | 2 +- .../Rector/FuncCall/IsAWithStringWithThirdArgumentRector.php | 2 +- .../RemoveAlwaysTrueConditionSetInConstructorRector.php | 4 ++-- rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php | 2 +- .../Rector/ClassConst/VarConstantCommentRector.php | 2 +- rules/CodingStyle/Rector/If_/NullableCompareToNullRector.php | 2 +- rules/DeadCode/Rector/Cast/RecastingRemovalRector.php | 2 +- .../Rector/If_/RemoveAlwaysTrueIfConditionRector.php | 2 +- .../Ternary/TernaryToBooleanOrFalseToBooleanAndRector.php | 2 +- .../FunctionLike/DowngradeScalarTypeDeclarationRector.php | 2 +- .../Rector/MethodCall/DispatchStringToObjectRector.php | 2 +- .../Rector/FuncCall/MysqlQueryMysqlErrorWithLinkRector.php | 2 +- .../RenameVariableToMatchMethodCallReturnTypeRector.php | 2 +- .../RenameForeachValueVariableToMatchExprVariableRector.php | 2 +- rules/Php52/Rector/Switch_/ContinueToBreakInSwitchRector.php | 2 +- rules/Php54/Rector/Break_/RemoveZeroBreakContinueRector.php | 2 +- .../Rector/BinaryOp/BinaryOpBetweenNumberAndStringRector.php | 2 +- rules/Php71/Rector/FuncCall/CountOnNullRector.php | 2 +- .../Php74/Rector/FuncCall/ArrayKeyExistsOnPropertyRector.php | 2 +- .../Rector/FuncCall/ArraySpreadInsteadOfArrayMergeRector.php | 2 +- .../FuncCall/MbStrrposEncodingArgumentPositionRector.php | 2 +- ...hangeReadOnlyVariableWithDefaultValueToConstantRector.php | 2 +- .../MethodCall/CallableInMethodCallToVariableRector.php | 2 +- .../Rector/ClassMethod/ReturnNeverTypeRector.php | 2 +- 29 files changed, 34 insertions(+), 31 deletions(-) diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index e6a1637d4f6..70ab32aafcf 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -127,7 +127,10 @@ public function isObjectType(Node $node, ObjectType $requiredObjectType): bool public function resolve(Node $node): Type { if ($node instanceof Ternary) { - return $this->resolveTernaryType($node); + $ternaryType = $this->resolveTernaryType($node); + if (! $ternaryType instanceof MixedType) { + return $ternaryType; + } } if ($node instanceof Coalesce) { diff --git a/rules/CodeQuality/Rector/Equal/UseIdenticalOverEqualWithSameTypeRector.php b/rules/CodeQuality/Rector/Equal/UseIdenticalOverEqualWithSameTypeRector.php index d15c69e8351..111cd74dec1 100644 --- a/rules/CodeQuality/Rector/Equal/UseIdenticalOverEqualWithSameTypeRector.php +++ b/rules/CodeQuality/Rector/Equal/UseIdenticalOverEqualWithSameTypeRector.php @@ -65,8 +65,8 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - $leftStaticType = $this->getStaticType($node->left); - $rightStaticType = $this->getStaticType($node->right); + $leftStaticType = $this->getType($node->left); + $rightStaticType = $this->getType($node->right); // objects can be different by content if ($leftStaticType instanceof ObjectType) { diff --git a/rules/CodeQuality/Rector/Expression/InlineIfToExplicitIfRector.php b/rules/CodeQuality/Rector/Expression/InlineIfToExplicitIfRector.php index 49ec900766e..cec01d5e6fb 100644 --- a/rules/CodeQuality/Rector/Expression/InlineIfToExplicitIfRector.php +++ b/rules/CodeQuality/Rector/Expression/InlineIfToExplicitIfRector.php @@ -92,7 +92,7 @@ private function processExplicitIf(Expression $expression): ?Node /** @var BooleanAnd|BooleanOr $booleanExpr */ $booleanExpr = $expression->expr; - $leftStaticType = $this->getStaticType($booleanExpr->left); + $leftStaticType = $this->getType($booleanExpr->left); if (! $leftStaticType instanceof BooleanType) { return null; } diff --git a/rules/CodeQuality/Rector/Foreach_/ForeachToInArrayRector.php b/rules/CodeQuality/Rector/Foreach_/ForeachToInArrayRector.php index d8dc9ac768e..d06767973a7 100644 --- a/rules/CodeQuality/Rector/Foreach_/ForeachToInArrayRector.php +++ b/rules/CodeQuality/Rector/Foreach_/ForeachToInArrayRector.php @@ -159,7 +159,7 @@ private function shouldSkipForeach(Foreach_ $foreach): bool return true; } - $foreachValueStaticType = $this->getStaticType($foreach->expr); + $foreachValueStaticType = $this->getType($foreach->expr); if ($foreachValueStaticType instanceof ObjectType) { return true; } diff --git a/rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php b/rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php index 53cfb5d7444..fa466b67ce1 100644 --- a/rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php +++ b/rules/CodeQuality/Rector/Foreach_/UnusedForeachValueToArrayKeysRector.php @@ -143,7 +143,7 @@ private function removeForeachValueAndUseArrayKeys(Foreach_ $foreach): void private function isArrayType(Expr $expr): bool { - $exprType = $this->getStaticType($expr); + $exprType = $this->getType($expr); if ($exprType instanceof ObjectType) { return false; } diff --git a/rules/CodeQuality/Rector/FuncCall/CompactToVariablesRector.php b/rules/CodeQuality/Rector/FuncCall/CompactToVariablesRector.php index 512e0acda9c..2b781d2bdcc 100644 --- a/rules/CodeQuality/Rector/FuncCall/CompactToVariablesRector.php +++ b/rules/CodeQuality/Rector/FuncCall/CompactToVariablesRector.php @@ -93,7 +93,7 @@ public function refactor(Node $node): ?Node $firstArg = $node->args[0]; $firstValue = $firstArg->value; - $firstValueStaticType = $this->getStaticType($firstValue); + $firstValueStaticType = $this->getType($firstValue); if (! $firstValueStaticType instanceof ConstantArrayType) { return null; } diff --git a/rules/CodeQuality/Rector/FuncCall/IsAWithStringWithThirdArgumentRector.php b/rules/CodeQuality/Rector/FuncCall/IsAWithStringWithThirdArgumentRector.php index ee4610ebe10..7ddae1dda81 100644 --- a/rules/CodeQuality/Rector/FuncCall/IsAWithStringWithThirdArgumentRector.php +++ b/rules/CodeQuality/Rector/FuncCall/IsAWithStringWithThirdArgumentRector.php @@ -72,7 +72,7 @@ public function refactor(Node $node): ?Node return null; } - $firstArgumentStaticType = $this->getStaticType($node->args[0]->value); + $firstArgumentStaticType = $this->getType($node->args[0]->value); if (! $firstArgumentStaticType instanceof StringType) { return null; } diff --git a/rules/CodeQuality/Rector/FunctionLike/RemoveAlwaysTrueConditionSetInConstructorRector.php b/rules/CodeQuality/Rector/FunctionLike/RemoveAlwaysTrueConditionSetInConstructorRector.php index 7e43a79c798..8446002966d 100644 --- a/rules/CodeQuality/Rector/FunctionLike/RemoveAlwaysTrueConditionSetInConstructorRector.php +++ b/rules/CodeQuality/Rector/FunctionLike/RemoveAlwaysTrueConditionSetInConstructorRector.php @@ -189,7 +189,7 @@ private function resolvePropertyFetchType(PropertyFetch $propertyFetch): Type $defaultValue = $property->props[0]->default; if ($defaultValue !== null) { - $resolvedTypes[] = $this->getStaticType($defaultValue); + $resolvedTypes[] = $this->getType($defaultValue); } $resolveAssignedType = $this->resolveAssignedTypeInStmtsByPropertyName($classLike->stmts, $propertyName); @@ -240,7 +240,7 @@ private function resolveAssignedTypeInStmtsByPropertyName(array $stmts, string $ return null; } - $resolvedTypes[] = $this->getStaticType($node->expr); + $resolvedTypes[] = $this->getType($node->expr); return null; }); diff --git a/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php b/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php index fdeb311a217..84095c94774 100644 --- a/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php +++ b/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php @@ -112,7 +112,7 @@ public function refactor(Node $node): ?Node return null; } - $conditionStaticType = $this->getStaticType($conditionNode); + $conditionStaticType = $this->getType($conditionNode); if ($conditionStaticType instanceof BooleanType || $conditionStaticType instanceof ConstantIntegerType) { return null; } diff --git a/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php b/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php index 059050c1d94..b70af59191c 100644 --- a/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php +++ b/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php @@ -76,7 +76,7 @@ public function refactor(Node $node): ?Node return null; } - $constType = $this->getStaticType($node->consts[0]->value); + $constType = $this->getType($node->consts[0]->value); if ($constType instanceof MixedType) { return null; } diff --git a/rules/CodingStyle/Rector/If_/NullableCompareToNullRector.php b/rules/CodingStyle/Rector/If_/NullableCompareToNullRector.php index 58f858ba204..cd336f892e1 100644 --- a/rules/CodingStyle/Rector/If_/NullableCompareToNullRector.php +++ b/rules/CodingStyle/Rector/If_/NullableCompareToNullRector.php @@ -84,7 +84,7 @@ public function refactor(Node $node): ?Node private function isNullableNonScalarType(Node $node): bool { - $staticType = $this->getStaticType($node); + $staticType = $this->getType($node); if ($staticType instanceof MixedType) { return false; } diff --git a/rules/DeadCode/Rector/Cast/RecastingRemovalRector.php b/rules/DeadCode/Rector/Cast/RecastingRemovalRector.php index a693adde970..58994f1810d 100644 --- a/rules/DeadCode/Rector/Cast/RecastingRemovalRector.php +++ b/rules/DeadCode/Rector/Cast/RecastingRemovalRector.php @@ -96,7 +96,7 @@ public function refactor(Node $node): ?Node return null; } - $nodeType = $this->getStaticType($node->expr); + $nodeType = $this->getType($node->expr); if ($nodeType instanceof MixedType) { return null; } diff --git a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php index f7edf0f6c16..d1c3ece86b4 100644 --- a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php +++ b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php @@ -71,7 +71,7 @@ public function refactor(Node $node): ?Node return null; } - $conditionStaticType = $this->getStaticType($node->cond); + $conditionStaticType = $this->getType($node->cond); if (! $conditionStaticType instanceof ConstantBooleanType) { return null; } diff --git a/rules/DeadCode/Rector/Ternary/TernaryToBooleanOrFalseToBooleanAndRector.php b/rules/DeadCode/Rector/Ternary/TernaryToBooleanOrFalseToBooleanAndRector.php index 7463bce9243..9c6c486b37f 100644 --- a/rules/DeadCode/Rector/Ternary/TernaryToBooleanOrFalseToBooleanAndRector.php +++ b/rules/DeadCode/Rector/Ternary/TernaryToBooleanOrFalseToBooleanAndRector.php @@ -79,7 +79,7 @@ public function refactor(Node $node): ?Node return null; } - $ifType = $this->getStaticType($node->if); + $ifType = $this->getType($node->if); if (! $ifType instanceof BooleanType) { return null; } diff --git a/rules/DowngradePhp70/Rector/FunctionLike/DowngradeScalarTypeDeclarationRector.php b/rules/DowngradePhp70/Rector/FunctionLike/DowngradeScalarTypeDeclarationRector.php index 503220de294..7249ef7a865 100644 --- a/rules/DowngradePhp70/Rector/FunctionLike/DowngradeScalarTypeDeclarationRector.php +++ b/rules/DowngradePhp70/Rector/FunctionLike/DowngradeScalarTypeDeclarationRector.php @@ -131,7 +131,7 @@ private function resolveRecastAssign(Param $param, Function_ | ClassMethod | Clo $paramName = $this->getName($param->var); $variable = new Variable($paramName); - $paramType = $this->getStaticType($param); + $paramType = $this->getType($param); $recastedVariable = $this->recastVariabletIfScalarType($variable, $paramType); if (! $recastedVariable instanceof Cast) { return null; diff --git a/rules/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector.php b/rules/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector.php index 601e79d6511..53cf8f89716 100644 --- a/rules/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector.php +++ b/rules/LeagueEvent/Rector/MethodCall/DispatchStringToObjectRector.php @@ -127,7 +127,7 @@ private function shouldSkip(MethodCall $methodCall): bool return true; } - return ! $this->getStaticType($methodCall->args[0]->value) instanceof StringType; + return ! $this->getType($methodCall->args[0]->value) instanceof StringType; } private function updateNode(MethodCall $methodCall): MethodCall diff --git a/rules/MysqlToMysqli/Rector/FuncCall/MysqlQueryMysqlErrorWithLinkRector.php b/rules/MysqlToMysqli/Rector/FuncCall/MysqlQueryMysqlErrorWithLinkRector.php index 1c49210cc7c..0fec7afb3a4 100644 --- a/rules/MysqlToMysqli/Rector/FuncCall/MysqlQueryMysqlErrorWithLinkRector.php +++ b/rules/MysqlToMysqli/Rector/FuncCall/MysqlQueryMysqlErrorWithLinkRector.php @@ -160,7 +160,7 @@ private function isProbablyMysql(Expr $expr): bool return true; } - $staticType = $this->getStaticType($expr); + $staticType = $this->getType($expr); $resourceType = new ResourceType(); if ($staticType->equals($resourceType)) { diff --git a/rules/Naming/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php b/rules/Naming/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php index 0e0b8f14b59..393d4fd3af4 100644 --- a/rules/Naming/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php +++ b/rules/Naming/Rector/Assign/RenameVariableToMatchMethodCallReturnTypeRector.php @@ -206,7 +206,7 @@ private function renameVariable(VariableAndCallAssign $variableAndCallAssign, st private function isClassTypeWithChildren(StaticCall | MethodCall | FuncCall $expr): bool { - $callStaticType = $this->getStaticType($expr); + $callStaticType = $this->getType($expr); $callStaticType = $this->typeUnwrapper->unwrapNullableType($callStaticType); if (! $callStaticType instanceof ObjectType) { diff --git a/rules/Naming/Rector/Foreach_/RenameForeachValueVariableToMatchExprVariableRector.php b/rules/Naming/Rector/Foreach_/RenameForeachValueVariableToMatchExprVariableRector.php index 8cce95bc5e3..4b2b8491cea 100644 --- a/rules/Naming/Rector/Foreach_/RenameForeachValueVariableToMatchExprVariableRector.php +++ b/rules/Naming/Rector/Foreach_/RenameForeachValueVariableToMatchExprVariableRector.php @@ -115,7 +115,7 @@ public function refactor(Node $node): ?Node private function isNotThisTypePropertyFetch(Expr $expr): bool { if ($expr instanceof PropertyFetch) { - $variableType = $this->getStaticType($expr->var); + $variableType = $this->getType($expr->var); return ! $variableType instanceof ThisType; } diff --git a/rules/Php52/Rector/Switch_/ContinueToBreakInSwitchRector.php b/rules/Php52/Rector/Switch_/ContinueToBreakInSwitchRector.php index d675ded93be..86d3786cfa3 100644 --- a/rules/Php52/Rector/Switch_/ContinueToBreakInSwitchRector.php +++ b/rules/Php52/Rector/Switch_/ContinueToBreakInSwitchRector.php @@ -110,7 +110,7 @@ private function processContinueStatement(Continue_ $continue): Break_ | Continu private function processVariableNum(Continue_ $continue, Variable $numVariable): Continue_ | Break_ { - $staticType = $this->getStaticType($numVariable); + $staticType = $this->getType($numVariable); if (! $staticType instanceof ConstantType) { return $continue; } diff --git a/rules/Php54/Rector/Break_/RemoveZeroBreakContinueRector.php b/rules/Php54/Rector/Break_/RemoveZeroBreakContinueRector.php index 7b460b382d1..492f8d8bb95 100644 --- a/rules/Php54/Rector/Break_/RemoveZeroBreakContinueRector.php +++ b/rules/Php54/Rector/Break_/RemoveZeroBreakContinueRector.php @@ -108,7 +108,7 @@ public function refactor(Node $node): ?Node private function processVariableNum(Break_ | Continue_ $stmt, Variable $numVariable): ?Node { - $staticType = $this->getStaticType($numVariable); + $staticType = $this->getType($numVariable); if ($staticType instanceof ConstantType) { if ($staticType instanceof ConstantIntegerType) { diff --git a/rules/Php71/Rector/BinaryOp/BinaryOpBetweenNumberAndStringRector.php b/rules/Php71/Rector/BinaryOp/BinaryOpBetweenNumberAndStringRector.php index 23707c69a1b..f67abfadcc2 100644 --- a/rules/Php71/Rector/BinaryOp/BinaryOpBetweenNumberAndStringRector.php +++ b/rules/Php71/Rector/BinaryOp/BinaryOpBetweenNumberAndStringRector.php @@ -117,7 +117,7 @@ private function isStringOrStaticNonNumbericString(Expr $expr): bool } $value = null; - $exprStaticType = $this->getStaticType($expr); + $exprStaticType = $this->getType($expr); if ($expr instanceof String_) { $value = $expr->value; diff --git a/rules/Php71/Rector/FuncCall/CountOnNullRector.php b/rules/Php71/Rector/FuncCall/CountOnNullRector.php index a9d14d0f098..aa24db0b954 100644 --- a/rules/Php71/Rector/FuncCall/CountOnNullRector.php +++ b/rules/Php71/Rector/FuncCall/CountOnNullRector.php @@ -95,7 +95,7 @@ public function refactor(Node $node): ?Node } // this can lead to false positive by phpstan, but that's best we can do - $onlyValueType = $this->getStaticType($countedNode); + $onlyValueType = $this->getType($countedNode); if ($onlyValueType instanceof ArrayType) { if (! $this->countableAnalyzer->isCastableArrayType($countedNode)) { return null; diff --git a/rules/Php74/Rector/FuncCall/ArrayKeyExistsOnPropertyRector.php b/rules/Php74/Rector/FuncCall/ArrayKeyExistsOnPropertyRector.php index 80a115e6b0e..ba3a3cf3613 100644 --- a/rules/Php74/Rector/FuncCall/ArrayKeyExistsOnPropertyRector.php +++ b/rules/Php74/Rector/FuncCall/ArrayKeyExistsOnPropertyRector.php @@ -82,7 +82,7 @@ public function refactor(Node $node): ?Node return null; } - $firstArgStaticType = $this->getStaticType($node->args[1]->value); + $firstArgStaticType = $this->getType($node->args[1]->value); if (! $firstArgStaticType instanceof ObjectType) { return null; } diff --git a/rules/Php74/Rector/FuncCall/ArraySpreadInsteadOfArrayMergeRector.php b/rules/Php74/Rector/FuncCall/ArraySpreadInsteadOfArrayMergeRector.php index b23de450d56..8d34c6ce548 100644 --- a/rules/Php74/Rector/FuncCall/ArraySpreadInsteadOfArrayMergeRector.php +++ b/rules/Php74/Rector/FuncCall/ArraySpreadInsteadOfArrayMergeRector.php @@ -133,7 +133,7 @@ private function shouldSkipArrayForInvalidTypeOrKeys(Expr $expr): bool return true; } - $arrayStaticType = $this->getStaticType($expr); + $arrayStaticType = $this->getType($expr); if ($this->isConstantArrayTypeWithStringKeyType($arrayStaticType)) { return true; } diff --git a/rules/Php74/Rector/FuncCall/MbStrrposEncodingArgumentPositionRector.php b/rules/Php74/Rector/FuncCall/MbStrrposEncodingArgumentPositionRector.php index 9d776d5ded8..1595e9e6f44 100644 --- a/rules/Php74/Rector/FuncCall/MbStrrposEncodingArgumentPositionRector.php +++ b/rules/Php74/Rector/FuncCall/MbStrrposEncodingArgumentPositionRector.php @@ -64,7 +64,7 @@ public function refactor(Node $node): ?Node return null; } - $secondArgType = $this->getStaticType($node->args[2]->value); + $secondArgType = $this->getType($node->args[2]->value); if ($secondArgType instanceof IntegerType) { return null; } diff --git a/rules/Privatization/Rector/Class_/ChangeReadOnlyVariableWithDefaultValueToConstantRector.php b/rules/Privatization/Rector/Class_/ChangeReadOnlyVariableWithDefaultValueToConstantRector.php index 6ef39f669a1..a3186e3c2b9 100644 --- a/rules/Privatization/Rector/Class_/ChangeReadOnlyVariableWithDefaultValueToConstantRector.php +++ b/rules/Privatization/Rector/Class_/ChangeReadOnlyVariableWithDefaultValueToConstantRector.php @@ -235,7 +235,7 @@ private function createPrivateClassConst(Variable $variable, Expr $expr): ClassC $this->mirrorComments($classConst, $variable); - $constantType = $this->getStaticType($classConst->consts[0]->value); + $constantType = $this->getType($classConst->consts[0]->value); $this->varAnnotationManipulator->decorateNodeWithType($classConst, $constantType); return $classConst; diff --git a/rules/Transform/Rector/MethodCall/CallableInMethodCallToVariableRector.php b/rules/Transform/Rector/MethodCall/CallableInMethodCallToVariableRector.php index c5017e93eec..604723404d3 100644 --- a/rules/Transform/Rector/MethodCall/CallableInMethodCallToVariableRector.php +++ b/rules/Transform/Rector/MethodCall/CallableInMethodCallToVariableRector.php @@ -105,7 +105,7 @@ public function refactor(Node $node): ?MethodCall } $arg = $node->args[$position]; - $argValueType = $this->getStaticType($arg->value); + $argValueType = $this->getType($arg->value); if (! $argValueType instanceof ClosureType) { continue; } diff --git a/rules/TypeDeclaration/Rector/ClassMethod/ReturnNeverTypeRector.php b/rules/TypeDeclaration/Rector/ClassMethod/ReturnNeverTypeRector.php index 7bad843846d..edb9939c78f 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/ReturnNeverTypeRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/ReturnNeverTypeRector.php @@ -135,7 +135,7 @@ private function hasNeverFuncCall(ClassMethod | Function_ $functionLike): bool continue; } - $stmtType = $this->getStaticType($stmt); + $stmtType = $this->getType($stmt); if ($stmtType instanceof NeverType) { $hasNeverType = true; } From 4ed236576a352a31588a9fcd240d2c8b01c78a3d Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 18:20:11 +0200 Subject: [PATCH 04/14] add breaking use-case --- .../skip_count_on_class_method_stmts.php.inc | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/skip_count_on_class_method_stmts.php.inc diff --git a/rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/skip_count_on_class_method_stmts.php.inc b/rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/skip_count_on_class_method_stmts.php.inc new file mode 100644 index 00000000000..7ec0741407d --- /dev/null +++ b/rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/skip_count_on_class_method_stmts.php.inc @@ -0,0 +1,13 @@ +stmts) === 5; + } +} From e3fe16702f9be9f0ee4ffa12bda6713b6b76922d Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 18:23:36 +0200 Subject: [PATCH 05/14] remove deprecated isAtLeastPhpVersion() method --- .../NodeTypeResolver/NodeTypeResolver.php | 4 +++ .../count_on_class_method_stmts.php.inc | 31 +++++++++++++++++++ .../skip_count_on_class_method_stmts.php.inc | 13 -------- .../ClassConst/VarConstantCommentRector.php | 3 ++ .../RemoveDelegatingParentCallRector.php | 2 +- .../ClassMethod/Php4ConstructorRector.php | 7 +++-- src/Rector/AbstractRector.php | 25 +++++---------- 7 files changed, 51 insertions(+), 34 deletions(-) create mode 100644 rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/count_on_class_method_stmts.php.inc delete mode 100644 rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/skip_count_on_class_method_stmts.php.inc diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index 70ab32aafcf..ac3cc1c5072 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -145,6 +145,9 @@ public function resolve(Node $node): Type $type = $this->resolveByNodeTypeResolvers($node); if ($type !== null) { $type = $this->accessoryNonEmptyStringTypeCorrector->correct($type); + + $type = $this->genericClassStringTypeCorrector->correct($type); + return $this->hasOffsetTypeCorrector->correct($type); } @@ -177,6 +180,7 @@ public function resolve(Node $node): Type $type = $scope->getType($node); $type = $this->accessoryNonEmptyStringTypeCorrector->correct($type); + $type = $this->genericClassStringTypeCorrector->correct($type); // hot fix for phpstan not resolving chain method calls if (! $node instanceof MethodCall) { diff --git a/rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/count_on_class_method_stmts.php.inc b/rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/count_on_class_method_stmts.php.inc new file mode 100644 index 00000000000..43d4dd539c9 --- /dev/null +++ b/rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/count_on_class_method_stmts.php.inc @@ -0,0 +1,31 @@ +stmts) === 5; + } +} + +?> +----- +stmts) === 5; + } +} + +?> diff --git a/rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/skip_count_on_class_method_stmts.php.inc b/rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/skip_count_on_class_method_stmts.php.inc deleted file mode 100644 index 7ec0741407d..00000000000 --- a/rules-tests/Php71/Rector/FuncCall/CountOnNullRector/Fixture/skip_count_on_class_method_stmts.php.inc +++ /dev/null @@ -1,13 +0,0 @@ -stmts) === 5; - } -} diff --git a/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php b/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php index b70af59191c..f5db7116686 100644 --- a/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php +++ b/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php @@ -77,6 +77,9 @@ public function refactor(Node $node): ?Node } $constType = $this->getType($node->consts[0]->value); + + $beforeConstantType = $this->nodeTypeResolver->getStaticType($node->consts[0]->value); + if ($constType instanceof MixedType) { return null; } diff --git a/rules/DeadCode/Rector/ClassMethod/RemoveDelegatingParentCallRector.php b/rules/DeadCode/Rector/ClassMethod/RemoveDelegatingParentCallRector.php index f1c23c2bc38..06959ba3a6b 100644 --- a/rules/DeadCode/Rector/ClassMethod/RemoveDelegatingParentCallRector.php +++ b/rules/DeadCode/Rector/ClassMethod/RemoveDelegatingParentCallRector.php @@ -149,7 +149,7 @@ private function matchClassMethodOnlyStmt(ClassMethod $classMethod): null | Stmt return null; } - if (count($classMethod->stmts) !== 1) { + if (count((array) $classMethod->stmts) !== 1) { return null; } diff --git a/rules/Php70/Rector/ClassMethod/Php4ConstructorRector.php b/rules/Php70/Rector/ClassMethod/Php4ConstructorRector.php index 4420039e1be..4f2d44fc57d 100644 --- a/rules/Php70/Rector/ClassMethod/Php4ConstructorRector.php +++ b/rules/Php70/Rector/ClassMethod/Php4ConstructorRector.php @@ -105,13 +105,14 @@ public function refactor(Node $node): ?Node $node->name = new Identifier(MethodName::CONSTRUCT); } - if ($node->stmts === null) { + $stmts = $node->stmts; + if ($stmts === null) { return null; } - if (count($node->stmts) === 1) { + if (count($stmts) === 1) { /** @var Expression|Expr $stmt */ - $stmt = $node->stmts[0]; + $stmt = $stmts[0]; if (! $stmt instanceof Expression) { return null; } diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index 2faf707d789..b65344f9614 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -323,6 +323,14 @@ protected function isObjectType(Node $node, ObjectType $objectType): bool return $this->nodeTypeResolver->isObjectType($node, $objectType); } + /** + * Use this method for getting expr|node type + */ + protected function getType(Node $node): Type + { + return $this->nodeTypeResolver->resolve($node); + } + /** * @deprecated * Use @see AbstractRector::getType() instead, as single method to get types @@ -341,14 +349,6 @@ protected function getObjectType(Node $node): Type return $this->getType($node); } - /** - * Use this method for getting expr|node type - */ - protected function getType(Node $node): Type - { - return $this->nodeTypeResolver->resolve($node); - } - /** * @param Node|Node[] $nodes */ @@ -365,15 +365,6 @@ protected function print(Node | array | null $node): string return $this->betterStandardPrinter->print($node); } - /** - * @deprecated Use FQN PhpVersionProvider service directly instead or implements provideMinPhpVersion, this method will be removed soon - * Or implement \Rector\VersionBonding\Contract\MinPhpVersionInterface - */ - protected function isAtLeastPhpVersion(int $version): bool - { - return $this->phpVersionProvider->isAtLeastPhpVersion($version); - } - protected function mirrorComments(Node $newNode, Node $oldNode): void { $newNode->setAttribute(AttributeKey::PHP_DOC_INFO, $oldNode->getAttribute(AttributeKey::PHP_DOC_INFO)); From ef34bec051d33f4b3dd125561aff6879261034ab Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 18:37:19 +0200 Subject: [PATCH 06/14] notes --- .../NodeTypeResolver/NodeTypeResolver.php | 82 ++++++++++--------- .../InferParamFromClassMethodReturnRector.php | 2 + 2 files changed, 47 insertions(+), 37 deletions(-) diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index ac3cc1c5072..1e177f04d56 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -124,7 +124,16 @@ public function isObjectType(Node $node, ObjectType $requiredObjectType): bool return $this->isMatchingUnionType($resolvedType, $requiredObjectType); } + /** + * @deprecated + * @see use NodeTypeResolver::getType() instead + */ public function resolve(Node $node): Type + { + return $this->getType($node); + } + + public function getType(Node $node): Type { if ($node instanceof Ternary) { $ternaryType = $this->resolveTernaryType($node); @@ -179,7 +188,9 @@ public function resolve(Node $node): Type } $type = $scope->getType($node); + $type = $this->accessoryNonEmptyStringTypeCorrector->correct($type); + $type = $this->genericClassStringTypeCorrector->correct($type); // hot fix for phpstan not resolving chain method calls @@ -215,15 +226,7 @@ public function getNativeType(Expr $expr): Type public function getStaticType(Node $node): Type { - if ($node instanceof Param) { - return $this->resolve($node); - } - - if ($node instanceof New_) { - return $this->resolve($node); - } - - if ($node instanceof Return_) { + if ($node instanceof Param || $node instanceof New_ || $node instanceof Return_) { return $this->resolve($node); } @@ -266,6 +269,9 @@ public function isNumberType(Node $node): bool } /** + * @deprecated + * Use @see NodeTypeResolver::resolve() instead and instanceof directly + * * @param class-string $staticTypeClass */ public function isStaticType(Node $node, string $staticTypeClass): bool @@ -321,20 +327,21 @@ public function getFullyQualifiedClassName(TypeWithClassName $typeWithClassName) return $typeWithClassName->getClassName(); } - /** - * @param Type[] $desiredTypes - */ - public function isSameObjectTypes(ObjectType $objectType, array $desiredTypes): bool - { - foreach ($desiredTypes as $desiredType) { - $desiredTypeEquals = $desiredType->equals($objectType); - if ($desiredTypeEquals) { - return true; - } - } - - return false; - } + // @todo possibly unused +// /** +// * @param Type[] $desiredTypes +// */ +// public function isSameObjectTypes(ObjectType $objectType, array $desiredTypes): bool +// { +// foreach ($desiredTypes as $desiredType) { +// $desiredTypeEquals = $desiredType->equals($objectType); +// if ($desiredTypeEquals) { +// return true; +// } +// } +// +// return false; +// } public function isMethodStaticCallOrClassMethodObjectType(Node $node, ObjectType $objectType): bool { @@ -355,20 +362,21 @@ public function isMethodStaticCallOrClassMethodObjectType(Node $node, ObjectType return $this->isObjectType($classLike, $objectType); } - public function resolveObjectTypeFromScope(Scope $scope): ?ObjectType - { - $classReflection = $scope->getClassReflection(); - if (! $classReflection instanceof ClassReflection) { - return null; - } - - $className = $classReflection->getName(); - if (! $this->reflectionProvider->hasClass($className)) { - return null; - } - - return new ObjectType($className, null, $classReflection); - } + // @note possibly unused +// public function resolveObjectTypeFromScope(Scope $scope): ?ObjectType +// { +// $classReflection = $scope->getClassReflection(); +// if (! $classReflection instanceof ClassReflection) { +// return null; +// } +// +// $className = $classReflection->getName(); +// if (! $this->reflectionProvider->hasClass($className)) { +// return null; +// } +// +// return new ObjectType($className, null, $classReflection); +// } private function isUnionTypeable(Type $first, Type $second): bool { diff --git a/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php b/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php index fcbe1b93ce1..155f2b78301 100644 --- a/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php +++ b/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php @@ -119,6 +119,8 @@ public function refactor(Node $node): ?Node $returnType = $this->returnTypeInferer->inferFunctionLike($returnClassMethod); + dump($returnType); + $currentPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); $paramType = $this->constantReturnToParamTypeConverter->convert($returnType); From 1649c8bad4d2d9a5ff3338075db4457f540335a9 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 18:47:18 +0200 Subject: [PATCH 07/14] use getType() --- .../NodeTypeResolver/NodeTypeResolver.php | 28 +++++++++---------- .../InferParamFromClassMethodReturnRector.php | 7 +++-- .../ConstantReturnToParamTypeConverter.php | 2 ++ .../GenericClassStringTypeNormalizer.php | 3 +- .../TypeInferer/ReturnTypeInferer.php | 4 +-- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index 1e177f04d56..de6e08d2e7b 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -108,7 +108,7 @@ public function isObjectType(Node $node, ObjectType $requiredObjectType): bool return false; } - $resolvedType = $this->resolve($node); + $resolvedType = $this->getType($node); if ($resolvedType instanceof MixedType) { return false; } @@ -130,7 +130,7 @@ public function isObjectType(Node $node, ObjectType $requiredObjectType): bool */ public function resolve(Node $node): Type { - return $this->getType($node); + return $this->getType($node); } public function getType(Node $node): Type @@ -143,8 +143,8 @@ public function getType(Node $node): Type } if ($node instanceof Coalesce) { - $first = $this->resolve($node->left); - $second = $this->resolve($node->right); + $first = $this->getType($node->left); + $second = $this->getType($node->right); if ($this->isUnionTypeable($first, $second)) { return new UnionType([$first, $second]); @@ -202,7 +202,7 @@ public function getType(Node $node): Type return $type; } - return $this->resolve($node->var); + return $this->getType($node->var); } /** @@ -210,7 +210,7 @@ public function getType(Node $node): Type */ public function isNullableType(Node $node): bool { - $nodeType = $this->resolve($node); + $nodeType = $this->getType($node); return TypeCombinator::containsNull($nodeType); } @@ -227,7 +227,7 @@ public function getNativeType(Expr $expr): Type public function getStaticType(Node $node): Type { if ($node instanceof Param || $node instanceof New_ || $node instanceof Return_) { - return $this->resolve($node); + return $this->getType($node); } if (! $node instanceof Expr) { @@ -239,7 +239,7 @@ public function getStaticType(Node $node): Type } if ($node instanceof Scalar) { - return $this->resolve($node); + return $this->getType($node); } $scope = $node->getAttribute(AttributeKey::SCOPE); @@ -285,7 +285,7 @@ public function isStaticType(Node $node, string $staticTypeClass): bool )); } - return is_a($this->resolve($node), $staticTypeClass); + return is_a($this->getType($node), $staticTypeClass); } /** @@ -293,7 +293,7 @@ public function isStaticType(Node $node, string $staticTypeClass): bool */ public function isNullableTypeOfSpecificType(Node $node, string $desiredType): bool { - $nodeType = $this->resolve($node); + $nodeType = $this->getType($node); if (! $nodeType instanceof UnionType) { return false; } @@ -503,18 +503,18 @@ private function resolveObjectType(ObjectType $resolvedObjectType, ObjectType $r private function resolveTernaryType(Ternary $ternary): MixedType|UnionType { if ($ternary->if !== null) { - $first = $this->resolve($ternary->if); - $second = $this->resolve($ternary->else); + $first = $this->getType($ternary->if); + $second = $this->getType($ternary->else); if ($this->isUnionTypeable($first, $second)) { return new UnionType([$first, $second]); } } - $condType = $this->resolve($ternary->cond); + $condType = $this->getType($ternary->cond); if ($this->isNullableType($ternary->cond) && $condType instanceof UnionType) { $first = $condType->getTypes()[0]; - $second = $this->resolve($ternary->else); + $second = $this->getType($ternary->else); if ($this->isUnionTypeable($first, $second)) { return new UnionType([$first, $second]); diff --git a/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php b/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php index 155f2b78301..3966b160998 100644 --- a/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php +++ b/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php @@ -119,11 +119,14 @@ public function refactor(Node $node): ?Node $returnType = $this->returnTypeInferer->inferFunctionLike($returnClassMethod); - dump($returnType); - $currentPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); $paramType = $this->constantReturnToParamTypeConverter->convert($returnType); + + // here is something broken + dump($paramType); + die; + if ($paramType instanceof MixedType) { continue; } diff --git a/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php b/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php index c36f136aa95..d8a75360887 100644 --- a/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php +++ b/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php @@ -69,6 +69,8 @@ private function unwrapConstantTypeToObjectType(Type $type): Type return $this->unwrapUnionType($type); } + dump($type);die; + return new MixedType(); } diff --git a/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php b/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php index 7ea728098f6..4b783bddb68 100644 --- a/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php +++ b/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php @@ -49,7 +49,8 @@ public function normalize(Type $type): ArrayType | UnionType | Type }); if ($type instanceof UnionType) { - return $this->resolveClassStringInUnionType($type); + return $type; +// Oreturn $this->resolveClassStringInUnionType($type); } if ($type instanceof ArrayType && $type->getKeyType() instanceof UnionType) { diff --git a/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php b/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php index 0380022f808..716f099765e 100644 --- a/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php +++ b/rules/TypeDeclaration/TypeInferer/ReturnTypeInferer.php @@ -64,8 +64,7 @@ public function inferFunctionLikeWithExcludedInferers(FunctionLike $functionLike ); $isAutoImport = $this->parameterProvider->provideBoolParameter(Option::AUTO_IMPORT_NAMES); - $isAutoImportFullyQuafiedReturn = $this->isAutoImportWithFullyQualifiedReturn($isAutoImport, $functionLike); - if ($isAutoImportFullyQuafiedReturn) { + if ($this->isAutoImportWithFullyQualifiedReturn($isAutoImport, $functionLike)) { return new MixedType(); } @@ -93,6 +92,7 @@ public function inferFunctionLikeWithExcludedInferers(FunctionLike $functionLike // normalize ConstStringType to ClassStringType $resolvedType = $this->genericClassStringTypeNormalizer->normalize($type); + return $this->resolveTypeWithVoidHandling($functionLike, $resolvedType); } From 4c86256ac6793a2f4392cbd4be14d7098bf71a29 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 18:55:24 +0200 Subject: [PATCH 08/14] fix unwrapping class string type to generic type --- phpstan.neon | 2 +- .../ClassConst/VarConstantCommentRector.php | 3 -- .../ClassMethod/NormalToFluentRector.php | 2 +- .../InferParamFromClassMethodReturnRector.php | 3 -- .../ConstantReturnToParamTypeConverter.php | 42 ++++++++++++------- 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 63e7cd538db..6caf3e91b07 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -314,7 +314,7 @@ parameters: - '#Cognitive complexity for "Rector\\BetterPhpDocParser\\PhpDocParser\\DoctrineAnnotationDecorator\:\:mergeNestedDoctrineAnnotations\(\)" is \d+, keep it under 9#' - '#Cognitive complexity for "Rector\\BetterPhpDocParser\\Printer\\PhpDocInfoPrinter\:\:printDocChildNode\(\)" is \d+, keep it under 9#' - - '#Cognitive complexity for "Rector\\NodeTypeResolver\\NodeTypeResolver\:\:resolve\(\)" is \d+, keep it under 9#' + - '#Cognitive complexity for "Rector\\NodeTypeResolver\\NodeTypeResolver\:\:getType\(\)" is \d+, keep it under 9#' - message: '#Property with protected modifier is not allowed\. Use interface contract method instead#' diff --git a/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php b/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php index f5db7116686..b70af59191c 100644 --- a/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php +++ b/rules/CodingStyle/Rector/ClassConst/VarConstantCommentRector.php @@ -77,9 +77,6 @@ public function refactor(Node $node): ?Node } $constType = $this->getType($node->consts[0]->value); - - $beforeConstantType = $this->nodeTypeResolver->getStaticType($node->consts[0]->value); - if ($constType instanceof MixedType) { return null; } diff --git a/rules/Defluent/Rector/ClassMethod/NormalToFluentRector.php b/rules/Defluent/Rector/ClassMethod/NormalToFluentRector.php index 367f74a3c54..05d6aeba13b 100644 --- a/rules/Defluent/Rector/ClassMethod/NormalToFluentRector.php +++ b/rules/Defluent/Rector/ClassMethod/NormalToFluentRector.php @@ -78,7 +78,7 @@ public function refactor(Node $node): ?Node return null; } - $classMethodStatementCount = count($node->stmts); + $classMethodStatementCount = count((array) $node->stmts); // iterate from bottom to up, so we can merge for ($i = $classMethodStatementCount - 1; $i >= 0; --$i) { diff --git a/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php b/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php index 3966b160998..e36194ba06d 100644 --- a/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php +++ b/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php @@ -124,9 +124,6 @@ public function refactor(Node $node): ?Node $paramType = $this->constantReturnToParamTypeConverter->convert($returnType); // here is something broken - dump($paramType); - die; - if ($paramType instanceof MixedType) { continue; } diff --git a/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php b/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php index d8a75360887..564616024a1 100644 --- a/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php +++ b/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php @@ -24,20 +24,7 @@ public function __construct( public function convert(Type $type): Type { if ($type instanceof UnionType) { - $flattenReturnTypes = TypeUtils::flattenTypes($type); - $unionedTypes = []; - foreach ($flattenReturnTypes as $flattenReturnType) { - if ($flattenReturnType instanceof ArrayType) { - $unionedTypes[] = $flattenReturnType->getItemType(); - } - } - - $resolvedTypes = []; - foreach ($unionedTypes as $unionedType) { - $resolvedTypes[] = $this->convert($unionedType); - } - - return new UnionType($resolvedTypes); + return $this->convertUnionType($type); } if ($type instanceof ConstantStringType) { @@ -48,6 +35,11 @@ public function convert(Type $type): Type return $this->unwrapConstantTypeToObjectType($type); } + // making generic class stirng type to object type + if ($type instanceof GenericClassStringType) { + return $type->getGenericType(); + } + return new MixedType(); } @@ -69,8 +61,6 @@ private function unwrapConstantTypeToObjectType(Type $type): Type return $this->unwrapUnionType($type); } - dump($type);die; - return new MixedType(); } @@ -86,4 +76,24 @@ private function unwrapUnionType(UnionType $unionType): Type return $this->typeFactory->createMixedPassedOrUnionType($types); } + + private function convertUnionType(UnionType $unionType): UnionType + { + $flattenReturnTypes = TypeUtils::flattenTypes($unionType); + + $unionedTypes = []; + foreach ($flattenReturnTypes as $flattenReturnType) { + if ($flattenReturnType instanceof ArrayType) { + $unionedTypes[] = $flattenReturnType->getItemType(); + } + } + + $resolvedTypes = []; + + foreach ($unionedTypes as $unionedType) { + $resolvedTypes[] = $this->convert($unionedType); + } + + return new UnionType($resolvedTypes); + } } From 4c594ed68d7ad6c26bf46ef9e81afc6902cb2e7e Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 18:59:44 +0200 Subject: [PATCH 09/14] remove unused methods --- .../NodeTypeResolver/NodeTypeResolver.php | 32 ------------------- 1 file changed, 32 deletions(-) diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index de6e08d2e7b..aa78da7a276 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -327,22 +327,6 @@ public function getFullyQualifiedClassName(TypeWithClassName $typeWithClassName) return $typeWithClassName->getClassName(); } - // @todo possibly unused -// /** -// * @param Type[] $desiredTypes -// */ -// public function isSameObjectTypes(ObjectType $objectType, array $desiredTypes): bool -// { -// foreach ($desiredTypes as $desiredType) { -// $desiredTypeEquals = $desiredType->equals($objectType); -// if ($desiredTypeEquals) { -// return true; -// } -// } -// -// return false; -// } - public function isMethodStaticCallOrClassMethodObjectType(Node $node, ObjectType $objectType): bool { if ($node instanceof MethodCall) { @@ -362,22 +346,6 @@ public function isMethodStaticCallOrClassMethodObjectType(Node $node, ObjectType return $this->isObjectType($classLike, $objectType); } - // @note possibly unused -// public function resolveObjectTypeFromScope(Scope $scope): ?ObjectType -// { -// $classReflection = $scope->getClassReflection(); -// if (! $classReflection instanceof ClassReflection) { -// return null; -// } -// -// $className = $classReflection->getName(); -// if (! $this->reflectionProvider->hasClass($className)) { -// return null; -// } -// -// return new ObjectType($className, null, $classReflection); -// } - private function isUnionTypeable(Type $first, Type $second): bool { return ! $first instanceof UnionType && ! $second instanceof UnionType && ! $second instanceof NullType; From 12f6663ad053865c0afcd1432f536551c1c5e6a5 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 19:02:25 +0200 Subject: [PATCH 10/14] fixes --- packages/NodeTypeResolver/NodeTypeResolver.php | 1 - .../Fixture/class_string_array_item.php.inc | 2 +- .../Fixture/class_string_array_item2.php.inc | 2 +- .../TypeAnalyzer/GenericClassStringTypeNormalizer.php | 3 +-- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index aa78da7a276..bc559cb7d61 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -20,7 +20,6 @@ use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\Return_; use PHPStan\Analyser\Scope; -use PHPStan\Reflection\ClassReflection; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Type\Accessory\NonEmptyArrayType; use PHPStan\Type\ArrayType; diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector/Fixture/class_string_array_item.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector/Fixture/class_string_array_item.php.inc index 71f86e89b08..b5a308a42c5 100644 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector/Fixture/class_string_array_item.php.inc +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector/Fixture/class_string_array_item.php.inc @@ -42,7 +42,7 @@ class DFactory {} class ClassStringArrayItem { /** - * @return array + * @return array */ public function getData() { diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector/Fixture/class_string_array_item2.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector/Fixture/class_string_array_item2.php.inc index 6a1a15599df..9ff19b1f87e 100644 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector/Fixture/class_string_array_item2.php.inc +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddArrayReturnDocTypeRector/Fixture/class_string_array_item2.php.inc @@ -40,7 +40,7 @@ class DFactory {} class ClassStringArrayItem2 { /** - * @return array + * @return class-string[] */ public function getData() { diff --git a/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php b/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php index 4b783bddb68..7ea728098f6 100644 --- a/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php +++ b/rules/TypeDeclaration/TypeAnalyzer/GenericClassStringTypeNormalizer.php @@ -49,8 +49,7 @@ public function normalize(Type $type): ArrayType | UnionType | Type }); if ($type instanceof UnionType) { - return $type; -// Oreturn $this->resolveClassStringInUnionType($type); + return $this->resolveClassStringInUnionType($type); } if ($type instanceof ArrayType && $type->getKeyType() instanceof UnionType) { From 84b708928147f7afae109e90c9439e48daf08f55 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 19:11:52 +0200 Subject: [PATCH 11/14] getting rid of isStaticType() --- packages/NodeTypeResolver/NodeTypeResolver.php | 5 +++-- .../CodeQuality/NodeManipulator/ExprBoolCaster.php | 3 ++- .../FuncCall/RemoveSoleValueSprintfRector.php | 4 +++- .../BooleanNotIdenticalToNotIdenticalRector.php | 13 +++++++++---- .../Identical/SimplifyBoolIdenticalTrueRector.php | 9 ++++----- .../Rector/If_/ExplicitBoolCompareRector.php | 7 ++++--- .../Ternary/SimplifyDuplicatedTernaryRector.php | 3 ++- .../Ternary/UnnecessaryTernaryExpressionRector.php | 9 ++++++--- rules/Php70/Rector/Assign/ListSplitStringRector.php | 3 ++- rules/Php71/Rector/FuncCall/CountOnNullRector.php | 7 +++---- .../Php72/Rector/FuncCall/GetClassOnNullRector.php | 6 ++---- src/Rector/AbstractRector.php | 10 +++++----- 12 files changed, 45 insertions(+), 34 deletions(-) diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index bc559cb7d61..35ab47a96d3 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -260,11 +260,12 @@ public function getStaticType(Node $node): Type public function isNumberType(Node $node): bool { - if ($this->isStaticType($node, IntegerType::class)) { + $nodeType = $this->getType($node); + if ($nodeType instanceof IntegerType) { return true; } - return $this->isStaticType($node, FloatType::class); + return $nodeType instanceof FloatType; } /** diff --git a/rules/CodeQuality/NodeManipulator/ExprBoolCaster.php b/rules/CodeQuality/NodeManipulator/ExprBoolCaster.php index 633e2609b9f..d487744aabb 100644 --- a/rules/CodeQuality/NodeManipulator/ExprBoolCaster.php +++ b/rules/CodeQuality/NodeManipulator/ExprBoolCaster.php @@ -60,7 +60,8 @@ private function isBoolCastNeeded(Expr $expr): bool return false; } - if ($this->nodeTypeResolver->isStaticType($expr, BooleanType::class)) { + $exprType = $this->nodeTypeResolver->getType($expr); + if ($exprType instanceof BooleanType) { return false; } diff --git a/rules/CodeQuality/Rector/FuncCall/RemoveSoleValueSprintfRector.php b/rules/CodeQuality/Rector/FuncCall/RemoveSoleValueSprintfRector.php index 570643615fc..2e441281dc6 100644 --- a/rules/CodeQuality/Rector/FuncCall/RemoveSoleValueSprintfRector.php +++ b/rules/CodeQuality/Rector/FuncCall/RemoveSoleValueSprintfRector.php @@ -96,7 +96,9 @@ public function refactor(Node $node): ?Node /** @var Arg $secondArg */ $secondArg = $node->args[1]; $valueArgument = $secondArg->value; - if (! $this->nodeTypeResolver->isStaticType($valueArgument, StringType::class)) { + + $valueType = $this->getType($valueArgument); + if (! $valueType instanceof StringType) { return null; } diff --git a/rules/CodeQuality/Rector/Identical/BooleanNotIdenticalToNotIdenticalRector.php b/rules/CodeQuality/Rector/Identical/BooleanNotIdenticalToNotIdenticalRector.php index ca006e1689d..03a2427b1fc 100644 --- a/rules/CodeQuality/Rector/Identical/BooleanNotIdenticalToNotIdenticalRector.php +++ b/rules/CodeQuality/Rector/Identical/BooleanNotIdenticalToNotIdenticalRector.php @@ -78,11 +78,14 @@ public function refactor(Node $node): ?Node if ($node->expr instanceof Identical) { $identical = $node->expr; - if (! $this->nodeTypeResolver->isStaticType($identical->left, BooleanType::class)) { + + $leftType = $this->getType($identical->left); + if (! $leftType instanceof BooleanType) { return null; } - if (! $this->nodeTypeResolver->isStaticType($identical->right, BooleanType::class)) { + $rightType = $this->getType($identical->right); + if (! $rightType instanceof BooleanType) { return null; } @@ -94,11 +97,13 @@ public function refactor(Node $node): ?Node private function processIdentical(Identical $identical): ?NotIdentical { - if (! $this->nodeTypeResolver->isStaticType($identical->left, BooleanType::class)) { + $leftType = $this->getType($identical->left); + if (! $leftType instanceof BooleanType) { return null; } - if (! $this->nodeTypeResolver->isStaticType($identical->right, BooleanType::class)) { + $rightType = $this->getType($identical->right); + if (! $rightType instanceof BooleanType) { return null; } diff --git a/rules/CodeQuality/Rector/Identical/SimplifyBoolIdenticalTrueRector.php b/rules/CodeQuality/Rector/Identical/SimplifyBoolIdenticalTrueRector.php index e3ebb4dee21..01ae3984de5 100644 --- a/rules/CodeQuality/Rector/Identical/SimplifyBoolIdenticalTrueRector.php +++ b/rules/CodeQuality/Rector/Identical/SimplifyBoolIdenticalTrueRector.php @@ -64,14 +64,13 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - if ($this->nodeTypeResolver->isStaticType( - $node->left, - BooleanType::class - ) && ! $this->valueResolver->isTrueOrFalse($node->left)) { + $leftType = $this->getType($node->left); + if ($leftType instanceof BooleanType && ! $this->valueResolver->isTrueOrFalse($node->left)) { return $this->processBoolTypeToNotBool($node, $node->left, $node->right); } - if (! $this->nodeTypeResolver->isStaticType($node->right, BooleanType::class)) { + $rightType = $this->getType($node->right); + if (! $rightType instanceof BooleanType) { return null; } diff --git a/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php b/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php index 84095c94774..85ae62c41ab 100644 --- a/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php +++ b/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php @@ -152,15 +152,16 @@ private function resolveNewConditionNode(Expr $expr, bool $isNegated): ?BinaryOp return $this->resolveString($isNegated, $expr); } - if ($this->nodeTypeResolver->isStaticType($expr, IntegerType::class)) { + $exprType = $this->getType($expr); + if ($exprType instanceof IntegerType) { return $this->resolveInteger($isNegated, $expr); } - if ($this->nodeTypeResolver->isStaticType($expr, FloatType::class)) { + if ($exprType instanceof FloatType) { return $this->resolveFloat($isNegated, $expr); } - if ($this->nodeTypeResolver->isNullableTypeOfSpecificType($expr, ObjectType::class)) { + if ($exprType instanceof ObjectType) { return $this->resolveNullable($isNegated, $expr); } diff --git a/rules/CodeQuality/Rector/Ternary/SimplifyDuplicatedTernaryRector.php b/rules/CodeQuality/Rector/Ternary/SimplifyDuplicatedTernaryRector.php index a2acb6901ce..7754285b29e 100644 --- a/rules/CodeQuality/Rector/Ternary/SimplifyDuplicatedTernaryRector.php +++ b/rules/CodeQuality/Rector/Ternary/SimplifyDuplicatedTernaryRector.php @@ -61,7 +61,8 @@ public function getNodeTypes(): array */ public function refactor(Node $node): ?Node { - if (! $this->nodeTypeResolver->isStaticType($node->cond, BooleanType::class)) { + $condType = $this->getType($node->cond); + if (! $condType instanceof BooleanType) { return null; } diff --git a/rules/CodeQuality/Rector/Ternary/UnnecessaryTernaryExpressionRector.php b/rules/CodeQuality/Rector/Ternary/UnnecessaryTernaryExpressionRector.php index b39adaaa606..ef52edaf6fe 100644 --- a/rules/CodeQuality/Rector/Ternary/UnnecessaryTernaryExpressionRector.php +++ b/rules/CodeQuality/Rector/Ternary/UnnecessaryTernaryExpressionRector.php @@ -110,7 +110,8 @@ private function processNonBinaryCondition(Expr $ifExpression, Expr $elseExpress private function processTrueIfExpressionWithFalseElseExpression(Expr $expr): Expr { - if ($this->nodeTypeResolver->isStaticType($expr, BooleanType::class)) { + $exprType = $this->getType($expr); + if ($exprType instanceof BooleanType) { return $expr; } @@ -120,14 +121,16 @@ private function processTrueIfExpressionWithFalseElseExpression(Expr $expr): Exp private function processFalseIfExpressionWithTrueElseExpression(Expr $expr): Expr { if ($expr instanceof BooleanNot) { - if ($this->nodeTypeResolver->isStaticType($expr->expr, BooleanType::class)) { + $negatedExprType = $this->getType($expr->expr); + if ($negatedExprType instanceof BooleanType) { return $expr->expr; } return new Bool_($expr->expr); } - if ($this->nodeTypeResolver->isStaticType($expr, BooleanType::class)) { + $exprType = $this->getType($expr); + if ($exprType instanceof BooleanType) { return new BooleanNot($expr); } diff --git a/rules/Php70/Rector/Assign/ListSplitStringRector.php b/rules/Php70/Rector/Assign/ListSplitStringRector.php index 050fd9f8662..5a4d42eb17f 100644 --- a/rules/Php70/Rector/Assign/ListSplitStringRector.php +++ b/rules/Php70/Rector/Assign/ListSplitStringRector.php @@ -52,7 +52,8 @@ public function refactor(Node $node): ?Node return null; } - if (! $this->nodeTypeResolver->isStaticType($node->expr, StringType::class)) { + $exprType = $this->getType($node->expr); + if (! $exprType instanceof StringType) { return null; } diff --git a/rules/Php71/Rector/FuncCall/CountOnNullRector.php b/rules/Php71/Rector/FuncCall/CountOnNullRector.php index aa24db0b954..5dd99820e78 100644 --- a/rules/Php71/Rector/FuncCall/CountOnNullRector.php +++ b/rules/Php71/Rector/FuncCall/CountOnNullRector.php @@ -108,10 +108,9 @@ public function refactor(Node $node): ?Node return $this->castToArray($countedNode, $node); } - if ($this->nodeTypeResolver->isNullableType($countedNode) || $this->nodeTypeResolver->isStaticType( - $countedNode, - NullType::class - )) { + $countedType = $this->getType($countedNode); + + if ($this->nodeTypeResolver->isNullableType($countedNode) || $countedType instanceof NullType) { $identical = new Identical($countedNode, $this->nodeFactory->createNull()); $ternary = new Ternary($identical, new LNumber(0), $node); // prevent infinity loop re-resolution diff --git a/rules/Php72/Rector/FuncCall/GetClassOnNullRector.php b/rules/Php72/Rector/FuncCall/GetClassOnNullRector.php index 0ecc5328a35..ac6b697d851 100644 --- a/rules/Php72/Rector/FuncCall/GetClassOnNullRector.php +++ b/rules/Php72/Rector/FuncCall/GetClassOnNullRector.php @@ -103,10 +103,8 @@ public function refactor(Node $node): ?Node return null; } - if (! $this->nodeTypeResolver->isNullableType($firstArgValue) && ! $this->nodeTypeResolver->isStaticType( - $firstArgValue, - NullType::class - )) { + $firstArgType = $this->getType($firstArgValue); + if (! $this->nodeTypeResolver->isNullableType($firstArgValue) && ! $firstArgType instanceof NullType) { return null; } diff --git a/src/Rector/AbstractRector.php b/src/Rector/AbstractRector.php index b65344f9614..da32d6bbfe1 100644 --- a/src/Rector/AbstractRector.php +++ b/src/Rector/AbstractRector.php @@ -328,25 +328,25 @@ protected function isObjectType(Node $node, ObjectType $objectType): bool */ protected function getType(Node $node): Type { - return $this->nodeTypeResolver->resolve($node); + return $this->nodeTypeResolver->getType($node); } /** * @deprecated * Use @see AbstractRector::getType() instead, as single method to get types */ - protected function getStaticType(Node $node): Type + protected function getObjectType(Node $node): Type { - return $this->nodeTypeResolver->getStaticType($node); + return $this->nodeTypeResolver->getType($node); } /** * @deprecated * Use @see AbstractRector::getType() instead, as single method to get types */ - protected function getObjectType(Node $node): Type + protected function getStaticType(Node $node): Type { - return $this->getType($node); + return $this->nodeTypeResolver->getType($node); } /** From 271e13ef9d947d52e57fa9549ece02183af17744 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 19:14:24 +0200 Subject: [PATCH 12/14] [Restoration] Remove InferParamFromClassMethodReturnRector, only temporary rule for local refactoring --- .../docs/rector_rules_overview.md | 83 ++++---- rector.php | 11 - .../Fixture/fixture.php.inc | 44 ---- .../Fixture/skip_alias_already.php.inc | 23 --- .../Fixture/skip_correct.php.inc | 21 -- .../Fixture/skip_empty_array.php.inc | 18 -- .../Fixture/skip_same_name.php.inc | 18 -- .../Fixture/union_types.php.inc | 46 ----- ...erParamFromClassMethodReturnRectorTest.php | 33 --- .../Source/SomeType.php | 10 - .../config/configured_rule.php | 22 -- .../InferParamFromClassMethodReturnRector.php | 189 ------------------ 12 files changed, 34 insertions(+), 484 deletions(-) delete mode 100644 rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/fixture.php.inc delete mode 100644 rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/skip_alias_already.php.inc delete mode 100644 rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/skip_correct.php.inc delete mode 100644 rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/skip_empty_array.php.inc delete mode 100644 rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/skip_same_name.php.inc delete mode 100644 rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/union_types.php.inc delete mode 100644 rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/InferParamFromClassMethodReturnRectorTest.php delete mode 100644 rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Source/SomeType.php delete mode 100644 rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/config/configured_rule.php delete mode 100644 rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php diff --git a/build/target-repository/docs/rector_rules_overview.md b/build/target-repository/docs/rector_rules_overview.md index e4596ab7709..d978ccc35b5 100644 --- a/build/target-repository/docs/rector_rules_overview.md +++ b/build/target-repository/docs/rector_rules_overview.md @@ -10,7 +10,7 @@ - [Carbon](#carbon) (2) -- [CodeQuality](#codequality) (68) +- [CodeQuality](#codequality) (69) - [CodingStyle](#codingstyle) (39) @@ -90,7 +90,7 @@ - [Renaming](#renaming) (11) -- [Restoration](#restoration) (6) +- [Restoration](#restoration) (5) - [Strict](#strict) (5) @@ -845,6 +845,38 @@ Make if conditions more explicit
+### ExplicitMethodCallOverMagicGetSetRector + +Replace magic property fetch using `__get()` and `__set()` with existing method get*()/set*() calls + +- class: [`Rector\CodeQuality\Rector\PropertyFetch\ExplicitMethodCallOverMagicGetSetRector`](../rules/CodeQuality/Rector/PropertyFetch/ExplicitMethodCallOverMagicGetSetRector.php) + +```diff + class MagicCallsObject + { + // adds magic __get() and __set() methods + use \Nette\SmartObject; + + private $name; + + public function getName() + { + return $this->name; + } + } + + class SomeClass + { + public function run(MagicObject $magicObject) + { +- return $magicObject->name; ++ return $magicObject->getName(); + } + } +``` + +
+ ### FixClassCaseSensitivityNameRector Change miss-typed case sensitivity name to correct one @@ -9651,53 +9683,6 @@ return static function (ContainerConfigurator $containerConfigurator): void {
-### InferParamFromClassMethodReturnRector - -Change `@param` doc based on another method return type - -:wrench: **configure it!** - -- class: [`Rector\Restoration\Rector\ClassMethod\InferParamFromClassMethodReturnRector`](../rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php) - -```php -use Rector\Restoration\Rector\ClassMethod\InferParamFromClassMethodReturnRector; -use Rector\Restoration\ValueObject\InferParamFromClassMethodReturn; -use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; -use Symplify\SymfonyPhpConfig\ValueObjectInliner; - -return static function (ContainerConfigurator $containerConfigurator): void { - $services = $containerConfigurator->services(); - - $services->set(InferParamFromClassMethodReturnRector::class) - ->call('configure', [[ - InferParamFromClassMethodReturnRector::INFER_PARAMS_FROM_CLASS_METHOD_RETURNS => ValueObjectInliner::inline([ - new InferParamFromClassMethodReturn('SomeClass', 'process', 'getNodeTypes'), - ]), - ]]); -}; -``` - -↓ - -```diff - class SomeClass - { - public function getNodeTypes(): array - { - return [String_::class]; - } - -+ /** -+ * @param String_ $node -+ */ - public function process(Node $node) - { - } - } -``` - -
- ### MakeTypedPropertyNullableIfCheckedRector Make typed property nullable if checked diff --git a/rector.php b/rector.php index 01d7f547e1d..502a38edf12 100644 --- a/rector.php +++ b/rector.php @@ -9,12 +9,9 @@ use Rector\CodingStyle\Rector\String_\SplitStringClassConstantToClassConstFetchRector; use Rector\CodingStyle\ValueObject\ReturnArrayClassMethodToYield; use Rector\Core\Configuration\Option; -use Rector\Core\Rector\AbstractRector; use Rector\Nette\Set\NetteSetList; use Rector\Php55\Rector\String_\StringClassNameToClassConstantRector; use Rector\PHPUnit\Set\PHPUnitSetList; -use Rector\Restoration\Rector\ClassMethod\InferParamFromClassMethodReturnRector; -use Rector\Restoration\ValueObject\InferParamFromClassMethodReturn; use Rector\Set\ValueObject\SetList; use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; use Symplify\SymfonyPhpConfig\ValueObjectInliner; @@ -38,15 +35,7 @@ $containerConfigurator->import(NetteSetList::NETTE_UTILS_CODE_QUALITY); $containerConfigurator->import(PHPUnitSetList::PHPUNIT_CODE_QUALITY); - $configuration = ValueObjectInliner::inline([ - new InferParamFromClassMethodReturn(AbstractRector::class, 'refactor', 'getNodeTypes'), - ]); - $services = $containerConfigurator->services(); - $services->set(InferParamFromClassMethodReturnRector::class) - ->call('configure', [[ - InferParamFromClassMethodReturnRector::INFER_PARAMS_FROM_CLASS_METHOD_RETURNS => $configuration, - ]]); // phpunit $services->set(PreferThisOrSelfMethodCallRector::class) diff --git a/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/fixture.php.inc b/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/fixture.php.inc deleted file mode 100644 index b3b8aaf045d..00000000000 --- a/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/fixture.php.inc +++ /dev/null @@ -1,44 +0,0 @@ - ------ - diff --git a/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/skip_alias_already.php.inc b/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/skip_alias_already.php.inc deleted file mode 100644 index 14b14a9bc92..00000000000 --- a/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Fixture/skip_alias_already.php.inc +++ /dev/null @@ -1,23 +0,0 @@ - ------ - diff --git a/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/InferParamFromClassMethodReturnRectorTest.php b/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/InferParamFromClassMethodReturnRectorTest.php deleted file mode 100644 index dff72efdb96..00000000000 --- a/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/InferParamFromClassMethodReturnRectorTest.php +++ /dev/null @@ -1,33 +0,0 @@ -doTestFileInfo($fileInfo); - } - - /** - * @return Iterator - */ - public function provideData(): Iterator - { - return $this->yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Source/SomeType.php b/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Source/SomeType.php deleted file mode 100644 index 3727b0b0f0e..00000000000 --- a/rules-tests/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector/Source/SomeType.php +++ /dev/null @@ -1,10 +0,0 @@ -services(); - - $configuration = ValueObjectInliner::inline([ - new InferParamFromClassMethodReturn(SomeType::class, 'process', 'getNodeTypes'), - ]); - - $services->set(InferParamFromClassMethodReturnRector::class) - ->call('configure', [[ - InferParamFromClassMethodReturnRector::INFER_PARAMS_FROM_CLASS_METHOD_RETURNS => $configuration, - ]]); -}; diff --git a/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php b/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php deleted file mode 100644 index e36194ba06d..00000000000 --- a/rules/Restoration/Rector/ClassMethod/InferParamFromClassMethodReturnRector.php +++ /dev/null @@ -1,189 +0,0 @@ - [ - new InferParamFromClassMethodReturn('SomeClass', 'process', 'getNodeTypes'), - ], - ] - ), - ]); - } - - /** - * @return array> - */ - public function getNodeTypes(): array - { - return [ClassMethod::class]; - } - - /** - * @param ClassMethod $node - */ - public function refactor(Node $node): ?Node - { - // must be exactly 1 param - if (count($node->params) !== 1) { - return null; - } - - $firstParam = $node->params[0]; - $paramName = $this->getName($firstParam); - - foreach ($this->inferParamFromClassMethodReturn as $singleInferParamFromClassMethodReturn) { - $returnClassMethod = $this->matchReturnClassMethod($node, $singleInferParamFromClassMethodReturn); - if (! $returnClassMethod instanceof ClassMethod) { - continue; - } - - $returnType = $this->returnTypeInferer->inferFunctionLike($returnClassMethod); - - $currentPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); - - $paramType = $this->constantReturnToParamTypeConverter->convert($returnType); - - // here is something broken - if ($paramType instanceof MixedType) { - continue; - } - - if ($this->isParamDocTypeEqualToPhpType($firstParam, $paramType)) { - return null; - } - - $this->phpDocTypeChanger->changeParamType($currentPhpDocInfo, $paramType, $firstParam, $paramName); - - return $node; - } - - return null; - } - - /** - * @param array $configuration - */ - public function configure(array $configuration): void - { - $inferParamsFromClassMethodReturns = $configuration[self::INFER_PARAMS_FROM_CLASS_METHOD_RETURNS] ?? []; - Assert::allIsInstanceOf($inferParamsFromClassMethodReturns, InferParamFromClassMethodReturn::class); - - $this->inferParamFromClassMethodReturn = $inferParamsFromClassMethodReturns; - } - - private function matchReturnClassMethod( - ClassMethod $classMethod, - InferParamFromClassMethodReturn $inferParamFromClassMethodReturn - ): ?ClassMethod { - $scope = $classMethod->getAttribute(AttributeKey::SCOPE); - if (! $scope instanceof Scope) { - return null; - } - - $classReflection = $scope->getClassReflection(); - if (! $classReflection instanceof ClassReflection) { - return null; - } - - if (! $classReflection->isSubclassOf($inferParamFromClassMethodReturn->getClass())) { - return null; - } - - if (! $this->isName($classMethod->name, $inferParamFromClassMethodReturn->getParamMethod())) { - return null; - } - - $classLike = $classMethod->getAttribute(AttributeKey::CLASS_NODE); - if (! $classLike instanceof Class_) { - return null; - } - - return $classLike->getMethod($inferParamFromClassMethodReturn->getReturnMethod()); - } - - private function isParamDocTypeEqualToPhpType(Param $param, Type $paramType): bool - { - $currentParamType = $this->nodeTypeResolver->getStaticType($param); - return $currentParamType->equals($paramType); - } -} From 5bc372739c3ae9e99c63edc19d5864bef286764f Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 19:14:47 +0200 Subject: [PATCH 13/14] remove isStaticType() method, already switched to type --- .../NodeTypeResolver/NodeTypeResolver.php | 21 ---- .../Rector/If_/ExplicitBoolCompareRector.php | 2 +- .../ConstantReturnToParamTypeConverter.php | 99 ------------------- .../InferParamFromClassMethodReturn.php | 30 ------ 4 files changed, 1 insertion(+), 151 deletions(-) delete mode 100644 rules/Restoration/Type/ConstantReturnToParamTypeConverter.php delete mode 100644 rules/Restoration/ValueObject/InferParamFromClassMethodReturn.php diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index 35ab47a96d3..1aebd3aa8cf 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -38,7 +38,6 @@ use PHPStan\Type\TypeWithClassName; use PHPStan\Type\UnionType; use Rector\Core\Configuration\RenamedClassesDataCollector; -use Rector\Core\Exception\ShouldNotHappenException; use Rector\Core\NodeAnalyzer\ClassAnalyzer; use Rector\NodeTypeResolver\Contract\NodeTypeResolverInterface; use Rector\NodeTypeResolver\Node\AttributeKey; @@ -268,26 +267,6 @@ public function isNumberType(Node $node): bool return $nodeType instanceof FloatType; } - /** - * @deprecated - * Use @see NodeTypeResolver::resolve() instead and instanceof directly - * - * @param class-string $staticTypeClass - */ - public function isStaticType(Node $node, string $staticTypeClass): bool - { - if (! is_a($staticTypeClass, Type::class, true)) { - throw new ShouldNotHappenException(sprintf( - '"%s" in "%s()" must be type of "%s"', - $staticTypeClass, - __METHOD__, - Type::class - )); - } - - return is_a($this->getType($node), $staticTypeClass); - } - /** * @param class-string $desiredType */ diff --git a/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php b/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php index 85ae62c41ab..4344289d228 100644 --- a/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php +++ b/rules/CodeQuality/Rector/If_/ExplicitBoolCompareRector.php @@ -161,7 +161,7 @@ private function resolveNewConditionNode(Expr $expr, bool $isNegated): ?BinaryOp return $this->resolveFloat($isNegated, $expr); } - if ($exprType instanceof ObjectType) { + if ($this->nodeTypeResolver->isNullableTypeOfSpecificType($expr, ObjectType::class)) { return $this->resolveNullable($isNegated, $expr); } diff --git a/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php b/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php deleted file mode 100644 index 564616024a1..00000000000 --- a/rules/Restoration/Type/ConstantReturnToParamTypeConverter.php +++ /dev/null @@ -1,99 +0,0 @@ -convertUnionType($type); - } - - if ($type instanceof ConstantStringType) { - return $this->unwrapConstantTypeToObjectType($type); - } - - if ($type instanceof ArrayType) { - return $this->unwrapConstantTypeToObjectType($type); - } - - // making generic class stirng type to object type - if ($type instanceof GenericClassStringType) { - return $type->getGenericType(); - } - - return new MixedType(); - } - - private function unwrapConstantTypeToObjectType(Type $type): Type - { - if ($type instanceof ArrayType) { - return $this->unwrapConstantTypeToObjectType($type->getItemType()); - } - - if ($type instanceof ConstantStringType) { - return new ObjectType($type->getValue()); - } - - if ($type instanceof GenericClassStringType && $type->getGenericType() instanceof ObjectType) { - return $type->getGenericType(); - } - - if ($type instanceof UnionType) { - return $this->unwrapUnionType($type); - } - - return new MixedType(); - } - - private function unwrapUnionType(UnionType $unionType): Type - { - $types = []; - foreach ($unionType->getTypes() as $unionedType) { - $unionType = $this->unwrapConstantTypeToObjectType($unionedType); - if ($unionType !== null) { - $types[] = $unionType; - } - } - - return $this->typeFactory->createMixedPassedOrUnionType($types); - } - - private function convertUnionType(UnionType $unionType): UnionType - { - $flattenReturnTypes = TypeUtils::flattenTypes($unionType); - - $unionedTypes = []; - foreach ($flattenReturnTypes as $flattenReturnType) { - if ($flattenReturnType instanceof ArrayType) { - $unionedTypes[] = $flattenReturnType->getItemType(); - } - } - - $resolvedTypes = []; - - foreach ($unionedTypes as $unionedType) { - $resolvedTypes[] = $this->convert($unionedType); - } - - return new UnionType($resolvedTypes); - } -} diff --git a/rules/Restoration/ValueObject/InferParamFromClassMethodReturn.php b/rules/Restoration/ValueObject/InferParamFromClassMethodReturn.php deleted file mode 100644 index e29b38ba98e..00000000000 --- a/rules/Restoration/ValueObject/InferParamFromClassMethodReturn.php +++ /dev/null @@ -1,30 +0,0 @@ -class; - } - - public function getParamMethod(): string - { - return $this->paramMethod; - } - - public function getReturnMethod(): string - { - return $this->returnMethod; - } -} From 29a676a21346998ae2cf0ae3dc78a0ca7c780f66 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 7 Oct 2021 19:30:13 +0200 Subject: [PATCH 14/14] simplify isNullableTypeOfSpecificType() --- packages/NodeTypeResolver/NodeTypeResolver.php | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/NodeTypeResolver/NodeTypeResolver.php b/packages/NodeTypeResolver/NodeTypeResolver.php index 1aebd3aa8cf..173686d937c 100644 --- a/packages/NodeTypeResolver/NodeTypeResolver.php +++ b/packages/NodeTypeResolver/NodeTypeResolver.php @@ -281,17 +281,8 @@ public function isNullableTypeOfSpecificType(Node $node, string $desiredType): b return false; } - if (count($nodeType->getTypes()) !== 2) { - return false; - } - - foreach ($nodeType->getTypes() as $type) { - if (is_a($type, $desiredType, true)) { - return true; - } - } - - return false; + $bareType = TypeCombinator::removeNull($nodeType); + return is_a($bareType, $desiredType, true); } /**