From 730bc221e992b3696319ce7e7ca8dce368ae7819 Mon Sep 17 00:00:00 2001 From: Corey Taylor Date: Mon, 20 Feb 2023 04:46:14 -0600 Subject: [PATCH] Re-add array_unique() stub which preserved array type --- .../Provider/FunctionReturnTypeProvider.php | 2 - .../ArrayUniqueReturnTypeProvider.php | 60 ------------------- stubs/CoreGenericFunctions.phpstub | 14 +++++ tests/ArrayFunctionCallTest.php | 31 ++++++++++ 4 files changed, 45 insertions(+), 62 deletions(-) delete mode 100644 src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayUniqueReturnTypeProvider.php diff --git a/src/Psalm/Internal/Provider/FunctionReturnTypeProvider.php b/src/Psalm/Internal/Provider/FunctionReturnTypeProvider.php index bdd59a0abc4..0d2552d8e48 100644 --- a/src/Psalm/Internal/Provider/FunctionReturnTypeProvider.php +++ b/src/Psalm/Internal/Provider/FunctionReturnTypeProvider.php @@ -22,7 +22,6 @@ use Psalm\Internal\Provider\ReturnTypeProvider\ArrayReverseReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\ArraySliceReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\ArraySpliceReturnTypeProvider; -use Psalm\Internal\Provider\ReturnTypeProvider\ArrayUniqueReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\BasenameReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\DirnameReturnTypeProvider; use Psalm\Internal\Provider\ReturnTypeProvider\FilterVarReturnTypeProvider; @@ -81,7 +80,6 @@ public function __construct() $this->registerClass(ArraySliceReturnTypeProvider::class); $this->registerClass(ArraySpliceReturnTypeProvider::class); $this->registerClass(ArrayReverseReturnTypeProvider::class); - $this->registerClass(ArrayUniqueReturnTypeProvider::class); $this->registerClass(ArrayFillReturnTypeProvider::class); $this->registerClass(ArrayFillKeysReturnTypeProvider::class); $this->registerClass(FilterVarReturnTypeProvider::class); diff --git a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayUniqueReturnTypeProvider.php b/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayUniqueReturnTypeProvider.php deleted file mode 100644 index 1b46a3fb901..00000000000 --- a/src/Psalm/Internal/Provider/ReturnTypeProvider/ArrayUniqueReturnTypeProvider.php +++ /dev/null @@ -1,60 +0,0 @@ - - */ - public static function getFunctionIds(): array - { - return ['array_unique']; - } - - public static function getFunctionReturnType(FunctionReturnTypeProviderEvent $event): Union - { - $statements_source = $event->getStatementsSource(); - $call_args = $event->getCallArgs(); - if (!$statements_source instanceof StatementsAnalyzer) { - return Type::getMixed(); - } - - $first_arg = $call_args[0]->value ?? null; - - $first_arg_array = $first_arg - && ($first_arg_type = $statements_source->node_data->getType($first_arg)) - && $first_arg_type->hasType('array') - && ($array_atomic_type = $first_arg_type->getArray()) - && ($array_atomic_type instanceof TArray - || $array_atomic_type instanceof TKeyedArray) - ? $array_atomic_type - : null; - - if (!$first_arg_array) { - return Type::getArray(); - } - - if ($first_arg_array instanceof TArray) { - if ($first_arg_array instanceof TNonEmptyArray) { - $first_arg_array = $first_arg_array->setCount(null); - } - - return new Union([$first_arg_array]); - } - - return new Union([$first_arg_array->getGenericArrayType()]); - } -} diff --git a/stubs/CoreGenericFunctions.phpstub b/stubs/CoreGenericFunctions.phpstub index eaf02d61a4b..b673f7069be 100644 --- a/stubs/CoreGenericFunctions.phpstub +++ b/stubs/CoreGenericFunctions.phpstub @@ -129,6 +129,20 @@ function array_flip(array $array) { } +/** + * @psalm-template TKey as array-key + * @psalm-template TValue + * @psalm-template TArray as array + * + * @param TArray $array + * + * @return (TArray is non-empty-array ? non-empty-array : array) + * @psalm-pure + */ +function array_unique(array $array, int $flags = 0) +{ +} + /** * @psalm-template TKey as array-key * @psalm-template TArray as array diff --git a/tests/ArrayFunctionCallTest.php b/tests/ArrayFunctionCallTest.php index af57d042028..bab65c90b32 100644 --- a/tests/ArrayFunctionCallTest.php +++ b/tests/ArrayFunctionCallTest.php @@ -2536,6 +2536,19 @@ function consumeArray(array $_input): void {} consumeArray([makeKey() => null]); ', ], + 'arrayUniquePreservesNonEmptyInput' => [ + 'code' => ' $input */ + function takes_non_empty_array(array $input): void {} + + takes_non_empty_array(array_unique(["test" => (object)[]])); + + /** @param non-empty-array $input */ + function takes_non_empty_int_array(array $input): void {} + + takes_non_empty_int_array(array_unique([(object)[]])); + ', + ], ]; } @@ -2809,6 +2822,24 @@ function merger(array $a, array $b) : array { ', 'error_message' => 'NamedArgumentNotAllowed', ], + 'arrayUniquePreservesEmptyInput' => [ + 'code' => ' $input */ + function takes_non_empty_array(array $input): void {} + + takes_non_empty_array(array_unique([])); + ', + 'error_message' => 'InvalidArgument', + ], + 'arrayUniqueConvertsListToArray' => [ + 'code' => ' $input */ + function takes_non_empty_list(array $input): void {} + + takes_non_empty_list(array_unique([(object)[]])); + ', + 'error_message' => 'ArgumentTypeCoercion', + ], ]; } }