66use PhpParser \Node \Expr ;
77use PhpParser \Node \Expr \MethodCall ;
88use PhpParser \Node \Identifier ;
9+ use PhpParser \Node \Stmt ;
10+ use PHPStan \Analyser \ExpressionContext ;
911use PHPStan \Analyser \Generator \ExprAnalysisRequest ;
1012use PHPStan \Analyser \Generator \ExprAnalysisResult ;
1113use PHPStan \Analyser \Generator \ExprHandler ;
1214use PHPStan \Analyser \Generator \GeneratorScope ;
1315use PHPStan \DependencyInjection \AutowiredService ;
1416use PHPStan \ShouldNotHappenException ;
17+ use function array_merge ;
1518
1619/**
1720 * @implements ExprHandler<MethodCall>
@@ -25,25 +28,40 @@ public function supports(Expr $expr): bool
2528 return $ expr instanceof MethodCall;
2629 }
2730
28- public function analyseExpr (Expr $ expr , GeneratorScope $ scope ): Generator
31+ public function analyseExpr (Stmt $ stmt , Expr $ expr , GeneratorScope $ scope, ExpressionContext $ context ): Generator
2932 {
3033 if (!$ expr ->name instanceof Identifier) {
3134 throw new ShouldNotHappenException ('Not implemented ' );
3235 }
3336
34- $ varResult = yield new ExprAnalysisRequest ($ expr ->var , $ scope );
35- $ currentScope = $ varResult ->scope ;
37+ $ varResult = yield new ExprAnalysisRequest ($ stmt , $ expr ->var , $ scope , $ context ->enterDeep ());
38+ $ throwPoints = $ varResult ->throwPoints ;
39+ $ impurePoints = $ varResult ->impurePoints ;
40+ $ isAlwaysTerminating = $ varResult ->isAlwaysTerminating ;
41+ $ hasYield = $ varResult ->hasYield ;
42+ $ scope = $ varResult ->scope ;
3643 $ argTypes = [];
3744
3845 foreach ($ expr ->getArgs () as $ arg ) {
39- $ argResult = yield new ExprAnalysisRequest ($ arg ->value , $ currentScope );
46+ $ argResult = yield new ExprAnalysisRequest ($ stmt , $ arg ->value , $ scope , $ context -> enterDeep () );
4047 $ argTypes [] = $ argResult ->type ;
41- $ currentScope = $ argResult ->scope ;
48+ $ scope = $ argResult ->scope ;
49+ $ throwPoints = array_merge ($ throwPoints , $ argResult ->throwPoints );
50+ $ impurePoints = array_merge ($ impurePoints , $ argResult ->impurePoints );
51+ $ isAlwaysTerminating = $ isAlwaysTerminating || $ argResult ->isAlwaysTerminating ;
52+ $ hasYield = $ hasYield || $ argResult ->hasYield ;
4253 }
4354
4455 if ($ varResult ->type ->hasMethod ($ expr ->name ->toString ())->yes ()) {
4556 $ method = $ varResult ->type ->getMethod ($ expr ->name ->toString (), $ scope );
46- return new ExprAnalysisResult ($ method ->getOnlyVariant ()->getReturnType (), $ scope );
57+ return new ExprAnalysisResult (
58+ $ method ->getOnlyVariant ()->getReturnType (),
59+ $ scope ,
60+ hasYield: $ hasYield ,
61+ isAlwaysTerminating: $ isAlwaysTerminating ,
62+ throwPoints: $ throwPoints ,
63+ impurePoints: $ impurePoints ,
64+ );
4765 }
4866
4967 throw new ShouldNotHappenException ('Not implemented ' );
0 commit comments