@@ -11,7 +11,7 @@ import {
1111 unless ,
1212 when ,
1313} from "@fxts/core" ;
14- import { allOf , isNode , isNodeType } from "./pred.ts" ;
14+ import { allOf , isNodeType } from "./pred.ts" ;
1515import type {
1616 AssignmentPattern ,
1717 BlockStatement ,
@@ -234,28 +234,57 @@ const collectReturnPaths = (
234234 ) ;
235235
236236function * flatten ( node : Node ) : Generator < ReturnStatement > {
237- if ( isNodeType ( "ReturnStatement" ) ( node ) ) yield node ;
237+ switch ( node . type ) {
238+ case "ReturnStatement" :
239+ yield node ;
240+ return ;
238241
239- if ( isNodeType ( "IfStatement" ) ( node ) ) {
240- // Collect returns from both branches
241- if ( node . consequent ) yield * flatten ( node . consequent ) ;
242- if ( node . alternate ) yield * flatten ( node . alternate ) ;
243- }
242+ case "IfStatement" :
243+ // Collect returns from both branches
244+ if ( node . consequent ) yield * flatten ( node . consequent ) ;
245+ if ( node . alternate ) yield * flatten ( node . alternate ) ;
246+ return ;
244247
245- if ( isNodeType ( "BlockStatement" ) ( node ) ) {
246- yield * node . body . map ( flatten ) . flatMap ( toArrayIfIter ) ;
247- }
248+ case "BlockStatement" :
249+ for ( const statement of node . body ) {
250+ yield * flatten ( statement ) ;
251+ }
252+ return ;
248253
249- for ( const child of Object . values ( node ) ) {
250- if ( isNode ( child ) ) {
251- yield * flatten ( child ) ;
252- } else if ( Array . isArray ( child ) ) {
253- yield * child . filter ( isNode ) . map ( flatten ) . flatMap ( toArrayIfIter ) ;
254- }
254+ case "SwitchStatement" :
255+ for ( const switchCase of node . cases ) {
256+ for ( const statement of switchCase . consequent ) {
257+ yield * flatten ( statement ) ;
258+ }
259+ }
260+ return ;
261+
262+ case "TryStatement" :
263+ yield * flatten ( node . block ) ;
264+ if ( node . handler ) yield * flatten ( node . handler . body ) ;
265+ if ( node . finalizer ) yield * flatten ( node . finalizer ) ;
266+ return ;
267+
268+ case "WhileStatement" :
269+ case "DoWhileStatement" :
270+ case "ForStatement" :
271+ case "ForInStatement" :
272+ case "ForOfStatement" :
273+ yield * flatten ( node . body ) ;
274+ return ;
275+
276+ case "LabeledStatement" :
277+ yield * flatten ( node . body ) ;
278+ return ;
279+
280+ case "WithStatement" :
281+ yield * flatten ( node . body ) ;
282+ return ;
283+
284+ default :
285+ // For other node types (expressions, declarations, etc.),
286+ // we don't traverse deeper to avoid infinite recursion
287+ // from circular references like `parent`
288+ return ;
255289 }
256290}
257-
258- const toArrayIfIter = < T > ( input : T | Iterable < T > ) : T [ ] =>
259- Symbol . iterator in Object ( input )
260- ? toArray ( input as Iterable < T > )
261- : [ input as T ] ;
0 commit comments