8383use PHPStan \Type \UnionType ;
8484use function array_key_exists ;
8585use function array_key_first ;
86+ use function array_keys ;
8687use function array_last ;
8788use function array_map ;
8889use function array_merge ;
@@ -596,7 +597,7 @@ public function specifyTypesInCondition(
596597 }
597598
598599 return $ this ->handleDefaultTruthyOrFalseyContext ($ context , $ expr , $ scope );
599- } elseif ($ expr instanceof FuncCall && !( $ expr -> name instanceof Name) ) {
600+ } elseif ($ expr instanceof FuncCall) {
600601 $ specifiedTypes = $ this ->specifyTypesFromCallableCall ($ context , $ expr , $ scope );
601602 if ($ specifiedTypes !== null ) {
602603 return $ specifiedTypes ;
@@ -754,10 +755,10 @@ public function specifyTypesInCondition(
754755 $ result = $ result ->setAlwaysOverwriteTypes ();
755756 }
756757 return $ result ->setNewConditionalExpressionHolders (array_merge (
757- $ this ->processBooleanNotSureConditionalTypes ($ scope , $ leftTypesForHolders , $ rightTypesForHolders ),
758- $ this ->processBooleanNotSureConditionalTypes ($ scope , $ rightTypesForHolders , $ leftTypesForHolders ),
759- $ this ->processBooleanSureConditionalTypes ($ scope , $ leftTypesForHolders , $ rightTypesForHolders ),
760- $ this ->processBooleanSureConditionalTypes ($ scope , $ rightTypesForHolders , $ leftTypesForHolders ),
758+ $ this ->processBooleanNotSureConditionalTypes ($ scope , $ leftTypesForHolders , $ rightTypesForHolders, $ rightScope ),
759+ $ this ->processBooleanNotSureConditionalTypes ($ scope , $ rightTypesForHolders , $ leftTypesForHolders, $ scope ),
760+ $ this ->processBooleanSureConditionalTypes ($ scope , $ leftTypesForHolders , $ rightTypesForHolders, $ rightScope ),
761+ $ this ->processBooleanSureConditionalTypes ($ scope , $ rightTypesForHolders , $ leftTypesForHolders, $ scope ),
761762 ))->setRootExpr ($ expr );
762763 }
763764
@@ -804,10 +805,10 @@ public function specifyTypesInCondition(
804805 $ result = $ result ->setAlwaysOverwriteTypes ();
805806 }
806807 return $ result ->setNewConditionalExpressionHolders (array_merge (
807- $ this ->processBooleanNotSureConditionalTypes ($ scope , $ leftTypes , $ rightTypes ),
808- $ this ->processBooleanNotSureConditionalTypes ($ scope , $ rightTypes , $ leftTypes ),
809- $ this ->processBooleanSureConditionalTypes ($ scope , $ leftTypes , $ rightTypes ),
810- $ this ->processBooleanSureConditionalTypes ($ scope , $ rightTypes , $ leftTypes ),
808+ $ this ->processBooleanNotSureConditionalTypes ($ scope , $ leftTypes , $ rightTypes, $ rightScope ),
809+ $ this ->processBooleanNotSureConditionalTypes ($ scope , $ rightTypes , $ leftTypes, $ scope ),
810+ $ this ->processBooleanSureConditionalTypes ($ scope , $ leftTypes , $ rightTypes, $ rightScope ),
811+ $ this ->processBooleanSureConditionalTypes ($ scope , $ rightTypes , $ leftTypes, $ scope ),
811812 ))->setRootExpr ($ expr );
812813 }
813814
@@ -2079,14 +2080,11 @@ private function augmentBooleanOrTruthyWithConditionalHolders(MutatingScope $sco
20792080 /**
20802081 * @return array<string, ConditionalExpressionHolder[]>
20812082 */
2082- private function processBooleanSureConditionalTypes (Scope $ scope , SpecifiedTypes $ leftTypes , SpecifiedTypes $ rightTypes ): array
2083+ private function processBooleanSureConditionalTypes (Scope $ scope , SpecifiedTypes $ leftTypes , SpecifiedTypes $ rightTypes, Scope $ rightScope ): array
20832084 {
20842085 $ conditionExpressionTypes = [];
20852086 foreach ($ leftTypes ->getSureTypes () as $ exprString => [$ expr , $ type ]) {
2086- if (!$ expr instanceof Expr \Variable) {
2087- continue ;
2088- }
2089- if (!is_string ($ expr ->name )) {
2087+ if (!$ this ->isTrackableExpression ($ expr )) {
20902088 continue ;
20912089 }
20922090
@@ -2105,10 +2103,7 @@ private function processBooleanSureConditionalTypes(Scope $scope, SpecifiedTypes
21052103 if (count ($ conditionExpressionTypes ) > 0 ) {
21062104 $ holders = [];
21072105 foreach ($ rightTypes ->getSureTypes () as $ exprString => [$ expr , $ type ]) {
2108- if (!$ expr instanceof Expr \Variable) {
2109- continue ;
2110- }
2111- if (!is_string ($ expr ->name )) {
2106+ if (!$ this ->isTrackableExpression ($ expr )) {
21122107 continue ;
21132108 }
21142109
@@ -2117,28 +2112,21 @@ private function processBooleanSureConditionalTypes(Scope $scope, SpecifiedTypes
21172112 }
21182113
21192114 $ conditions = $ conditionExpressionTypes ;
2120- foreach ($ conditions as $ conditionExprString => $ conditionExprTypeHolder ) {
2121- $ conditionExpr = $ conditionExprTypeHolder ->getExpr ();
2122- if (!$ conditionExpr instanceof Expr \Variable) {
2123- continue ;
2124- }
2125- if (!is_string ($ conditionExpr ->name )) {
2115+ foreach (array_keys ($ conditions ) as $ conditionExprString ) {
2116+ if ($ conditionExprString !== $ exprString ) {
21262117 continue ;
21272118 }
2128- if ($ conditionExpr ->name !== $ expr ->name ) {
2129- continue ;
2130- }
2131-
21322119 unset($ conditions [$ conditionExprString ]);
21332120 }
21342121
21352122 if (count ($ conditions ) === 0 ) {
21362123 continue ;
21372124 }
21382125
2126+ $ targetScope = $ expr instanceof Expr \Variable ? $ scope : $ rightScope ;
21392127 $ holder = new ConditionalExpressionHolder (
21402128 $ conditions ,
2141- ExpressionTypeHolder::createYes ($ expr , TypeCombinator::intersect ($ scope ->getType ($ expr ), $ type )),
2129+ ExpressionTypeHolder::createYes ($ expr , TypeCombinator::intersect ($ targetScope ->getType ($ expr ), $ type )),
21422130 );
21432131 $ holders [$ exprString ][$ holder ->getKey ()] = $ holder ;
21442132 }
@@ -2149,6 +2137,17 @@ private function processBooleanSureConditionalTypes(Scope $scope, SpecifiedTypes
21492137 return [];
21502138 }
21512139
2140+ private function isTrackableExpression (Expr $ expr ): bool
2141+ {
2142+ if ($ expr instanceof Expr \Variable) {
2143+ return is_string ($ expr ->name );
2144+ }
2145+
2146+ return $ expr instanceof Expr \PropertyFetch
2147+ || $ expr instanceof Expr \ArrayDimFetch
2148+ || $ expr instanceof Expr \StaticPropertyFetch;
2149+ }
2150+
21522151 /**
21532152 * Flatten a deep BooleanOr chain into leaf expressions and process them
21542153 * without recursive filterByFalseyValue calls. This reduces O(n^2) to O(n)
@@ -2279,14 +2278,11 @@ private function specifyTypesForFlattenedBooleanAnd(
22792278 /**
22802279 * @return array<string, ConditionalExpressionHolder[]>
22812280 */
2282- private function processBooleanNotSureConditionalTypes (Scope $ scope , SpecifiedTypes $ leftTypes , SpecifiedTypes $ rightTypes ): array
2281+ private function processBooleanNotSureConditionalTypes (Scope $ scope , SpecifiedTypes $ leftTypes , SpecifiedTypes $ rightTypes, Scope $ rightScope ): array
22832282 {
22842283 $ conditionExpressionTypes = [];
22852284 foreach ($ leftTypes ->getSureNotTypes () as $ exprString => [$ expr , $ type ]) {
2286- if (!$ expr instanceof Expr \Variable) {
2287- continue ;
2288- }
2289- if (!is_string ($ expr ->name )) {
2285+ if (!$ this ->isTrackableExpression ($ expr )) {
22902286 continue ;
22912287 }
22922288
@@ -2299,10 +2295,7 @@ private function processBooleanNotSureConditionalTypes(Scope $scope, SpecifiedTy
22992295 if (count ($ conditionExpressionTypes ) > 0 ) {
23002296 $ holders = [];
23012297 foreach ($ rightTypes ->getSureNotTypes () as $ exprString => [$ expr , $ type ]) {
2302- if (!$ expr instanceof Expr \Variable) {
2303- continue ;
2304- }
2305- if (!is_string ($ expr ->name )) {
2298+ if (!$ this ->isTrackableExpression ($ expr )) {
23062299 continue ;
23072300 }
23082301
@@ -2311,28 +2304,21 @@ private function processBooleanNotSureConditionalTypes(Scope $scope, SpecifiedTy
23112304 }
23122305
23132306 $ conditions = $ conditionExpressionTypes ;
2314- foreach ($ conditions as $ conditionExprString => $ conditionExprTypeHolder ) {
2315- $ conditionExpr = $ conditionExprTypeHolder ->getExpr ();
2316- if (!$ conditionExpr instanceof Expr \Variable) {
2307+ foreach (array_keys ($ conditions ) as $ conditionExprString ) {
2308+ if ($ conditionExprString !== $ exprString ) {
23172309 continue ;
23182310 }
2319- if (!is_string ($ conditionExpr ->name )) {
2320- continue ;
2321- }
2322- if ($ conditionExpr ->name !== $ expr ->name ) {
2323- continue ;
2324- }
2325-
23262311 unset($ conditions [$ conditionExprString ]);
23272312 }
23282313
23292314 if (count ($ conditions ) === 0 ) {
23302315 continue ;
23312316 }
23322317
2318+ $ targetScope = $ expr instanceof Expr \Variable ? $ scope : $ rightScope ;
23332319 $ holder = new ConditionalExpressionHolder (
23342320 $ conditions ,
2335- ExpressionTypeHolder::createYes ($ expr , TypeCombinator::remove ($ scope ->getType ($ expr ), $ type )),
2321+ ExpressionTypeHolder::createYes ($ expr , TypeCombinator::remove ($ targetScope ->getType ($ expr ), $ type )),
23362322 );
23372323 $ holders [$ exprString ][$ holder ->getKey ()] = $ holder ;
23382324 }
0 commit comments