mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
fix array_column with possibly_undefined keys (#4719)
This commit is contained in:
parent
b084e2c4bd
commit
0df867cdff
@ -92,10 +92,13 @@ class ArrayColumnReturnTypeProvider implements \Psalm\Plugin\Hook\FunctionReturn
|
|||||||
// calculate results
|
// calculate results
|
||||||
if ($row_shape instanceof Type\Atomic\TKeyedArray) {
|
if ($row_shape instanceof Type\Atomic\TKeyedArray) {
|
||||||
if ((null !== $value_column_name) && isset($row_shape->properties[$value_column_name])) {
|
if ((null !== $value_column_name) && isset($row_shape->properties[$value_column_name])) {
|
||||||
if ($input_array_not_empty) {
|
$result_element_type = $row_shape->properties[$value_column_name];
|
||||||
|
// When the selected key is possibly_undefined, the resulting array can be empty
|
||||||
|
if ($input_array_not_empty && $result_element_type->possibly_undefined !== true) {
|
||||||
$have_at_least_one_res = true;
|
$have_at_least_one_res = true;
|
||||||
}
|
}
|
||||||
$result_element_type = $row_shape->properties[$value_column_name];
|
//array_column skips undefined elements so resulting type is necesseraly defined
|
||||||
|
$result_element_type->possibly_undefined = false;
|
||||||
} else {
|
} else {
|
||||||
$result_element_type = Type::getMixed();
|
$result_element_type = Type::getMixed();
|
||||||
}
|
}
|
||||||
|
@ -1151,6 +1151,8 @@ class ArrayFunctionCallTest extends TestCase
|
|||||||
function makeShapeArray(): array { return []; }
|
function makeShapeArray(): array { return []; }
|
||||||
/** @return array<array{0:string}|int> */
|
/** @return array<array{0:string}|int> */
|
||||||
function makeUnionArray(): array { return []; }
|
function makeUnionArray(): array { return []; }
|
||||||
|
/** @return array<string, array{x?:int, y?:int, width?:int, height?:int}> */
|
||||||
|
function makeKeyedArray(): array { return []; }
|
||||||
$a = array_column([[1], [2], [3]], 0);
|
$a = array_column([[1], [2], [3]], 0);
|
||||||
$b = array_column([["a" => 1], ["a" => 2], ["a" => 3]], "a");
|
$b = array_column([["a" => 1], ["a" => 2], ["a" => 3]], "a");
|
||||||
$c = array_column([["k" => "a", "v" => 1], ["k" => "b", "v" => 2]], "v", "k");
|
$c = array_column([["k" => "a", "v" => 1], ["k" => "b", "v" => 2]], "v", "k");
|
||||||
@ -1162,6 +1164,10 @@ class ArrayFunctionCallTest extends TestCase
|
|||||||
$i = array_column(makeShapeArray(), 0);
|
$i = array_column(makeShapeArray(), 0);
|
||||||
$j = array_column(makeUnionArray(), 0);
|
$j = array_column(makeUnionArray(), 0);
|
||||||
$k = array_column([[0 => "test"]], 0);
|
$k = array_column([[0 => "test"]], 0);
|
||||||
|
$l = array_column(makeKeyedArray(), "y");
|
||||||
|
$m_prepare = makeKeyedArray();
|
||||||
|
assert($m_prepare !== []);
|
||||||
|
$m = array_column($m_prepare, "y");
|
||||||
',
|
',
|
||||||
'assertions' => [
|
'assertions' => [
|
||||||
'$a' => 'non-empty-list<int>',
|
'$a' => 'non-empty-list<int>',
|
||||||
@ -1175,6 +1181,8 @@ class ArrayFunctionCallTest extends TestCase
|
|||||||
'$i' => 'list<string>',
|
'$i' => 'list<string>',
|
||||||
'$j' => 'list<mixed>',
|
'$j' => 'list<mixed>',
|
||||||
'$k' => 'non-empty-list<string>',
|
'$k' => 'non-empty-list<string>',
|
||||||
|
'$l' => 'list<int>',
|
||||||
|
'$m' => 'list<int>',
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
'splatArrayIntersect' => [
|
'splatArrayIntersect' => [
|
||||||
@ -1870,6 +1878,15 @@ class ArrayFunctionCallTest extends TestCase
|
|||||||
}
|
}
|
||||||
}'
|
}'
|
||||||
],
|
],
|
||||||
|
'arrayColumnwithKeyedArrayWithoutRedundantUnion' => [
|
||||||
|
'<?php
|
||||||
|
/**
|
||||||
|
* @param array<string, array{x?:int, y?:int, width?:int, height?:int}> $foos
|
||||||
|
*/
|
||||||
|
function foo(array $foos): void {
|
||||||
|
array_multisort($formLayoutFields, SORT_ASC, array_column($foos, "y"));
|
||||||
|
}'
|
||||||
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user