Skip to content

csharp func_start: Invocation Shield doesn't cover multi-line bare call statements ending in ';' #1418

Closed

Description

@squid-protocol

Summary

tests/tools/tree_sitter_accuracy_audit.py --lang csharp measures func_start precision at only
63.4% (329 extra_functions against 576 real functions in the language-crucible csharp
corpus). A confirmed root cause: csharp's func_start regex
(gitgalaxy/standards/language_standards.py, "csharp" -> rules["func_start"]) still matches
a multi-line bare call statement as a function definition when the call's argument list ends in a
bare ; with no { -- the "Invocation Shield" added for #1221/#1314 doesn't fully cover this
shape.

Repro (confirmed against language-crucible/data/csharp/roslyn/LanguageParser.cs)

The real method is defined once, at line 6907:

        private void AccumulateExplicitInterfaceName(

...but running csharp's func_start regex directly against this file finds
4 matches for the name AccumulateExplicitInterfaceName, not 1:

3934:                        AccumulateExplicitInterfaceName(
6838:                        AccumulateExplicitInterfaceName(
6907:        private void AccumulateExplicitInterfaceName(     <- the real definition
7010:                    AccumulateExplicitInterfaceName(

Lines 3934/6838/7010 are ordinary multi-line call statements (AccumulateExplicitInterfaceName(ref explicitInterfaceName, ref separator);), not declarations -- they have no modifier, no return
type, and terminate in a bare ; several lines below the name. Since the accuracy audit tool
compares GitGalaxy's per-name match COUNT against tree-sitter's ground-truth count per file (not
just set membership), these 3 spurious extra matches on an otherwise-correctly-found real name
inflate extra_functions by 3 for this one name alone -- and the same shape recurs throughout the
corpus (CheckFeatureAvailability, GetWellKnownType, TypeSymbol.Equals,
instrumentation.Kinds.Contains, etc. in CSharpCompilation.cs/MethodCompiler.cs).

Suggested fix shape

Csharp legitimately needs to allow a bare-;-terminated signature for real cases (abstract/
interface/partial method declarations, e.g. void Foo(int x);), which is presumably why the
lookahead currently tolerates it -- the gap is that it doesn't distinguish those from an ordinary
call statement that also has no modifier/return-type prefix. Compare against how rust's
equivalent gap was closed (#1319: only allow the bare-; tolerance on branches that already
matched a modifier/return-type-shaped prefix, not on the zero-prefix path) and how dart's own
three-way alternative split (#1221, see the adjacent comment block in the same file) handles
exactly this modifier-vs-no-modifier distinction already. Verify against
tests/extraction/languages/test_csharp.py (must not regress legitimate bodyless interface/
abstract method declarations) and re-run
python tests/tools/tree_sitter_accuracy_audit.py --lang csharp --regenerate to confirm
extra_functions drops without found_functions (571) regressing.

Scope note

This only affects func_start/args/class_start name-extraction accuracy (the extraction-
gauntlet pillar from epic #813), not GitGalaxy's risk-scoring rules, which are unaffected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugUnintended behavior or logic failure in the enginecore-engineModifications to the central physics and parsing enginepriority: mediumtestingUnit, integration, and E2E pipeline verificationthreat: false-positiveAccuracy tuning: Engine incorrectly flagged safe code

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions