# 機能設計書 113-Analyzers

## 概要

本ドキュメントは、Avaloniaフレームワークの静的コード解析機能について、その設計と実装を詳細に記述する機能設計書である。Roslyn Analyzerを使用して、Avaloniaアプリケーションのコード品質を向上させる。

### 本機能の処理概要

Analyzersは、Avaloniaアプリケーション開発において、AvaloniaProperty の使用パターン、Bitmap の初期化方法などを静的に解析し、潜在的な問題を検出するRoslyn Analyzer群である。

**業務上の目的・背景**：AvaloniaのAvaloniaPropertyシステムは強力だが、不適切な使用方法により実行時エラーやパフォーマンス問題が発生する可能性がある。従来、これらの問題は実行時まで発見されなかったが、静的解析により開発時に早期発見が可能となる。また、ベストプラクティスに沿ったコードの記述を促進し、コードの保守性を向上させる。

**機能の利用シーン**：開発者がVisual Studio、JetBrains Rider等のIDEでコードを編集している際にリアルタイムで警告が表示される。ビルド時にも警告・エラーとして報告され、CI/CD環境でのコード品質チェックにも活用できる。

**主要な処理内容**：
1. AvaloniaPropertyの登録パターンの解析
2. AvaloniaPropertyの格納先の検証
3. プロパティオーナーと型の整合性チェック
4. CLRプロパティアクセサの検証
5. Bitmapの初期化パターンの検出

**関連システム・外部連携**：Roslyn Compiler、Visual Studio/Rider等のIDE、MSBuild

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | アナライザーはUI非依存のコンパイル時処理 |

## 機能種別

静的コード解析 / コンパイル時検証 / 開発支援ツール

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | アナライザーはパラメータを取らない | - |

### 入力データソース

- プロジェクト内のC#ソースコード
- Avalonia関連の参照アセンブリ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Diagnostics | Diagnostic[] | 検出された問題の診断情報 |

### 出力先

- IDEのエラーリスト/警告リスト
- ビルドログ
- CI/CDのビルドレポート

## 処理フロー

### 処理シーケンス

```
1. コンパイル開始時にアナライザー登録
   └─ RegisterCompilationStartAction()
2. AvaloniaObject型の検出
   └─ GetTypeByMetadataName("Avalonia.AvaloniaObject")
3. 構文ノードの解析
   └─ RegisterSyntaxNodeAction()
4. シンボル解析
   └─ RegisterSymbolAction()
5. 診断の報告
   └─ context.ReportDiagnostic()
```

### フローチャート

```mermaid
flowchart TD
    A[コンパイル開始] --> B{Avalonia参照あり?}
    B -->|No| C[スキップ]
    B -->|Yes| D[CompileAnalyzer生成]
    D --> E[構文ノード解析登録]
    E --> F[シンボル解析登録]
    F --> G[操作解析登録]
    G --> H{問題検出?}
    H -->|Yes| I[診断報告]
    H -->|No| J[完了]
    I --> J
    C --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 静的・読み取り専用格納 | AvaloniaPropertyはstatic readonlyフィールドに格納すべき | AVP1000 |
| BR-002 | 静的コンストラクタ登録 | Register/AddOwnerは静的コンストラクタまたは静的初期化子で呼び出すべき | AVP1001 |
| BR-003 | ジェネリック型オーナー禁止 | ジェネリック型はAvaloniaPropertyのオーナーになるべきでない | AVP1002 |
| BR-004 | オーナー型一致 | AvaloniaPropertyのオーナーは格納先の型と一致すべき | AVP1010 |
| BR-005 | プロパティアクセサ純粋性 | StyledPropertyのCLRアクセサは副作用を持つべきでない | AVP1030 |

### 計算ロジック

診断の重大度判定は各DiagnosticDescriptorで定義される：
```csharp
private static readonly DiagnosticDescriptor InappropriatePropertyAssignment = new(
    "AVP1000",
    "AvaloniaProperty objects should be stored appropriately",
    "Incorrect AvaloniaProperty storage: {0} should be static and readonly",
    Category,
    DiagnosticSeverity.Warning,
    isEnabledByDefault: true,
    ...);
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AVP0001 | 情報 | CLRプロパティとAvaloniaPropertyの関連付け | 情報提供のみ |
| AVP1000 | 警告 | AvaloniaPropertyがstatic readonlyでない | 修飾子を修正 |
| AVP1001 | 警告 | Register/AddOwnerが静的コンストラクタ外で呼ばれた | 呼び出し位置を修正 |
| AVP1002 | 警告 | ジェネリック型がオーナー | 非ジェネリック型に変更 |
| AVP1010 | 警告 | オーナー型が格納先と不一致 | オーナー型を修正 |
| AVP1011 | 警告 | 予期しないプロパティアクセス | 所有権を確認 |
| AVP1012 | 警告 | SetValueの不適切な使用 | SetCurrentValueを使用 |
| AVP1013 | 警告 | 冗長なAddOwner呼び出し | 呼び出しを削除 |
| AVP1020 | 警告 | プロパティ名の重複 | 名前を一意に |
| AVP1021 | 警告 | プロパティ名の曖昧さ | 名前を明確に |
| AVP1022 | 警告 | プロパティ名の不一致 | 名前を合わせる |
| AVP1030 | 警告 | アクセサに副作用 | 副作用を除去 |
| AVP1031 | 警告 | アクセサの欠落 | アクセサを追加 |
| AVP1032 | 警告 | アクセシビリティの不一致 | アクセシビリティを合わせる |
| AVP1040 | 警告 | プロパティ型の不一致 | 型を合わせる |
| AVBMP001 | 警告 | Bitmapをavaresから直接初期化 | AssetLoaderを使用 |

### リトライ仕様

アナライザーはリトライを行わない。

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

該当なし。

## パフォーマンス要件

- 並行実行をサポート（EnableConcurrentExecution）
- 生成されたコードは解析対象外（ConfigureGeneratedCodeAnalysis）

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

- 解析はコンパイル時にのみ実行される
- 外部入力による影響はない

## 備考

- isEnabledByDefault: falseの診断は明示的に有効化が必要
- 一部の診断はプロパティメタデータの自動生成が完了するまで無効

---

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

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

### 推奨読解順序

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

まず、アナライザーで使用されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | DiagnosticIds.cs | `src/tools/Avalonia.Analyzers.CSharp/DiagnosticIds.cs` | 診断IDの定義 |
| 1-2 | AvaloniaPropertyDescription | `src/tools/Avalonia.Analyzers.CSharp/AvaloniaPropertyAnalyzer.cs` | プロパティ記述クラス（339-444行目） |

**読解のコツ**: Roslyn DiagnosticAnalyzerの基本概念（DiagnosticDescriptor、AnalysisContext）を理解しておくとよい。

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

処理の起点となるアナライザークラスを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AvaloniaPropertyAnalyzer.cs | `src/tools/Avalonia.Analyzers.CSharp/AvaloniaPropertyAnalyzer.cs` | AvaloniaProperty解析の基底クラス |

**主要処理フロー**:
1. **196-208行目**: Initialize()でコンパイル開始アクションを登録
2. **201-206行目**: AvaloniaObject型の存在チェック
3. **205行目**: CompileAnalyzerのインスタンス化

#### Step 3: コンパイル解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AvaloniaPropertyAnalyzer.CompileAnalyzer.cs | `src/tools/Avalonia.Analyzers.CSharp/AvaloniaPropertyAnalyzer.CompileAnalyzer.cs` | コンパイル時解析の実装 |

#### Step 4: C#固有の解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AvaloniaPropertyAnalyzer.CSharp.cs | `src/tools/Avalonia.Analyzers.CSharp/AvaloniaPropertyAnalyzer.CSharp.cs` | C#構文固有の解析 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | BitmapAnalyzer.cs | `src/tools/Avalonia.Analyzers.CSharp/BitmapAnalyzer.cs` | Bitmap初期化の解析 |
| 5-2 | OnPropertyChangedOverrideAnalyzer.cs | `src/tools/Avalonia.Analyzers.CSharp/OnPropertyChangedOverrideAnalyzer.cs` | OnPropertyChangedオーバーライドの解析 |

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

```
Roslyn Compiler
    │
    ├─ AvaloniaPropertyAnalyzer.Initialize()
    │      └─ RegisterCompilationStartAction()
    │             └─ CompileAnalyzer (新規インスタンス)
    │                    ├─ RegisterSyntaxNodeAction()
    │                    ├─ RegisterSymbolAction()
    │                    └─ RegisterOperationAction()
    │
    └─ BitmapAnalyzer.Initialize()
           └─ RegisterSyntaxNodeAction(ObjectCreationExpression)
                  └─ AnalyzeNode()
```

### データフロー図

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

C#ソースコード ───────▶ SyntaxNodeAnalysis ──────▶ Diagnostic[]
                            │
                            ▼
                       SymbolAnalysis
                            │
                            ▼
Roslyn Compilation ────▶ OperationAnalysis
                            │
                            ▼
                       CompilationEndAction
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AvaloniaPropertyAnalyzer.cs | `src/tools/Avalonia.Analyzers.CSharp/AvaloniaPropertyAnalyzer.cs` | ソース | AvaloniaProperty解析基底 |
| AvaloniaPropertyAnalyzer.CompileAnalyzer.cs | `src/tools/Avalonia.Analyzers.CSharp/AvaloniaPropertyAnalyzer.CompileAnalyzer.cs` | ソース | コンパイル時解析 |
| AvaloniaPropertyAnalyzer.CSharp.cs | `src/tools/Avalonia.Analyzers.CSharp/AvaloniaPropertyAnalyzer.CSharp.cs` | ソース | C#固有の解析 |
| BitmapAnalyzer.cs | `src/tools/Avalonia.Analyzers.CSharp/BitmapAnalyzer.cs` | ソース | Bitmap初期化解析 |
| OnPropertyChangedOverrideAnalyzer.cs | `src/tools/Avalonia.Analyzers.CSharp/OnPropertyChangedOverrideAnalyzer.cs` | ソース | OnPropertyChanged解析 |
| DiagnosticIds.cs | `src/tools/Avalonia.Analyzers.CSharp/DiagnosticIds.cs` | ソース | 診断ID定義 |
| AvaloniaAnalysisException.cs | `src/tools/Avalonia.Analyzers.CSharp/AvaloniaAnalysisException.cs` | ソース | 例外クラス |
