-
-
Notifications
You must be signed in to change notification settings - Fork 11.3k
Park TS/JS member calls whose receiver type lives in another repo (#3152) #3387
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: v8
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,10 +6,10 @@ | |
| `merge-graphs` and `global add` read. The two-repo graph was missing precisely the | ||
| edges that make it a call graph. | ||
|
|
||
| The Java, C++, C# and Swift resolvers now park those calls on the caller node and | ||
| this pass finishes them after the merge. The cases below pin what it must NOT do | ||
| as much as what it must: the single-definition guard, the cross-repo-only scope, | ||
| and the language guard are what keep it from fabricating an edge from a name | ||
| The Java, C++, C#, Swift and TS/JS resolvers now park those calls on the caller | ||
| node and this pass finishes them after the merge. The cases below pin what it must | ||
| NOT do as much as what it must: the single-definition guard, the cross-repo-only | ||
| scope, and the language guard are what keep it from fabricating an edge from a name | ||
| collision. | ||
| """ | ||
| from __future__ import annotations | ||
|
|
@@ -45,6 +45,7 @@ def _needs(module: str): | |
| needs_cpp = _needs("tree_sitter_cpp") | ||
| needs_csharp = _needs("tree_sitter_c_sharp") | ||
| needs_swift = _needs("tree_sitter_swift") | ||
| needs_typescript = _needs("tree_sitter_typescript") | ||
|
|
||
|
|
||
| def _caller(repo: str, parked: list[dict], node_id: str = "app_run", | ||
|
|
@@ -177,6 +178,33 @@ def test_a_defines_member_does_not_answer_a_java_call(): | |
| assert link_cross_repo_member_calls(G) == 0 | ||
|
|
||
|
|
||
| PARKED_TS = [{"callee": "greet", "receiver_type": "Greeter", "lang": "typescript", | ||
| "line": "L4"}] | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("declaring_file", ["src/greeter.ts", "src/greeter.js", | ||
| "src/greeter.mjs", "src/greeter.tsx"]) | ||
| def test_a_typescript_call_binds_across_the_whole_js_family(declaring_file: str): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
fans out to 6 callees (efferent coupling). Grounded coupling-delta finding (deterministic), not an LLM guess. |
||
| # One key for TS and JS: a TS class legitimately answers a JS call site, so | ||
| # splitting the two would drop every TS<->JS cross-repo call. | ||
| G = _graph( | ||
| caller=_caller("a", PARKED_TS, source_file="src/app.ts"), | ||
| declarations=[(_declaration("b", "Greeter", declaring_file), | ||
| _method("b", ".greet()", source_file=declaring_file))], | ||
| ) | ||
| assert link_cross_repo_member_calls(G) == 1, declaring_file | ||
| assert _added_calls(G) == {("a::app_run", "b::greeter_greet")} | ||
|
|
||
|
|
||
| def test_a_typescript_call_does_not_bind_to_a_python_declaration(): | ||
| G = _graph( | ||
| caller=_caller("a", PARKED_TS, source_file="src/app.ts"), | ||
| declarations=[(_declaration("b", "Greeter", "greeter.py"), | ||
| _method("b", ".greet()", source_file="greeter.py"))], | ||
| ) | ||
| assert link_cross_repo_member_calls(G) == 0 | ||
|
|
||
|
|
||
| def test_the_definition_answers_before_a_same_named_declaration(): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
fans out to 6 callees (efferent coupling). Grounded coupling-delta finding (deterministic), not an LLM guess. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
fans out to 6 callees (efferent coupling). Grounded coupling-delta finding (deterministic), not an LLM guess. |
||
| # A C++ class declares `void greet();` in its header (`defines`) and defines | ||
| # it out of line in the `.cpp` (`method`). Both hang off the one folded class | ||
|
|
@@ -364,6 +392,16 @@ def test_a_java_build_parks_the_call_and_the_merge_finishes_it(tmp_path: Path): | |
| ("src/Greeter.cs", "class Greeter { public void Greet() {} }\n"), | ||
| marks=needs_csharp, id="csharp-field-receiver", | ||
| ), | ||
| pytest.param( | ||
| "typescript", "greet", | ||
| ("src/app.ts", 'import { Greeter } from "greeter-pkg";\n' | ||
| "export class App {\n" | ||
| " constructor(private greeter: Greeter) {}\n" | ||
| " run(): void { this.greeter.greet(); }\n" | ||
| "}\n"), | ||
| ("src/greeter.ts", "export class Greeter {\n greet(): void {}\n}\n"), | ||
| marks=needs_typescript, id="typescript-parameter-property", | ||
| ), | ||
| pytest.param( | ||
| "swift", "greet", | ||
| ("src/App.swift", "class App {\n" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test_a_typescript_call_binds_across_the_whole_js_family()fans out to 6 callees (efferent coupling).
Grounded coupling-delta finding (deterministic), not an LLM guess.