diff --git a/graphify/extract.py b/graphify/extract.py index bd8d541c5..1025f3e80 100644 --- a/graphify/extract.py +++ b/graphify/extract.py @@ -4975,6 +4975,11 @@ def _resolve_python_member_calls( _emit_call(caller, children[0], rc) +# Every suffix the TS/JS extractors claim. The member-call resolver both activates on +# and parks by this set, so a pure-ESM (`.mjs`) repo is not silently left out. +_JS_TS_SUFFIXES = (".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs") + + def _resolve_typescript_member_calls( per_file: list[dict], all_nodes: list[dict], @@ -7049,7 +7054,8 @@ register_language_resolver( LanguageResolver("ruby_member_calls", frozenset({".rb", ".rake"}), resolve_ruby_member_calls) ) register_language_resolver( - LanguageResolver("typescript_member_calls", frozenset({".ts", ".tsx", ".mts", ".cts", ".js", ".jsx"}), _resolve_typescript_member_calls) + LanguageResolver("typescript_member_calls", frozenset(_JS_TS_SUFFIXES), + _resolve_typescript_member_calls) ) # C++ (#1547) and ObjC (#1556) receiver-typed member-call resolution. `.h` is in # both suffix sets because it routes to extract_cpp or extract_objc by content; the diff --git a/tests/test_ts_receiver_member_calls.py b/tests/test_ts_receiver_member_calls.py index 03771cbb8..5752156ac 100644 --- a/tests/test_ts_receiver_member_calls.py +++ b/tests/test_ts_receiver_member_calls.py @@ -296,3 +296,14 @@ def test_public_property_sharing_a_private_methods_node_keeps_its_edge(tmp_path) "export function go(c: Ctx): number { return c.respond(); }\n"), }) assert any("go" in str(s) and "respond" in str(t) for s, t in calls), calls + + +def test_a_pure_esm_corpus_still_activates_the_resolver(tmp_path): + # `.mjs` and `.cjs` route to extract_js like `.js` does, so a repo that uses + # only those must not be the one shape where the resolver never runs. + calls, _ = _calls(tmp_path, { + "svc.mjs": "export class Svc {\n doThing() { return 1; }\n}\n", + "app.mjs": ('import { Svc } from "./svc.mjs";\nconst s = new Svc();\n' + "export function usesDirect() { return s.doThing(); }\n"), + }) + assert any("usesDirect" in s and "doThing" in t for s, t in calls)