@@ -97,7 +97,14 @@ public function supports(Expr $expr): bool
9797 return $ expr instanceof Assign || $ expr instanceof Expr \AssignRef;
9898 }
9999
100- public function analyseExpr (Stmt $ stmt , Expr $ expr , GeneratorScope $ scope , ExprAnalysisResultStorage $ storage , ExpressionContext $ context ): Generator
100+ public function analyseExpr (
101+ Stmt $ stmt ,
102+ Expr $ expr ,
103+ GeneratorScope $ scope ,
104+ ExprAnalysisResultStorage $ storage ,
105+ ExpressionContext $ context ,
106+ ?callable $ alternativeNodeCallback ,
107+ ): Generator
101108 {
102109 $ gen = $ this ->processAssignVar (
103110 $ scope ,
@@ -106,7 +113,8 @@ public function analyseExpr(Stmt $stmt, Expr $expr, GeneratorScope $scope, ExprA
106113 $ expr ->expr ,
107114 $ storage ,
108115 $ context ,
109- static function (GeneratorScope $ scope ) use ($ stmt , $ expr , $ context ): Generator {
116+ $ alternativeNodeCallback ,
117+ static function (GeneratorScope $ scope ) use ($ stmt , $ expr , $ context , $ alternativeNodeCallback ): Generator {
110118 $ impurePoints = [];
111119 if ($ expr instanceof AssignRef) {
112120 $ referencedExpr = $ expr ->expr ;
@@ -134,7 +142,7 @@ static function (GeneratorScope $scope) use ($stmt, $expr, $context): Generator
134142 );
135143 }
136144
137- $ result = yield new ExprAnalysisRequest ($ stmt , $ expr ->expr , $ scope , $ context ->enterDeep ());
145+ $ result = yield new ExprAnalysisRequest ($ stmt , $ expr ->expr , $ scope , $ context ->enterDeep (), $ alternativeNodeCallback );
138146 $ scope = $ result ->scope ;
139147
140148 if ($ expr instanceof AssignRef) {
@@ -360,6 +368,7 @@ private function processStmtVarAnnotation(GeneratorScope $scope, Node\Stmt $stmt
360368 }
361369
362370 /**
371+ * @param (callable(Node, Scope, callable(Node, Scope): void): void)|null $alternativeNodeCallback
363372 * @param Closure(GeneratorScope $scope): Generator<int, ExprAnalysisRequest|NodeCallbackRequest|TypeExprRequest, ExprAnalysisResult|TypeExprResult, ExprAnalysisResult> $processExprCallback
364373 * @return Generator<int, ExprAnalysisRequest|NodeCallbackRequest|TypeExprRequest, ExprAnalysisResult|TypeExprResult, ExprAnalysisResult>
365374 */
@@ -370,6 +379,7 @@ private function processAssignVar(
370379 Expr $ assignedExpr ,
371380 ExprAnalysisResultStorage $ storage ,
372381 ExpressionContext $ context ,
382+ ?callable $ alternativeNodeCallback ,
373383 Closure $ processExprCallback ,
374384 bool $ enterExpressionAssign ,
375385 ): Generator
@@ -394,13 +404,13 @@ private function processAssignVar(
394404 if ($ if === null ) {
395405 $ if = $ assignedExpr ->cond ;
396406 }
397- $ truthyResult = yield new ExprAnalysisRequest ($ stmt , $ if , $ scope , $ context ->enterDeep ());
407+ $ truthyResult = yield new ExprAnalysisRequest ($ stmt , $ if , $ scope , $ context ->enterDeep (), $ alternativeNodeCallback );
398408 if ($ assignedExpr ->if === null ) {
399409 $ condResult = $ truthyResult ;
400410 } else {
401- $ condResult = yield new ExprAnalysisRequest ($ stmt , $ assignedExpr ->cond , $ scope , $ context ->enterDeep ());
411+ $ condResult = yield new ExprAnalysisRequest ($ stmt , $ assignedExpr ->cond , $ scope , $ context ->enterDeep (), $ alternativeNodeCallback );
402412 }
403- $ falseyResult = yield new ExprAnalysisRequest ($ stmt , $ assignedExpr ->else , $ scope , $ context ->enterDeep ());
413+ $ falseyResult = yield new ExprAnalysisRequest ($ stmt , $ assignedExpr ->else , $ scope , $ context ->enterDeep (), $ alternativeNodeCallback );
404414
405415 if (
406416 $ truthyResult ->type ->isSuperTypeOf ($ falseyResult ->type )->no ()
@@ -479,7 +489,7 @@ private function processAssignVar(
479489 if ($ enterExpressionAssign ) {
480490 $ scope = $ scope ->enterExpressionAssign ($ var );
481491 }
482- $ varResult = yield new ExprAnalysisRequest ($ stmt , $ var , $ scope , $ context ->enterDeep ());
492+ $ varResult = yield new ExprAnalysisRequest ($ stmt , $ var , $ scope , $ context ->enterDeep (), $ alternativeNodeCallback );
483493 $ hasYield = $ varResult ->hasYield ;
484494 $ throwPoints = $ varResult ->throwPoints ;
485495 $ impurePoints = $ varResult ->impurePoints ;
@@ -507,7 +517,7 @@ private function processAssignVar(
507517 $ offsetNativeTypes [] = [null , $ dimFetch ];
508518
509519 } else {
510- $ dimExprResult = yield new ExprAnalysisRequest ($ stmt , $ dimExpr , $ scope , $ context ->enterDeep ());
520+ $ dimExprResult = yield new ExprAnalysisRequest ($ stmt , $ dimExpr , $ scope , $ context ->enterDeep (), $ alternativeNodeCallback );
511521 $ offsetTypes [] = [$ dimExprResult ->type , $ dimFetch ];
512522 $ offsetNativeTypes [] = [$ dimExprResult ->nativeType , $ dimFetch ];
513523
@@ -653,7 +663,7 @@ static function (): void {
653663 specifiedFalseyTypes: new SpecifiedTypes (),
654664 );
655665 } elseif ($ var instanceof PropertyFetch) {
656- $ objectResult = yield new ExprAnalysisRequest ($ stmt , $ var ->var , $ scope , $ context );
666+ $ objectResult = yield new ExprAnalysisRequest ($ stmt , $ var ->var , $ scope , $ context, $ alternativeNodeCallback );
657667 $ hasYield = $ objectResult ->hasYield ;
658668 $ throwPoints = $ objectResult ->throwPoints ;
659669 $ impurePoints = $ objectResult ->impurePoints ;
@@ -664,7 +674,7 @@ static function (): void {
664674 if ($ var ->name instanceof Node \Identifier) {
665675 $ propertyName = $ var ->name ->name ;
666676 } else {
667- $ propertyNameResult = yield new ExprAnalysisRequest ($ stmt , $ var ->name , $ scope , $ context );
677+ $ propertyNameResult = yield new ExprAnalysisRequest ($ stmt , $ var ->name , $ scope , $ context, $ alternativeNodeCallback );
668678 $ hasYield = $ hasYield || $ propertyNameResult ->hasYield ;
669679 $ throwPoints = array_merge ($ throwPoints , $ propertyNameResult ->throwPoints );
670680 $ impurePoints = array_merge ($ impurePoints , $ propertyNameResult ->impurePoints );
@@ -775,7 +785,7 @@ static function (): void {
775785 if ($ var ->class instanceof Node \Name) {
776786 $ propertyHolderType = $ scope ->resolveTypeByName ($ var ->class );
777787 } else {
778- $ varClassResult = yield new ExprAnalysisRequest ($ stmt , $ var ->class , $ scope , $ context );
788+ $ varClassResult = yield new ExprAnalysisRequest ($ stmt , $ var ->class , $ scope , $ context, $ alternativeNodeCallback );
779789 $ propertyHolderType = $ varClassResult ->type ;
780790 }
781791
@@ -788,7 +798,7 @@ static function (): void {
788798 if ($ var ->name instanceof Node \Identifier) {
789799 $ propertyName = $ var ->name ->name ;
790800 } else {
791- $ propertyNameResult = yield new ExprAnalysisRequest ($ stmt , $ var ->name , $ scope , $ context );
801+ $ propertyNameResult = yield new ExprAnalysisRequest ($ stmt , $ var ->name , $ scope , $ context, $ alternativeNodeCallback );
792802 $ hasYield = $ propertyNameResult ->hasYield ;
793803 $ throwPoints = $ propertyNameResult ->throwPoints ;
794804 $ impurePoints = $ propertyNameResult ->impurePoints ;
@@ -884,15 +894,15 @@ static function (): void {
884894 $ itemScope = $ this ->lookForSetAllowedUndefinedExpressions ($ itemScope , $ arrayItem ->value );
885895 yield new NodeCallbackRequest ($ arrayItem , $ itemScope );
886896 if ($ arrayItem ->key !== null ) {
887- $ keyResult = yield new ExprAnalysisRequest ($ stmt , $ arrayItem ->key , $ itemScope , $ context ->enterDeep ());
897+ $ keyResult = yield new ExprAnalysisRequest ($ stmt , $ arrayItem ->key , $ itemScope , $ context ->enterDeep (), $ alternativeNodeCallback );
888898 $ hasYield = $ hasYield || $ keyResult ->hasYield ;
889899 $ throwPoints = array_merge ($ throwPoints , $ keyResult ->throwPoints );
890900 $ impurePoints = array_merge ($ impurePoints , $ keyResult ->impurePoints );
891901 $ isAlwaysTerminating = $ isAlwaysTerminating || $ keyResult ->isAlwaysTerminating ;
892902 $ itemScope = $ keyResult ->scope ;
893903 }
894904
895- $ valueResult = yield new ExprAnalysisRequest ($ stmt , $ arrayItem ->value , $ itemScope , $ context ->enterDeep ());
905+ $ valueResult = yield new ExprAnalysisRequest ($ stmt , $ arrayItem ->value , $ itemScope , $ context ->enterDeep (), $ alternativeNodeCallback );
896906 $ hasYield = $ hasYield || $ valueResult ->hasYield ;
897907 $ throwPoints = array_merge ($ throwPoints , $ valueResult ->throwPoints );
898908 $ impurePoints = array_merge ($ impurePoints , $ valueResult ->impurePoints );
@@ -910,6 +920,7 @@ static function (): void {
910920 new GetOffsetValueTypeExpr ($ assignedExpr , $ dimExpr ),
911921 $ storage ,
912922 $ context ,
923+ $ alternativeNodeCallback ,
913924 static function (GeneratorScope $ scope ): Generator {
914925 yield from [];
915926 return new ExprAnalysisResult (
@@ -964,7 +975,8 @@ static function (GeneratorScope $scope): Generator {
964975 }
965976
966977 // 1. eval root expr
967- $ varResult = yield new ExprAnalysisRequest ($ stmt , $ var , $ scope , $ context ->enterDeep ());
978+ $ varResult = yield new ExprAnalysisRequest ($ stmt , $ var , $ scope , $ context ->enterDeep (), static function () {
979+ }); // todo Noop...
968980 $ hasYield = $ varResult ->hasYield ;
969981 $ throwPoints = $ varResult ->throwPoints ;
970982 $ impurePoints = $ varResult ->impurePoints ;
0 commit comments