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:
- Raw string literals (
"""...""") — C# 11
- Interpolated raw strings (
$"""...""") — C# 11
- 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
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 currentmainsource code. The extraction loop atSymbolExtractor.cs:441-452has no string-literal-aware preprocessing — onlyStripLeadingCSharpAttributeListsfor attribute removal. All three C# multi-line string forms continue to leak phantom symbols:"""...""") — C# 11$"""...""") — C# 11@"...") — classic C#Repro
Expected:
RealMethod,DocsExample,VerbatimExample,InterpExample,AnotherReal+Svc+ namespace = 7 symbols.Actual (15 symbols, 8 phantoms):
Suspected root cause
src/CodeIndex/Indexer/SymbolExtractor.cs:441-452— the extraction loop:No string-literal state tracking. Every line is matched against every pattern regardless of whether it's inside a string literal. The
StripLeadingCSharpAttributeListscall 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:
symbols,definition,outline,inspect,mapall return phantom results.map's entrypoint heuristic can rank a fixturefunction mainas the top entrypoint.unusedandhotspotsare polluted with phantom symbol counts.symbols App --exact --lang csharpreturned 52 phantom rows (per Symbol extractor doesn't track string-literal boundaries: code inside C#"""..."""raw strings (and other multi-line strings) becomes phantom symbols — 52 fakeclass Approws on cdidx itself, topmapentrypoint is a Lua fixture string #177).Scope
Same as #177:
src/CodeIndex/Indexer/SymbolExtractor.cs— add string-literal-aware preprocessing for C# (raw""", interpolated$""", verbatim@"), and generalize to Python"""/ Rustr#"/ 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
"""..."""raw strings (and other multi-line strings) becomes phantom symbols — 52 fakeclass Approws on cdidx itself, topmapentrypoint is a Lua fixture string #177 (closed) — original raw string phantom report. This issue documents the regression / incomplete fix.propertysymbols (incl. constant patterns producing nonsensical names like0) #208 (closed) — switch expression arm phantom properties. Also appears unfixed in current source despite being closed.Environment
/root/.local/bin/cdidx)mainbranch —SymbolExtractor.cs:441-452has no string-literal tracking.