mirror of
https://github.com/morluto/rea.git
synced 2026-10-28 10:25:42 +00:00
fix(javascript): bound static getter reference expansion
Replace recursive getter histories with a query-owned worklist and memo. Bound precise expansion at 512 states and widen growing receiver cycles; retain escaped roots and constructed children rather than silently dropping suffixes. Carry the resource limit through semantic coverage, worker transport and graph Evidence while preserving direct writes, imports and unrelated literal facts. The small source probe reduced 65/326 paths to one widened reference for five and six getters. The original large Claude artifact was not rerun. Validate receiver/alias/mutation controls and compiled CLI/MCP consumers. Refs #3839, #3848 Co-authored-by: Yi Han <yhan606@aucklanduni.ac.nz>
This commit is contained in:
1 parent
461eb16128
commit
880b3a510b
17 files changed
+1308
-524
No files matched your search
+65
@@ -7,6 +7,13 @@ import { describe, expect, it } from "vitest";
|
||||
import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js";
|
||||
import { parseJavaScriptApplicationGraph } from "../../../../src/domain/javascript/javascriptApplicationGraph.js";
|
||||
import { compareJavaScriptApplicationVersions } from "../../../../src/domain/javascript/javascriptApplicationVersionComparison.js";
|
||||
import { semanticResourceLimitReason } from "../../../../src/domain/javascript/javascriptSemanticResourceLimits.js";
|
||||
import { getterExpansionSource } from "../../../fixtures/javascriptGetterExpansion.js";
|
||||
import { scanCanonicalArtifactInventory } from "../../../fixtures/artifactInventory.js";
|
||||
import { readJavaScriptArtifactFiles } from "../../../support/javascriptApplicationScope.js";
|
||||
import { createJavaScriptArtifactReader } from "../../../../src/artifacts/javascript/JavaScriptArtifactReader.js";
|
||||
import { analyzeJavaScriptArtifactFiles } from "../../../../src/application/javascript/JavaScriptArtifactAnalysis.js";
|
||||
import { buildJavaScriptArtifactGraph } from "../../../../src/application/javascript/JavaScriptArtifactGraphBuilder.js";
|
||||
|
||||
import {
|
||||
findExportNode,
|
||||
@@ -16,6 +23,64 @@ import {
|
||||
writeFixtureFiles,
|
||||
} from "../../../support/javascriptApplicationFixture.js";
|
||||
|
||||
const relationshipGraph = async (root: string) => {
|
||||
const snapshot = await scanCanonicalArtifactInventory(root, {});
|
||||
const reader = createJavaScriptArtifactReader(root, "directory");
|
||||
try {
|
||||
const files = await readJavaScriptArtifactFiles(reader, snapshot);
|
||||
return buildJavaScriptArtifactGraph(
|
||||
snapshot,
|
||||
files,
|
||||
analyzeJavaScriptArtifactFiles(files),
|
||||
);
|
||||
} finally {
|
||||
await reader.close();
|
||||
}
|
||||
};
|
||||
|
||||
it.each([
|
||||
["getter-expansion", getterExpansionSource()],
|
||||
[
|
||||
"primitive-candidates",
|
||||
`const result = ${Array.from({ length: 20 }, () => '(true ? "a" : "b")').join(" + ")};`,
|
||||
],
|
||||
] as const)(
|
||||
"deduplicates %s limitations on import and export relationships",
|
||||
async (limit, source) => {
|
||||
const root = await createTestTempDirectory("rea-module-limit-evidence-");
|
||||
await writeFixtureFiles(root, {
|
||||
"entry.js": `import imported from "./dep.js"; ${source} export { result };`,
|
||||
"dep.js": "export default 42;",
|
||||
});
|
||||
const graph = await relationshipGraph(root);
|
||||
const module = findSourceModule(graph, "entry.js");
|
||||
const relationships = graph.edges.filter(
|
||||
({ source_node_id, relation, properties }) =>
|
||||
source_node_id === module?.node_id &&
|
||||
(relation === "exposes" ||
|
||||
(relation === "imports" && properties.module_link_kind === "import")),
|
||||
);
|
||||
expect(relationships.map(({ relation }) => relation).sort()).toEqual([
|
||||
"exposes",
|
||||
"imports",
|
||||
]);
|
||||
for (const { evidence } of relationships) {
|
||||
expect(
|
||||
evidence.limitations.filter(
|
||||
(reason) => reason === semanticResourceLimitReason(limit),
|
||||
),
|
||||
).toEqual([semanticResourceLimitReason(limit)]);
|
||||
expect(evidence.coverage.status).toBe("partial");
|
||||
expect(evidence.limitations).toContain(
|
||||
"Static syntax does not prove that this relationship executes at runtime.",
|
||||
);
|
||||
expect(evidence.limitations).toContain(
|
||||
"Values and aliases were recovered from inert syntax only; no JavaScript was executed.",
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
describe("cross-version source module identity", () => {
|
||||
it("keeps a source module unchanged when only a sibling file changes", async () => {
|
||||
const root = await createTestTempDirectory("rea-source-module-sibling-");
|
||||
|
||||
Reference in new issue
Block a user