From df74ab44817d3b7f8ecafb333ec99899fe634f9d Mon Sep 17 00:00:00 2001 From: safishamsi Date: Fri, 10 Jul 2026 21:57:16 +0100 Subject: [PATCH] test(csharp): chained call off new X(...) resolves (#1770) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The reported bug — a method chained directly onto a `new X(...)` expression (no intermediate variable) producing no calls edge — is already fixed on v8: `new Merger(ctx).Combine(...)` emits calls -> Merger.Combine. Add a regression test so the fluent new-expression receiver stays covered. Co-Authored-By: Claude Opus 4.8 (1M context) --- tests/test_csharp_member_calls.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/test_csharp_member_calls.py b/tests/test_csharp_member_calls.py index d83265d9..0dba3ed3 100644 --- a/tests/test_csharp_member_calls.py +++ b/tests/test_csharp_member_calls.py @@ -141,3 +141,27 @@ def test_unqualified_call_still_resolves(tmp_path): ) }) assert any("_r_a" in s and "helper" in t for s, t in calls), "no regression on unqualified calls" + + +def test_method_chained_off_new_expression_resolves(tmp_path): + """#1770: a method invoked directly on a `new X(...)` object-creation + expression (no intermediate variable) must still emit a calls edge to the + constructed type's method — the fluent `new X(...).M()` pattern.""" + calls, r = _calls(tmp_path, { + "S.cs": ( + "public class Merger {\n" + " public Merger(int x) {}\n" + " public int Combine(int a, bool b) { return a; }\n" + "}\n" + "public class Svc {\n" + " public int Run(int ctx) {\n" + " return new Merger(ctx).Combine(ctx, true);\n" + " }\n" + "}\n" + ) + }) + label = {n["id"]: n.get("label") for n in r["nodes"]} + assert any( + "run" in s and label.get(t) == ".Combine()" + for s, t in calls + ), f"chained call off new Merger(...) not captured: {[(s, label.get(t)) for s, t in calls]}"