@@ -155,6 +155,8 @@ class MutatingScope implements Scope
155
155
156
156
private bool $ treatPhpDocTypesAsCertain ;
157
157
158
+ private bool $ afterExtractCall ;
159
+
158
160
private ?Scope $ parentScope ;
159
161
160
162
/**
@@ -181,6 +183,7 @@ class MutatingScope implements Scope
181
183
* @param array<MethodReflection|FunctionReflection> $inFunctionCallsStack
182
184
* @param string[] $dynamicConstantNames
183
185
* @param bool $treatPhpDocTypesAsCertain
186
+ * @param bool $afterExtractCall
184
187
* @param Scope|null $parentScope
185
188
*/
186
189
public function __construct (
@@ -207,6 +210,7 @@ public function __construct(
207
210
array $ inFunctionCallsStack = [],
208
211
array $ dynamicConstantNames = [],
209
212
bool $ treatPhpDocTypesAsCertain = true ,
213
+ bool $ afterExtractCall = false ,
210
214
?Scope $ parentScope = null
211
215
)
212
216
{
@@ -237,6 +241,7 @@ public function __construct(
237
241
$ this ->inFunctionCallsStack = $ inFunctionCallsStack ;
238
242
$ this ->dynamicConstantNames = $ dynamicConstantNames ;
239
243
$ this ->treatPhpDocTypesAsCertain = $ treatPhpDocTypesAsCertain ;
244
+ $ this ->afterExtractCall = $ afterExtractCall ;
240
245
$ this ->parentScope = $ parentScope ;
241
246
}
242
247
@@ -335,9 +340,30 @@ private function getVariableTypes(): array
335
340
return $ this ->variableTypes ;
336
341
}
337
342
338
- private function isRootScope (): bool
343
+ private function canAnyVariableExist (): bool
344
+ {
345
+ return ($ this ->function === null && !$ this ->isInAnonymousFunction ()) || $ this ->afterExtractCall ;
346
+ }
347
+
348
+ public function afterExtractCall (): self
339
349
{
340
- return $ this ->function === null && !$ this ->isInAnonymousFunction ();
350
+ return $ this ->scopeFactory ->create (
351
+ $ this ->context ,
352
+ $ this ->isDeclareStrictTypes (),
353
+ $ this ->constantTypes ,
354
+ $ this ->getFunction (),
355
+ $ this ->getNamespace (),
356
+ $ this ->getVariableTypes (),
357
+ $ this ->moreSpecificTypes ,
358
+ $ this ->inClosureBindScopeClass ,
359
+ $ this ->anonymousFunctionReflection ,
360
+ $ this ->isInFirstLevelStatement (),
361
+ $ this ->currentlyAssignedExpressions ,
362
+ $ this ->nativeExpressionTypes ,
363
+ $ this ->inFunctionCallsStack ,
364
+ true ,
365
+ $ this ->parentScope
366
+ );
341
367
}
342
368
343
369
public function hasVariableType (string $ variableName ): TrinaryLogic
@@ -347,7 +373,7 @@ public function hasVariableType(string $variableName): TrinaryLogic
347
373
}
348
374
349
375
if (!isset ($ this ->variableTypes [$ variableName ])) {
350
- if ($ this ->isRootScope ()) {
376
+ if ($ this ->canAnyVariableExist ()) {
351
377
return TrinaryLogic::createMaybe ();
352
378
}
353
379
@@ -1957,6 +1983,7 @@ public function doNotTreatPhpDocTypesAsCertain(): Scope
1957
1983
$ this ->inFunctionCallsStack ,
1958
1984
$ this ->dynamicConstantNames ,
1959
1985
false ,
1986
+ $ this ->afterExtractCall ,
1960
1987
$ this ->parentScope
1961
1988
);
1962
1989
}
@@ -2213,6 +2240,7 @@ public function pushInFunctionCall($reflection): self
2213
2240
$ this ->currentlyAssignedExpressions ,
2214
2241
$ this ->nativeExpressionTypes ,
2215
2242
$ stack ,
2243
+ $ this ->afterExtractCall ,
2216
2244
$ this ->parentScope
2217
2245
);
2218
2246
}
@@ -2236,6 +2264,7 @@ public function popInFunctionCall(): self
2236
2264
$ this ->currentlyAssignedExpressions ,
2237
2265
$ this ->nativeExpressionTypes ,
2238
2266
$ stack ,
2267
+ $ this ->afterExtractCall ,
2239
2268
$ this ->parentScope
2240
2269
);
2241
2270
}
@@ -2622,6 +2651,7 @@ public function enterAnonymousFunction(
2622
2651
[],
2623
2652
$ nativeTypes ,
2624
2653
[],
2654
+ false ,
2625
2655
$ this
2626
2656
);
2627
2657
}
@@ -2668,6 +2698,7 @@ public function enterArrowFunction(Expr\ArrowFunction $arrowFunction): self
2668
2698
[],
2669
2699
[],
2670
2700
[],
2701
+ $ this ->afterExtractCall ,
2671
2702
$ this ->parentScope
2672
2703
);
2673
2704
}
@@ -2782,6 +2813,7 @@ public function enterExpressionAssign(Expr $expr): self
2782
2813
$ currentlyAssignedExpressions ,
2783
2814
$ this ->nativeExpressionTypes ,
2784
2815
[],
2816
+ $ this ->afterExtractCall ,
2785
2817
$ this ->parentScope
2786
2818
);
2787
2819
}
@@ -2806,6 +2838,7 @@ public function exitExpressionAssign(Expr $expr): self
2806
2838
$ currentlyAssignedExpressions ,
2807
2839
$ this ->nativeExpressionTypes ,
2808
2840
[],
2841
+ $ this ->afterExtractCall ,
2809
2842
$ this ->parentScope
2810
2843
);
2811
2844
}
@@ -2861,6 +2894,7 @@ public function assignVariable(string $variableName, Type $type, ?TrinaryLogic $
2861
2894
$ this ->currentlyAssignedExpressions ,
2862
2895
$ nativeTypes ,
2863
2896
$ this ->inFunctionCallsStack ,
2897
+ $ this ->afterExtractCall ,
2864
2898
$ this ->parentScope
2865
2899
);
2866
2900
}
@@ -2890,6 +2924,7 @@ public function unsetExpression(Expr $expr): self
2890
2924
[],
2891
2925
$ nativeTypes ,
2892
2926
[],
2927
+ $ this ->afterExtractCall ,
2893
2928
$ this ->parentScope
2894
2929
);
2895
2930
} elseif ($ expr instanceof Expr \ArrayDimFetch && $ expr ->dim !== null ) {
@@ -2948,6 +2983,7 @@ public function specifyExpressionType(Expr $expr, Type $type): self
2948
2983
$ this ->currentlyAssignedExpressions ,
2949
2984
$ this ->nativeExpressionTypes ,
2950
2985
$ this ->inFunctionCallsStack ,
2986
+ $ this ->afterExtractCall ,
2951
2987
$ this ->parentScope
2952
2988
);
2953
2989
}
@@ -2979,6 +3015,7 @@ public function specifyExpressionType(Expr $expr, Type $type): self
2979
3015
$ this ->currentlyAssignedExpressions ,
2980
3016
$ nativeTypes ,
2981
3017
$ this ->inFunctionCallsStack ,
3018
+ $ this ->afterExtractCall ,
2982
3019
$ this ->parentScope
2983
3020
);
2984
3021
} elseif ($ expr instanceof Expr \ArrayDimFetch && $ expr ->dim !== null ) {
@@ -3055,6 +3092,7 @@ public function invalidateExpression(Expr $expressionToInvalidate, bool $require
3055
3092
$ this ->currentlyAssignedExpressions ,
3056
3093
[],
3057
3094
[],
3095
+ $ this ->afterExtractCall ,
3058
3096
$ this ->parentScope
3059
3097
);
3060
3098
}
@@ -3167,6 +3205,7 @@ public function exitFirstLevelStatements(): self
3167
3205
$ this ->currentlyAssignedExpressions ,
3168
3206
$ this ->nativeExpressionTypes ,
3169
3207
$ this ->inFunctionCallsStack ,
3208
+ $ this ->afterExtractCall ,
3170
3209
$ this ->parentScope
3171
3210
);
3172
3211
}
@@ -3202,6 +3241,7 @@ private function addMoreSpecificTypes(array $types): self
3202
3241
$ this ->currentlyAssignedExpressions ,
3203
3242
$ this ->nativeExpressionTypes ,
3204
3243
[],
3244
+ $ this ->afterExtractCall ,
3205
3245
$ this ->parentScope
3206
3246
);
3207
3247
}
@@ -3221,7 +3261,7 @@ public function mergeWith(?self $otherScope): self
3221
3261
3222
3262
$ ourVariableTypes = $ this ->getVariableTypes ();
3223
3263
$ theirVariableTypes = $ otherScope ->getVariableTypes ();
3224
- if ($ this ->isRootScope ()) {
3264
+ if ($ this ->canAnyVariableExist ()) {
3225
3265
foreach (array_keys ($ theirVariableTypes ) as $ name ) {
3226
3266
if (array_key_exists ($ name , $ ourVariableTypes )) {
3227
3267
continue ;
@@ -3253,6 +3293,7 @@ public function mergeWith(?self $otherScope): self
3253
3293
return $ holder ->getCertainty ()->yes ();
3254
3294
})),
3255
3295
[],
3296
+ $ this ->afterExtractCall && $ otherScope ->afterExtractCall ,
3256
3297
$ this ->parentScope
3257
3298
);
3258
3299
}
@@ -3323,6 +3364,7 @@ public function processFinallyScope(self $finallyScope, self $originalFinallySco
3323
3364
array_map ($ typeToVariableHolder , $ originalFinallyScope ->nativeExpressionTypes )
3324
3365
)),
3325
3366
[],
3367
+ $ this ->afterExtractCall ,
3326
3368
$ this ->parentScope
3327
3369
);
3328
3370
}
@@ -3414,6 +3456,7 @@ public function processClosureScope(
3414
3456
[],
3415
3457
$ this ->nativeExpressionTypes ,
3416
3458
$ this ->inFunctionCallsStack ,
3459
+ $ this ->afterExtractCall ,
3417
3460
$ this ->parentScope
3418
3461
);
3419
3462
}
@@ -3462,6 +3505,7 @@ public function processAlwaysIterableForeachScopeWithoutPollute(self $finalScope
3462
3505
[],
3463
3506
$ nativeTypes ,
3464
3507
[],
3508
+ $ this ->afterExtractCall ,
3465
3509
$ this ->parentScope
3466
3510
);
3467
3511
}
@@ -3506,6 +3550,7 @@ public function generalizeWith(self $otherScope): self
3506
3550
[],
3507
3551
$ nativeTypes ,
3508
3552
[],
3553
+ $ this ->afterExtractCall ,
3509
3554
$ this ->parentScope
3510
3555
);
3511
3556
}
0 commit comments