Files
reverse-engineering-anything/src/domain/javascript/javascriptSemanticTraversal.test.ts
T
morluto c7530f9a81 perf(javascript): reduce analysis and source-map work (#955)
* perf(javascript): reduce semantic traversal overhead

* perf(source-maps): reuse validated regular map rows
2026-10-07 20:33:35 +08:00

67 lines
2.1 KiB
TypeScript

import * as t from "@babel/types";
import { expect, it } from "vitest";
import { parseJavaScriptSource } from "./javascriptSourceParser.js";
import { traverseJavaScriptAst } from "./javascriptSemanticTraversal.js";
it("preserves source-tree enter/exit order and detached ancestor snapshots", () => {
const parsed = parseJavaScriptSource("const answer = first + second;");
if (parsed === null)
throw new TypeError("Expected a parsed JavaScript fixture");
const visits: string[] = [];
const snapshots: (readonly t.Node[])[] = [];
traverseJavaScriptAst(parsed.program, {
enter: (node, parent, readAncestors) => {
visits.push(`enter:${node.type}`);
const ancestors = readAncestors();
expect(ancestors.at(-1) ?? null).toBe(parent);
if (t.isIdentifier(node)) snapshots.push(ancestors);
},
exit: (node) => visits.push(`exit:${node.type}`),
});
expect(visits).toEqual([
"enter:Program",
"enter:VariableDeclaration",
"enter:VariableDeclarator",
"enter:Identifier",
"exit:Identifier",
"enter:BinaryExpression",
"enter:Identifier",
"exit:Identifier",
"enter:Identifier",
"exit:Identifier",
"exit:BinaryExpression",
"exit:VariableDeclarator",
"exit:VariableDeclaration",
"exit:Program",
]);
expect(snapshots.map((nodes) => nodes.map(({ type }) => type))).toEqual([
["Program", "VariableDeclaration", "VariableDeclarator"],
[
"Program",
"VariableDeclaration",
"VariableDeclarator",
"BinaryExpression",
],
[
"Program",
"VariableDeclaration",
"VariableDeclarator",
"BinaryExpression",
],
]);
});
it("skips sparse child slots without disturbing sibling visit order", () => {
const parsed = parseJavaScriptSource("const values = [first, , second];");
if (parsed === null)
throw new TypeError("Expected a parsed JavaScript fixture");
const identifiers: string[] = [];
traverseJavaScriptAst(parsed.program, {
enter: (node) => {
if (t.isIdentifier(node)) identifiers.push(node.name);
},
});
expect(identifiers).toEqual(["values", "first", "second"]);
});