Skip to content

Commit 5b10da3

Browse files
Introduce filterTypes
1 parent 7869053 commit 5b10da3

File tree

2 files changed

+30
-54
lines changed

2 files changed

+30
-54
lines changed

src/Analyser/MutatingScope.php

Lines changed: 8 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5594,18 +5594,10 @@ 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) {
5597+
$typeWithMethod = $typeWithMethod->filterTypes(fn (Type $innerType) => $innerType->hasMethod($methodName)->yes());
5598+
if ($typeWithMethod === null) {
56065599
return null;
56075600
}
5608-
$typeWithMethod = TypeCombinator::union(...$newTypes);
56095601
}
56105602

56115603
if (!$typeWithMethod->hasMethod($methodName)->yes()) {
@@ -5709,18 +5701,10 @@ private function methodCallReturnType(Type $typeWithMethod, string $methodName,
57095701
public function getPropertyReflection(Type $typeWithProperty, string $propertyName): ?ExtendedPropertyReflection
57105702
{
57115703
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) {
5704+
$typeWithProperty = $typeWithProperty->filterTypes(fn (Type $innerType) => $innerType->hasProperty($propertyName)->yes());
5705+
if ($typeWithProperty === null) {
57215706
return null;
57225707
}
5723-
$typeWithProperty = TypeCombinator::union(...$newTypes);
57245708
}
57255709
if (!$typeWithProperty->hasProperty($propertyName)->yes()) {
57265710
return null;
@@ -5749,18 +5733,10 @@ private function propertyFetchType(Type $fetchedOnType, string $propertyName, Ex
57495733
public function getConstantReflection(Type $typeWithConstant, string $constantName): ?ConstantReflection
57505734
{
57515735
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) {
5736+
$typeWithConstant = $typeWithConstant->filterTypes(fn (Type $innerType) => $innerType->hasConstant($constantName)->yes());
5737+
if ($typeWithConstant === null) {
57615738
return null;
57625739
}
5763-
$typeWithConstant = TypeCombinator::union(...$newTypes);
57645740
}
57655741
if (!$typeWithConstant->hasConstant($constantName)->yes()) {
57665742
return null;
@@ -5804,18 +5780,7 @@ private function getNativeConstantTypes(): array
58045780
public function getIterableKeyType(Type $iteratee): Type
58055781
{
58065782
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();
5817-
}
5818-
$iteratee = TypeCombinator::union(...$newTypes);
5783+
$iteratee = $iteratee->filterTypes(fn (Type $innerType) => $innerType->isIterable()->yes()) ?? $iteratee;
58195784
}
58205785

58215786
return $iteratee->getIterableKeyType();
@@ -5824,18 +5789,7 @@ public function getIterableKeyType(Type $iteratee): Type
58245789
public function getIterableValueType(Type $iteratee): Type
58255790
{
58265791
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();
5837-
}
5838-
$iteratee = TypeCombinator::union(...$newTypes);
5792+
$iteratee = $iteratee->filterTypes(fn (Type $innerType) => $innerType->isIterable()->yes()) ?? $iteratee;
58395793
}
58405794

58415795
return $iteratee->getIterableValueType();

src/Type/UnionType.php

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

89+
/**
90+
* @param callable(Type $type): bool $filterCb
91+
*
92+
* @return Type|null
93+
*/
94+
public function filterTypes(callable $filterCb): ?Type
95+
{
96+
$newTypes = [];
97+
foreach ($this->getTypes() as $innerType) {
98+
if (!$filterCb($innerType)) {
99+
continue;
100+
}
101+
102+
$newTypes[] = $innerType;
103+
}
104+
if (count($newTypes) === 0) {
105+
return null;
106+
}
107+
108+
return TypeCombinator::union(...$newTypes);
109+
}
110+
89111
public function isNormalized(): bool
90112
{
91113
return $this->normalized;

0 commit comments

Comments
 (0)