fix(csharp): recover conditional-directive parses and keep same-arity overload families reachable - #790
Conversation
…attered interfaces recover
… cannot orphan phantom declarations
There was a problem hiding this comment.
Code Review
This pull request improves C# parsing and call resolution by keeping same-arity overload families reachable during bare call resolution and recovering from parse errors caused by interleaved conditional directives by blanking them (retaining only the first branch). Feedback on these changes suggests removing an unused constant _CSHARP_DIRECTIVE_PREFIXES, simplifying a redundant boolean check in _blank_csharp_directives, and correcting a misleading comment regarding which branches are kept during preprocessor recovery.
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.
…cognitive-complexity criticals
…heck, fix stale recovery comment
|
@greptile review |
…o clear sonarcloud complexity
|
@greptile review |
|
@greptile review |
|
@greptile review |
|



What
Second-repo C# dead-code dogfood, on Serilog (follows the Polly campaign, #782 through #789): Serilog's report goes from 36 findings to ZERO across three root-cause fixes, with Polly and the retrieval eval as regression guards (Polly stays at its single verified true positive; eval numbers identical).
Root causes and fixes
#if FEATURE_DEFAULT_INTERFACE; the grammar misparses each member into a property declaration NAMED after the directive condition, with only single-line inner ERROR nodes. Result: 12 phantom nodes namedFEATURE_DEFAULT_INTERFACE, one namedif, and every real ILogger member registered as a module-level Function. The C# path of the parse-recovery wrapper now retries with conditional-directive lines blanked whenever the tree has any error; the trigger ishas_errorplus an error-node count, never the line-span metric, which scores single-line errors as zero.#if X bodyA #else bodyB #endifaround an expression-bodied member leaves the second body orphaned at declaration position, misparsing into a bare phantom method (Polly's DelegatingComponent grew a parameterless ExecuteComponent under the first blanking). Blanking now keeps only the FIRST branch of each group, with nested groups inside a skipped branch staying skipped.FormatExactNumericValue(value, output)through nine switch arms to nine same-ARITY overloads differing only by parameter type; bare-call resolution picked one and the other eight reported dead (alsoGetLevelMoniker,StructureValue.Render, and the whole PropertyValueConverter/PropertyBinder cascade behind them). A resolved bare call now also emits CALLS to its same-arity signature siblings across partial parts and bases, keeping the family reachable. This is reduction-invisible to the retrieval eval by construction, and the Roslyn oracle counts every switch arm anyway.Validation
PolicyBuildertrue positive (the intermediate keep-both-branches state briefly introduced a phantom there, caught by the regression guard and fixed by keep-first-branch).