Skip to content

Commit 2778efa

Browse files
committed
Fixed infinite recursion
1 parent 2b3ce26 commit 2778efa

1 file changed

Lines changed: 50 additions & 21 deletions

File tree

packages/lint/src/lib/property-checker.ts

Lines changed: 50 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -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";
1515
import type {
1616
AssignmentPattern,
1717
BlockStatement,
@@ -234,28 +234,57 @@ const collectReturnPaths = (
234234
);
235235

236236
function* 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

Comments
 (0)