# 機能設計書 15-バックグラウンドコンパイラ

## 概要

本ドキュメントは、F#コンパイラサービスのバックグラウンドコンパイラ（BackgroundCompiler）の機能設計を記述する。BackgroundCompilerは、IDEでのリアルタイムなコード解析を実現するため、ファイルのパースと型チェックをバックグラウンドで非同期に実行する。

### 本機能の処理概要

BackgroundCompilerは、ユーザーのコード編集に応じてバックグラウンドでパースと型チェックを実行し、結果をキャッシュして高速な応答を実現する。

**業務上の目的・背景**：IDEでのリアルタイムなIntelliSense、エラー表示、シンボル解決を実現するには、コード変更に迅速に対応する必要がある。BackgroundCompilerはこれらの処理をバックグラウンドで非同期に実行し、UIスレッドをブロックしない。

**機能の利用シーン**：
- Visual StudioでのF#コード編集
- VS CodeでのF#開発
- コード補完候補の提供
- リアルタイムエラー検出

**主要な処理内容**：
1. ファイルのパースとキャッシュ管理
2. インクリメンタルビルダーの生成と管理
3. ファイル単位の型チェック
4. プロジェクト全体のチェック
5. 結果のキャッシュと無効化

**関連システム・外部連携**：
- FSharpChecker（API層）
- IncrementalBuilder（インクリメンタルビルド）
- TransparentCompiler（代替実装）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | テキストエディタ | 主機能 | リアルタイムパース、エラー検出 |
| 4 | エラー一覧 | 出力先 | 診断情報の表示 |

## 機能種別

非同期コンパイル / キャッシュ管理 / インクリメンタルビルド

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| fileName | string | Yes | ソースファイル名 | 有効なファイルパス |
| sourceText | ISourceText | Yes | ソースコード | - |
| options | FSharpProjectOptions | Yes | プロジェクトオプション | - |
| parsingOptions | FSharpParsingOptions | Yes | パースオプション | - |

### 入力データソース

- エディタバッファからのソースコード
- プロジェクトシステムからのオプション

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| FSharpParseFileResults | FSharpParseFileResults | パース結果 |
| FSharpCheckFileResults | FSharpCheckFileResults | 型チェック結果 |
| FSharpCheckFileAnswer | FSharpCheckFileAnswer | チェック応答（成功/中断） |

### 出力先

- キャッシュ（parseFileCache, checkFileInProjectCache）
- イベント経由で通知

## 処理フロー

### 処理シーケンス

```
1. パースリクエスト受信
   └─ キャッシュ確認、ヒットすれば返却
2. パース実行
   └─ ParseAndCheckFile.parseFileを呼び出し
3. 結果キャッシュ
   └─ ハッシュ値をキーとしてキャッシュ
4. 型チェックリクエスト
   └─ IncrementalBuilder取得/生成
5. 依存ファイルチェック
   └─ 先行ファイルの型チェック結果を取得
6. ファイル型チェック
   └─ FSharpCheckFileResults.CheckOneFile
7. 結果キャッシュと通知
```

### フローチャート

```mermaid
flowchart TD
    A[パースリクエスト] --> B{キャッシュヒット?}
    B -->|Yes| C[キャッシュ結果返却]
    B -->|No| D[ParseFile実行]
    D --> E[結果キャッシュ]
    E --> F[FSharpParseFileResults]

    G[型チェックリクエスト] --> H{キャッシュヒット?}
    H -->|Yes| I[キャッシュ結果返却]
    H -->|No| J[IncrementalBuilder取得]
    J --> K[依存ファイルチェック]
    K --> L[CheckOneFile]
    L --> M[結果キャッシュ]
    M --> N[FSharpCheckFileAnswer]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ハッシュベースキャッシュ | ソースコードのハッシュ値でキャッシュキーを生成 | パース/チェック時 |
| BR-02 | スタンプ比較 | ProjectTimeStampでキャッシュ有効性を判定 | キャッシュ取得時 |
| BR-03 | 類似ビルダー再利用 | オプションが類似していれば既存ビルダーを再利用 | getSimilarOrCreateBuilder |
| BR-04 | 統計カウンタ | actualParseFileCount/actualCheckFileCountで実行回数を追跡 | パース/チェック時 |

### 計算ロジック

キャッシュキー: `(fileName, sourceText.GetHashCode(), options)`

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ビルダー生成失敗 | プロジェクト設定が不正 | creationDiagsとしてエラー返却 |
| - | キャッシュ無効化 | タイムスタンプ不一致 | キャッシュを削除して再計算 |

### リトライ仕様

キャッシュミス時は自動的に再計算。

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

該当なし

## パフォーマンス要件

- キャッシュヒット時: 即座に結果返却
- パース: 数十ms以内
- 型チェック: インクリメンタルビルドで最適化

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

特になし

## 備考

- GraphNodeを使用した遅延評価
- parseCacheLockでスレッドセーフなキャッシュ操作

---

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BackgroundCompiler.fs | `src/Compiler/Service/BackgroundCompiler.fs` | キャッシュ構造（parseFileCache, checkFileInProjectCache） |

#### Step 2: パース処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BackgroundCompiler.fs | `src/Compiler/Service/BackgroundCompiler.fs` | ParseFile関数（561-616行目） |

**主要処理フロー**:
- **574-578行目**: キャッシュ確認
- **580-593行目**: ParseAndCheckFile.parseFile呼び出し
- **598行目**: 結果キャッシュ

#### Step 3: 型チェック処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | BackgroundCompiler.fs | `src/Compiler/Service/BackgroundCompiler.fs` | getCheckFileNode（529-559行目） |
| 3-2 | BackgroundCompiler.fs | `src/Compiler/Service/BackgroundCompiler.fs` | CheckOneFileImplAux（687-731行目） |

**主要処理フロー**:
- **532-533行目**: キャッシュキー生成
- **538-556行目**: GraphNodeでの遅延評価設定
- **705-727行目**: FSharpCheckFileResults.CheckOneFile呼び出し

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

```
BackgroundCompiler
    │
    ├─ ParseFile
    │      ├─ parseCacheLock.AcquireLock (キャッシュ確認)
    │      ├─ ParseAndCheckFile.parseFile
    │      └─ parseFileCache.Set (キャッシュ登録)
    │
    ├─ getOrCreateBuilder
    │      └─ IncrementalBuilder.CreateIncrementalBuilderAsync
    │
    ├─ CheckFileInProjectAllowingStaleCachedResults
    │      ├─ GetCachedCheckFileResult
    │      └─ CheckOneFileImpl
    │             ├─ getCheckFileNode (GraphNode取得)
    │             └─ FSharpCheckFileResults.CheckOneFile
    │
    └─ GetBackgroundParseResultsForFileInProject
           └─ builder.GetParseResultsForFile
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BackgroundCompiler.fs | `src/Compiler/Service/BackgroundCompiler.fs` | ソース | バックグラウンドコンパイラのコア実装 |
| IncrementalBuild.fs | `src/Compiler/Service/IncrementalBuild.fs` | ソース | インクリメンタルビルダー |
| ParseAndCheckInputs.fs | `src/Compiler/Driver/ParseAndCheckInputs.fs` | ソース | パース処理 |
| FSharpCheckerResults.fs | `src/Compiler/Service/FSharpCheckerResults.fs` | ソース | 結果型定義 |
