Skip to content

Commit 21aaf30

Browse files
authored
refactor(scripts): walk the AST with estree-walker in arch-lint (#561)
1 parent fe77161 commit 21aaf30

1 file changed

Lines changed: 9 additions & 17 deletions

File tree

‎.github/scripts/arch-lint.ts‎

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
import { existsSync, readdirSync, readFileSync } from "node:fs";
1212
import { dirname, join, relative, resolve } from "node:path";
1313
import { inspect } from "node:util";
14+
import { type Node as ESTreeNode, walk } from "estree-walker";
1415
import { err, ok, Result } from "neverthrow";
15-
import { type Node, parseSync } from "oxc-parser";
16+
import { type Node, type Program, parseSync } from "oxc-parser";
1617
import { parseDocument } from "yaml";
1718
import { z } from "zod";
1819
import { countNoun, quote } from "../../src/text.js";
@@ -133,19 +134,10 @@ function layerOf(arch: Architecture, path: string): string | undefined {
133134
)?.[0];
134135
}
135136

136-
function* nodesOf(value: unknown): Generator<Node> {
137-
if (Array.isArray(value)) {
138-
for (const item of value) {
139-
yield* nodesOf(item);
140-
}
141-
} else if (typeof value === "object" && value !== null) {
142-
if ("type" in value && typeof value.type === "string") {
143-
yield value as Node;
144-
}
145-
for (const child of Object.values(value)) {
146-
yield* nodesOf(child);
147-
}
148-
}
137+
/** `visit` on every node of `program`, preorder. estree-walker finds the children by the fields carrying a `type`,
138+
* so oxc's TypeScript nodes walk like the ESTree ones; only its signature is typed to ESTree, hence the casts. */
139+
function eachNode(program: Program, visit: (node: Node) => void): void {
140+
walk(program as unknown as ESTreeNode, { enter: (node) => visit(node as unknown as Node) });
149141
}
150142

151143
/** The expression under the wrappers parentheses and TypeScript add: `(require)(x)`, `require!(x)`,
@@ -222,9 +214,9 @@ export function importSpecifiers(text: string, file: string): string[] {
222214
);
223215
}
224216
const specifiers = new Set<string>();
225-
for (const node of nodesOf(program)) {
217+
eachNode(program, (node) => {
226218
if (!isModuleLoad(node)) {
227-
continue;
219+
return;
228220
}
229221
const specifier = literalModuleRequest(node);
230222
if (specifier === undefined) {
@@ -233,7 +225,7 @@ export function importSpecifiers(text: string, file: string): string[] {
233225
);
234226
}
235227
specifiers.add(specifier);
236-
}
228+
});
237229
return [...specifiers].filter((specifier) => /^\.\.?\//.test(specifier));
238230
}
239231

0 commit comments

Comments
 (0)