Skip to content

Commit 7dd643d

Browse files
Rework
1 parent 300c9d0 commit 7dd643d

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

src/Type/Php/InArrayFunctionTypeSpecifyingExtension.php

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
use PHPStan\Reflection\FunctionReflection;
1717
use PHPStan\Type\Accessory\NonEmptyArrayType;
1818
use PHPStan\Type\ArrayType;
19+
use PHPStan\Type\Constant\ConstantArrayType;
1920
use PHPStan\Type\FunctionTypeSpecifyingExtension;
2021
use PHPStan\Type\MixedType;
21-
use PHPStan\Type\NeverType;
2222
use PHPStan\Type\Type;
2323
use PHPStan\Type\TypeCombinator;
2424
use function count;
@@ -167,10 +167,9 @@ public function specifyTypes(FunctionReflection $functionReflection, FuncCall $n
167167
}
168168

169169
/**
170-
* Computes the type to narrow the needle against, or null if no narrowing
171-
* should occur. In true context, returns the array value type directly.
172-
* In false context, returns only the values guaranteed to be in every
173-
* possible variant of the array.
170+
* Computes the type to narrow the needle against, or null if no narrowing should occur.
171+
* In true context, returns the array value type directly.
172+
* In false context, returns only the values guaranteed to be in every possible variant of the array.
174173
*/
175174
private function computeNeedleNarrowingType(TypeSpecifierContext $context, Type $needleType, Type $arrayType, Type $arrayValueType): ?Type
176175
{
@@ -187,35 +186,43 @@ private function computeNeedleNarrowingType(TypeSpecifierContext $context, Type
187186
}
188187

189188
$arrays = $arrayType->getArrays();
190-
$innerValueTypes = [];
189+
$guaranteedValueTypePerArray = [];
191190
foreach ($arrays as $array) {
192-
$constantArrays = $array->getConstantArrays();
193-
if (count($constantArrays) > 0) {
194-
foreach ($constantArrays as $constantArray) {
195-
$guaranteedTypes = [];
196-
foreach ($constantArray->getValueTypes() as $i => $valueType) {
197-
if (!$constantArray->isOptionalKey($i)) {
198-
$guaranteedTypes[] = $valueType;
199-
}
191+
if ($array instanceof ConstantArrayType) {
192+
$innerGuaranteeValueType = [];
193+
foreach ($array->getValueTypes() as $i => $valueType) {
194+
if ($array->isOptionalKey($i)) {
195+
continue;
200196
}
201-
$innerValueTypes[] = count($guaranteedTypes) > 0
202-
? TypeCombinator::union(...$guaranteedTypes)
203-
: new NeverType();
197+
198+
$finiteTypes = $valueType->getFiniteTypes();
199+
if (count($finiteTypes) !== 1) {
200+
continue;
201+
}
202+
203+
$innerGuaranteeValueType[] = $finiteTypes[0];
204+
}
205+
206+
if (count($innerGuaranteeValueType) === 0) {
207+
return null;
204208
}
209+
210+
$guaranteedValueTypePerArray[] = TypeCombinator::union(...$innerGuaranteeValueType);
205211
} else {
206-
$valueType = $array->getIterableValueType();
207-
if (count($valueType->getFiniteTypes()) === 1) {
208-
$innerValueTypes[] = $valueType;
212+
$finiteValueType = $array->getIterableValueType()->getFiniteTypes();
213+
if (count($finiteValueType) !== 1) {
214+
return null;
209215
}
216+
217+
$guaranteedValueTypePerArray[] = $finiteValueType[0];
210218
}
211219
}
212220

213-
if (count($innerValueTypes) === 0) {
221+
if (count($guaranteedValueTypePerArray) === 0) {
214222
return null;
215223
}
216224

217-
$guaranteedValueType = TypeCombinator::intersect(...$innerValueTypes);
218-
225+
$guaranteedValueType = TypeCombinator::intersect(...$guaranteedValueTypePerArray);
219226
if (count($guaranteedValueType->getFiniteTypes()) === 0) {
220227
return null;
221228
}

0 commit comments

Comments
 (0)