From 602e26edd4acbc3b77ebd5bbf06a5f36c2692e24 Mon Sep 17 00:00:00 2001 From: HypeMC Date: Sat, 17 Sep 2022 21:21:33 +0200 Subject: [PATCH] Fix array_column with object and column name null --- .../ArrayColumnReturnTypeProvider.php | 9 +- tests/ReturnTypeProvider/ArrayColumnTest.php | 92 +++++++++++++++++++ 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php index 89e68a1eaa4..b9d45b1c3ef 100644 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayColumnReturnTypeProvider.php @@ -36,7 +36,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev return Type::getMixed(); } - $row_shape = null; + $row_type = $row_shape = null; $input_array_not_empty = false; // calculate row shape @@ -45,7 +45,6 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev && $first_arg_type->hasArray() ) { $input_array = $first_arg_type->getAtomicTypes()['array']; - $row_type = null; if ($input_array instanceof TKeyedArray) { $row_type = $input_array->getGenericArrayType()->type_params[1]; } elseif ($input_array instanceof TArray) { @@ -104,7 +103,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev } $result_key_type = Type::getArrayKey(); - $result_element_type = null; + $result_element_type = null !== $row_type && $value_column_name_is_null ? $row_type : null; $have_at_least_one_res = false; // calculate results if ($row_shape instanceof TKeyedArray) { @@ -116,9 +115,7 @@ public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $ev } //array_column skips undefined elements so resulting type is necessarily defined $result_element_type->possibly_undefined = false; - } elseif ($value_column_name_is_null) { - $result_element_type = new Union([$row_shape]); - } else { + } elseif (!$value_column_name_is_null) { $result_element_type = Type::getMixed(); } diff --git a/tests/ReturnTypeProvider/ArrayColumnTest.php b/tests/ReturnTypeProvider/ArrayColumnTest.php index 5b5cf4d2276..400dad77465 100644 --- a/tests/ReturnTypeProvider/ArrayColumnTest.php +++ b/tests/ReturnTypeProvider/ArrayColumnTest.php @@ -3,10 +3,12 @@ namespace Psalm\Tests\ReturnTypeProvider; use Psalm\Tests\TestCase; +use Psalm\Tests\Traits\InvalidCodeAnalysisTestTrait; use Psalm\Tests\Traits\ValidCodeAnalysisTestTrait; class ArrayColumnTest extends TestCase { + use InvalidCodeAnalysisTestTrait; use ValidCodeAnalysisTestTrait; public function providerValidCodeParse(): iterable @@ -61,5 +63,95 @@ function f(array $shape): array { } ', ]; + + yield 'arrayColumnWithObjectsAndColumnNameNull' => [ + 'foo(); + } + ', + ]; + + yield 'arrayColumnWithIntersectionAndColumnNameNull' => [ + 'foo(); + $instance->bar(); + } + ', + ]; + + yield 'arrayColumnWithArrayAndColumnNameNull' => [ + ' "", "instance" => new C]], null, "name") as $array) { + $array["instance"]->foo(); + } + ', + ]; + + yield 'arrayColumnWithListOfObject' => [ + ' $instances */ + $instances = []; + foreach (array_column($instances, null, "name") as $instance) { + foo($instance); + } + ', + ]; + + yield 'arrayColumnWithListOfArrays' => [ + ' $arrays */ + $arrays = []; + foreach (array_column($arrays, null, "name") as $array) { + foo($array); + } + ', + ]; + } + + public function providerInvalidCodeParse(): iterable + { + yield 'arrayColumnWithArrayAndColumnNameNull' => [ + ' $arrays */ + $arrays = []; + foreach (array_column($arrays, null, "name") as $array) { + $array["instance"]->foo(); + } + ', + 'error_message' => 'MixedMethodCall', + ]; } }