From 38b203599f0d5f0601288a3c28006e268ec9d9bf Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Tue, 21 Apr 2026 19:31:45 +0100 Subject: [PATCH] =?UTF-8?q?feat(csharp-scope):=20parity=20Unit=204=20?= =?UTF-8?q?=E2=80=94=20callsite=20arity=20synthesis=20(infra)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Synthesize @reference.arity on every invocation_expression and object_creation_expression by counting `argument` named children of the backing `argument_list`. Wires the capture-to-Callsite pipeline shared extractor already consumes (`scope-extractor.ts:878`). No parity-count movement: the remaining arity-adjacent failures (overload disambiguation, optional-parameter dedup, variadic resolution) need type-based argument inference or member-call dedup, both explicitly deferred in the plan's Known Limitations section. This commit is infrastructure — future work lands on top of it. Legacy 175/175 green; 21 parity failures remain. --- .../ingestion/languages/csharp/captures.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/gitnexus/src/core/ingestion/languages/csharp/captures.ts b/gitnexus/src/core/ingestion/languages/csharp/captures.ts index 110ddf247..8270c20a5 100644 --- a/gitnexus/src/core/ingestion/languages/csharp/captures.ts +++ b/gitnexus/src/core/ingestion/languages/csharp/captures.ts @@ -143,6 +143,30 @@ export function emitCsharpScopeCaptures( } } + // Synthesize `@reference.arity` on every callsite so the + // registry's arity filter can narrow overloads. Count the + // `argument` named children of the backing `argument_list`. + // Python doesn't synthesize this today; C# needs it because the + // language has method overloading and the suite asserts overload + // resolution. + const callTag = ( + ['@reference.call.free', '@reference.call.member', '@reference.call.constructor'] as const + ).find((t) => grouped[t] !== undefined); + if (callTag !== undefined && grouped['@reference.arity'] === undefined) { + const anchor = grouped[callTag]!; + const callNode = + findNodeAtRange(tree.rootNode, anchor.range, 'invocation_expression') ?? + findNodeAtRange(tree.rootNode, anchor.range, 'object_creation_expression'); + if (callNode !== null) { + const argList = callNode.childForFieldName('arguments'); + const n = + argList === null + ? 0 + : argList.namedChildren.filter((c) => c !== null && c.type === 'argument').length; + grouped['@reference.arity'] = syntheticCapture('@reference.arity', callNode, String(n)); + } + } + out.push(grouped); // Synthesize primary-constructor declarations on class/record