1
0
mirror of https://github.com/danog/psalm.git synced 2025-01-22 13:51:54 +01:00

Merge pull request #7760 from mtk3d/fix/array_column_type_inference

Fix #7750: array_column type inference
This commit is contained in:
orklah 2022-03-07 19:00:37 +01:00 committed by GitHub
commit 769e316f52
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 31 additions and 21 deletions

View File

@ -77,6 +77,7 @@ class ArrayColumnReturnTypeProvider implements FunctionReturnTypeProviderInterfa
} }
$value_column_name = null; $value_column_name = null;
$value_column_name_is_null = false;
// calculate value column name // calculate value column name
if (($second_arg_type = $statements_source->node_data->getType($call_args[1]->value))) { if (($second_arg_type = $statements_source->node_data->getType($call_args[1]->value))) {
if ($second_arg_type->isSingleIntLiteral()) { if ($second_arg_type->isSingleIntLiteral()) {
@ -84,6 +85,7 @@ class ArrayColumnReturnTypeProvider implements FunctionReturnTypeProviderInterfa
} elseif ($second_arg_type->isSingleStringLiteral()) { } elseif ($second_arg_type->isSingleStringLiteral()) {
$value_column_name = $second_arg_type->getSingleStringLiteral()->value; $value_column_name = $second_arg_type->getSingleStringLiteral()->value;
} }
$value_column_name_is_null = $second_arg_type->isNull();
} }
$key_column_name = null; $key_column_name = null;
@ -114,6 +116,8 @@ class ArrayColumnReturnTypeProvider implements FunctionReturnTypeProviderInterfa
} }
//array_column skips undefined elements so resulting type is necessarily defined //array_column skips undefined elements so resulting type is necessarily defined
$result_element_type->possibly_undefined = false; $result_element_type->possibly_undefined = false;
} elseif ($value_column_name_is_null) {
$result_element_type = new Union([$row_shape]);
} else { } else {
$result_element_type = Type::getMixed(); $result_element_type = Type::getMixed();
} }

View File

@ -1297,34 +1297,40 @@ class ArrayFunctionCallTest extends TestCase
function makeKeyedArray(): array { return []; } 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([["a" => 1], ["a" => 2], ["a" => 3]], null, "a");
$d = array_column([], 0); $d = array_column([["a" => 1], ["a" => 2], ["a" => 3]], null, "b");
$e = array_column(makeMixedArray(), 0); $e = array_column([["a" => 1], ["a" => 2], ["a" => 3]], rand(0,1) ? "a" : "b", "b");
$f = array_column(makeMixedArray(), 0, "k"); $f = array_column([["k" => "a", "v" => 1], ["k" => "b", "v" => 2]], "v", "k");
$g = array_column(makeMixedArray(), 0, null); $g = array_column([], 0);
$h = array_column(makeGenericArray(), 0); $h = array_column(makeMixedArray(), 0);
$i = array_column(makeShapeArray(), 0); $i = array_column(makeMixedArray(), 0, "k");
$j = array_column(makeUnionArray(), 0); $j = array_column(makeMixedArray(), 0, null);
$k = array_column([[0 => "test"]], 0); $k = array_column(makeGenericArray(), 0);
$l = array_column(makeKeyedArray(), "y"); $l = array_column(makeShapeArray(), 0);
$m_prepare = makeKeyedArray(); $m = array_column(makeUnionArray(), 0);
assert($m_prepare !== []); $n = array_column([[0 => "test"]], 0);
$m = array_column($m_prepare, "y"); $o = array_column(makeKeyedArray(), "y");
$p_prepare = makeKeyedArray();
assert($p_prepare !== []);
$p = array_column($p_prepare, "y");
', ',
'assertions' => [ 'assertions' => [
'$a' => 'non-empty-list<int>', '$a' => 'non-empty-list<int>',
'$b' => 'non-empty-list<int>', '$b' => 'non-empty-list<int>',
'$c' => 'non-empty-array<string, int>', '$c' => 'array<int, array{a: int}>',
'$d' => 'list<mixed>', '$d' => 'array<array-key, array{a: int}>',
'$e' => 'list<mixed>', '$e' => 'array<array-key, mixed>',
'$f' => 'array<array-key, mixed>', '$f' => 'non-empty-array<string, int>',
'$g' => 'list<mixed>', '$g' => 'list<mixed>',
'$h' => 'list<mixed>', '$h' => 'list<mixed>',
'$i' => 'list<string>', '$i' => 'array<array-key, mixed>',
'$j' => 'list<mixed>', '$j' => 'list<mixed>',
'$k' => 'non-empty-list<string>', '$k' => 'list<mixed>',
'$l' => 'list<int>', '$l' => 'list<string>',
'$m' => 'list<int>', '$m' => 'list<mixed>',
'$n' => 'non-empty-list<string>',
'$o' => 'list<int>',
'$p' => 'list<int>',
], ],
], ],
'splatArrayIntersect' => [ 'splatArrayIntersect' => [