# 機能設計書 66-診断エンジン

## 概要

本ドキュメントは、Roslyn IDE機能の一つである「診断エンジン（Diagnostics）」機能の設計を記述する。この機能は、Roslynアナライザーを実行してコード診断を行い、その結果を各種IDE機能（エラー一覧、ライトバルブ等）に提供する基盤機能である。

### 本機能の処理概要

**業務上の目的・背景**：コード品質の向上と潜在的なバグの早期発見は、ソフトウェア開発において重要な課題である。本機能は、コンパイラ診断とRoslynアナライザーによる診断を統合的に管理・実行し、リアルタイムでコード品質のフィードバックを提供する基盤として機能する。

**機能の利用シーン**：開発者がコードを編集すると、バックグラウンドで診断が実行され、エラー・警告・情報がエディタに表示される。「コード分析の実行」コマンドで明示的に全プロジェクトの診断を実行することも可能。

**主要な処理内容**：
1. ワークスペースの変更を監視し、診断の再計算をトリガー
2. ホストアナライザー（IDE組み込み）とプロジェクトアナライザー（PackageReference）を管理
3. ドキュメント/プロジェクト単位で診断を計算
4. 診断結果を各種コンシューマー（エラー一覧、ライトバルブ等）に配信
5. リモートホスト（OOP）での診断実行をサポート

**関連システム・外部連携**：ワークスペースサービス、Solution Crawler、LSP（Language Server Protocol）、リモートホスト（OOP）と連携。

**権限による制御**：バックグラウンド分析スコープをオプションで制御可能（オープンファイルのみ、全ドキュメント等）。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 48 | アナライザー設定ビュー | 主機能 | アナライザー設定の一覧表示 |
| 49 | 重大度コントロール | 補助機能 | 診断の重大度ドロップダウン選択 |

## 機能種別

診断基盤 / コード分析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| project | Project | Yes | 診断対象プロジェクト | null不可 |
| document | TextDocument | No | 診断対象ドキュメント | - |
| range | TextSpan? | No | 診断対象範囲 | - |
| diagnosticIdFilter | DiagnosticIdFilter | No | 対象診断IDフィルタ | - |
| priority | CodeActionRequestPriority? | No | 優先度 | - |
| diagnosticKind | DiagnosticKind | No | 診断種別 | - |

### 入力データソース

- ソリューション/プロジェクト/ドキュメント
- アナライザー参照（HostAnalyzerReference、PackageReference）
- EditorConfig設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DiagnosticData | ImmutableArray&lt;DiagnosticData&gt; | 診断データ配列 |
| DiagnosticDescriptor | ImmutableArray&lt;DiagnosticDescriptor&gt; | 診断記述子配列 |

### 出力先

- エラー一覧（Error List）
- エディタ（波線、ライトバルブ）
- LSPクライアント

## 処理フロー

### 処理シーケンス

```
1. ワークスペース変更検知
   └─ DocumentActiveContextChangedHandler等
2. 診断リフレッシュ要求
   └─ RequestDiagnosticRefresh呼び出し
3. アナライザー取得
   ├─ ホストアナライザー（_hostAnalyzerStateMap）
   └─ プロジェクトアナライザー（_projectAnalyzerStateMap）
4. 診断計算
   ├─ リモート（OOP）で実行
   └─ またはインプロセスで実行
5. 結果配信
   └─ DiagnosticsRefresherで各コンシューマーに通知
```

### フローチャート

```mermaid
flowchart TD
    A[ワークスペース変更] --> B[RequestDiagnosticRefresh]
    B --> C[アナライザー取得]
    C --> D{OOP利用可能?}
    D -->|Yes| E[リモートで診断実行]
    D -->|No| F[インプロセスで診断実行]
    E --> G[DiagnosticAnalysisResult]
    F --> G
    G --> H[DiagnosticsRefresher通知]
    H --> I[各コンシューマーに配信]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-66-01 | バックグラウンド分析スコープ | オープンファイルのみ/全ドキュメントの選択可能 | BackgroundAnalysisScopeOption |
| BR-66-02 | コンパイラ診断スコープ | コンパイラ診断の分析範囲を制御 | CompilerDiagnosticsScopeOption |
| BR-66-03 | アナライザー例外時クラッシュ | デバッグ目的でアナライザー例外時にクラッシュ可能 | dotnet_crash_on_analyzer_exception |
| BR-66-04 | 非優先アナライザー | 高コストアナライザーは低優先度で実行 | IsDeprioritizedAnalyzer |
| BR-66-05 | フェーディング連動 | FadeOutオプション変更時に診断を再計算 | FadeOutUnusedImports等 |

### 計算ロジック

診断IDフィルタリング:
- DiagnosticIdFilter.All: すべての診断
- DiagnosticIdFilter.Include: 指定IDのみ

## データベース操作仕様

### 操作別データベース影響一覧

本機能はデータベース操作を行わない。

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AD0001 | アナライザー例外 | アナライザー実行中に例外発生 | 診断として報告 |
| - | リモート通信エラー | OOP通信失敗 | インプロセスにフォールバック |

### リトライ仕様

リモート通信失敗時はインプロセス処理にフォールバック

## トランザクション仕様

該当なし

## パフォーマンス要件

- 高コストアナライザー（SymbolEnd/SemanticModel action）は非優先化
- インクリメンタル分析でメンバー編集時の再計算を最小化
- リモートホスト（OOP）での並列実行

## セキュリティ考慮事項

- アナライザーはサンドボックス環境で実行されない点に注意
- 信頼できるアナライザーのみを使用することを推奨

## 備考

AnalyzerExceptionDiagnosticId = "AD0001"はコンパイラと共有

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: インターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IDiagnosticAnalyzerService.cs | `src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs` | サービスインターフェース |

**主要API**:
- **22行目**: RequestDiagnosticRefresh - 診断リフレッシュ要求
- **31-32行目**: ForceRunCodeAnalysisDiagnosticsAsync - 強制診断実行
- **66-67行目**: GetDiagnosticsForIdsAsync - ID指定診断取得
- **89-94行目**: GetDiagnosticsForSpanAsync - スパン指定診断取得

#### Step 2: サービス実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | DiagnosticAnalyzerService.cs | `src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService.cs` | サービス実装（メイン） |

**主要処理フロー**:
1. **23-38行目**: ファクトリーでサービス作成
2. **51行目**: AnalyzerExceptionDiagnosticId定数
3. **67行目**: _hostAnalyzerStateMap（ホストアナライザー管理）
4. **73行目**: _projectAnalyzerStateMap（プロジェクトアナライザー管理）
5. **85-91行目**: オプション変更時の診断リフレッシュ
6. **116-117行目**: RequestDiagnosticRefresh実装

#### Step 3: 診断計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | DiagnosticAnalyzerService_CoreAnalyze.cs | `src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService_CoreAnalyze.cs` | 診断計算のコアロジック |
| 3-2 | DocumentAnalysisExecutor.cs | `src/Features/Core/Portable/Diagnostics/Service/DocumentAnalysisExecutor.cs` | ドキュメント診断実行 |

#### Step 4: リモート/インプロセス振り分けを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | DiagnosticAnalyzerService_RemoteOrLocalDispatcher.cs | `src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService_RemoteOrLocalDispatcher.cs` | OOP/In-proc振り分け |

### プログラム呼び出し階層図

```
IDiagnosticAnalyzerService
    │
    ├─ RequestDiagnosticRefresh
    │      └─ IDiagnosticsRefresher.RequestWorkspaceRefresh
    │
    ├─ GetDiagnosticsForSpanAsync
    │      │
    │      ├─ GetProjectAnalyzers_OnlyCallInProcess
    │      │      ├─ _hostAnalyzerStateMap
    │      │      └─ _projectAnalyzerStateMap
    │      │
    │      └─ AnalyzeInProcessAsync / RemoteInvoke
    │             │
    │             └─ DocumentAnalysisExecutor
    │                    │
    │                    └─ CompilationWithAnalyzers.GetAnalysisResultAsync
    │
    ├─ ForceRunCodeAnalysisDiagnosticsAsync
    │      └─ 全アナライザー強制実行
    │
    └─ GetDiagnosticDescriptorsPerReferenceAsync
           └─ アナライザー参照ごとの診断記述子取得
```

### データフロー図

```
[入力]                          [処理]                               [出力]

Workspace変更       ───▶  DiagnosticAnalyzerService
                                  │
                                  ▼
                         アナライザー取得
                    (Host + Project Analyzers)
                                  │
                                  ▼
                         CompilationWithAnalyzers
                                  │
                    ┌─────────────┴─────────────┐
                    ▼                           ▼
            RemoteHost (OOP)           InProcess
                    │                           │
                    └───────────┬───────────────┘
                                ▼
                    DiagnosticAnalysisResult
                                │
                                ▼
                    IDiagnosticsRefresher       ───▶  Error List
                                                ───▶  Editor (波線)
                                                ───▶  LSP Client
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IDiagnosticAnalyzerService.cs | `src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs` | ソース | サービスインターフェース |
| DiagnosticAnalyzerService.cs | `src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService.cs` | ソース | サービス実装（メイン） |
| DiagnosticAnalyzerService_CoreAnalyze.cs | `src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService_CoreAnalyze.cs` | ソース | コア分析ロジック |
| DiagnosticAnalyzerService_GetDiagnosticsForSpan.cs | `src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService_GetDiagnosticsForSpan.cs` | ソース | スパン診断取得 |
| DiagnosticAnalyzerService_RemoteOrLocalDispatcher.cs | `src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService_RemoteOrLocalDispatcher.cs` | ソース | OOP振り分け |
| DiagnosticAnalyzerService.HostAnalyzerInfo.cs | `src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService.HostAnalyzerInfo.cs` | ソース | ホストアナライザー情報 |
| DiagnosticAnalyzerService.ProjectStates.cs | `src/Features/Core/Portable/Diagnostics/Service/DiagnosticAnalyzerService.ProjectStates.cs` | ソース | プロジェクト状態管理 |
| DocumentAnalysisExecutor.cs | `src/Features/Core/Portable/Diagnostics/Service/DocumentAnalysisExecutor.cs` | ソース | ドキュメント診断実行 |
| DiagnosticOptionsStorage.cs | `src/Features/Core/Portable/Diagnostics/Options/DiagnosticOptionsStorage.cs` | ソース | オプション設定 |
| IDiagnosticsRefresher.cs | `src/Features/Core/Portable/Diagnostics/IDiagnosticsRefresher.cs` | ソース | 診断リフレッシャー |
| DiagnosticAnalyzerTelemetry.cs | `src/Features/Core/Portable/Diagnostics/DiagnosticAnalyzerTelemetry.cs` | ソース | テレメトリ |
