用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/rudironsoni/Synaxis --skill dotnet-roslyn-analyzers命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
AI-powered wiki generation for code repositories with commands, agents, and skills
Routes .NET/C# work to domain skills. Loads coding-standards for code paths.
Skill manifest management for dotnet-agent-harness. Tracks skill dependencies, conflicts, version compatibility, and provides validation and resolution tools. Triggers on: skill manifest, dependency resolution, skill compatibility, version conflicts, build manifest, validate dependencies.
基于 SOC 职业分类
正在显示 SKILL.md
| name | dotnet-roslyn-analyzers |
| description | Authors Roslyn analyzers. DiagnosticAnalyzer, CodeFixProvider, CodeRefactoring, multi-version. |
Guidance for authoring custom Roslyn analyzers, code fix providers, code refactoring providers, and diagnostic suppressors. Covers project setup, DiagnosticDescriptor conventions, analysis context registration, code fix actions, code refactoring actions, multi-Roslyn-version targeting (3.8 through 4.14), testing with Microsoft.CodeAnalysis.Testing, NuGet packaging, and performance best practices.
For extended code examples (CodeRefactoringProvider implementation, multi-version project structure, test matrix
configuration), see details.md in this skill directory.
Cross-references: [skill:dotnet-csharp-source-generators] for shared Roslyn packaging concepts and IIncrementalGenerator patterns, [skill:dotnet-add-analyzers] for consuming and configuring analyzers, [skill:dotnet-testing-strategy] for general test organization and framework selection, [skill:dotnet-csharp-coding-standards] for naming conventions applied to analyzer code.
Analyzer projects must target netstandard2.0. The compiler loads analyzers into various host processes (Visual
Studio on .NET Framework/Mono, MSBuild on .NET Core, dotnet build CLI) -- targeting net8.0+ breaks compatibility
with hosts that do not run on that runtime.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<IsRoslynComponent>true</IsRoslynComponent>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="3.11.0" PrivateAssets="all" />
</ItemGroup>
</Project>
```csharp
- `EnforceExtendedAnalyzerRules` enables RS-series meta-diagnostics that catch common analyzer authoring mistakes.
- `IsRoslynComponent` enables IDE tooling support for the project.
- `LangVersion>latest` lets you write modern C# in the analyzer itself while still targeting `netstandard2.0`.
- All Roslyn SDK packages must use `PrivateAssets="all"` to avoid shipping them as transitive dependencies.
---
## DiagnosticAnalyzer
Every analyzer inherits from `DiagnosticAnalyzer` and must be decorated with `[DiagnosticAnalyzer(LanguageNames.CSharp)]`.
```csharp
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public sealed class NoPublicFieldsAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "MYLIB001";
private static readonly DiagnosticDescriptor Rule = new(
id: DiagnosticId,
title: "Public fields should be properties",
messageFormat: "Field '{0}' is public; use a property instead",
category: "Design",
defaultSeverity: DiagnosticSeverity.Warning,
isEnabledByDefault: true,
helpLinkUri: $"https://example.com/docs/rules/{DiagnosticId}");
public override ImmutableArray SupportedDiagnostics { get; }
= ImmutableArray.Create(Rule);
public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
context.RegisterSymbolAction(AnalyzeField, SymbolKind.Field);
}
private static void AnalyzeField(SymbolAnalysisContext context)
{
var field = (IFieldSymbol)context.Symbol;
if (field.DeclaredAccessibility == Accessibility.Public
&& !field.IsConst && !field.IsReadOnly)
{
context.ReportDiagnostic(Diagnostic.Create(Rule, field.Locations[0], field.Name));
}
}
}
```text
### Analysis Context Registration
| Method | Granularity | Use When |
|--------|-------------|----------|
| `RegisterSyntaxNodeAction` | Individual syntax nodes | Pattern matching on specific syntax |
| `RegisterSymbolAction` | Declared symbols | Checking symbol-level properties |
| `RegisterOperationAction` | IL-level operations | Analyzing semantic operations |
| `RegisterSyntaxTreeAction` | Entire syntax tree | File-level checks |
| `RegisterCompilationStartAction` | Compilation start | Accumulate state across compilation |
| `RegisterCompilationAction` | Full compilation | One-shot analysis after all files |
---
## DiagnosticDescriptor Conventions
### ID Prefix Patterns
| Pattern | Example | When |
|---------|---------|------|
| `PROJ###` | `MYLIB001` | Single-project analyzers |
| `AREA####` | `PERF0001` | Category-scoped analyzers |
| `XX####` | `MA0042` | Short-prefix convention |
Avoid prefixes reserved by the .NET platform: `CA`, `CS`, `RS`, `IDE`, `IL`, `SYSLIB`.
### Severity Selection
| Severity | Use When |
|----------|----------|
| `Error` | Code will not work correctly at runtime |
| `Warning` | Code works but violates best practices |
| `Info` | Suggestion for improvement |
| `Hidden` | IDE-only refactoring suggestion |
Default to `Warning` for most rules. Always provide a non-null `helpLinkUri` (RS1015 enforces this).
---
## CodeFixProvider
Code fix providers offer automated corrections for diagnostics. Key patterns:
- **EquivalenceKey:** Every `CodeAction` must have a unique `equivalenceKey` for FixAll support (RS1010, RS1011)
- **Document vs. Solution modification:** Use `createChangedDocument` for single-file fixes, `createChangedSolution` for cross-file renames
- **Trivia preservation:** Always transfer leading/trailing trivia from replaced nodes
- **FixAllProvider:** Return `WellKnownFixAllProviders.BatchFixer` for batch-applicable fixes
See `details.md` for the complete CodeFixProvider implementation with property conversion.
---
## DiagnosticSuppressor
Conditionally suppresses diagnostics from other analyzers when EditorConfig cannot express the suppression condition. Requires Roslyn 3.8+.
| Approach | Use When |
|----------|----------|
| EditorConfig severity override | Suppression applies unconditionally |
| `[SuppressMessage]` attribute | Suppression applies to a specific location |
| `DiagnosticSuppressor` | Suppression depends on code structure or patterns |
---
## Multi-Roslyn-Version Targeting
### Version Boundaries
| Roslyn Version | Ships With | Key APIs Added |
|---------------|------------|----------------|
| 3.8 | VS 16.8 / .NET 5 SDK | `DiagnosticSuppressor` |
| 4.2 | VS 17.2 / .NET 6 SDK | Improved incremental analysis |
| 4.4 | VS 17.4 / .NET 7 SDK | `ForAttributeWithMetadataName` |
| 4.8 | VS 17.8 / .NET 8 U1 | `CollectionExpression` support |
| 4.14 | VS 17.14 / .NET 10 SDK | Latest API surface |
Use conditional compilation constants (`ROSLYN_X_Y_OR_GREATER`) and version-specific NuGet paths (`analyzers/dotnet/roslyn{version}/cs/`). See `details.md` for the complete multi-version project structure.
---
## Testing Analyzers
Use `Microsoft.CodeAnalysis.Testing` for ergonomic analyzer testing:
```csharp
using Verify = Microsoft.CodeAnalysis.CSharp.Testing.CSharpAnalyzerVerifier<
NoPublicFieldsAnalyzer,
Microsoft.CodeAnalysis.Testing.DefaultVerifier>;
public class NoPublicFieldsAnalyzerTests
{
[Fact]
public async Task PublicField_ReportsDiagnostic()
{
var test = """
public class MyClass
{
public int {|MYLIB001:Value|};
}
""";
await Verify.VerifyAnalyzerAsync(test);
}
}
```text
### Diagnostic Markup Syntax
| Markup | Meaning |
|--------|---------|
| `[|text|]` | Diagnostic expected on `text` (single descriptor) |
| `{|DIAG_ID:text|}` | Diagnostic with specific ID expected |
---
## NuGet Packaging
Analyzers ship as NuGet packages with assemblies in `analyzers/dotnet/cs/`, not `lib/`.
```xml
false
true
true
```text
---
## Performance Best Practices
- **Resolve types once per compilation** inside `RegisterCompilationStartAction`, not per-node/symbol callbacks
- **Cache `SupportedDiagnostics`** as `ImmutableArray` field, not expression-bodied property
- **Enable concurrent execution** -- always call `context.EnableConcurrentExecution()`
- **Filter early** -- register for the most specific `SyntaxKind` possible
- **Avoid `Compilation.GetSemanticModel()`** -- use the `SemanticModel` from the analysis context (RS1030)
---
## Common Meta-Diagnostics (RS-Series)
| ID | Title | What It Catches |
|----|-------|-----------------|
| RS1001 | Missing `DiagnosticAnalyzerAttribute` | Analyzer class missing attribute |
| RS1008 | Avoid storing per-compilation data | Instance fields with compilation data |
| RS1010 | Create code actions with unique `EquivalenceKey` | Missing equivalence key |
| RS1015 | Provide non-null `helpLinkUri` | Empty help link |
| RS1016 | Code fix providers should provide FixAll support | Missing `GetFixAllProvider()` |
| RS1024 | Symbols should be compared for equality | Using `==` instead of `SymbolEqualityComparer` |
| RS1026 | Enable concurrent execution | Missing `EnableConcurrentExecution()` |
| RS1030 | Do not invoke `Compilation.GetSemanticModel()` | Using wrong semantic model source |
| RS1041 | Compiler extensions should target `netstandard2.0` | Wrong target framework |
---
## References
- [Tutorial: Write your first analyzer and code fix](https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/tutorials/how-to-write-csharp-analyzer-code-fix)
- [Roslyn SDK overview](https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/)
- [Microsoft.CodeAnalysis.Testing](https://github.com/dotnet/roslyn-sdk/tree/main/src/Microsoft.CodeAnalysis.Testing)
- [Analyzer NuGet packaging conventions](https://learn.microsoft.com/en-us/nuget/guides/analyzers-conventions)
- [dotnet/roslyn-analyzers (RS diagnostic source)](https://github.com/dotnet/roslyn-analyzers)
- [Meziantou.Analyzer (exemplar project)](https://github.com/meziantou/Meziantou.Analyzer)