@@ -106,7 +106,7 @@ private function processStmtNodes(
106106 {
107107 $ stack = [];
108108
109- $ gen = $ this ->analyseStmts ($ stmts , $ scope );
109+ $ gen = $ this ->analyseStmts ($ stmts , $ scope, null );
110110 $ gen ->current ();
111111
112112 // Trampoline loop
@@ -125,21 +125,35 @@ private function processStmtNodes(
125125 $ nodeCallback ,
126126 );
127127
128+ $ gen ->next ();
129+ continue ;
130+ } elseif ($ yielded instanceof AlternativeNodeCallbackRequest) {
131+ $ alternativeNodeCallback = $ yielded ->nodeCallback ;
132+ $ this ->invokeNodeCallback (
133+ $ fibersStorage ,
134+ $ exprAnalysisResultStorage ,
135+ $ yielded ->node ,
136+ $ yielded ->scope ,
137+ static function (Node $ node , Scope $ scope ) use ($ alternativeNodeCallback , $ nodeCallback ): void {
138+ $ alternativeNodeCallback ($ node , $ scope , $ nodeCallback );
139+ },
140+ );
141+
128142 $ gen ->next ();
129143 continue ;
130144 } elseif ($ yielded instanceof ExprAnalysisRequest) {
131145 $ stack [] = $ gen ;
132- $ gen = $ this ->analyseExpr ($ exprAnalysisResultStorage , $ yielded ->expr , $ yielded ->scope );
146+ $ gen = $ this ->analyseExpr ($ exprAnalysisResultStorage , $ yielded ->expr , $ yielded ->scope , $ yielded -> alternativeNodeCallback );
133147 $ gen ->current ();
134148 continue ;
135149 } elseif ($ yielded instanceof StmtAnalysisRequest) {
136150 $ stack [] = $ gen ;
137- $ gen = $ this ->analyseStmt ($ yielded ->stmt , $ yielded ->scope );
151+ $ gen = $ this ->analyseStmt ($ yielded ->stmt , $ yielded ->scope , $ yielded -> alternativeNodeCallback );
138152 $ gen ->current ();
139153 continue ;
140154 } elseif ($ yielded instanceof StmtsAnalysisRequest) {
141155 $ stack [] = $ gen ;
142- $ gen = $ this ->analyseStmts ($ yielded ->stmts , $ yielded ->scope );
156+ $ gen = $ this ->analyseStmts ($ yielded ->stmts , $ yielded ->scope , $ yielded -> alternativeNodeCallback );
143157 $ gen ->current ();
144158 continue ;
145159 } else { // phpcs:ignore
@@ -184,24 +198,31 @@ static function () {
184198
185199 /**
186200 * @param array<Stmt> $stmts
201+ * @param (callable(Node, Scope, callable(Node, Scope): void): void)|null $alternativeNodeCallback
202+ *
187203 * @return Generator<int, StmtAnalysisRequest, StmtAnalysisResult, StmtAnalysisResult>
188204 */
189- private function analyseStmts (array $ stmts , GeneratorScope $ scope ): Generator
205+ private function analyseStmts (array $ stmts , GeneratorScope $ scope, ? callable $ alternativeNodeCallback ): Generator
190206 {
191207 foreach ($ stmts as $ stmt ) {
192- $ result = yield new StmtAnalysisRequest ($ stmt , $ scope );
208+ $ result = yield new StmtAnalysisRequest ($ stmt , $ scope, $ alternativeNodeCallback );
193209 $ scope = $ result ->scope ;
194210 }
195211
196212 return new StmtAnalysisResult ($ scope );
197213 }
198214
199215 /**
200- * @return Generator<int, ExprAnalysisRequest|StmtAnalysisRequest|StmtsAnalysisRequest|NodeCallbackRequest, ExprAnalysisResult|StmtAnalysisResult, StmtAnalysisResult>
216+ * @param (callable(Node, Scope, callable(Node, Scope): void): void)|null $alternativeNodeCallback
217+ * @return Generator<int, ExprAnalysisRequest|StmtAnalysisRequest|StmtsAnalysisRequest|NodeCallbackRequest|AlternativeNodeCallbackRequest, ExprAnalysisResult|StmtAnalysisResult, StmtAnalysisResult>
201218 */
202- private function analyseStmt (Stmt $ stmt , GeneratorScope $ scope ): Generator
219+ private function analyseStmt (Stmt $ stmt , GeneratorScope $ scope, ? callable $ alternativeNodeCallback ): Generator
203220 {
204- yield new NodeCallbackRequest ($ stmt , $ scope );
221+ if ($ alternativeNodeCallback === null ) {
222+ yield new NodeCallbackRequest ($ stmt , $ scope );
223+ } else {
224+ yield new AlternativeNodeCallbackRequest ($ stmt , $ scope , $ alternativeNodeCallback );
225+ }
205226
206227 /**
207228 * @var StmtHandler<Stmt> $stmtHandler
@@ -221,11 +242,16 @@ private function analyseStmt(Stmt $stmt, GeneratorScope $scope): Generator
221242 }
222243
223244 /**
224- * @return Generator<int, ExprAnalysisRequest|NodeCallbackRequest, ExprAnalysisResult, ExprAnalysisResult>
245+ * @param (callable(Node, Scope, callable(Node, Scope): void): void)|null $alternativeNodeCallback
246+ * @return Generator<int, ExprAnalysisRequest|NodeCallbackRequest|AlternativeNodeCallbackRequest, ExprAnalysisResult, ExprAnalysisResult>
225247 */
226- private function analyseExpr (ExprAnalysisResultStorage $ storage , Expr $ expr , GeneratorScope $ scope ): Generator
248+ private function analyseExpr (ExprAnalysisResultStorage $ storage , Expr $ expr , GeneratorScope $ scope, ? callable $ alternativeNodeCallback ): Generator
227249 {
228- yield new NodeCallbackRequest ($ expr , $ scope );
250+ if ($ alternativeNodeCallback === null ) {
251+ yield new NodeCallbackRequest ($ expr , $ scope );
252+ } else {
253+ yield new AlternativeNodeCallbackRequest ($ expr , $ scope , $ alternativeNodeCallback );
254+ }
229255
230256 /**
231257 * @var ExprHandler<Expr> $exprHandler
0 commit comments