# 機能設計書 14-FSharpChecker

## 概要

本ドキュメントは、F#コンパイラサービスの中核となるFSharpCheckerクラスの機能設計を記述する。FSharpCheckerは、IDE統合やコード分析ツールに対して、F#ソースコードのパース、型チェック、IntelliSense機能を提供するAPIを公開する。

### 本機能の処理概要

FSharpCheckerは、F#コンパイラの機能をサービスとして公開し、外部ツール（IDE、エディタ、分析ツール）からF#コードの解析・型チェック・コード補完などの機能を利用可能にする。

**業務上の目的・背景**：Visual StudioやVS CodeなどのIDEでF#のIntelliSense（コード補完、エラー検出、定義へのジャンプなど）を実現するには、コンパイラの解析機能にアクセスする必要がある。FSharpCheckerはこれらの機能を統一的なAPIとして提供し、ツール開発者が容易にF#言語サポートを実装できるようにする。

**機能の利用シーン**：
- Visual StudioのF#エディタでのIntelliSense
- VS Code + Ionide拡張機能
- F#スクリプトファイルの編集支援
- コード分析ツール（FSharpLint等）
- ドキュメント生成ツール

**主要な処理内容**：
1. ソースファイルのパース（AST生成）
2. プロジェクト全体の型チェック
3. インクリメンタル型チェック（ファイル単位）
4. スクリプトファイルのプロジェクトオプション推論
5. コード補完候補の生成
6. シンボル情報の提供
7. セマンティック分類（構文ハイライト用）

**関連システム・外部連携**：
- BackgroundCompiler（バックグラウンド処理）
- TransparentCompiler（透過コンパイラ）
- Visual Studio統合（FSharp.Editor）
- 言語サーバープロトコル（LSP）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | プロジェクトプロパティ | 補助機能 | プロジェクトオプションの設定 |
| 2 | テキストエディタ | 主機能 | IntelliSense、コード補完、エラー表示 |
| 3 | ソリューションエクスプローラー | 補助機能 | プロジェクト構成の取得 |
| 4 | エラー一覧 | 出力先 | コンパイル診断の表示 |
| 5 | 出力ウィンドウ | 出力先 | コンパイラ出力の表示 |

## 機能種別

コンパイラサービスAPI / IDE統合 / 言語解析

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- プロジェクトファイル（.fsproj）から取得したオプション
- エディタバッファのソースコード
- コマンドライン引数（スクリプト実行時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| FSharpParseFileResults | FSharpParseFileResults | パース結果（AST、診断情報） |
| FSharpCheckFileResults | FSharpCheckFileResults | 型チェック結果（シンボル情報、診断情報） |
| FSharpCheckProjectResults | FSharpCheckProjectResults | プロジェクト全体のチェック結果 |
| diagnostics | FSharpDiagnostic[] | エラー・警告情報 |

### 出力先

- API呼び出し元に返却
- イベント経由で通知（BeforeBackgroundFileCheck, FileChecked等）

## 処理フロー

### 処理シーケンス

```
1. プロジェクトオプション取得
   └─ GetProjectOptionsFromScript / GetProjectOptionsFromCommandLineArgs
2. パースリクエスト
   └─ ParseFile / ParseFileInProject
3. バックグラウンド型チェック開始
   └─ CheckFileInProject / CheckProjectInBackground
4. インクリメンタルビルド
   └─ IncrementalBuilder経由で依存ファイルを順次チェック
5. 結果通知
   └─ イベント発火、結果オブジェクト返却
```

### フローチャート

```mermaid
flowchart TD
    A[ソースコード変更] --> B[ParseFile]
    B --> C[FSharpParseFileResults]
    C --> D{プロジェクトコンテキスト?}
    D -->|Yes| E[CheckFileInProject]
    D -->|No| F[スタンドアロンパース]
    E --> G[BackgroundCompiler処理]
    G --> H[依存ファイルチェック]
    H --> I[FSharpCheckFileResults]
    I --> J[イベント通知]
    J --> K[IDE更新]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | シングルトン | FSharpChecker.Instanceでグローバルインスタンスを提供 | 共有使用時 |
| BR-02 | 非同期処理 | 重い処理は非同期（Async）で実行 | 常時 |
| BR-03 | キャッシュ | パース/チェック結果をキャッシュして再利用 | 同一内容の再チェック時 |
| BR-04 | INTERACTIVE定義 | スクリプト実行時は--define:INTERACTIVEを追加 | isInteractive=true |
| BR-05 | EDITING定義 | 編集モード時は--define:EDITINGを追加 | isEditing=true |

### 計算ロジック

なし（コンパイラ解析機能の提供）

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

### 操作別データベース影響一覧

該当なし（データベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パースエラー | 構文が不正 | FSharpDiagnosticとして返却 |
| - | 型エラー | 型チェック失敗 | FSharpDiagnosticとして返却 |
| - | 参照解決失敗 | アセンブリが見つからない | 診断情報として報告 |

### リトライ仕様

バックグラウンド処理は自動的にキャンセル・再開される。

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

該当なし

## パフォーマンス要件

- パース処理: 数十ms以内
- インクリメンタルチェック: 前回結果を活用して高速化
- メモリ使用量: keepAssemblyContents等のオプションで制御

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

- ソースコードの安全な取り扱い
- 外部アセンブリ参照の信頼性確認

## 備考

- parallelReferenceResolutionオプションで並列参照解決
- useSyntaxTreeCacheオプションで構文木キャッシュ
- captureIdentifiersWhenParsingでパース時に識別子をキャプチャ

---

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

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

### 推奨読解順序

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

まず、FSharpCheckerで使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | service.fs | `src/Compiler/Service/service.fs` | FSharpChecker型の定義 |
| 1-2 | service.fs | `src/Compiler/Service/service.fs` | FSharpProjectOptions型の構築（561-573行目） |

**読解のコツ**: FSharpProjectOptionsはプロジェクトの設定を保持。SourceFiles、OtherOptions、ReferencedProjectsが主要フィールド。

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

処理の起点となる関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | service.fs | `src/Compiler/Service/service.fs` | GetProjectOptionsFromScript（505-539行目） |
| 2-2 | service.fs | `src/Compiler/Service/service.fs` | GetProjectOptionsFromCommandLineArgs（541-573行目） |
| 2-3 | service.fs | `src/Compiler/Service/service.fs` | GetParsingOptionsFromCommandLineArgs（575-609行目） |

**主要処理フロー**:
- **505-539行目**: スクリプトファイルからプロジェクトスナップショットを取得
- **541-573行目**: コマンドライン引数からプロジェクトオプションを構築
- **575-609行目**: パースオプションの生成、条件定義の設定

#### Step 3: イベント通知を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | service.fs | `src/Compiler/Service/service.fs` | イベントプロパティ（611-617行目） |

**主要処理フロー**:
- **611行目**: BeforeBackgroundFileCheck - バックグラウンドチェック開始前
- **613行目**: FileParsed - ファイルパース完了
- **615行目**: FileChecked - ファイル型チェック完了
- **617行目**: ProjectChecked - プロジェクト全体チェック完了

#### Step 4: トークナイザを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | service.fs | `src/Compiler/Service/service.fs` | TokenizeLine（628-640行目） |
| 4-2 | service.fs | `src/Compiler/Service/service.fs` | TokenizeFile（643-656行目） |

**主要処理フロー**:
- **628-640行目**: 1行のトークン化、状態を維持して次の行へ
- **643-656行目**: ファイル全体のトークン化

#### Step 5: CompilerEnvironmentを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | service.fs | `src/Compiler/Service/service.fs` | CompilerEnvironmentクラス（669-725行目） |

**主要処理フロー**:
- **676-677行目**: BinFolderOfDefaultFSharpCompiler - コンパイラバイナリの場所
- **697-699行目**: GetConditionalDefinesForEditing - 編集用条件定義
- **711行目**: IsScriptFile - スクリプトファイル判定
- **714-718行目**: IsCompilable - コンパイル可能ファイル判定

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

```
FSharpChecker (API層)
    │
    ├─ GetProjectOptionsFromScript
    │      └─ backgroundCompiler.GetProjectSnapshotFromScript
    │
    ├─ GetProjectOptionsFromCommandLineArgs
    │      └─ FSharpProjectOptions構築
    │
    ├─ GetParsingOptionsFromCommandLineArgs
    │      ├─ TcConfigBuilder.CreateNew
    │      ├─ ApplyCommandLineArgs
    │      └─ FSharpParsingOptions.FromTcConfigBuilder
    │
    ├─ ParseFile / ParseFileInProject
    │      └─ backgroundCompiler.ParseFile
    │
    ├─ CheckFileInProject
    │      └─ backgroundCompiler.CheckFileInProject
    │
    └─ イベント (BeforeBackgroundFileCheck, FileParsed, FileChecked, ProjectChecked)
           └─ BackgroundCompiler経由で発火
```

### データフロー図

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

ソースコード ────────▶ FSharpChecker.ParseFile ─────▶ FSharpParseFileResults
     │                      │
     │                      ▼
プロジェクト設定 ──────▶ BackgroundCompiler ─────────▶ キャッシュ
     │                      │
     │                      ▼
     │              CheckFileInProject
     │                      │
     │                      ▼
     │              FSharpCheckFileResults
     │                      │
     │                      ▼
IDE ◀──────────────── イベント通知
                            │
                            ├─ FileParsed
                            ├─ FileChecked
                            └─ ProjectChecked
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| service.fs | `src/Compiler/Service/service.fs` | ソース | FSharpCheckerのパブリックAPI |
| BackgroundCompiler.fs | `src/Compiler/Service/BackgroundCompiler.fs` | ソース | バックグラウンド処理実装 |
| TransparentCompiler.fs | `src/Compiler/Service/TransparentCompiler.fs` | ソース | 透過コンパイラ実装 |
| FSharpCheckerResults.fs | `src/Compiler/Service/FSharpCheckerResults.fs` | ソース | 結果型の定義 |
| ServiceDeclarationLists.fs | `src/Compiler/Service/ServiceDeclarationLists.fs` | ソース | 補完候補生成 |
| IncrementalBuild.fs | `src/Compiler/Service/IncrementalBuild.fs` | ソース | インクリメンタルビルド |
