.NET/C# ソースコードアナライザーとコード修正プロバイダーの開発と配布方法

開発環境の準備

Visual Studioの拡張開発ワークロードをインストールする必要があります。まだインストールしていない場合は、公式ドキュメントを参照してセットアップを完了してください。

プロジェクトの作成

Visual Studioを起動し、新しいプロジェクトを作成します。プロジェクトテンプレートから「Analyzer with Code Fix (.NET Standard)」を選択します。プロジェクト名を設定し、作成をクリックします。

例としてプロジェクト名を「SampleAnalyzer」とします。プロジェクト作成後、必要に応じて.NET Standardのバージョン(デフォルトは1.3)やNuGetパッケージを更新します。

初回デバッグ

F5キーを押すと、デバッグ用のVisual Studio実験用インスタンスが起動します。テスト用の新しいプロジェクト(例:.NET Coreコンソールアプリ)を作成し、テンプレート提供のアナライザー機能を確認できます。

プロジェクト構造の解析

ソリューションには3つのプロジェクトが含まれます:

  • メインアナライザープロジェクト(NuGetパッケージ生成)
  • Visual Studio拡張プロジェクト(VSIXパッケージ生成)
  • 単体テストプロジェクト

アナライザーの基本実装

DiagnosticAnalyzerを継承したクラスを作成します:

[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class SampleAnalyzer : DiagnosticAnalyzer
{
    public const string DiagnosticId = "SampleAnalyzer";
    
    private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(
        DiagnosticId, 
        "Sample Rule", 
        "Sample message", 
        "Category", 
        DiagnosticSeverity.Warning, 
        true);
    
    public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics 
        => ImmutableArray.Create(Rule);
    
    public override void Initialize(AnalysisContext context)
    {
        context.RegisterSyntaxNodeAction(AnalyzeProperty, SyntaxKind.PropertyDeclaration);
    }
    
    private void AnalyzeProperty(SyntaxNodeAnalysisContext context)
    {
        var propertyNode = (PropertyDeclarationSyntax)context.Node;
        var diagnostic = Diagnostic.Create(Rule, propertyNode.GetLocation());
        context.ReportDiagnostic(diagnostic);
    }
}

コード修正プロバイダーの実装

CodeFixProviderを継承したクラスを作成します:

[ExportCodeFixProvider(LanguageNames.CSharp), Shared]
public class SampleCodeFixProvider : CodeFixProvider
{
    public override ImmutableArray<string> FixableDiagnosticIds 
        => ImmutableArray.Create(SampleAnalyzer.DiagnosticId);
    
    public override async Task RegisterCodeFixesAsync(CodeFixContext context)
    {
        var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
        var diagnostic = context.Diagnostics.First();
        var propertyDecl = (PropertyDeclarationSyntax)root.FindNode(diagnostic.Location.SourceSpan);
        
        context.RegisterCodeFix(
            CodeAction.Create(
                "Convert to notification property",
                ct => ConvertPropertyAsync(context.Document, propertyDecl, ct),
                "SampleFix"),
            diagnostic);
    }
    
    private async Task<Solution> ConvertPropertyAsync(Document document, 
        PropertyDeclarationSyntax propertyDecl, CancellationToken cancellationToken)
    {
        // プロパティ変換ロジックを実装
        var root = await document.GetSyntaxRootAsync(cancellationToken);
        var newRoot = root.ReplaceNode(propertyDecl, CreateNewProperty(propertyDecl));
        return document.WithSyntaxRoot(newRoot).Project.Solution;
    }
    
    private PropertyDeclarationSyntax CreateNewProperty(PropertyDeclarationSyntax originalProperty)
    {
        // 新しいプロパティ構文の生成
        return originalProperty;
    }
}

配布方法

アナライザーはNuGetパッケージとして、またはVisual Studio拡張として配布できます。各プロジェクトの出力ディレクトリに生成されるパッケージファイルを使用して公開できます。

テストと検証

単体テストプロジェクトを使用してアナライザーの機能を検証します。テストコードでは、様々なコードパターンに対してアナライザーが正しく動作することを確認します。

タグ: Roslyn csharp VisualStudio NuGet SourceGenerator

7月8日 23:47 投稿