# 機能設計書 111-BuildTasks

## 概要

本ドキュメントは、Avaloniaフレームワークのビルドタスク機能について、その設計と実装を詳細に記述する機能設計書である。MSBuildカスタムタスクを提供し、XAMLコンパイルとリソース生成を行う。

### 本機能の処理概要

BuildTasksは、Avaloniaアプリケーションのビルドプロセスにおいて、XAMLファイルのコンパイルとリソースのパッケージングを担当するMSBuildカスタムタスク群である。

**業務上の目的・背景**：Avaloniaアプリケーション開発において、XAMLファイルをILコードにコンパイルし、実行時のXAMLパース処理を不要にすることで、アプリケーションの起動時間を大幅に短縮する。また、リソースファイルを効率的にパッケージングし、実行時にアクセス可能にする必要がある。従来のXAML実行時解析では、パフォーマンスの低下とデバッグの困難さが課題であったが、コンパイル時処理によりこれらを解決する。

**機能の利用シーン**：開発者がMSBuildでAvaloniaプロジェクトをビルドする際に、自動的にタスクが実行される。Visual Studio、JetBrains Rider、dotnet CLIなどの開発環境でのビルド時に透過的に動作する。CI/CD環境での自動ビルドにおいても、同様に機能する。

**主要な処理内容**：
1. XAMLファイルの解析とコンパイル（CompileAvaloniaXamlTask）
2. リソースファイルのパッケージング（GenerateAvaloniaResourcesTask）
3. ILコードの生成と既存アセンブリへの挿入
4. コンパイル時バインディングの処理
5. 参照アセンブリへのコンパイル済み型の反映

**関連システム・外部連携**：MSBuildビルドシステム、Mono.Cecilライブラリ（IL操作）、XamlXコンパイラ、.NET SDK

**権限による制御**：特になし（ビルド環境の設定に依存）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | ビルドタスクはUI非依存のビルド時処理 |

## 機能種別

ビルドツール / コンパイル処理 / コード生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ProjectDirectory | string | Yes | プロジェクトのルートディレクトリ | パスが存在すること |
| AssemblyFile | ITaskItem | Yes | コンパイル対象のアセンブリファイル | ファイルが存在すること |
| RefAssemblyFile | ITaskItem | No | 参照アセンブリファイル | - |
| References | ITaskItem[] | No | 参照アセンブリの一覧 | - |
| VerifyIl | bool | No | ILコードの検証を行うか | - |
| DefaultCompileBindings | bool | No | デフォルトでコンパイル済みバインディングを使用するか | - |
| SkipXamlCompilation | bool | No | XAMLコンパイルをスキップするか | - |
| SignAssembly | bool | No | アセンブリに署名するか | - |
| AssemblyOriginatorKeyFile | string | No | 署名用のキーファイルパス | - |
| CreateSourceInfo | bool | No | ソース情報を生成するか | - |

### 入力データソース

- プロジェクト内のXAMLファイル（.axaml, .xaml, .paml）
- コンパイル済みアセンブリ（.dll）
- 参照アセンブリ
- AvaloniaResourceアイテムグループ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| OutputAssembly | byte[] | コンパイル済みXAMLコードが挿入されたアセンブリ |
| RefOutputAssembly | byte[] | 参照アセンブリ |
| ResourcesFile | byte[] | パッケージングされたリソースファイル |
| CompileResult | bool | コンパイル成功/失敗 |

### 出力先

- コンパイル済みアセンブリファイル
- リソースファイル（.avares）
- PDBファイル（デバッグシンボル）

## 処理フロー

### 処理シーケンス

```
1. CompileAvaloniaXamlTask実行
   └─ MSBuildによりタスクが呼び出される
2. CecilTypeSystemの初期化
   └─ Mono.Cecilを使用してアセンブリを読み込む
3. XAMLファイルの収集
   └─ .axaml, .xaml, .pamlファイルを検索
4. 各XAMLファイルの処理
   └─ XamlXパーサーで解析
   └─ コンパイラ変換の適用
   └─ ILコードの生成
5. ローダーディスパッチャーの生成
   └─ 実行時ローダー用のメソッド生成
6. アセンブリの書き出し
   └─ 変更されたアセンブリを保存
```

### フローチャート

```mermaid
flowchart TD
    A[ビルド開始] --> B[CompileAvaloniaXamlTask実行]
    B --> C[CecilTypeSystem初期化]
    C --> D{XAMLファイルあり?}
    D -->|No| E[処理スキップ]
    D -->|Yes| F[XAMLファイル解析]
    F --> G[x:Class解決]
    G --> H[コンパイラ変換適用]
    H --> I[ILコード生成]
    I --> J[AvaloniaXamlLoader.Load置換]
    J --> K[アセンブリ書き出し]
    K --> L[ビルド完了]
    E --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | XAMLファイル拡張子 | .axaml, .xaml, .pamlのいずれかの拡張子を持つファイルを処理対象とする | 常時 |
| BR-002 | x:Precompile制御 | x:Precompile="false"が指定されたXAMLはコンパイルをスキップ | XAMLにディレクティブがある場合 |
| BR-003 | x:Class必須 | コードビハインドと関連付けるにはx:Classディレクティブが必要 | 常時 |
| BR-004 | 型の存在確認 | x:Classで指定された型がアセンブリ内に存在すること | 常時 |
| BR-005 | 重複チェック | 同一のx:Classは複数のXAMLファイルで使用不可 | 常時 |

### 計算ロジック

コンパイル時バインディングのメタデータ属性追加：
```csharp
// AssemblyMetadataAttributeとしてバインディング設定を埋め込む
var arg1 = "AvaloniaUseCompiledBindingsByDefault";
var arg2 = defaultCompileBindings.ToString();
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| TransformError | コンパイルエラー | XAMLの解析に失敗 | XAMLの構文を修正 |
| EmitError | コード生成エラー | ILコード生成に失敗 | エラーメッセージを確認 |
| Unknown | 未知のエラー | 予期しない例外 | スタックトレースを確認 |
| InvalidXAML | 解析エラー | 無効なXAML構文 | XAMLの構文を修正 |
| DuplicateXClass | 重複エラー | x:Classの重複 | 重複を解消 |

### リトライ仕様

ビルドタスクはリトライを行わない。エラー発生時はビルド失敗として処理を終了する。

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

ビルドタスクはトランザクション管理を行わない。ビルド失敗時は出力ファイルは生成されない。

## パフォーマンス要件

- 大規模プロジェクト（100以上のXAMLファイル）でも数十秒以内にコンパイル完了
- インクリメンタルビルドにより、変更のないファイルは再コンパイルしない

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

- 署名付きアセンブリのサポート（AssemblyOriginatorKeyFile）
- ビルド出力ディレクトリへの書き込み権限が必要

## 備考

- DebuggerLaunch オプションによりビルドタスクのデバッグが可能
- VerboseExceptions オプションにより詳細なエラー情報を出力可能

---

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

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

### 推奨読解順序

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

まず、ビルドタスクで使用されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | XamlFileInfo.cs | `src/Avalonia.Build.Tasks/XamlFileInfo.cs` | XAMLファイルの情報を保持する構造体 |
| 1-2 | XamlCompilerTaskExecutor.CompileResult | `src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs` | コンパイル結果を表すクラス（37-47行目） |

**読解のコツ**: MSBuildのITaskItem、IBuildEngineインターフェースの基本を理解しておくとよい。

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

処理の起点となるMSBuildタスククラスを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CompileAvaloniaXamlTask.cs | `src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs` | MSBuildから呼び出されるXAMLコンパイルタスク |
| 2-2 | GenerateAvaloniaResourcesTask.cs | `src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs` | リソースパッケージングタスク |

**主要処理フロー**:
1. **12-50行目**: Execute()メソッドでXamlCompilerTaskExecutor.Compileを呼び出す
2. **28-35行目**: コンパイラの各種オプションを渡してコンパイル実行
3. **37-47行目**: 結果に応じてファイルのコピーまたは終了

#### Step 3: コンパイラ本体を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | XamlCompilerTaskExecutor.cs | `src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs` | コンパイルの中核ロジック |

**主要処理フロー**:
- **49-102行目**: Compile静的メソッドがコンパイルのエントリーポイント
- **104-676行目**: CompileCoreでXAMLファイルごとの処理
- **162-175行目**: ヘルパー型定義の生成
- **281-664行目**: CompileGroupでXAMLファイルグループのコンパイル
- **517-580行目**: AvaloniaXamlLoader.Load()呼び出しの置換処理

#### Step 4: ヘルパークラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | XamlCompilerTaskExecutor.Helpers.cs | `src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.Helpers.cs` | ヘルパーメソッド群 |
| 4-2 | DeterministicIdGenerator.cs | `src/Avalonia.Build.Tasks/DeterministicIdGenerator.cs` | 決定論的ID生成 |
| 4-3 | Extensions.cs | `src/Avalonia.Build.Tasks/Extensions.cs` | 拡張メソッド |

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

```
MSBuild
    │
    ├─ CompileAvaloniaXamlTask.Execute()
    │      └─ XamlCompilerTaskExecutor.Compile()
    │             ├─ CecilTypeSystem (アセンブリ読み込み)
    │             ├─ CompileCore()
    │             │      ├─ XDocumentXamlParser.Parse()
    │             │      ├─ AvaloniaXamlIlCompiler.Transform()
    │             │      └─ AvaloniaXamlIlCompiler.Compile()
    │             └─ AssemblyDefinition.Write()
    │
    └─ GenerateAvaloniaResourcesTask.Execute()
           ├─ BuildResourceSources()
           ├─ PreProcessXamlFiles()
           └─ Pack()
```

### データフロー図

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

.axaml/.xaml ───────▶ XamlCompilerTaskExecutor ────▶ 修正済み.dll
    files                    │
                             │
   .dll ────────────▶ CecilTypeSystem ─────────────▶ .pdb
 (input)                     │
                             │
リソースファイル ────▶ GenerateAvaloniaResourcesTask ──▶ .resources
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CompileAvaloniaXamlTask.cs | `src/Avalonia.Build.Tasks/CompileAvaloniaXamlTask.cs` | ソース | XAMLコンパイルタスク |
| GenerateAvaloniaResourcesTask.cs | `src/Avalonia.Build.Tasks/GenerateAvaloniaResourcesTask.cs` | ソース | リソース生成タスク |
| XamlCompilerTaskExecutor.cs | `src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.cs` | ソース | コンパイラ本体 |
| XamlCompilerTaskExecutor.Helpers.cs | `src/Avalonia.Build.Tasks/XamlCompilerTaskExecutor.Helpers.cs` | ソース | ヘルパーメソッド |
| XamlFileInfo.cs | `src/Avalonia.Build.Tasks/XamlFileInfo.cs` | ソース | XAMLファイル情報 |
| DeterministicIdGenerator.cs | `src/Avalonia.Build.Tasks/DeterministicIdGenerator.cs` | ソース | ID生成 |
| Extensions.cs | `src/Avalonia.Build.Tasks/Extensions.cs` | ソース | 拡張メソッド |
| SpanCompat.cs | `src/Avalonia.Build.Tasks/SpanCompat.cs` | ソース | Span互換性 |
| XamlCompilerDiagnosticsFilter.cs | `src/Avalonia.Build.Tasks/XamlCompilerDiagnosticsFilter.cs` | ソース | 診断フィルター |
| ComInteropHelper.cs | `src/Avalonia.Build.Tasks/ComInteropHelper.cs` | ソース | COM相互運用 |
