fix(csharp): recover same-scope arity-pair and partial-sibling INHERITS edges#774
Conversation
There was a problem hiding this comment.
Code Review
This pull request addresses issue #764 by improving the handling of C# arity pairs and partial generic siblings. It updates the class ingestion logic to correctly identify same-scope declarations and ensures that inheritance edges are correctly resolved by stripping the DUP_QN_MARKER during evaluation. Additionally, new tests were added to verify these scenarios, and the project version was updated. The review feedback suggests improving the readability and robustness of string manipulation logic in evals/cgr_graph.py by breaking down chained operations and adding guards for delimiters.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
|



What
Fixes #764: all three same-scope arity-pair shapes now emit their INHERITS edge.
ITtlStrategy : ITtlStrategy<object>+ITtlStrategy<TResult>in one file): the two types collide on natural qn and the second registers as aDUP_QN_MARKERvariant. The base resolves to the child itself and the self-loop guard refused the edge. Now the sibling recovery consultsfunction_registry.variants(natural_qn)first: the same-scope variants bucket holds exactly the file-scope declarations of that simple name, so the unique other type declaration IS the written sibling, whichever of the pair the child happens to be. A 3+ arity family stays conservatively refused.ExecuteParameters<T> : ExecuteParametersinside a test class): same mechanism, one nesting level down.PredicateBuilder : PredicateBuilder<object>where the generic ispartialacross two files): the recovery saw two candidate qns and refused. The existingcsharp_partial_groupsindex already knows the parts are ONE type; when every in-package candidate sits in a single partial group, the recovery returns the deterministic representative (min).The recovered edge targets a
@linevariant qn, which leaked into the eval's simple-name reduction (ExecuteParameters@132vs the oracle'sExecuteParameters), so both cgr-side name-edge reducers inevals/cgr_graph.pynow strip the marker — the same normalizationdead_code.pyalready applies to leaf names.Why the reversed order already worked
When the generic declares first it takes the bare qn and the child registers as the variant; the written base then resolves to the bare sibling at parse time and never hits the self-loop guard. A regression pin covers that order.
Validation
Strict RED → GREEN in commit history: the three shape tests fail on main (
test(csharp): RED ...), then the parser fix turns them green; the eval-normalization RED (test(evals): RED ...) demonstrates the marker leak with the parser fix applied, then the reducer fix turns it green.Polly L1, both frontends (
treesitterandCSHARP_FRONTEND=hybrid):Full suite green.