Skip to content

Commit

Permalink
Fix #2408 - existing offsets checked with isset should be valid
Browse files Browse the repository at this point in the history
  • Loading branch information
muglug committed Dec 18, 2019
1 parent 456aa1c commit af28d65
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ public static function updateArrayType(

$parent_var_id = null;

$offset_already_existed = false;
$full_var_id = true;

$child_stmt = null;
Expand Down Expand Up @@ -330,6 +331,14 @@ public static function updateArrayType(
&& !$child_stmt_var_type->hasObjectType()
) {
$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;
}

Expand Down Expand Up @@ -519,10 +528,21 @@ public static function updateArrayType(
$array_atomic_key_type = Type::getMixed();
}

$array_atomic_type = new TNonEmptyArray([
$array_atomic_key_type,
$current_type,
]);
if ($offset_already_existed
&& $child_stmt
&& $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 {
$array_atomic_type = new TNonEmptyList($current_type);
}
Expand Down
8 changes: 8 additions & 0 deletions src/Psalm/Type/Union.php
Original file line number Diff line number Diff line change
Expand Up @@ -618,6 +618,14 @@ public function hasArray()
return isset($this->types['array']);
}

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

/**
* @return bool
*/
Expand Down
13 changes: 13 additions & 0 deletions tests/ArrayAssignmentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,19 @@ function foo(array $arr) : string {
'$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";
}
}
}',
],
];
}

Expand Down

0 comments on commit af28d65

Please sign in to comment.