# 機能設計書 112-Roslynアナライザー

## 概要

本ドキュメントは、Roslyn自体のコード品質を維持するための内部アナライザー群（RoslynAnalyzers）の機能設計を定義する。パフォーマンス敏感なコードの割り当て分析やPublic API追跡など、Roslynプロジェクト固有の品質管理機能を提供する。

### 本機能の処理概要

RoslynAnalyzersは、Roslynコンパイラ・IDE機能の開発において、パフォーマンス問題の早期検出、Public API互換性の維持、アナライザー開発のベストプラクティス遵守を支援する診断アナライザー群である。

**業務上の目的・背景**：Roslynはコンパイラとして高いパフォーマンス要件があり、意図しないメモリ割り当てやAPI破壊的変更を防ぐ必要がある。本機能は、コード変更時に自動的にこれらの問題を検出し、品質を維持する。

**機能の利用シーン**：
- Roslynのソースコード編集時に、リアルタイムで診断メッセージを表示
- CIパイプラインでのビルド時に、品質基準違反を検出
- Public API変更時に、PublicAPI.txtファイルとの整合性を確認
- パフォーマンス敏感なコード（[PerformanceSensitive]属性付き）での割り当て警告

**主要な処理内容**：
1. PerformanceSensitiveAnalyzers：ヒープ割り当てを引き起こすコードパターンの検出
2. PublicApiAnalyzers：Public APIの宣言とPublicAPI.txtファイルの整合性チェック
3. Microsoft.CodeAnalysis.Analyzers：アナライザー開発のベストプラクティス検証
4. ドキュメント・設定ファイル生成ツール群

**関連システム・外部連携**：Roslyn Diagnostics API、MSBuildビルドシステム、Visual Studio IDE

**権限による制御**：特になし。ビルド時に自動実行される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 48 | アナライザー設定ビュー | 補助機能 | Roslynアナライザールールの設定 |

## 機能種別

コード分析 / 診断 / コード品質管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| Compilation | Compilation | Yes | 分析対象のコンパイル情報 | null不可 |
| AdditionalFiles | ImmutableArray<AdditionalText> | No | PublicAPI.txt等の追加ファイル | - |
| AnalyzerOptions | AnalyzerOptions | No | EditorConfig設定等 | - |

### 入力データソース

- ソースコード：構文木・セマンティックモデル
- 追加ファイル：PublicAPI.Shipped.txt、PublicAPI.Unshipped.txt
- EditorConfig：アナライザー設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Diagnostic | Diagnostic | 検出された問題の診断情報 |
| DiagnosticSeverity | DiagnosticSeverity | 重大度（Error/Warning/Info等） |
| CodeFix | CodeAction | 自動修正アクション（該当する場合） |

### 出力先

- Visual Studio エラーリスト
- ビルド出力
- SARIF形式レポート

## 処理フロー

### 処理シーケンス

```
1. PerformanceSensitiveAnalyzer実行
   └─ [PerformanceSensitive]属性の検出
   └─ 属性付きメソッド内の割り当てパターン分析
   └─ 該当する割り当てに対して診断を報告

2. DeclarePublicApiAnalyzer実行
   └─ PublicAPI.txtファイルの読み込み・解析
   └─ 公開シンボルの列挙
   └─ ファイル内容との差分を検出
   └─ 不足・余剰のAPI宣言を報告

3. DiagnosticAnalyzerCorrectnessAnalyzer実行
   └─ DiagnosticAnalyzer派生クラスの検出
   └─ 実装パターンの検証
   └─ ベストプラクティス違反を報告
```

### フローチャート

```mermaid
flowchart TD
    A[コンパイル開始] --> B[RegisterCompilationStartAction]
    B --> C{PerformanceSensitive属性あり?}
    C -->|Yes| D[RegisterOperationBlockStartAction]
    D --> E[割り当てパターン分析]
    E --> F[診断レポート]
    C -->|No| G[スキップ]

    B --> H[PublicAPI.txt読み込み]
    H --> I[シンボルアクション登録]
    I --> J[API差分検出]
    J --> F

    F --> K[終了]
    G --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 属性トリガー | [PerformanceSensitive]属性付きメソッドのみ割り当て分析を実行 | 常時 |
| BR-002 | API追跡必須 | Publicシンボルは必ずPublicAPI.txtに記載が必要 | Public API分析有効時 |
| BR-003 | 削除マーカー | 削除されたAPIは*REMOVED*プレフィックスで記録 | Unshippedファイルのみ |
| BR-004 | Nullable追跡 | #nullable enableディレクティブでNullable参照型追跡を有効化 | ファイル先頭のみ有効 |

### 計算ロジック

- 割り当て検出：構文パターン（new式、ボックス化、クロージャキャプチャ等）をオペレーションレベルで分析

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

該当なし（静的コード分析のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| RS0016 | Warning | Public APIがPublicAPI.txtに未記載 | ファイルにAPIを追加 |
| RS0017 | Warning | PublicAPI.txtに記載されたAPIが存在しない | 記載を削除または*REMOVED*追加 |
| RS0041 | Error | Shippedファイルに*REMOVED*マーカーがある | Unshippedファイルに移動 |
| HAA0301 | Info | 明示的なヒープ割り当て | 割り当ての必要性を確認 |
| HAA0302 | Info | クロージャによるキャプチャ | ローカル関数やstatic lambdaを検討 |

### リトライ仕様

リトライなし（分析エラーはそのまま報告）

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

該当なし

## パフォーマンス要件

- 並行実行：EnableConcurrentExecution()により複数ファイル同時分析
- インクリメンタル分析：シンボル・構文単位での増分分析をサポート

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

特になし（ローカルコード分析のみ）

## 備考

- Roslyn開発チーム内部で使用されるアナライザーだが、一般のアナライザー開発者も参考にできる
- PublicApiAnalyzersはNuGetパッケージとして公開されている

---

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

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

### 推奨読解順序

#### Step 1: データ構造を理解する

まず、アナライザーの設定と診断ルールの定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AllocationRules.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/AllocationRules.cs` | 割り当て診断ルールの定義 |
| 1-2 | DiagnosticIds.cs | `src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/Core/DiagnosticIds.cs` | 診断ID定数の定義 |

**読解のコツ**: DiagnosticDescriptorの定義パターンを理解しておくと、各アナライザーの目的が明確になる。

#### Step 2: エントリーポイントを理解する

各アナライザーのInitializeメソッドがエントリーポイント。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractAllocationAnalyzer.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/AbstractAllocationAnalyzer.cs` | パフォーマンスアナライザーの基底クラス |
| 2-2 | DeclarePublicApiAnalyzer.cs | `src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.cs` | Public APIアナライザーのエントリーポイント |

**主要処理フロー（AbstractAllocationAnalyzer.cs）**:
1. **17-19行目**: Initialize - 並行実行を有効化、生成コード分析を設定
2. **29-45行目**: RegisterCompilationStartAction - PerformanceSensitive属性の検出
3. **40-44行目**: RegisterOperationBlockStartAction - オペレーションブロック分析の登録
4. **48-62行目**: RegisterOperationAnalysis - 指定されたオペレーション種別の分析

**主要処理フロー（DeclarePublicApiAnalyzer.cs）**:
1. **97-105行目**: Initialize - コンパイル開始アクションを登録
2. **107-154行目**: OnCompilationStart - Public/InternalAPIファイルの検証と分析登録
3. **140-152行目**: RegisterImplActions - シンボルアクションとコンパイル終了アクションを登録

#### Step 3: 個別アナライザーを理解する

パフォーマンス分析の具体的な実装を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ExplicitAllocationAnalyzer.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/ExplicitAllocationAnalyzer.cs` | 明示的な割り当て（new式等）の検出 |
| 3-2 | DisplayClassAllocationAnalyzer.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/CSharp/Analyzers/DisplayClassAllocationAnalyzer.cs` | クロージャキャプチャの検出 |
| 3-3 | TypeConversionAllocationAnalyzer.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/CSharp/Analyzers/TypeConversionAllocationAnalyzer.cs` | ボックス化等の型変換割り当て検出 |

#### Step 4: コードフィックスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | DeclarePublicApiFix.cs | `src/RoslynAnalyzers/PublicApiAnalyzers/Core/CodeFixes/DeclarePublicApiFix.cs` | Public APIファイルへの自動追加 |
| 4-2 | AvoidAllocationWithArrayEmptyCodeFix.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/CSharp/CodeFixes/AvoidAllocationWithArrayEmptyCodeFix.cs` | Array.Empty<T>()への変換 |

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

```
DiagnosticAnalyzer.Initialize()
    │
    ├─ AbstractAllocationAnalyzer.Initialize()
    │      ├─ EnableConcurrentExecution()
    │      ├─ ConfigureGeneratedCodeAnalysis()
    │      └─ RegisterCompilationStartAction()
    │             └─ AttributeChecker.TryGetContainsPerformanceSensitiveInfo()
    │                    └─ RegisterOperationAction() [割り当て検出]
    │
    └─ DeclarePublicApiAnalyzer.Initialize()
           └─ RegisterCompilationStartAction()
                  ├─ TryGetApiData() [PublicAPI.txt読み込み]
                  ├─ ValidateApiFiles() [ファイル検証]
                  └─ RegisterImplActions()
                         ├─ RegisterSymbolAction() [シンボル分析]
                         └─ RegisterCompilationEndAction() [最終レポート]
```

### データフロー図

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

ソースコード ─────────────▶ Compilation ──▶ SyntaxTree/SemanticModel
                                   │
                                   ▼
PublicAPI.Shipped.txt ────▶ ApiData構造体 ──▶ シンボル照合
PublicAPI.Unshipped.txt ──┘                         │
                                                    ▼
                                          Diagnostic (RS0016, RS0017, etc.)
                                                    │
                                                    ▼
                                          ─────▶ エラーリスト / ビルド出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractAllocationAnalyzer.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/AbstractAllocationAnalyzer.cs` | ソース | パフォーマンスアナライザー基底クラス |
| AllocationRules.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/AllocationRules.cs` | ソース | 割り当て診断ルール定義 |
| ExplicitAllocationAnalyzer.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/Core/ExplicitAllocationAnalyzer.cs` | ソース | 明示的割り当て検出 |
| DisplayClassAllocationAnalyzer.cs | `src/RoslynAnalyzers/PerformanceSensitiveAnalyzers/CSharp/Analyzers/DisplayClassAllocationAnalyzer.cs` | ソース | クロージャ検出 |
| DeclarePublicApiAnalyzer.cs | `src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.cs` | ソース | Public API追跡メインクラス |
| DeclarePublicApiAnalyzer.Impl.cs | `src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/DeclarePublicApiAnalyzer.Impl.cs` | ソース | Public API追跡実装 |
| PublicApiFile.cs | `src/RoslynAnalyzers/PublicApiAnalyzers/Core/Analyzers/PublicApiFile.cs` | ソース | APIファイル解析 |
| DeclarePublicApiFix.cs | `src/RoslynAnalyzers/PublicApiAnalyzers/Core/CodeFixes/DeclarePublicApiFix.cs` | ソース | API追加コードフィックス |
| DiagnosticDescriptorCreationAnalyzer.cs | `src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/DiagnosticDescriptorCreationAnalyzer.cs` | ソース | アナライザー開発検証 |
| CompareSymbolsCorrectlyAnalyzer.cs | `src/RoslynAnalyzers/Microsoft.CodeAnalysis.Analyzers/Core/MetaAnalyzers/CompareSymbolsCorrectlyAnalyzer.cs` | ソース | シンボル比較検証 |
| Program.cs (GenerateDocumentation) | `src/RoslynAnalyzers/Tools/GenerateDocumentationAndConfigFiles/Program.cs` | ソース | ドキュメント生成ツール |
