Skip to content

Commit b26d08c

Browse files
committed
More pair-wise intersect
1 parent 1c5af0d commit b26d08c

File tree

4 files changed

+53
-13
lines changed

4 files changed

+53
-13
lines changed

src/Reflection/Type/IntersectionTypeMethodReflection.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,9 +94,18 @@ public function getVariants(): array
9494
}
9595
}
9696

97-
$returnType = TypeCombinator::intersect(...$returnTypes);
98-
$phpDocReturnType = TypeCombinator::intersect(...$phpDocReturnTypes);
99-
$nativeReturnType = TypeCombinator::intersect(...$nativeReturnTypes);
97+
$returnType = $returnTypes[0];
98+
for ($i = 1, $count = count($returnTypes); $i < $count; $i++) {
99+
$returnType = TypeCombinator::intersect($returnType, $returnTypes[$i]);
100+
}
101+
$phpDocReturnType = $phpDocReturnTypes[0];
102+
for ($i = 1, $count = count($phpDocReturnTypes); $i < $count; $i++) {
103+
$phpDocReturnType = TypeCombinator::intersect($phpDocReturnType, $phpDocReturnTypes[$i]);
104+
}
105+
$nativeReturnType = $nativeReturnTypes[0];
106+
for ($i = 1, $count = count($nativeReturnTypes); $i < $count; $i++) {
107+
$nativeReturnType = TypeCombinator::intersect($nativeReturnType, $nativeReturnTypes[$i]);
108+
}
100109
return array_map(static fn (ExtendedParametersAcceptor $acceptor): ExtendedParametersAcceptor => new ExtendedFunctionVariant(
101110
$acceptor->getTemplateTypeMap(),
102111
$acceptor->getResolvedTemplateTypeMap(),
@@ -188,7 +197,11 @@ public function getThrowType(): ?Type
188197
return null;
189198
}
190199

191-
return TypeCombinator::intersect(...$types);
200+
$result = $types[0];
201+
for ($i = 1, $count = count($types); $i < $count; $i++) {
202+
$result = TypeCombinator::intersect($result, $types[$i]);
203+
}
204+
return $result;
192205
}
193206

194207
public function hasSideEffects(): TrinaryLogic

src/Reflection/Type/IntersectionTypePropertyReflection.php

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use PHPStan\TrinaryLogic;
1010
use PHPStan\Type\Type;
1111
use PHPStan\Type\TypeCombinator;
12-
use function array_map;
1312
use function count;
1413
use function implode;
1514

@@ -92,7 +91,7 @@ public function hasPhpDocType(): bool
9291

9392
public function getPhpDocType(): Type
9493
{
95-
return TypeCombinator::intersect(...array_map(static fn (ExtendedPropertyReflection $property): Type => $property->getPhpDocType(), $this->properties));
94+
return $this->pairwiseIntersect(static fn (ExtendedPropertyReflection $property): Type => $property->getPhpDocType());
9695
}
9796

9897
public function hasNativeType(): bool
@@ -102,17 +101,29 @@ public function hasNativeType(): bool
102101

103102
public function getNativeType(): Type
104103
{
105-
return TypeCombinator::intersect(...array_map(static fn (ExtendedPropertyReflection $property): Type => $property->getNativeType(), $this->properties));
104+
return $this->pairwiseIntersect(static fn (ExtendedPropertyReflection $property): Type => $property->getNativeType());
106105
}
107106

108107
public function getReadableType(): Type
109108
{
110-
return TypeCombinator::intersect(...array_map(static fn (ExtendedPropertyReflection $property): Type => $property->getReadableType(), $this->properties));
109+
return $this->pairwiseIntersect(static fn (ExtendedPropertyReflection $property): Type => $property->getReadableType());
111110
}
112111

113112
public function getWritableType(): Type
114113
{
115-
return TypeCombinator::intersect(...array_map(static fn (ExtendedPropertyReflection $property): Type => $property->getWritableType(), $this->properties));
114+
return $this->pairwiseIntersect(static fn (ExtendedPropertyReflection $property): Type => $property->getWritableType());
115+
}
116+
117+
/**
118+
* @param callable(ExtendedPropertyReflection): Type $getType
119+
*/
120+
private function pairwiseIntersect(callable $getType): Type
121+
{
122+
$result = $getType($this->properties[0]);
123+
for ($i = 1, $count = count($this->properties); $i < $count; $i++) {
124+
$result = TypeCombinator::intersect($result, $getType($this->properties[$i]));
125+
}
126+
return $result;
116127
}
117128

118129
public function canChangeTypeAfterAssignment(): bool

src/Type/IntersectionType.php

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,7 +1378,11 @@ public function traverse(callable $cb): Type
13781378
}
13791379

13801380
if ($changed) {
1381-
return TypeCombinator::intersect(...$types);
1381+
$result = $types[0];
1382+
for ($i = 1, $count = count($types); $i < $count; $i++) {
1383+
$result = TypeCombinator::intersect($result, $types[$i]);
1384+
}
1385+
return $result;
13821386
}
13831387

13841388
return $this;
@@ -1415,7 +1419,11 @@ public function traverseSimultaneously(Type $right, callable $cb): Type
14151419
return $this;
14161420
}
14171421

1418-
return TypeCombinator::intersect(...$newTypes);
1422+
$result = $newTypes[0];
1423+
for ($i = 1, $count = count($newTypes); $i < $count; $i++) {
1424+
$result = TypeCombinator::intersect($result, $newTypes[$i]);
1425+
}
1426+
return $result;
14191427
}
14201428

14211429
return $this;
@@ -1481,7 +1489,11 @@ private function intersectResults(
14811489
private function intersectTypes(callable $getType): Type
14821490
{
14831491
$operands = array_map($getType, $this->types);
1484-
return TypeCombinator::intersect(...$operands);
1492+
$result = $operands[0];
1493+
for ($i = 1, $count = count($operands); $i < $count; $i++) {
1494+
$result = TypeCombinator::intersect($result, $operands[$i]);
1495+
}
1496+
return $result;
14851497
}
14861498

14871499
public function toPhpDocNode(): TypeNode

src/Type/TypeCombinator.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1668,7 +1668,11 @@ private static function mergeIntersectionsForUnion(IntersectionType $a, Intersec
16681668
return null;
16691669
}
16701670

1671-
return self::intersect(...$mergedTypes);
1671+
$result = $mergedTypes[0];
1672+
for ($i = 1, $count = count($mergedTypes); $i < $count; $i++) {
1673+
$result = self::intersect($result, $mergedTypes[$i]);
1674+
}
1675+
return $result;
16721676
}
16731677

16741678
public static function removeFalsey(Type $type): Type

0 commit comments

Comments
 (0)