1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Hopefully final fixes

This commit is contained in:
Brown 2020-07-21 23:59:11 -04:00
parent 7ef3d4711f
commit 962265e98e
4 changed files with 42 additions and 18 deletions

View File

@ -406,6 +406,20 @@ class ArrayFunctionArgumentsAnalyzer
*/
$replacement_array_type = $replacement_arg_type->getAtomicTypes()['array'];
if ($replacement_array_type instanceof ObjectLike) {
$was_list = $replacement_array_type->is_list;
$replacement_array_type = $replacement_array_type->getGenericArrayType();
if ($was_list) {
if ($replacement_array_type instanceof TNonEmptyArray) {
$replacement_array_type = new TNonEmptyList($replacement_array_type->type_params[1]);
} else {
$replacement_array_type = new TList($replacement_array_type->type_params[1]);
}
}
}
$by_ref_type = TypeCombination::combineTypes([$array_type, $replacement_array_type]);
AssignmentAnalyzer::assignByRefParam(
@ -465,7 +479,13 @@ class ArrayFunctionArgumentsAnalyzer
\array_shift($array_properties);
if (!$array_properties) {
$array_properties = [$array_atomic_type->previous_value_type ?: Type::getMixed()];
$array_properties = [
$array_atomic_type->previous_value_type
? clone $array_atomic_type->previous_value_type
: Type::getMixed()
];
$array_properties[0]->possibly_undefined = true;
}
$array_atomic_type->properties = $array_properties;

View File

@ -32,8 +32,6 @@ class ArrayTypeComparator
) : bool {
$all_types_contain = true;
$prior_input_type_part = $input_type_part;
if ($container_type_part instanceof ObjectLike
&& $input_type_part instanceof TArray
) {
@ -215,17 +213,6 @@ class ArrayTypeComparator
if ($container_type_part instanceof Type\Atomic\TNonEmptyArray
&& !$input_type_part instanceof Type\Atomic\TNonEmptyArray
&& !($input_type_part instanceof ObjectLike
&& ($input_type_part->sealed
|| $input_type_part->previous_value_type
|| \array_filter(
$input_type_part->properties,
function ($prop_type) {
return !$prop_type->possibly_undefined;
}
)
)
)
) {
if ($all_types_contain && $atomic_comparison_result) {
$atomic_comparison_result->type_coerced = true;

View File

@ -455,6 +455,7 @@ class TypeCombination
$array_type = new ObjectLike([$generic_type_params[1]]);
$array_type->previous_key_type = Type::getInt();
$array_type->previous_value_type = $combination->array_type_params[1];
$array_type->is_list = true;
} else {
$array_type = new TNonEmptyList($generic_type_params[1]);

View File

@ -292,6 +292,17 @@ class ArrayFunctionCallTest extends TestCase
return 0;
}',
],
'arrayShiftFunkyObjectLikeList' => [
'<?php
/**
* @param non-empty-list<string>|array{null} $arr
* @return array<int, string>
*/
function foo(array $arr) {
array_shift($arr);
return $arr;
}'
],
'arrayPopNonEmptyAfterCountEqualsOne' => [
'<?php
/** @var array<string, int> */
@ -1013,18 +1024,23 @@ class ArrayFunctionCallTest extends TestCase
'assertions' => [],
'error_levels' => ['MissingClosureReturnType', 'MixedAssignment'],
],
'arraySplice' => [
'arraySpliceArray' => [
'<?php
$a = [1, 2, 3];
$c = $a;
$b = ["a", "b", "c"];
array_splice($a, -1, 1, $b);
$d = [1, 2, 3];
$e = array_splice($d, -1, 1);',
array_splice($a, rand(-10, 0), rand(0, 10), $b);',
'assertions' => [
'$a' => 'non-empty-list<int|string>',
'$b' => 'array{string, string, string}',
'$c' => 'array{int, int, int}',
],
],
'arraySpliceReturn' => [
'<?php
$d = [1, 2, 3];
$e = array_splice($d, -1, 1);',
'assertions' => [
'$e' => 'array<array-key, mixed>'
],
],