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

array_column check result non-emptyness (#3813)

* Update

* Update test

* Fix test

* Fix test

* inline function res in test

* cs
This commit is contained in:
Evgeniy 2020-07-14 14:13:45 -07:00 committed by GitHub
parent 3c9028c182
commit fcd2ac3078
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 8 deletions

View File

@ -31,6 +31,7 @@ class ArrayColumnReturnTypeProvider implements \Psalm\Plugin\Hook\FunctionReturn
}
$row_shape = null;
$input_array_not_empty = false;
// calculate row shape
if (($first_arg_type = $statements_source->node_data->getType($call_args[0]->value))
@ -54,6 +55,10 @@ class ArrayColumnReturnTypeProvider implements \Psalm\Plugin\Hook\FunctionReturn
$row_shape = $row_type->getAtomicTypes()['array'];
}
}
$input_array_not_empty = $input_array instanceof Type\Atomic\TNonEmptyList ||
$input_array instanceof Type\Atomic\TNonEmptyArray ||
$input_array instanceof Type\Atomic\ObjectLike;
}
$value_column_name = null;
@ -83,9 +88,13 @@ class ArrayColumnReturnTypeProvider implements \Psalm\Plugin\Hook\FunctionReturn
$result_key_type = Type::getArrayKey();
$result_element_type = null;
$have_at_least_one_res = false;
// calculate results
if ($row_shape instanceof Type\Atomic\ObjectLike) {
if ((null !== $value_column_name) && isset($row_shape->properties[$value_column_name])) {
if ($input_array_not_empty) {
$have_at_least_one_res = true;
}
$result_element_type = $row_shape->properties[$value_column_name];
} else {
$result_element_type = Type::getMixed();
@ -96,10 +105,16 @@ class ArrayColumnReturnTypeProvider implements \Psalm\Plugin\Hook\FunctionReturn
}
}
return new Type\Union([
isset($call_args[2]) && (string) $third_arg_type !== 'null'
? new Type\Atomic\TArray([$result_key_type, $result_element_type ?? Type::getMixed()])
: new Type\Atomic\TList($result_element_type ?? Type::getMixed())
]);
if (isset($call_args[2]) && (string)$third_arg_type !== 'null') {
$type = $have_at_least_one_res ?
new Type\Atomic\TNonEmptyArray([$result_key_type, $result_element_type ?? Type::getMixed()])
: new Type\Atomic\TArray([$result_key_type, $result_element_type ?? Type::getMixed()]);
} else {
$type = $have_at_least_one_res ?
new Type\Atomic\TNonEmptyList($result_element_type ?? Type::getMixed())
: new Type\Atomic\TList($result_element_type ?? Type::getMixed());
}
return new Type\Union([$type]);
}
}

View File

@ -811,11 +811,12 @@ class ArrayFunctionCallTest extends TestCase
$h = array_column(makeGenericArray(), 0);
$i = array_column(makeShapeArray(), 0);
$j = array_column(makeUnionArray(), 0);
$k = array_column([[0 => "test"]], 0);
',
'assertions' => [
'$a' => 'list<int>',
'$b' => 'list<int>',
'$c' => 'array<string, int>',
'$a' => 'non-empty-list<int>',
'$b' => 'non-empty-list<int>',
'$c' => 'non-empty-array<string, int>',
'$d' => 'list<mixed>',
'$e' => 'list<mixed>',
'$f' => 'array<array-key, mixed>',
@ -823,6 +824,7 @@ class ArrayFunctionCallTest extends TestCase
'$h' => 'list<mixed>',
'$i' => 'list<string>',
'$j' => 'list<mixed>',
'$k' => 'non-empty-list<string>',
],
],
'splatArrayIntersect' => [