Summary
A C# method decorated with [Theory] is classified as function instead of test.method when following [InlineData(...)] attributes span multiple physical lines or contain complex literals.
The method declaration and range are extracted correctly, but the test classifier walks attributes one physical line at a time and stops at a continuation line that does not begin with [. This is a residual of #1961, which introduced the test.method distinction.
Environment
origin/main: c642bc4c3dda4ef659df8e6b699e10f61da3c836
cdidx v1.44.3, locally built
- fresh repository-wide index
- full net8.0 and net9.0 suites pass
Reproduction
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll symbols \
--name SymbolIdentity_NonCSharpBroadAmbiguityDoesNotPersistCrossProductOrAttributeCallers \
--lang csharp \
--path tests/CodeIndex.Tests/DbReaderSymbolIdentityTests.cs \
--db .cdidx/codeindex.db --json=array
dotnet ./src/CodeIndex/bin/Debug/net8.0/cdidx.dll symbols \
--name GetUnusedSymbols_MultilineAttributeLiteralWithBracketInString_KeepsReflectionContext \
--lang csharp --path tests/CodeIndex.Tests/DbReaderTests.cs \
--db .cdidx/codeindex.db --json=array
The first method has [Theory] at line 538, multiline InlineData blocks through line 550, and its declaration at line 551. The second has [Theory] at line 7797, complex multiline attributes through line 7814, and its declaration at line 7815.
Both rows currently return:
Nearby simple [Fact] and [Theory] methods remain test.method.
Expected behavior
Both methods are xUnit theories and must be emitted as test.method. Classification must survive a contiguous attribute block regardless of physical line breaks or bracket-like content inside correctly lexed literals/comments.
Root cause
IsCSharpTestMethod in src/CodeIndex/Indexer/Symbols/SymbolExtractor.DeclarationMetadata.cs:122 walks backward by physical line. Each preceding line must begin with [ and contain ] on the same line. A continuation such as a string argument terminates the scan before it reaches [Theory].
CSharpLineHasTestMethodAttribute is also physical-line-oriented and cannot represent one multiline attribute list as a lexical unit.
Focused PR scope
One PR should replace the line-only backward scan with a bounded, lexical, attribute-block-aware classifier while preserving the existing C# test-attribute taxonomy.
Non-goals
- Do not add a Roslyn dependency.
- Do not redesign symbol kinds or infer tests from method names alone.
- Do not broaden this PR to non-C# frameworks/languages.
- Do not parse arbitrary attribute constructor semantics.
Implementation guidance and cautions
- Reuse existing C# lexical/string/comment machinery where practical.
- Balance complete attribute blocks, ignoring brackets, commas, quotes, and comment markers inside normal, verbatim, raw, interpolated, and character literals.
- Keep line/character/item budgets explicit.
- Stop at real declaration/member boundaries and prevent a prior member's
[Theory] leaking forward.
- Preserve target-specified attributes such as
return:, assembly:, and module: without treating them as method test markers.
- Continue recognizing namespaced and
Attribute-suffixed forms already supported.
Required tests
- One and several multiline
InlineData attributes.
- Attributes split across brackets, parentheses, and argument lines.
- Comments between attributes.
- Namespaced
Xunit.TheoryAttribute.
- Normal, verbatim, raw, and interpolated strings containing brackets and triple-quote runs.
- Same-line multiple attributes and non-test multiline attributes.
- Member boundaries that prevent marker leakage.
- Existing Fact, Theory, MSTest, and NUnit variants.
Assert outline, symbols --kind test.method, inspect, and exclude-tests/unused behavior.
Acceptance criteria
- The methods at lines 551 and 7815 are emitted as
test.method.
- Existing simple classifications remain correct.
- Complex literals do not create phantom attributes.
- Attribute ownership never crosses a member boundary.
- The scan remains bounded.
Regression history
This is a direct residual of #1961 and should be referenced in regression tests and the bilingual changelog. No newer exact issue was found.
Summary
A C# method decorated with
[Theory]is classified asfunctioninstead oftest.methodwhen following[InlineData(...)]attributes span multiple physical lines or contain complex literals.The method declaration and range are extracted correctly, but the test classifier walks attributes one physical line at a time and stops at a continuation line that does not begin with
[. This is a residual of #1961, which introduced thetest.methoddistinction.Environment
origin/main:c642bc4c3dda4ef659df8e6b699e10f61da3c836cdidx v1.44.3, locally builtReproduction
The first method has
[Theory]at line 538, multilineInlineDatablocks through line 550, and its declaration at line 551. The second has[Theory]at line 7797, complex multiline attributes through line 7814, and its declaration at line 7815.Both rows currently return:
{"kind":"function"}Nearby simple
[Fact]and[Theory]methods remaintest.method.Expected behavior
Both methods are xUnit theories and must be emitted as
test.method. Classification must survive a contiguous attribute block regardless of physical line breaks or bracket-like content inside correctly lexed literals/comments.Root cause
IsCSharpTestMethodinsrc/CodeIndex/Indexer/Symbols/SymbolExtractor.DeclarationMetadata.cs:122walks backward by physical line. Each preceding line must begin with[and contain]on the same line. A continuation such as a string argument terminates the scan before it reaches[Theory].CSharpLineHasTestMethodAttributeis also physical-line-oriented and cannot represent one multiline attribute list as a lexical unit.Focused PR scope
One PR should replace the line-only backward scan with a bounded, lexical, attribute-block-aware classifier while preserving the existing C# test-attribute taxonomy.
Non-goals
Implementation guidance and cautions
[Theory]leaking forward.return:,assembly:, andmodule:without treating them as method test markers.Attribute-suffixed forms already supported.Required tests
InlineDataattributes.Xunit.TheoryAttribute.Assert outline,
symbols --kind test.method, inspect, and exclude-tests/unused behavior.Acceptance criteria
test.method.Regression history
test.methodand required parameterized/preceding-line decorators.This is a direct residual of #1961 and should be referenced in regression tests and the bilingual changelog. No newer exact issue was found.