Skip to content

C# raw string phantom symbols persist: """...""", $"""...""", and @"..." content still captured as real symbols (#177 regression) #363

Description

@Widthdom

Summary

#177 (closed as completed) reported that C# raw string literal content ("""...""") creates phantom symbols. The issue persists in both the v1.10.0 binary and the current main source code. The extraction loop at SymbolExtractor.cs:441-452 has no string-literal-aware preprocessing — only StripLeadingCSharpAttributeLists for attribute removal. All three C# multi-line string forms continue to leak phantom symbols:

  1. Raw string literals ("""...""") — C# 11
  2. Interpolated raw strings ($"""...""") — C# 11
  3. Verbatim strings (@"...") — classic C#

Repro

CDIDX=/root/.local/bin/cdidx
mkdir -p /tmp/dogfood/cs-raw-string-phantom
cat > /tmp/dogfood/cs-raw-string-phantom/R.cs <<'EOF'
namespace CsRawStringPhantom;

public class Svc
{
    public int RealMethod() => 0;

    public string DocsExample() => """
        public void FakeMethod() { }
        public int FakeProp { get; set; }
        public class FakeClass { }
        public interface IFakeIface { }
        public delegate int FakeDel();
        public event System.EventHandler FakeEvent;
        public Foo() { }
        """;

    public string VerbatimExample() => @"
        public void VerbatimFake() { }
    ";

    public string InterpExample() => $"""
        public void InterpFake() { }
        """;

    public int AnotherReal() => 1;
}
EOF
"$CDIDX" index /tmp/dogfood/cs-raw-string-phantom --rebuild
"$CDIDX" symbols --db /tmp/dogfood/cs-raw-string-phantom/.cdidx/codeindex.db

Expected: RealMethod, DocsExample, VerbatimExample, InterpExample, AnotherReal + Svc + namespace = 7 symbols.

Actual (15 symbols, 8 phantoms):

function   AnotherReal          R.cs:30
function   DocsExample          R.cs:9-10
class      FakeClass            R.cs:12    ← PHANTOM (inside """)
delegate   FakeDel              R.cs:14    ← PHANTOM
event      FakeEvent            R.cs:15    ← PHANTOM
function   FakeMethod           R.cs:10    ← PHANTOM
property   FakeProp             R.cs:11    ← PHANTOM
interface  IFakeIface           R.cs:13    ← PHANTOM
function   InterpFake           R.cs:26    ← PHANTOM (inside $""")
function   RealMethod           R.cs:6
class      Svc                  R.cs:3-31
function   VerbatimExample      R.cs:20-21
function   VerbatimFake         R.cs:21    ← PHANTOM (inside @")
namespace  CsRawStringPhantom  R.cs:1
function   Foo                  R.cs:16    ← PHANTOM

Suspected root cause

src/CodeIndex/Indexer/SymbolExtractor.cs:441-452 — the extraction loop:

var lines = content.Split('\n');
for (int i = 0; i < lines.Length; i++)
{
    var line = lines[i];
    var matchLine = lang == "csharp" ? StripLeadingCSharpAttributeLists(line) : line;
    foreach (var pattern in patterns)
    {
        var match = pattern.Regex.Match(matchLine);
        ...

No string-literal state tracking. Every line is matched against every pattern regardless of whether it's inside a string literal. The StripLeadingCSharpAttributeLists call is the only C#-specific preprocessing, and it handles attributes, not strings.

#177 was closed as completed (2026-04-16) but no corresponding fix is visible in the extraction loop. Either the fix was reverted, was in a branch that wasn't merged, or the close was premature.

Why this matters

As documented extensively in #177:

Scope

Same as #177:

  • src/CodeIndex/Indexer/SymbolExtractor.cs — add string-literal-aware preprocessing for C# (raw """, interpolated $""", verbatim @"), and generalize to Python """ / Rust r#" / JS template literals.
  • src/CodeIndex/Indexer/ReferenceExtractor.cs — same preprocessing needed.
  • tests/CodeIndex.Tests/SymbolExtractorTests.cs — fixtures asserting zero phantom symbols from string literal content.

Related

Environment

  • cdidx: v1.10.0 (/root/.local/bin/cdidx)
  • Source: current main branch — SymbolExtractor.cs:441-452 has no string-literal tracking.
  • Platform: Linux 4.4.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions