DisCatSharp Analyzer and Code Fix Authoring
This page documents the current authoring model for DisCatSharp.Analyzer and DisCatSharp.Analyzer.CodeFixes.
Project layout
DisCatSharp.Tools\DisCatSharp.Analyzer\DisCatSharp.Analyzer- owns diagnostics, descriptors, and analyzer logic
DisCatSharp.Tools\DisCatSharp.Analyzer\DisCatSharp.Analyzer.CodeFixes- owns Roslyn code fixes and reusable rewrite helpers
DisCatSharp.Tools\DisCatSharp.Analyzer\DisCatSharp.Analyzer.Package- packs both assemblies into the NuGet analyzer package
DisCatSharp.Tests\DisCatSharp.Analyzer.Tests- regression tests for diagnostics and code fixes
Current shared infrastructure
The analyzer and code-fix projects now share a small foundation:
DisCatSharpDiagnosticIds- centralized diagnostic IDs
DisCatSharpDiagnosticProperties- shared property keys for analyzer-to-code-fix metadata
SingleDiagnosticCodeFixProvider- base class for one-diagnostic fixers
CodeFixSemanticHelpers- semantic helpers for creation/type matching
CodeFixSyntaxHelpers- reusable initializer/property rewrite helpers
This is the preferred starting point for future rule-specific fixes.
Adding a new diagnostic
- Add a diagnostic ID to
DisCatSharpDiagnosticIds. - Add or reuse resource strings in
Resources.resx. - Add the descriptor in
DisCatSharpAnalyzer. - Register the analyzer logic for the relevant symbol or syntax shape.
- If the code fix needs extra analyzer metadata, add a shared property name to
DisCatSharpDiagnosticProperties. - Add or update docs under
DisCatSharp.Docs\vs\analyzer\. - Add regression coverage in
DisCatSharp.Tests\DisCatSharp.Analyzer.Tests.
Adding a new code fix
For one diagnostic, inherit from SingleDiagnosticCodeFixProvider.
Every code-fix diagnostic must also get its own article under DisCatSharp.Docs\vs\analyzer\dcs\.
Typical pattern:
- Read any analyzer-supplied metadata from
Diagnostic.Properties. - Use semantic helpers to identify the right nodes or symbols.
- Use syntax helpers to rewrite initializers, assignments, or other syntax shapes.
- Keep transformations deterministic and idempotent.
- Cover both the analyzer diagnostic and the code-fix result with tests.
Diagnostic ID taxonomy
The existing shipped diagnostics keep their historical IDs for compatibility, even if they predate the current categorization.
For new diagnostics, prefer category-based ranges:
DCS0XXXDisCatSharp.Attributesbased diagnostics
DCS1XXX- core
DisCatSharpdiagnostics, migrations, and cross-cutting code-fix families
- core
DCS2XXXDisCatSharp.ApplicationCommandsdiagnostics and code-fix families
DCS3XXXDisCatSharp.CommandsNextdiagnostics and code-fix families
DCS4XXXDisCatSharp.Interactivitydiagnostics and code-fix families
DCS5XXXDisCatSharp.Voicediagnostics and code-fix families
DCS6XXXDisCatSharp.Lavalinkdiagnostics and code-fix families
DCS7XXXDisCatSharp.Commondiagnostics and code-fix families
DCS8XXX- hosting, dependency injection, and configuration diagnostics and code-fix families
DCS9XXX- reserved
When adding a new code-fix diagnostic, choose an ID in the subsystem family rather than reusing the old mixed numbering style.
If a future subsystem grows large enough, split a new dedicated family rather than overloading an unrelated existing one.
Migration fixer guidance
Future breaking-change fixers should start with rule-specific logic, but use the shared helpers wherever possible.
Recommended first-class migration categories:
- symbol rename
- namespace move and using rewrite
- object initializer/property injection
- invocation replacement
- signature reshaping when arguments or call shape change
If multiple fixers need the same metadata model, promote that pattern into shared infrastructure after the second real use case rather than inventing a broad manifest up front.
Validation commands
Use these commands before merging analyzer/tooling changes:
dotnet test .\DisCatSharp.Tests\DisCatSharp.Analyzer.Tests\DisCatSharp.Analyzer.Tests.csproj -c Debug --nologo
dotnet build .\DisCatSharp.Tools\DisCatSharp.Tools.slnx -c Debug --nologo