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

Fix #2408 - existing offsets checked with isset should be valid

This commit is contained in:
Matthew Brown 2019-12-18 23:48:25 +00:00
parent 456aa1c569
commit af28d650f3
3 changed files with 45 additions and 4 deletions

View File

@ -144,6 +144,7 @@ class ArrayAssignmentAnalyzer
$parent_var_id = null; $parent_var_id = null;
$offset_already_existed = false;
$full_var_id = true; $full_var_id = true;
$child_stmt = null; $child_stmt = null;
@ -330,6 +331,14 @@ class ArrayAssignmentAnalyzer
&& !$child_stmt_var_type->hasObjectType() && !$child_stmt_var_type->hasObjectType()
) { ) {
$array_var_id = $root_var_id . implode('', $var_id_additions); $array_var_id = $root_var_id . implode('', $var_id_additions);
$parent_var_id = $root_var_id . implode('', \array_slice($var_id_additions, 0, -1));
if (isset($context->vars_in_scope[$array_var_id])
&& !$context->vars_in_scope[$array_var_id]->possibly_undefined
) {
$offset_already_existed = true;
}
$context->vars_in_scope[$array_var_id] = clone $assignment_type; $context->vars_in_scope[$array_var_id] = clone $assignment_type;
} }
@ -519,10 +528,21 @@ class ArrayAssignmentAnalyzer
$array_atomic_key_type = Type::getMixed(); $array_atomic_key_type = Type::getMixed();
} }
$array_atomic_type = new TNonEmptyArray([ if ($offset_already_existed
$array_atomic_key_type, && $child_stmt
$current_type, && $parent_var_id
]); && ($parent_type = $context->vars_in_scope[$parent_var_id] ?? null)
&& $parent_type->hasList()
) {
$array_atomic_type = new TNonEmptyList(
$current_type,
);
} else {
$array_atomic_type = new TNonEmptyArray([
$array_atomic_key_type,
$current_type,
]);
}
} else { } else {
$array_atomic_type = new TNonEmptyList($current_type); $array_atomic_type = new TNonEmptyList($current_type);
} }

View File

@ -618,6 +618,14 @@ class Union
return isset($this->types['array']); return isset($this->types['array']);
} }
/**
* @return bool
*/
public function hasList()
{
return isset($this->types['array']) && $this->types['array'] instanceof Atomic\TList;
}
/** /**
* @return bool * @return bool
*/ */

View File

@ -1273,6 +1273,19 @@ class ArrayAssignmentTest extends TestCase
'$arr3' => 'array{1: int, 2: int, 3: int, 4: int}', '$arr3' => 'array{1: int, 2: int, 3: int, 4: int}',
] ]
], ],
'listPropertyAssignmentAfterIsset' => [
'<?php
class Collection {
/** @var list<string> */
private $list = [];
public function override(int $offset): void {
if (isset($this->list[$offset])) {
$this->list[$offset] = "a";
}
}
}',
],
]; ];
} }