Skip to content

Commit

Permalink
Begin fixing vimeo#8942
Browse files Browse the repository at this point in the history
  • Loading branch information
danog committed Dec 19, 2022
1 parent bde77f7 commit b91ad2c
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -650,17 +650,18 @@ private static function updateArrayAssignmentChildType(
} else {
assert($array_atomic_type_list !== null);
$array_atomic_type = new TKeyedArray(
array_fill(
[...array_fill(
$atomic_root_type_array->getMinCount(),
count($atomic_root_type_array->properties)-1,
$array_atomic_type_list
), ...array_fill(
0,
count($atomic_root_type_array->properties),
$array_atomic_type_list,
),
count($atomic_root_type_array->properties)-1,
Type::getNever()
)],
null,
[
Type::getListKey(),
$array_atomic_type_list,
],
true,
null,
true
);
}
$from_countable_object_like = true;
Expand Down
26 changes: 26 additions & 0 deletions src/Psalm/Type/Atomic/TKeyedArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ public function __construct(
$this->fallback_params = $fallback_params;
$this->is_list = $is_list;
$this->from_docblock = $from_docblock;
if ($this->is_list) {
$last_k = -1;
$had_possibly_undefined = false;
ksort($this->properties);
foreach ($this->properties as $k => $v) {
if (is_string($k) || $last_k !== ($k-1) || ($had_possibly_undefined && !$v->possibly_undefined)) {
$this->is_list = false;
break;
}
$had_possibly_undefined = $v->possibly_undefined || $had_possibly_undefined;
$last_k = $k;
}
}
}

/**
Expand All @@ -98,6 +111,19 @@ public function setProperties(array $properties): self
}
$cloned = clone $this;
$cloned->properties = $properties;
if ($cloned->is_list) {
$last_k = -1;
$had_possibly_undefined = false;
ksort($cloned->properties);
foreach ($cloned->properties as $k => $v) {
if (is_string($k) || $last_k !== ($k-1) || ($had_possibly_undefined && !$v->possibly_undefined)) {
$cloned->is_list = false;
break;
}
$had_possibly_undefined = $v->possibly_undefined || $had_possibly_undefined;
$last_k = $k;
}
}
return $cloned;
}

Expand Down
38 changes: 38 additions & 0 deletions tests/ArrayAccessTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,44 @@ function foo(array $a, int $b): void {
public function providerValidCodeParse(): iterable
{
return [
'testBuildList' => [
'code' => '<?php
$a = [];
if (random_int(0, 1)) {
$a []= 0;
}
if (random_int(0, 1)) {
$a []= 1;
}
$pre = $a;
$a []= 2;
',
'assertions' => [
'$pre===' => 'list{0?: 0|1, 1?: 1}',
'$a===' => 'list{0: 0|1|2, 1?: 1|2, 2?: 2}',
]
],
'testBuildListOther' => [
'code' => '<?php
$list = [];
$entropy = random_int(0, 2);
if ($entropy === 0) {
$list[] = "A";
} elseif ($entropy === 1) {
$list[] = "B";
}
$list[] = "C";
',
'assertions' => [
'$list===' => "list{0: 'A'|'B'|'C', 1?: 'C'}"
]
],
'instanceOfStringOffset' => [
'code' => '<?php
class A {
Expand Down

0 comments on commit b91ad2c

Please sign in to comment.