1
0
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:
orklah 2020-11-27 23:05:54 +01:00 committed by Daniil Gentili
parent b084e2c4bd
commit 0df867cdff
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
2 changed files with 22 additions and 2 deletions

View File

@ -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();
} }

View File

@ -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"));
}'
],
]; ];
} }