From 95a5f207c944ca8c1f9796e51593be3b687bbba1 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 06:57:45 +0700 Subject: [PATCH 01/10] [TypedPropertyFromAssignsRector] Handle parse_url() native function with second arg on TypedPropertyFromAssignsRector --- .../parse_url_with_second_arg.php.inc | 31 +++++++++++++++++++ src/NodeTypeResolver/NodeTypeResolver.php | 20 ++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc diff --git a/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc new file mode 100644 index 00000000000..6fb67f20925 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc @@ -0,0 +1,31 @@ +host = parse_url($url, \PHP_URL_HOST); + } +} + +?> +----- +host = parse_url($url, \PHP_URL_HOST); + } +} + +?> diff --git a/src/NodeTypeResolver/NodeTypeResolver.php b/src/NodeTypeResolver/NodeTypeResolver.php index 9f48b1c5c42..3b58e3eb4e3 100644 --- a/src/NodeTypeResolver/NodeTypeResolver.php +++ b/src/NodeTypeResolver/NodeTypeResolver.php @@ -9,11 +9,13 @@ use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\BinaryOp\Coalesce; use PhpParser\Node\Expr\ClassConstFetch; +use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\New_; use PhpParser\Node\Expr\NullsafeMethodCall; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\Ternary; +use PhpParser\Node\Name; use PhpParser\Node\NullableType; use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\ClassConst; @@ -23,6 +25,7 @@ use PHPStan\Analyser\Scope; use PHPStan\Broker\ClassAutoloadingException; use PHPStan\Reflection\ClassReflection; +use PHPStan\Reflection\Native\NativeFunctionReflection; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Type\ArrayType; use PHPStan\Type\Constant\ConstantArrayType; @@ -559,6 +562,23 @@ private function resolveNativeTypeWithBuiltinMethodCallFallback(Expr $expr, Scop } } + if ($expr instanceof FuncCall) { + if (! $expr->name instanceof Name) { + return $scope->getNativeType($expr); + } + + if (! $this->reflectionProvider->hasFunction($expr->name, $scope)) { + return $scope->getNativeType($expr); + } + + $functionReflection = $this->reflectionProvider->getFunction($expr->name, $scope); + if (! $functionReflection instanceof NativeFunctionReflection) { + return $scope->getNativeType($expr); + } + + return $scope->getType($expr); + } + return $scope->getNativeType($expr); } } From 7c6f0c78538b9f4b7cbee8e749d7f58443c2f80e Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 06:58:44 +0700 Subject: [PATCH 02/10] update fixture --- .../FixtureComplexTypes/parse_url_with_second_arg.php.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc index 6fb67f20925..985d86b64b3 100644 --- a/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc +++ b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc @@ -20,7 +20,7 @@ namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsR final class ParseUrlWithSecondArg { - private $host = null; + private string|bool|null $host = null; public function _cosntructor(string $url) { From c23da1db59fbf42e16c6c93c87067fdad312c8fe Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 07:11:29 +0700 Subject: [PATCH 03/10] Fix type constant --- .../FixtureComplexTypes/parse_url_with_second_arg.php.inc | 2 +- .../TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc index 985d86b64b3..0a3c20fb83b 100644 --- a/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc +++ b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc @@ -20,7 +20,7 @@ namespace Rector\Tests\TypeDeclaration\Rector\Property\TypedPropertyFromAssignsR final class ParseUrlWithSecondArg { - private string|bool|null $host = null; + private string|false|null $host = null; public function _cosntructor(string $url) { diff --git a/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php b/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php index 3ff1e60a3a1..8a54a46478e 100644 --- a/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php +++ b/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php @@ -90,7 +90,7 @@ private function resolveTypeWithVerifyDefaultValue(Property $property, array $as return null; } - return $inferredType; + return $this->typeFactory->createMixedPassedOrUnionType($assignedExprTypes, true); } private function shouldSkipWithDifferentDefaultValueType(?Expr $expr, Type $inferredType): bool From 7580122af126dbc233acfd6dde78e0bcd44d8edb Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 07:12:44 +0700 Subject: [PATCH 04/10] Fix type constant --- .../TypeInferer/AssignToPropertyTypeInferer.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php b/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php index 8a54a46478e..23e83321f11 100644 --- a/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php +++ b/rules/TypeDeclaration/TypeInferer/AssignToPropertyTypeInferer.php @@ -86,10 +86,13 @@ private function resolveTypeWithVerifyDefaultValue(Property $property, array $as } $inferredType = $this->typeFactory->createMixedPassedOrUnionType($assignedExprTypes); + // to compare with default value, constant type must not be kept + // eg, use more general bool over false or true if ($this->shouldSkipWithDifferentDefaultValueType($defaultPropertyValue, $inferredType)) { return null; } + // returns with constant as final result return $this->typeFactory->createMixedPassedOrUnionType($assignedExprTypes, true); } From 66f4f8342781117e4aba789bd7cb4bbcde274109 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 07:15:22 +0700 Subject: [PATCH 05/10] fix --- .../DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php index f4b74f71ec6..dda5c3084fb 100644 --- a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php +++ b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php @@ -141,6 +141,10 @@ private function shouldSkipFromVariable(Expr $expr): bool } } } + + if ($type instanceof \PHPStan\Type\MixedType) { + return true; + } } return false; From 8788f22154af65ed5504fc19d55df0ea351b6d73 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 07:15:36 +0700 Subject: [PATCH 06/10] fix --- .../DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php index dda5c3084fb..7d8c383f26c 100644 --- a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php +++ b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php @@ -19,6 +19,7 @@ use PhpParser\Node\Stmt\If_; use PhpParser\NodeVisitor; use PHPStan\Type\IntersectionType; +use PHPStan\Type\MixedType; use Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer; use Rector\NodeAnalyzer\ExprAnalyzer; use Rector\PhpParser\Node\BetterNodeFinder; @@ -142,7 +143,7 @@ private function shouldSkipFromVariable(Expr $expr): bool } } - if ($type instanceof \PHPStan\Type\MixedType) { + if ($type instanceof MixedType) { return true; } } From 7dcd618085f53bc985e4d09dc687f4dcf65820b6 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 07:17:07 +0700 Subject: [PATCH 07/10] typo fix --- .../FixtureComplexTypes/parse_url_with_second_arg.php.inc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc index 0a3c20fb83b..1ce1f1a1f9b 100644 --- a/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc +++ b/rules-tests/TypeDeclaration/Rector/Property/TypedPropertyFromAssignsRector/FixtureComplexTypes/parse_url_with_second_arg.php.inc @@ -6,7 +6,7 @@ final class ParseUrlWithSecondArg { private $host = null; - public function _cosntructor(string $url) + public function __construct(string $url) { $this->host = parse_url($url, \PHP_URL_HOST); } @@ -22,7 +22,7 @@ final class ParseUrlWithSecondArg { private string|false|null $host = null; - public function _cosntructor(string $url) + public function __construct(string $url) { $this->host = parse_url($url, \PHP_URL_HOST); } From 26c048001f3d36f50e81e6e7da9a426034848d70 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 07:36:44 +0700 Subject: [PATCH 08/10] rollback tweak to find another solution --- .../Rector/If_/RemoveAlwaysTrueIfConditionRector.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php index 7d8c383f26c..f4b74f71ec6 100644 --- a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php +++ b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php @@ -19,7 +19,6 @@ use PhpParser\Node\Stmt\If_; use PhpParser\NodeVisitor; use PHPStan\Type\IntersectionType; -use PHPStan\Type\MixedType; use Rector\DeadCode\NodeAnalyzer\SafeLeftTypeBooleanAndOrAnalyzer; use Rector\NodeAnalyzer\ExprAnalyzer; use Rector\PhpParser\Node\BetterNodeFinder; @@ -142,10 +141,6 @@ private function shouldSkipFromVariable(Expr $expr): bool } } } - - if ($type instanceof MixedType) { - return true; - } } return false; From 0b67861ebbc35ded9b24d4df053a794ac5955d87 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 07:42:02 +0700 Subject: [PATCH 09/10] fix --- .../Rector/If_/RemoveAlwaysTrueIfConditionRector.php | 4 ++++ src/NodeAnalyzer/ExprAnalyzer.php | 9 ++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php index f4b74f71ec6..a00eed1790c 100644 --- a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php +++ b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php @@ -141,6 +141,10 @@ private function shouldSkipFromVariable(Expr $expr): bool } } } + + if ($type instanceof \PHPStan\Type\MixedType) { + dump_node($variable); + } } return false; diff --git a/src/NodeAnalyzer/ExprAnalyzer.php b/src/NodeAnalyzer/ExprAnalyzer.php index a588d81ed2b..121637a3d02 100644 --- a/src/NodeAnalyzer/ExprAnalyzer.php +++ b/src/NodeAnalyzer/ExprAnalyzer.php @@ -40,12 +40,15 @@ public function isNonTypedFromParam(Expr $expr): bool } $nativeType = $scope->getNativeType($expr); - if ($nativeType instanceof MixedType && ! $nativeType->isExplicitMixed()) { + $type = $scope->getType($expr); + if ( + ($nativeType instanceof MixedType && ! $nativeType->isExplicitMixed()) + || + ($nativeType instanceof MixedType && ! $type instanceof MixedType) + ) { return true; } - $type = $scope->getType($expr); - if ($nativeType instanceof ObjectWithoutClassType && ! $type instanceof ObjectWithoutClassType) { return true; } From 40b6ea8c8237dd20e4b6fa5c0d19a43ba7813992 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Thu, 12 Dec 2024 07:42:49 +0700 Subject: [PATCH 10/10] fix --- .../DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php index a00eed1790c..f4b74f71ec6 100644 --- a/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php +++ b/rules/DeadCode/Rector/If_/RemoveAlwaysTrueIfConditionRector.php @@ -141,10 +141,6 @@ private function shouldSkipFromVariable(Expr $expr): bool } } } - - if ($type instanceof \PHPStan\Type\MixedType) { - dump_node($variable); - } } return false;