Skip to content

Commit fd0eb88

Browse files
Try other strategy
1 parent be1a369 commit fd0eb88

1 file changed

Lines changed: 38 additions & 62 deletions

File tree

src/Analyser/TypeSpecifier.php

Lines changed: 38 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -734,15 +734,7 @@ public function specifyTypesInCondition(
734734
$leftTypes = $this->specifyTypesInCondition($scope, $expr->left, $context)->setRootExpr($expr);
735735
$rightScope = $scope->filterByTruthyValue($expr->left);
736736
$rightTypes = $this->specifyTypesInCondition($rightScope, $expr->right, $context)->setRootExpr($expr);
737-
if ($context->true()) {
738-
$types = $leftTypes->unionWith($rightTypes);
739-
} else {
740-
$normalizedLeft = $leftTypes->normalize($scope);
741-
$normalizedRight = $rightTypes->normalize($rightScope);
742-
$normalizedLeft = $this->propagateArrayDimFetchNarrowingsToParent($normalizedLeft, $scope);
743-
$normalizedRight = $this->propagateArrayDimFetchNarrowingsToParent($normalizedRight, $rightScope);
744-
$types = $normalizedLeft->intersectWith($normalizedRight);
745-
}
737+
$types = $context->true() ? $leftTypes->unionWith($rightTypes) : $leftTypes->normalize($scope)->intersectWith($rightTypes->normalize($rightScope));
746738
if ($context->false()) {
747739
$leftTypesForHolders = $leftTypes;
748740
$rightTypesForHolders = $rightTypes;
@@ -796,11 +788,7 @@ public function specifyTypesInCondition(
796788
) {
797789
$types = $leftTypes->normalize($scope);
798790
} else {
799-
$normalizedLeft = $leftTypes->normalize($scope);
800-
$normalizedRight = $rightTypes->normalize($rightScope);
801-
$normalizedLeft = $this->propagateArrayDimFetchNarrowingsToParent($normalizedLeft, $scope);
802-
$normalizedRight = $this->propagateArrayDimFetchNarrowingsToParent($normalizedRight, $rightScope);
803-
$types = $normalizedLeft->intersectWith($normalizedRight);
791+
$types = $leftTypes->normalize($scope)->intersectWith($rightTypes->normalize($rightScope));
804792
$types = $this->augmentBooleanOrTruthyWithConditionalHolders($scope, $rightScope, $expr, $types);
805793
}
806794
} else {
@@ -2088,54 +2076,6 @@ private function augmentBooleanOrTruthyWithConditionalHolders(MutatingScope $sco
20882076
return $types;
20892077
}
20902078

2091-
private function propagateArrayDimFetchNarrowingsToParent(SpecifiedTypes $normalizedTypes, Scope $scope): SpecifiedTypes
2092-
{
2093-
$additionalSureTypes = [];
2094-
foreach ($normalizedTypes->getSureTypes() as $exprString => [$exprNode, $type]) {
2095-
if (
2096-
!$exprNode instanceof ArrayDimFetch
2097-
|| $exprNode->dim === null
2098-
|| $exprNode->var instanceof ArrayDimFetch
2099-
) {
2100-
continue;
2101-
}
2102-
2103-
$dimType = $scope->getType($exprNode->dim)->toArrayKey();
2104-
if (!$dimType instanceof ConstantIntegerType && !$dimType instanceof ConstantStringType) { // @phpstan-ignore phpstanApi.instanceofType
2105-
continue;
2106-
}
2107-
2108-
$parentExprString = $this->exprPrinter->printExpr($exprNode->var);
2109-
if (isset($normalizedTypes->getSureTypes()[$parentExprString]) || isset($additionalSureTypes[$parentExprString])) {
2110-
continue;
2111-
}
2112-
2113-
$parentType = $scope->getType($exprNode->var);
2114-
if ($parentType instanceof MixedType || !$parentType->isArray()->yes()) {
2115-
continue;
2116-
}
2117-
2118-
$narrowedParentType = TypeCombinator::intersect(
2119-
$parentType,
2120-
new HasOffsetValueType($dimType, $type),
2121-
);
2122-
if ($narrowedParentType instanceof NeverType) {
2123-
continue;
2124-
}
2125-
2126-
$additionalSureTypes[$parentExprString] = [$exprNode->var, $narrowedParentType];
2127-
}
2128-
2129-
if ($additionalSureTypes === []) {
2130-
return $normalizedTypes;
2131-
}
2132-
2133-
return new SpecifiedTypes(
2134-
$normalizedTypes->getSureTypes() + $additionalSureTypes,
2135-
[],
2136-
);
2137-
}
2138-
21392079
/**
21402080
* @return array<string, ConditionalExpressionHolder[]>
21412081
*/
@@ -2646,6 +2586,42 @@ private function createForExpr(
26462586
}
26472587
}
26482588

2589+
if (
2590+
$expr instanceof ArrayDimFetch
2591+
&& $expr->dim !== null
2592+
&& !$context->null()
2593+
) {
2594+
$dimType = $scope->getType($expr->dim);
2595+
if ($dimType instanceof ConstantIntegerType || $dimType->getConstantStrings() !== []) {
2596+
$varType = $scope->getType($expr->var);
2597+
$constantArrays = $varType->getConstantArrays();
2598+
if ($constantArrays !== []) {
2599+
$typesToRemove = [];
2600+
foreach ($constantArrays as $constantArray) {
2601+
if (!$constantArray->hasOffsetValueType($dimType)->yes()) {
2602+
continue;
2603+
}
2604+
$offsetValueType = $constantArray->getOffsetValueType($dimType);
2605+
if ($context->false()) {
2606+
if ($type->isSuperTypeOf($offsetValueType)->yes()) {
2607+
$typesToRemove[] = $constantArray;
2608+
}
2609+
} elseif ($context->true()) {
2610+
if ($type->isSuperTypeOf($offsetValueType)->no()) {
2611+
$typesToRemove[] = $constantArray;
2612+
}
2613+
}
2614+
}
2615+
2616+
if ($typesToRemove !== [] && count($typesToRemove) < count($constantArrays)) {
2617+
$typeToRemove = TypeCombinator::union(...$typesToRemove);
2618+
$varExprString = $this->exprPrinter->printExpr($expr->var);
2619+
$sureNotTypes[$varExprString] = [$expr->var, $typeToRemove];
2620+
}
2621+
}
2622+
}
2623+
}
2624+
26492625
$types = new SpecifiedTypes($sureTypes, $sureNotTypes);
26502626
if (isset($containsNull) && !$containsNull) {
26512627
return $this->createNullsafeTypes($originalExpr, $scope, $context, $type)->unionWith($types);

0 commit comments

Comments
 (0)