# 機能設計書 1-F#コンパイラ（fsc）

## 概要

本ドキュメントは、F#コンパイラ（fsc）の機能設計を記述する。F#コンパイラは、F#ソースコードを.NET IL（中間言語）にコンパイルする中核機能であり、パース、型チェック、最適化、ILコード生成の各フェーズを統合的に実行する。

### 本機能の処理概要

F#コンパイラ（fsc）は、F#言語で記述されたソースコードを.NETプラットフォーム上で実行可能な中間言語（IL）バイナリに変換するコンパイラである。

**業務上の目的・背景**：F#は関数型プログラミングを第一級でサポートする.NET言語であり、型安全性と表現力の高さを両立している。fscは、この言語仕様を忠実に実装し、開発者が記述したF#コードを.NETランタイム上で効率的に実行できるバイナリに変換する役割を担う。コンパイラは、静的型付け言語としての型安全性を保証しながら、最適化によって高性能なコードを生成する。

**機能の利用シーン**：開発者がF#プロジェクトをビルドする際、MSBuildまたはコマンドラインからfscが呼び出される。IDEでのインクリメンタルビルド、CI/CDパイプラインでの本番ビルド、スクリプトコンパイルなど、あらゆるF#コードのコンパイル時に本機能が使用される。

**主要な処理内容**：
1. コマンドライン引数の解析とコンパイラ設定の構築（TcConfigBuilder）
2. ソースファイルの解析（パース）と構文木（AST）の生成
3. 参照アセンブリのインポートとTcImportsの構築
4. 型チェック（型推論、制約解決、エラー検出）の実行
5. シグネチャデータと最適化データのエンコード
6. 最適化パスの適用（インライン化、定数畳み込み等）
7. ILコード生成（IlxGen）
8. 静的リンク（オプション）
9. .NETバイナリ（.dll/.exe）の出力

**関連システム・外部連携**：.NET SDK、MSBuild、NuGetパッケージマネージャーと連携する。型プロバイダーを通じて外部データソース（SQLデータベース、JSONスキーマ等）とも連携可能。

**権限による制御**：コンパイラ自体には権限制御は存在しないが、コンパイルオプション（--standalone、--optimize等）によって出力形式や最適化レベルを制御できる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | ビルドプロパティページ | 主画面 | コンパイルオプション、出力パス、デバッグ情報等のビルド設定 |

## 機能種別

コンパイル処理（ソースコード変換）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sourceFiles | string list | Yes | コンパイル対象のF#ソースファイルパス | .fs/.fsx/.fsi拡張子、ファイル存在確認 |
| --out | string | No | 出力ファイルパス | 有効なファイルパス |
| --target | string | No | 出力種別（exe/library/module） | exe/library/module/winexe |
| --reference | string list | No | 参照アセンブリ | アセンブリ参照解決可能 |
| --optimize | bool | No | 最適化有効/無効 | +/-形式 |
| --debug | string | No | デバッグ情報形式 | full/pdbonly/portable/embedded |
| --define | string list | No | 条件付きコンパイルシンボル | 有効な識別子 |
| --nowarn | int list | No | 抑制する警告番号 | 有効な警告番号 |

### 入力データソース

- ファイルシステム上のF#ソースファイル（.fs、.fsi、.fsx）
- NuGetパッケージからの参照アセンブリ
- SDKからのフレームワークアセンブリ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| outputAssembly | .dll/.exe | コンパイル済み.NETアセンブリ |
| pdbFile | .pdb | デバッグ情報ファイル（オプション） |
| xmlDocFile | .xml | XMLドキュメントファイル（オプション） |
| interfaceFile | .fsi | 生成されたシグネチャファイル（--sigオプション時） |

### 出力先

- 指定された出力ディレクトリまたは現在のディレクトリ

## 処理フロー

### 処理シーケンス

```
1. main1: 初期化フェーズ
   ├─ コンソールエンコーディング設定
   ├─ TcConfigBuilder作成
   ├─ コマンドライン引数解析（ProcessCommandLineFlags）
   ├─ スクリプトコンパイル調整（AdjustForScriptCompile）
   ├─ フレームワークアセンブリインポート
   ├─ ソースファイルパース（ParseInputFiles）
   └─ 型チェック実行（CheckClosedInputSet）

2. main2: シグネチャ出力フェーズ
   ├─ シグネチャファイル書き出し（--sig時）
   ├─ アセンブリバージョン属性検証
   └─ XMLドキュメント生成

3. main3: 最適化フェーズ
   ├─ シグネチャデータエンコード
   ├─ 最適化実行（ApplyAllOptimizations）
   ├─ 最適化データエンコード
   └─ 末尾呼び出しチェック

4. main4: ILコード生成フェーズ
   ├─ 静的リンカー準備
   ├─ IlxAssemblyGenerator作成
   ├─ ILコード生成（GenerateIlxCode）
   └─ メインモジュール構築

5. main5: 静的リンクフェーズ
   └─ 依存アセンブリの静的リンク（オプション）

6. main6: バイナリ出力フェーズ
   ├─ ILBinaryWriter.WriteILBinaryFile
   ├─ FSharp.Core.dllコピー（オプション）
   └─ 完了報告
```

### フローチャート

```mermaid
flowchart TD
    A[開始: コマンドライン引数] --> B[TcConfigBuilder構築]
    B --> C[参照アセンブリ解決]
    C --> D[ソースファイルパース]
    D --> E{パースエラー?}
    E -->|Yes| F[エラー報告・終了]
    E -->|No| G[型チェック実行]
    G --> H{型エラー?}
    H -->|Yes| F
    H -->|No| I[最適化実行]
    I --> J[ILコード生成]
    J --> K[静的リンク]
    K --> L[バイナリ出力]
    L --> M[終了: 成功]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | ソースファイル必須 | 少なくとも1つの実装ファイル（.fs）が必要 | 常時 |
| BR-002 | エントリーポイント | exe出力時はmain関数または[<EntryPoint>]属性が必要 | --target:exe時 |
| BR-003 | 循環参照禁止 | モジュール間の循環参照は禁止 | 常時 |
| BR-004 | シグネチャ整合性 | .fsiファイルと.fsファイルの型定義は一致必須 | .fsi存在時 |

### 計算ロジック

コンパイルフェーズは6段階（main1〜main6）に分割され、各フェーズは前フェーズの出力を入力として受け取る。エラー発生時は即座にexiter.Exitが呼び出され、コンパイルが中断される。

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

該当なし（ファイルベースの処理）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FS0001 | 型エラー | 型の不一致 | 型注釈の追加または修正 |
| FS0039 | 未定義識別子 | 存在しない識別子の参照 | 識別子の定義または参照の修正 |
| FS0041 | パターンマッチ不完全 | パターンの網羅性不足 | ワイルドカードパターンの追加 |
| FS2024 | 静的リンクエラー | 静的リンク不可能なアセンブリ | --standaloneオプションの見直し |

### リトライ仕様

コンパイラはリトライを行わない。エラー発生時はエラーコードとともにプロセスが終了する。

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

該当なし（ファイル出力はアトミックではない）

## パフォーマンス要件

- 中規模プロジェクト（100ファイル程度）で数秒〜数十秒以内のコンパイル完了
- --parallelオプションによる参照解決の並列化をサポート
- インクリメンタルビルド時は変更ファイルのみ再コンパイル

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

- 型プロバイダーの実行には信頼されたアセンブリのみを使用すべき
- コンパイル時コード実行（型プロバイダー）のサンドボックス化は限定的

## 備考

F#コンパイラはF#自身で実装されており、ブートストラップコンパイル可能。オープンソースとしてGitHubで開発されている。

---

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

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

### 推奨読解順序

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

コンパイラの設定と状態を表すデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CompilerConfig.fs | `src/Compiler/Driver/CompilerConfig.fs` | TcConfig、TcConfigBuilderの定義。コンパイラ設定の全体像を把握 |
| 1-2 | TypedTree.fs | `src/Compiler/TypedTree/TypedTree.fs` | 型付き構文木（TAST）の定義。コンパイラ内部表現の理解 |

**読解のコツ**: TcConfigBuilderはミュータブルな設定ビルダーで、コマンドライン解析中に更新される。TcConfigはイミュータブルな最終設定。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | fsc.fs | `src/Compiler/Driver/fsc.fs` | メインエントリーポイント。main1〜main6の6フェーズ構成を理解 |

**主要処理フロー**:
1. **434-687行目**: main1関数 - 初期化、パース、型チェック
2. **691-784行目**: main2関数 - シグネチャ出力、XMLドキュメント生成
3. **786-914行目**: main3関数 - 最適化実行、データエンコード
4. **916-1025行目**: main4関数 - ILコード生成
5. **1027-1071行目**: main5関数 - 静的リンク
6. **1073-1200行目**: main6関数 - バイナリ出力

#### Step 3: コマンドライン解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CompilerOptions.fs | `src/Compiler/Driver/CompilerOptions.fs` | コマンドラインオプションの定義と解析ロジック |

**主要処理フロー**:
- **ProcessCommandLineFlags関数（259-295行目）**: 引数解析とソースファイル収集

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ParseAndCheckInputs.fs | `src/Compiler/Driver/ParseAndCheckInputs.fs` | ParseInputFiles関数でソースをASTに変換 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | CheckDeclarations.fs | `src/Compiler/Checking/CheckDeclarations.fs` | トップレベル宣言の型チェック |
| 5-2 | CheckExpressions.fs | `src/Compiler/Checking/Expressions/CheckExpressions.fs` | 式の型チェック |

#### Step 6: 最適化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | Optimizer.fs | `src/Compiler/Optimize/Optimizer.fs` | 最適化パスの適用ロジック |
| 6-2 | OptimizeInputs.fs | `src/Compiler/Driver/OptimizeInputs.fs` | ApplyAllOptimizations関数 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 7-1 | IlxGen.fs | `src/Compiler/CodeGen/IlxGen.fs` | F#型付き構文木からILへの変換 |
| 7-2 | CreateILModule.fs | `src/Compiler/Driver/CreateILModule.fs` | ILモジュールの構築 |

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

```
CompileFromCommandLineArguments
    │
    ├─ main1 (初期化・パース・型チェック)
    │      ├─ ProcessCommandLineFlags
    │      ├─ AdjustForScriptCompile
    │      ├─ TcImports.BuildFrameworkTcImports
    │      ├─ ParseInputFiles
    │      └─ TypeCheck (CheckClosedInputSet)
    │
    ├─ main2 (シグネチャ・XMLドキュメント)
    │      ├─ InterfaceFileWriter.WriteInterfaceFile
    │      └─ XmlDocWriter.WriteXmlDocFile
    │
    ├─ main3 (最適化)
    │      ├─ EncodeSignatureData
    │      ├─ ApplyAllOptimizations
    │      └─ EncodeOptimizationData
    │
    ├─ main4 (ILコード生成)
    │      ├─ StaticLink準備
    │      ├─ CreateIlxAssemblyGenerator
    │      ├─ GenerateIlxCode
    │      └─ MainModuleBuilder.CreateMainModule
    │
    ├─ main5 (静的リンク)
    │      └─ staticLinker
    │
    └─ main6 (バイナリ出力)
           └─ ILBinaryWriter.WriteILBinaryFile
```

### データフロー図

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

ソースファイル(.fs)  ──▶  ParseInputFiles        ──▶  ParsedInput (AST)
                              │
参照アセンブリ       ──▶  TcImports構築          ──▶  TcGlobals, TcImports
                              │
                              ▼
ParsedInput          ──▶  TypeCheck              ──▶  TypedAssembly (TAST)
                              │
                              ▼
TypedAssembly        ──▶  ApplyAllOptimizations  ──▶  OptimizedAssembly
                              │
                              ▼
OptimizedAssembly    ──▶  GenerateIlxCode        ──▶  ILModuleDef
                              │
                              ▼
ILModuleDef          ──▶  WriteILBinaryFile      ──▶  .dll/.exe ファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| fsc.fs | `src/Compiler/Driver/fsc.fs` | ソース | コンパイラメインドライバー |
| CompilerConfig.fs | `src/Compiler/Driver/CompilerConfig.fs` | ソース | コンパイラ設定管理 |
| CompilerOptions.fs | `src/Compiler/Driver/CompilerOptions.fs` | ソース | コマンドラインオプション定義 |
| ParseAndCheckInputs.fs | `src/Compiler/Driver/ParseAndCheckInputs.fs` | ソース | パース・型チェック統合 |
| OptimizeInputs.fs | `src/Compiler/Driver/OptimizeInputs.fs` | ソース | 最適化統合 |
| CreateILModule.fs | `src/Compiler/Driver/CreateILModule.fs` | ソース | ILモジュール構築 |
| IlxGen.fs | `src/Compiler/CodeGen/IlxGen.fs` | ソース | ILコード生成 |
| ilwrite.fs | `src/Compiler/AbstractIL/ilwrite.fs` | ソース | ILバイナリ書き出し |
| StaticLinking.fs | `src/Compiler/Driver/StaticLinking.fs` | ソース | 静的リンク処理 |
| XmlDocFileWriter.fs | `src/Compiler/Driver/XmlDocFileWriter.fs` | ソース | XMLドキュメント出力 |
| CompilerDiagnostics.fs | `src/Compiler/Driver/CompilerDiagnostics.fs` | ソース | 診断メッセージ処理 |
