# 機能設計書 112-Generators

## 概要

本ドキュメントは、Avaloniaフレームワークのソースジェネレーター機能について、その設計と実装を詳細に記述する機能設計書である。Roslyn Source Generatorを使用してXAMLファイルから自動的にC#コードを生成する。

### 本機能の処理概要

Generatorsは、Avaloniaアプリケーション開発において、XAMLファイルに定義されたx:Name属性を持つ要素に対応するC#プロパティを自動生成するRoslyn Source Generator機能である。

**業務上の目的・背景**：Avaloniaアプリケーション開発では、XAMLで定義したコントロールをコードビハインドから参照するために、従来はFindControl等のメソッドを使用する必要があった。これは実行時の型安全性が保証されず、タイプミスによるバグの原因となっていた。ソースジェネレーターにより、コンパイル時にプロパティが自動生成されることで、型安全なコントロールアクセスが可能になり、IntelliSenseによるコード補完も利用できるようになる。

**機能の利用シーン**：開発者がXAMLファイルでx:Name属性を持つコントロールを定義した際、自動的に対応するC#プロパティがpartialクラスに生成される。Visual Studio、JetBrains Rider等のIDEでのコード編集時にリアルタイムで生成が行われる。

**主要な処理内容**：
1. XAMLファイルの解析とx:Name属性の抽出
2. 名前付き要素の型解決
3. partialクラスの生成
4. InitializeComponentメソッドの生成
5. DevTools接続コードの生成（デバッグビルド時）

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ソースジェネレーターはUI非依存のコンパイル時処理 |

## 機能種別

ソースコード生成 / コンパイル時処理 / 開発支援ツール

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| AvaloniaNameGeneratorBehavior | Behavior | No | 生成動作モード（OnlyProperties/InitializeComponent） | 列挙値 |
| AvaloniaNameGeneratorFilterByPath | GlobPattern | No | 処理対象ファイルのパスフィルター | Glob形式 |
| AvaloniaNameGeneratorFilterByNamespace | GlobPattern | No | 処理対象の名前空間フィルター | Glob形式 |
| AvaloniaNameGeneratorViewFileNamingStrategy | ViewFileNamingStrategy | No | 出力ファイル名の命名規則 | 列挙値 |
| AvaloniaNameGeneratorClassFieldModifier | NamedFieldModifier | No | フィールドのアクセス修飾子 | 列挙値 |
| AvaloniaNameGeneratorAttachDevTools | bool | No | DevTools接続コードを生成するか | - |

### 入力データソース

- AdditionalFilesとして登録されたXAMLファイル（.axaml, .xaml, .paml）
- SourceItemGroup="AvaloniaXaml"のメタデータを持つファイル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| GeneratedSource | string | 生成されたC#ソースコード |
| FileName | string | 生成ファイル名（{ClassName}.g.csまたは{Namespace}.{ClassName}.g.cs） |

### 出力先

- コンパイラが管理する生成ソースファイル（obj配下）

## 処理フロー

### 処理シーケンス

```
1. IncrementalGeneratorの初期化
   └─ Initialize()メソッドでパイプラインを構築
2. オプションの読み込み
   └─ AnalyzerConfigOptionsからプロジェクト設定を取得
3. XAMLファイルのフィルタリング
   └─ 拡張子とSourceItemGroupでフィルタリング
4. XAMLの解析
   └─ XamlXViewResolverでビュー情報を抽出
   └─ XamlXNameResolverでx:Name要素を抽出
5. 型の解決
   └─ RoslynTypeSystemで型情報を解決
6. コード生成
   └─ ICodeGeneratorでC#コードを生成
7. ソース出力
   └─ context.AddSource()で出力
```

### フローチャート

```mermaid
flowchart TD
    A[コンパイル開始] --> B[Initialize]
    B --> C[XAMLファイル収集]
    C --> D{ファイルフィルタ}
    D -->|対象外| E[スキップ]
    D -->|対象| F[XAML解析]
    F --> G{x:Classあり?}
    G -->|No| E
    G -->|Yes| H[x:Name抽出]
    H --> I[型解決]
    I --> J{型解決成功?}
    J -->|No| K[診断出力]
    J -->|Yes| L[コード生成]
    L --> M[ソース出力]
    M --> N[完了]
    E --> N
    K --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | x:Class必須 | コード生成にはx:Classディレクティブが必要 | 常時 |
| BR-002 | AvaloniaXamlグループ | SourceItemGroup="AvaloniaXaml"のファイルのみ処理 | 常時 |
| BR-003 | StyledElement派生 | x:Name要素の型はStyledElementの派生である必要がある | 常時 |
| BR-004 | Window判定 | Windowクラスの場合はDevTools接続コードを生成可能 | AttachDevToolsオプション有効時 |
| BR-005 | フィールド修飾子 | x:FieldModifier属性でアクセス修飾子を指定可能 | 属性が指定された場合 |

### 計算ロジック

ファイル名の決定：
```csharp
var fileName = options.AvaloniaNameGeneratorViewFileNamingStrategy switch
{
    ViewFileNamingStrategy.ClassName => $"{view.ClassName}.g.cs",
    ViewFileNamingStrategy.NamespaceAndClassName => $"{view.Namespace}.{view.ClassName}.g.cs",
    _ => throw new ArgumentOutOfRangeException()
};
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AVN0001 | ParseFailed | XAMLの解析に失敗 | XAML構文を修正 |
| AVN0002 | InvalidType | x:Classで指定された型が見つからない | 型名を確認 |
| AVN0003 | NamedElementFailed | 名前付き要素の処理に失敗 | 要素定義を確認 |
| AVN9999 | InternalError | 内部エラー | スタックトレースを確認 |

### リトライ仕様

ソースジェネレーターはリトライを行わない。エラーは診断として報告される。

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

該当なし。

## パフォーマンス要件

- インクリメンタルソースジェネレーターにより、変更されたファイルのみを再処理
- XAML解析はC#コンパイルと独立して実行され、C#ファイル変更時の再解析を回避

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

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

## 備考

- Roslynのインクリメンタルソースジェネレーター（IIncrementalGenerator）を使用
- TrackingNamesによりデバッグ時のパイプライン追跡が可能

---

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

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

### 推奨読解順序

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

まず、ジェネレーターで使用されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Options.cs | `src/tools/Avalonia.Generators/NameGenerator/Options.cs` | 生成オプションの定義 |
| 1-2 | INameResolver.cs | `src/tools/Avalonia.Generators/Common/Domain/INameResolver.cs` | 名前解決のインターフェース |
| 1-3 | IViewResolver.cs | `src/tools/Avalonia.Generators/Common/Domain/IViewResolver.cs` | ビュー解決のインターフェース |

**読解のコツ**: Roslyn Source Generatorの基本概念（IIncrementalGenerator、IncrementalGeneratorInitializationContext）を理解しておくとよい。

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

処理の起点となるジェネレータークラスを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AvaloniaNameIncrementalGenerator.cs | `src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameIncrementalGenerator.cs` | ジェネレーターのエントリーポイント |

**主要処理フロー**:
1. **21-226行目**: Initialize()でパイプラインを構築
2. **24-26行目**: オプションプロバイダーの設定
3. **29-58行目**: XAMLファイルのフィルタリング
4. **63-115行目**: XAML解析とx:Name抽出
5. **129-186行目**: 型解決と名前解決
6. **189-224行目**: コード生成と出力

#### Step 3: コード生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | InitializeComponentCodeGenerator.cs | `src/tools/Avalonia.Generators/NameGenerator/InitializeComponentCodeGenerator.cs` | InitializeComponent生成 |
| 3-2 | OnlyPropertiesCodeGenerator.cs | `src/tools/Avalonia.Generators/NameGenerator/OnlyPropertiesCodeGenerator.cs` | プロパティのみ生成 |

**主要処理フロー**:
- **24-83行目**: GenerateCode()でC#コードを生成
- **31-47行目**: プロパティ定義の生成
- **52-79行目**: InitializeComponentメソッドの生成

#### Step 4: XAML解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | XamlXViewResolver.cs | `src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs` | ビュー情報の解決 |
| 4-2 | XamlXNameResolver.cs | `src/tools/Avalonia.Generators/Common/XamlXNameResolver.cs` | x:Name要素の解決 |

#### Step 5: 型システムを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | RoslynTypeSystem.cs | `src/tools/Avalonia.Generators/Compiler/RoslynTypeSystem.cs` | Roslyn型システム統合 |
| 5-2 | MiniCompiler.cs | `src/tools/Avalonia.Generators/Compiler/MiniCompiler.cs` | 軽量XAMLコンパイラ |
| 5-3 | NoopTypeSystem.cs | `src/tools/Avalonia.Generators/Compiler/NoopTypeSystem.cs` | 型なし解析用 |

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

```
Roslyn Compiler
    │
    └─ AvaloniaNameIncrementalGenerator.Initialize()
           ├─ AnalyzerConfigOptionsProvider (オプション読み込み)
           ├─ AdditionalTextsProvider (XAMLファイル収集)
           │      └─ Where() フィルタリング
           ├─ XamlXViewResolver.ResolveView()
           │      └─ MiniCompiler (XAML解析)
           ├─ XamlXNameResolver.ResolveXmlNames()
           ├─ RoslynTypeSystem.FindType()
           └─ ICodeGenerator.GenerateCode()
                  ├─ InitializeComponentCodeGenerator
                  └─ OnlyPropertiesCodeGenerator
```

### データフロー図

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

.axaml/.xaml ───────▶ XamlXViewResolver ────────▶ ResolvedXmlView
    files               │
                        ▼
                   XamlXNameResolver ────────▶ ResolvedXmlName[]
                        │
                        ▼
   C#コード ───────▶ RoslynTypeSystem ─────────▶ ResolvedName[]
 (参照用)               │
                        ▼
                   ICodeGenerator ─────────────▶ {ClassName}.g.cs
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AvaloniaNameIncrementalGenerator.cs | `src/tools/Avalonia.Generators/NameGenerator/AvaloniaNameIncrementalGenerator.cs` | ソース | ジェネレーター本体 |
| InitializeComponentCodeGenerator.cs | `src/tools/Avalonia.Generators/NameGenerator/InitializeComponentCodeGenerator.cs` | ソース | InitializeComponent生成 |
| OnlyPropertiesCodeGenerator.cs | `src/tools/Avalonia.Generators/NameGenerator/OnlyPropertiesCodeGenerator.cs` | ソース | プロパティ生成 |
| Options.cs | `src/tools/Avalonia.Generators/NameGenerator/Options.cs` | ソース | オプション定義 |
| NameGeneratorDiagnostics.cs | `src/tools/Avalonia.Generators/NameGenerator/NameGeneratorDiagnostics.cs` | ソース | 診断定義 |
| TrackingNames.cs | `src/tools/Avalonia.Generators/NameGenerator/TrackingNames.cs` | ソース | トラッキング名 |
| INameGenerator.cs | `src/tools/Avalonia.Generators/NameGenerator/INameGenerator.cs` | ソース | インターフェース |
| XamlXViewResolver.cs | `src/tools/Avalonia.Generators/Common/XamlXViewResolver.cs` | ソース | ビュー解決 |
| XamlXNameResolver.cs | `src/tools/Avalonia.Generators/Common/XamlXNameResolver.cs` | ソース | 名前解決 |
| GlobPattern.cs | `src/tools/Avalonia.Generators/Common/GlobPattern.cs` | ソース | Globパターン |
| RoslynTypeSystem.cs | `src/tools/Avalonia.Generators/Compiler/RoslynTypeSystem.cs` | ソース | Roslyn型システム |
| MiniCompiler.cs | `src/tools/Avalonia.Generators/Compiler/MiniCompiler.cs` | ソース | 軽量コンパイラ |
| GeneratorOptions.cs | `src/tools/Avalonia.Generators/GeneratorOptions.cs` | ソース | グローバルオプション |
| GeneratorExtensions.cs | `src/tools/Avalonia.Generators/GeneratorExtensions.cs` | ソース | 拡張メソッド |
