mirror of
https://github.com/morluto/rea
synced 2026-10-27 14:42:18 -04:00
fix(javascript): preserve path reasons, module coverage, and property provenance (#5651)
* fix(javascript): preserve selected path host resolution reasons Classify ELOOP and ENAMETOOLONG while resolving the caller-selected input so the path and host code stay on the invalid-request issue. Refs #5623 Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(javascript): count summary coverage in module units Use the module population for both examined and total counts. Non-module graph nodes remain in the application coverage section. Refs #5464 Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(javascript): connect direct property reads to return and argument flow Record the unwrapped value expression and alias the object projection's read occurrence so a direct member read stays in backward provenance. Refs #5585, #5648 Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(javascript): count return wrappers against expression depth Evaluate the original return expression so erased TypeScript and Flow wrappers stay inside the expression-depth budget. Keep the unwrapped node for identity and value ranges. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(javascript): describe ELOOP as unresolved symlink traversal A host can return ELOOP for a cycle or for a chain past its traversal limit. Keep the selected path and code without asserting that a cycle exists. Co-authored-by: morluto <morluto@users.noreply.github.com> * test(javascript): skip symlink traversal fixtures on Windows Keep the overlong-name case portable. Windows does not produce ELOOP for these fixtures, matching the other path-failure tests. Co-authored-by: morluto <morluto@users.noreply.github.com> * fix(javascript): describe ENAMETOOLONG as a path or component limit realpath reports that code for a long component and for a long full path. Keep the selected path and host code without claiming only a filename was too long. Co-authored-by: morluto <morluto@users.noreply.github.com> * style(javascript): format return-depth and object-read changes oxfmt rejected the return-depth test and the object-read index. No behavior change. Co-authored-by: morluto <morluto@users.noreply.github.com> * test(ida): expect unchanged invalid requests to be nonretryable The shared projector no longer marks invalid_request retryable. This lookup assertion was not updated with that contract. Co-authored-by: morluto <morluto@users.noreply.github.com> --------- Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: morluto <morluto@users.noreply.github.com>
This commit is contained in:
@@ -172,6 +172,56 @@ it("continues to project an ordinary member access as a property read", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps a directly returned or passed property in backward provenance", () => {
|
||||
const source = `
|
||||
const settings = { index: "products" };
|
||||
function viaLocal() {
|
||||
const value = settings.index;
|
||||
return value;
|
||||
}
|
||||
function viaMember() {
|
||||
return settings.index;
|
||||
}
|
||||
function viaParen() {
|
||||
return (settings.index);
|
||||
}
|
||||
const arrow = () => settings.index;
|
||||
function take(value) { return value; }
|
||||
function added() { return settings.index + "!"; }
|
||||
const a = viaLocal();
|
||||
const b = viaMember();
|
||||
const direct = settings.index;
|
||||
const c = viaParen();
|
||||
const d = arrow();
|
||||
const e = take(settings.index);
|
||||
const g = take((settings.index));
|
||||
const kept = settings.index;
|
||||
const local = take(kept);
|
||||
const concatenated = added();
|
||||
`;
|
||||
const graph = graphFor(source);
|
||||
const provenance = (binding: string, candidates: boolean) => {
|
||||
const node = graph.nodes.find(
|
||||
(item) => item.kind === "binding" && item.label === binding,
|
||||
);
|
||||
if (node === undefined) throw new Error(`missing ${binding}`);
|
||||
const trace = queryJavaScriptSemanticGraph(graph, {
|
||||
seed: { kind: "semantic-node", node_id: node.node_id },
|
||||
direction: "backward-provenance",
|
||||
include_ambiguous_dynamic_edges: candidates,
|
||||
});
|
||||
return trace.nodes.some(
|
||||
(item) => item.kind === "literal" && item.properties.value === "products",
|
||||
);
|
||||
};
|
||||
for (const binding of ["a", "b", "direct", "c", "d", "e", "g", "local"]) {
|
||||
expect(provenance(binding, false), binding).toBe(true);
|
||||
expect(provenance(binding, true), `${binding} candidates`).toBe(true);
|
||||
}
|
||||
expect(provenance("concatenated", false)).toBe(false);
|
||||
expect(provenance("concatenated", true)).toBe(false);
|
||||
});
|
||||
|
||||
it("keeps dynamic calls explicit and returns complete deterministic results", () => {
|
||||
const graph = graphFor(`
|
||||
const handlers = { ready() { return 1; } };
|
||||
|
||||
Reference in New Issue
Block a user