1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +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']; $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]); $by_ref_type = TypeCombination::combineTypes([$array_type, $replacement_array_type]);
AssignmentAnalyzer::assignByRefParam( AssignmentAnalyzer::assignByRefParam(
@ -465,7 +479,13 @@ class ArrayFunctionArgumentsAnalyzer
\array_shift($array_properties); \array_shift($array_properties);
if (!$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; $array_atomic_type->properties = $array_properties;

View File

@ -32,8 +32,6 @@ class ArrayTypeComparator
) : bool { ) : bool {
$all_types_contain = true; $all_types_contain = true;
$prior_input_type_part = $input_type_part;
if ($container_type_part instanceof ObjectLike if ($container_type_part instanceof ObjectLike
&& $input_type_part instanceof TArray && $input_type_part instanceof TArray
) { ) {
@ -215,17 +213,6 @@ class ArrayTypeComparator
if ($container_type_part instanceof Type\Atomic\TNonEmptyArray if ($container_type_part instanceof Type\Atomic\TNonEmptyArray
&& !$input_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) { if ($all_types_contain && $atomic_comparison_result) {
$atomic_comparison_result->type_coerced = true; $atomic_comparison_result->type_coerced = true;

View File

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

View File

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