Skip to content

Commit d8c0a36

Browse files
committed
ExpressionTypeHolder - variadic mergeWith preparation
1 parent cbaa3c9 commit d8c0a36

3 files changed

Lines changed: 25 additions & 11 deletions

File tree

src/Analyser/ExpressionTypeHolder.php

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use PHPStan\TrinaryLogic;
77
use PHPStan\Type\Type;
88
use PHPStan\Type\TypeCombinator;
9+
use function count;
910

1011
final class ExpressionTypeHolder
1112
{
@@ -33,21 +34,34 @@ public function equals(self $other): bool
3334
return $this->type->equals($other->type);
3435
}
3536

36-
public function and(self $other): self
37+
public function and(self ...$others): self
3738
{
38-
if ($this->type->equals($other->type)) {
39-
if ($this->certainty->equals($other->certainty)) {
40-
return $this;
39+
if ($others === []) {
40+
return $this;
41+
}
42+
43+
$types = [$this->type];
44+
$certainty = $this->certainty;
45+
foreach ($others as $other) {
46+
$certainty = $certainty->and($other->certainty);
47+
if ($types[0] === $other->type || $other->type->equals($types[0])) {
48+
continue;
4149
}
50+
$types[] = $other->type;
51+
}
4252

43-
$type = $this->type;
44-
} else {
45-
$type = TypeCombinator::union($this->type, $other->type);
53+
if (count($types) === 1) {
54+
return new self(
55+
$this->expr,
56+
$types[0],
57+
$certainty,
58+
);
4659
}
60+
4761
return new self(
4862
$this->expr,
49-
$type,
50-
$this->certainty->and($other->certainty),
63+
TypeCombinator::union(...$types),
64+
$certainty,
5165
);
5266
}
5367

tests/PHPStan/Analyser/nsrt/array-key-exists.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public function doBar(array $a, array $b, array $c, int $key1, string $key2, int
101101
assertType("'3'|'4'", $key2);
102102
}
103103
if (array_key_exists($key3, [3 => 'foo', 4 => 'bar'])) {
104-
assertType("3|4|'3'|'4'", $key3);
104+
assertType("(3|4|'3'|'4')", $key3);
105105
}
106106
if (array_key_exists($key4, [3 => 'foo', 4 => 'bar'])) {
107107
assertType("(3|4|'3'|'4')", $key4);

tests/PHPStan/Analyser/nsrt/key-exists.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public function doBar(array $a, array $b, array $c, int $key1, string $key2, int
100100
assertType("'3'|'4'", $key2);
101101
}
102102
if (key_exists($key3, [3 => 'foo', 4 => 'bar'])) {
103-
assertType("3|4|'3'|'4'", $key3);
103+
assertType("(3|4|'3'|'4')", $key3);
104104
}
105105
if (key_exists($key4, [3 => 'foo', 4 => 'bar'])) {
106106
assertType("(3|4|'3'|'4')", $key4);

0 commit comments

Comments
 (0)