From f9fe72cbcbb86c7da04239dfa5610abb6c59e3ab Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 5 Jan 2025 14:33:49 +0100 Subject: [PATCH 1/2] MinMaxFunctionReturnTypeExtension: Cleanup `instanceof ConstantScalarType` --- phpstan-baseline.neon | 2 +- src/Type/Php/MinMaxFunctionReturnTypeExtension.php | 4 ++-- .../PHPStan/Analyser/LegacyNodeScopeResolverTest.php | 12 ++++++++---- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 9977a1992d..163d7548dc 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1425,7 +1425,7 @@ parameters: - message: "#^Doing instanceof PHPStan\\\\Type\\\\ConstantScalarType is error\\-prone and deprecated\\. Use Type\\:\\:isConstantScalarValue\\(\\) or Type\\:\\:getConstantScalarTypes\\(\\) or Type\\:\\:getConstantScalarValues\\(\\) instead\\.$#" - count: 4 + count: 2 path: src/Type/Php/MinMaxFunctionReturnTypeExtension.php - diff --git a/src/Type/Php/MinMaxFunctionReturnTypeExtension.php b/src/Type/Php/MinMaxFunctionReturnTypeExtension.php index 20128f0a92..570beeb49b 100644 --- a/src/Type/Php/MinMaxFunctionReturnTypeExtension.php +++ b/src/Type/Php/MinMaxFunctionReturnTypeExtension.php @@ -187,13 +187,13 @@ private function compareTypes( { if ( $firstType->isConstantArray()->yes() - && $secondType instanceof ConstantScalarType + && $secondType->isConstantScalarValue()->yes() ) { return $secondType; } if ( - $firstType instanceof ConstantScalarType + $firstType->isConstantScalarValue()->yes() && $secondType->isConstantArray()->yes() ) { return $firstType; diff --git a/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php b/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php index 42b0d24959..33acc684ac 100644 --- a/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php @@ -2363,14 +2363,18 @@ public function dataBinaryOperations(): array 'array', 'max($arrayOfUnknownIntegers, $arrayOfUnknownIntegers)', ], - /*[ - 'array(1, 1, 1, 1)', + [ + 'array{1, 1, 1, 1}', 'max(array(2, 2, 2), 5, array(1, 1, 1, 1))', ], [ - 'array', + 'array|int', // could be array 'max($arrayOfUnknownIntegers, $integer, $arrayOfUnknownIntegers)', - ],*/ + ], + [ + '5', + 'min(array(2, 2, 2), 5, array(1, 1, 1, 1))', + ], [ '1.1', 'min(...[1.1, 2.2, 3.3])', From 11728d7b8a8e248d749aa0fedae4c2bc5b40e703 Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 5 Jan 2025 15:17:12 +0100 Subject: [PATCH 2/2] generalize array logic --- phpstan-baseline.neon | 5 ---- .../Php/MinMaxFunctionReturnTypeExtension.php | 13 +++++----- .../Analyser/LegacyNodeScopeResolverTest.php | 24 +++++++++++++++++++ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 163d7548dc..a13f84546b 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1428,11 +1428,6 @@ parameters: count: 2 path: src/Type/Php/MinMaxFunctionReturnTypeExtension.php - - - message: "#^Doing instanceof PHPStan\\\\Type\\\\ConstantType is error\\-prone and deprecated\\. Use Type\\:\\:isConstantValue\\(\\) or Type\\:\\:generalize\\(\\) instead\\.$#" - count: 1 - path: src/Type/Php/MinMaxFunctionReturnTypeExtension.php - - message: "#^Doing instanceof PHPStan\\\\Type\\\\Constant\\\\ConstantArrayType is error\\-prone and deprecated\\. Use Type\\:\\:getConstantArrays\\(\\) instead\\.$#" count: 2 diff --git a/src/Type/Php/MinMaxFunctionReturnTypeExtension.php b/src/Type/Php/MinMaxFunctionReturnTypeExtension.php index 570beeb49b..5beabcbcf3 100644 --- a/src/Type/Php/MinMaxFunctionReturnTypeExtension.php +++ b/src/Type/Php/MinMaxFunctionReturnTypeExtension.php @@ -11,7 +11,6 @@ use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\Constant\ConstantBooleanType; use PHPStan\Type\ConstantScalarType; -use PHPStan\Type\ConstantType; use PHPStan\Type\DynamicFunctionReturnTypeExtension; use PHPStan\Type\ErrorType; use PHPStan\Type\Type; @@ -152,16 +151,16 @@ private function processType( { $resultType = null; foreach ($types as $type) { - if (!$type instanceof ConstantType) { - return TypeCombinator::union(...$types); - } - if ($resultType === null) { $resultType = $type; continue; } $compareResult = $this->compareTypes($resultType, $type); + if ($compareResult === null) { + return TypeCombinator::union(...$types); + } + if ($functionName === 'min') { if ($compareResult === $type) { $resultType = $type; @@ -186,7 +185,7 @@ private function compareTypes( ): ?Type { if ( - $firstType->isConstantArray()->yes() + $firstType->isArray()->yes() && $secondType->isConstantScalarValue()->yes() ) { return $secondType; @@ -194,7 +193,7 @@ private function compareTypes( if ( $firstType->isConstantScalarValue()->yes() - && $secondType->isConstantArray()->yes() + && $secondType->isArray()->yes() ) { return $firstType; } diff --git a/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php b/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php index 33acc684ac..ac0c1c6ec9 100644 --- a/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php +++ b/tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php @@ -2367,10 +2367,34 @@ public function dataBinaryOperations(): array 'array{1, 1, 1, 1}', 'max(array(2, 2, 2), 5, array(1, 1, 1, 1))', ], + [ + 'array{int, int, int}', + 'max($arrayOfIntegers, 5)', + ], + [ + 'array', + 'max($arrayOfUnknownIntegers, 5)', + ], [ 'array|int', // could be array 'max($arrayOfUnknownIntegers, $integer, $arrayOfUnknownIntegers)', ], + [ + 'array', + 'max($arrayOfUnknownIntegers, $conditionalInt)', + ], + [ + '5', + 'min($arrayOfIntegers, 5)', + ], + [ + '5', + 'min($arrayOfUnknownIntegers, 5)', + ], + [ + '1|2', + 'min($arrayOfUnknownIntegers, $conditionalInt)', + ], [ '5', 'min(array(2, 2, 2), 5, array(1, 1, 1, 1))',