mirror of
https://github.com/danog/psalm.git
synced 2025-01-21 21:31:13 +01:00
narrowed reset
and end
return type (#3950)
* narrowed `reset` return type BUT psalm seems to ignore the stub * narrowed `reset` and `end` return type, this time for real * fixed UnusedVariable Issue * fixed RedundantCondition Issue caused by `end`s return type being more precise * Improve solution slightly Co-authored-by: Matthew Brown <github@muglug.com>
This commit is contained in:
parent
84130770f4
commit
f831ebdbcf
@ -1164,7 +1164,7 @@ class ClassLikes
|
||||
unset($uses_flipped[$old_fq_class_name]);
|
||||
$old_class_name_parts = explode('\\', $old_fq_class_name);
|
||||
$old_class_name = end($old_class_name_parts);
|
||||
if (strtolower($old_class_name) === strtolower($alias)) {
|
||||
if ($old_class_name === strtolower($alias)) {
|
||||
$new_class_name_parts = explode('\\', $new_fq_class_name);
|
||||
$new_class_name = end($new_class_name_parts);
|
||||
$uses_flipped[strtolower($new_fq_class_name)] = $new_class_name;
|
||||
@ -1321,7 +1321,7 @@ class ClassLikes
|
||||
unset($uses_flipped[$old_fq_class_name]);
|
||||
$old_class_name_parts = explode('\\', $old_fq_class_name);
|
||||
$old_class_name = end($old_class_name_parts);
|
||||
if (strtolower($old_class_name) === strtolower($alias)) {
|
||||
if ($old_class_name === strtolower($alias)) {
|
||||
$new_class_name_parts = explode('\\', $new_fq_class_name);
|
||||
$new_class_name = end($new_class_name_parts);
|
||||
$uses_flipped[strtolower($new_fq_class_name)] = $new_class_name;
|
||||
|
@ -46,18 +46,25 @@ class ArrayPointerAdjustmentReturnTypeProvider implements \Psalm\Plugin\Hook\Fun
|
||||
|
||||
if ($first_arg_array instanceof Type\Atomic\TArray) {
|
||||
$value_type = clone $first_arg_array->type_params[1];
|
||||
$definitely_has_items = $first_arg_array instanceof Type\Atomic\TNonEmptyArray;
|
||||
} elseif ($first_arg_array instanceof Type\Atomic\TList) {
|
||||
$value_type = clone $first_arg_array->type_param;
|
||||
$definitely_has_items = $first_arg_array instanceof Type\Atomic\TNonEmptyList;
|
||||
} else {
|
||||
$value_type = $first_arg_array->getGenericValueType();
|
||||
$definitely_has_items = $value_type instanceof Type\Atomic\TNonEmptyArray;
|
||||
}
|
||||
|
||||
$value_type->addType(new Type\Atomic\TFalse);
|
||||
if ($value_type->isEmpty()) {
|
||||
$value_type = Type::getFalse();
|
||||
} elseif (($function_id !== 'reset' && $function_id !== 'end') || !$definitely_has_items) {
|
||||
$value_type->addType(new Type\Atomic\TFalse);
|
||||
|
||||
$codebase = $statements_source->getCodebase();
|
||||
|
||||
$codebase = $statements_source->getCodebase();
|
||||
|
||||
if ($codebase->config->ignore_internal_falsable_issues) {
|
||||
$value_type->ignore_falsable_issues = true;
|
||||
if ($codebase->config->ignore_internal_falsable_issues) {
|
||||
$value_type->ignore_falsable_issues = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $value_type;
|
||||
|
@ -885,6 +885,158 @@ class ArrayFunctionCallTest extends TestCase
|
||||
'$b' => 'null'
|
||||
],
|
||||
],
|
||||
'arrayResetNonEmptyArray' => [
|
||||
'<?php
|
||||
/** @return non-empty-array<string, int> */
|
||||
function makeArray(): array { return ["one" => 1, "two" => 3]; }
|
||||
$a = makeArray();
|
||||
$b = reset($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'int'
|
||||
],
|
||||
],
|
||||
'arrayResetNonEmptyList' => [
|
||||
'<?php
|
||||
/** @return non-empty-list<int> */
|
||||
function makeArray(): array { return [1, 3]; }
|
||||
$a = makeArray();
|
||||
$b = reset($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'int'
|
||||
],
|
||||
],
|
||||
'arrayResetNonEmptyObjectLike' => [
|
||||
'<?php
|
||||
$a = ["one" => 1, "two" => 3];
|
||||
$b = reset($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'int'
|
||||
],
|
||||
],
|
||||
'arrayResetEmptyArray' => [
|
||||
'<?php
|
||||
$a = [];
|
||||
$b = reset($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false'
|
||||
],
|
||||
],
|
||||
'arrayResetEmptyList' => [
|
||||
'<?php
|
||||
/** @return list<empty> */
|
||||
function makeArray(): array { return []; }
|
||||
$a = makeArray();
|
||||
$b = reset($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false'
|
||||
],
|
||||
],
|
||||
'arrayResetMaybeEmptyArray' => [
|
||||
'<?php
|
||||
/** @return array<string, int> */
|
||||
function makeArray(): array { return ["one" => 1, "two" => 3]; }
|
||||
$a = makeArray();
|
||||
$b = reset($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false|int'
|
||||
],
|
||||
],
|
||||
'arrayResetMaybeEmptyList' => [
|
||||
'<?php
|
||||
/** @return list<int> */
|
||||
function makeArray(): array { return []; }
|
||||
$a = makeArray();
|
||||
$b = reset($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false|int'
|
||||
],
|
||||
],
|
||||
'arrayResetMaybeEmptyObjectLike' => [
|
||||
'<?php
|
||||
/** @return array{foo?: int} */
|
||||
function makeArray(): array { return []; }
|
||||
$a = makeArray();
|
||||
$b = reset($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false|int'
|
||||
],
|
||||
],
|
||||
'arrayEndNonEmptyArray' => [
|
||||
'<?php
|
||||
/** @return non-empty-array<string, int> */
|
||||
function makeArray(): array { return ["one" => 1, "two" => 3]; }
|
||||
$a = makeArray();
|
||||
$b = end($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'int'
|
||||
],
|
||||
],
|
||||
'arrayEndNonEmptyList' => [
|
||||
'<?php
|
||||
/** @return non-empty-list<int> */
|
||||
function makeArray(): array { return [1, 3]; }
|
||||
$a = makeArray();
|
||||
$b = end($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'int'
|
||||
],
|
||||
],
|
||||
'arrayEndNonEmptyObjectLike' => [
|
||||
'<?php
|
||||
$a = ["one" => 1, "two" => 3];
|
||||
$b = end($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'int'
|
||||
],
|
||||
],
|
||||
'arrayEndEmptyArray' => [
|
||||
'<?php
|
||||
$a = [];
|
||||
$b = end($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false'
|
||||
],
|
||||
],
|
||||
'arrayEndEmptyList' => [
|
||||
'<?php
|
||||
/** @return list<empty> */
|
||||
function makeArray(): array { return []; }
|
||||
$a = makeArray();
|
||||
$b = end($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false'
|
||||
],
|
||||
],
|
||||
'arrayEndMaybeEmptyArray' => [
|
||||
'<?php
|
||||
/** @return array<string, int> */
|
||||
function makeArray(): array { return ["one" => 1, "two" => 3]; }
|
||||
$a = makeArray();
|
||||
$b = end($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false|int'
|
||||
],
|
||||
],
|
||||
'arrayEndMaybeEmptyList' => [
|
||||
'<?php
|
||||
/** @return list<int> */
|
||||
function makeArray(): array { return []; }
|
||||
$a = makeArray();
|
||||
$b = end($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false|int'
|
||||
],
|
||||
],
|
||||
'arrayEndMaybeEmptyObjectLike' => [
|
||||
'<?php
|
||||
/** @return array{foo?: int} */
|
||||
function makeArray(): array { return []; }
|
||||
$a = makeArray();
|
||||
$b = end($a);',
|
||||
'assertions' => [
|
||||
'$b' => 'false|int'
|
||||
],
|
||||
],
|
||||
'arrayColumnInference' => [
|
||||
'<?php
|
||||
function makeMixedArray(): array { return []; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user