Skip to content

Commit 88b12f8

Browse files
Introduce UnionType::filterTypes
1 parent a7628e2 commit 88b12f8

File tree

2 files changed

+26
-58
lines changed

2 files changed

+26
-58
lines changed

src/Analyser/MutatingScope.php

Lines changed: 9 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5594,18 +5594,7 @@ private function exactInstantiation(New_ $node, string $className): ?Type
55945594
private function filterTypeWithMethod(Type $typeWithMethod, string $methodName): ?Type
55955595
{
55965596
if ($typeWithMethod instanceof UnionType) {
5597-
$newTypes = [];
5598-
foreach ($typeWithMethod->getTypes() as $innerType) {
5599-
if (!$innerType->hasMethod($methodName)->yes()) {
5600-
continue;
5601-
}
5602-
5603-
$newTypes[] = $innerType;
5604-
}
5605-
if (count($newTypes) === 0) {
5606-
return null;
5607-
}
5608-
$typeWithMethod = TypeCombinator::union(...$newTypes);
5597+
$typeWithMethod = $typeWithMethod->filterTypes(static fn (Type $innerType) => $innerType->hasMethod($methodName)->yes());
56095598
}
56105599

56115600
if (!$typeWithMethod->hasMethod($methodName)->yes()) {
@@ -5709,18 +5698,7 @@ private function methodCallReturnType(Type $typeWithMethod, string $methodName,
57095698
public function getPropertyReflection(Type $typeWithProperty, string $propertyName): ?ExtendedPropertyReflection
57105699
{
57115700
if ($typeWithProperty instanceof UnionType) {
5712-
$newTypes = [];
5713-
foreach ($typeWithProperty->getTypes() as $innerType) {
5714-
if (!$innerType->hasProperty($propertyName)->yes()) {
5715-
continue;
5716-
}
5717-
5718-
$newTypes[] = $innerType;
5719-
}
5720-
if (count($newTypes) === 0) {
5721-
return null;
5722-
}
5723-
$typeWithProperty = TypeCombinator::union(...$newTypes);
5701+
$typeWithProperty = $typeWithProperty->filterTypes(static fn (Type $innerType) => $innerType->hasProperty($propertyName)->yes());
57245702
}
57255703
if (!$typeWithProperty->hasProperty($propertyName)->yes()) {
57265704
return null;
@@ -5749,18 +5727,7 @@ private function propertyFetchType(Type $fetchedOnType, string $propertyName, Ex
57495727
public function getConstantReflection(Type $typeWithConstant, string $constantName): ?ConstantReflection
57505728
{
57515729
if ($typeWithConstant instanceof UnionType) {
5752-
$newTypes = [];
5753-
foreach ($typeWithConstant->getTypes() as $innerType) {
5754-
if (!$innerType->hasConstant($constantName)->yes()) {
5755-
continue;
5756-
}
5757-
5758-
$newTypes[] = $innerType;
5759-
}
5760-
if (count($newTypes) === 0) {
5761-
return null;
5762-
}
5763-
$typeWithConstant = TypeCombinator::union(...$newTypes);
5730+
$typeWithConstant = $typeWithConstant->filterTypes(static fn (Type $innerType) => $innerType->hasConstant($constantName)->yes());
57645731
}
57655732
if (!$typeWithConstant->hasConstant($constantName)->yes()) {
57665733
return null;
@@ -5804,18 +5771,10 @@ private function getNativeConstantTypes(): array
58045771
public function getIterableKeyType(Type $iteratee): Type
58055772
{
58065773
if ($iteratee instanceof UnionType) {
5807-
$newTypes = [];
5808-
foreach ($iteratee->getTypes() as $innerType) {
5809-
if (!$innerType->isIterable()->yes()) {
5810-
continue;
5811-
}
5812-
5813-
$newTypes[] = $innerType;
5814-
}
5815-
if (count($newTypes) === 0) {
5816-
return $iteratee->getIterableKeyType();
5774+
$filtered = $iteratee->filterTypes(static fn (Type $innerType) => $innerType->isIterable()->yes());
5775+
if (!$filtered instanceof NeverType) {
5776+
$iteratee = $filtered;
58175777
}
5818-
$iteratee = TypeCombinator::union(...$newTypes);
58195778
}
58205779

58215780
return $iteratee->getIterableKeyType();
@@ -5824,18 +5783,10 @@ public function getIterableKeyType(Type $iteratee): Type
58245783
public function getIterableValueType(Type $iteratee): Type
58255784
{
58265785
if ($iteratee instanceof UnionType) {
5827-
$newTypes = [];
5828-
foreach ($iteratee->getTypes() as $innerType) {
5829-
if (!$innerType->isIterable()->yes()) {
5830-
continue;
5831-
}
5832-
5833-
$newTypes[] = $innerType;
5834-
}
5835-
if (count($newTypes) === 0) {
5836-
return $iteratee->getIterableValueType();
5786+
$filtered = $iteratee->filterTypes(static fn (Type $innerType) => $innerType->isIterable()->yes());
5787+
if (!$filtered instanceof NeverType) {
5788+
$iteratee = $filtered;
58375789
}
5838-
$iteratee = TypeCombinator::union(...$newTypes);
58395790
}
58405791

58415792
return $iteratee->getIterableValueType();

src/Type/UnionType.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,23 @@ public function getTypes(): array
8686
return $this->types;
8787
}
8888

89+
/**
90+
* @param callable(Type $type): bool $filterCb
91+
*/
92+
public function filterTypes(callable $filterCb): Type
93+
{
94+
$newTypes = [];
95+
foreach ($this->getTypes() as $innerType) {
96+
if (!$filterCb($innerType)) {
97+
continue;
98+
}
99+
100+
$newTypes[] = $innerType;
101+
}
102+
103+
return TypeCombinator::union(...$newTypes);
104+
}
105+
89106
public function isNormalized(): bool
90107
{
91108
return $this->normalized;

0 commit comments

Comments
 (0)