# アーキテクチャ設計書

## 概要

本ドキュメントは、F#コンパイラおよび関連ツール群（dotnet/fsharp）のアーキテクチャ設計を記述するものである。このプロジェクトは、F#言語のコンパイラ、コアライブラリ、エディタツール、Visual Studio統合、およびF# Interactiveを含む包括的な言語処理系である。

## システム全体構成

### アーキテクチャ概要図

アーキテクチャの詳細な構成図は[アーキテクチャ構成図.md](./アーキテクチャ構成図.md)を参照のこと。

### システム境界と外部連携

| 外部システム | 連携方式 | 用途 |
| --- | --- | --- |
| .NET SDK | CLI / NuGet | ビルドシステム統合、ランタイム依存関係解決 |
| MSBuild | MSBuild Tasks API | プロジェクトビルド統合（FSharp.Build） |
| Visual Studio | VSIX / Language Server Protocol | IDE統合、エディタ機能提供 |
| NuGet | NuGet Client API | パッケージ依存関係管理（F# Interactive） |
| .NET Runtime | System.Reflection.Emit | 動的コード生成（F# Interactive） |

## レイヤー構成

### アーキテクチャスタイル

本プロジェクトは**パイプライン・アーキテクチャ**を採用している。コンパイラは、ソースコードを入力として受け取り、複数のフェーズ（字句解析、構文解析、型検査、最適化、コード生成、IL出力）を順次通過させ、最終的に.NETアセンブリを出力する。

各フェーズは独立したモジュールとして設計されており、中間表現（AST、TypedTree、Abstract IL）を介してデータを受け渡す。これにより、各フェーズの責務が明確に分離され、保守性と拡張性が確保されている。

### レイヤー定義

| レイヤー | 責務 | 主なコンポーネント |
| --- | --- | --- |
| Utilities | コンパイラ非依存の汎用ユーティリティ | illib.fs, FileSystem.fs, Caches.fs, TaggedCollections.fs |
| Facilities | コンパイラ固有の基盤機能 | DiagnosticsLogger.fs, LanguageFeatures.fs, prim-lexing.fs, prim-parsing.fs |
| AbstractIL | .NET IL の読み書き・操作 | il.fs, ilread.fs, ilwrite.fs, ilreflect.fs |
| SyntaxTree | 字句解析・構文解析・AST定義 | lex.fsl, pars.fsy, SyntaxTree.fs, LexFilter.fs |
| TypedTree | 型付き構文木・型システム基盤 | TypedTree.fs, TypedTreeOps.fs, TcGlobals.fs |
| Checking | 型検査・名前解決・制約解決 | CheckDeclarations.fs, ConstraintSolver.fs, NameResolution.fs |
| Optimize | 最適化・lowering処理 | Optimizer.fs, LowerStateMachines.fs, InnerLambdasToTopLevelFuncs.fs |
| CodeGen | ILコード生成 | IlxGen.fs, EraseClosures.fs, EraseUnions.fs |
| Driver | コンパイラ統合・オプション処理 | fsc.fs, CompilerConfig.fs, ParseAndCheckInputs.fs |
| Symbols | 公開シンボルAPI | Symbols.fs, FSharpDiagnostic.fs, Exprs.fs |
| Service | 言語サービスAPI・インクリメンタルビルド | service.fs, BackgroundCompiler.fs, IncrementalBuild.fs |
| Interactive | F# Interactive REPL | fsi.fs, FSharpInteractiveServer.fs |

### レイヤー間の依存関係ルール

依存関係は以下の方向に制限される（上位から下位への依存のみ許可）：

1. **Service/Interactive** → Driver → CodeGen → Optimize → Checking → TypedTree → SyntaxTree → Facilities → Utilities
2. **AbstractIL** は SyntaxTree/TypedTree と並列し、CodeGen/Driver から参照される
3. **Symbols** は Service から参照され、TypedTree/Checking の上位に位置する

禁止される参照：
- 下位レイヤーから上位レイヤーへの直接参照
- Utilities からの他コンパイラモジュールへの参照
- SyntaxTree から Checking への直接参照（TypedTree を経由すること）

## モジュール構成

### ドメイン分割

| ドメイン | 責務 | 関連モジュール |
| --- | --- | --- |
| Lexing/Parsing | ソースコードのトークン化とAST生成 | lex.fsl, pars.fsy, LexFilter.fs, ParseHelpers.fs |
| Type System | 型定義・型推論・制約解決 | TypedTree.fs, ConstraintSolver.fs, infos.fs |
| Name Resolution | 名前空間・スコープ・オーバーロード解決 | NameResolution.fs, AccessibilityLogic.fs |
| Pattern Matching | パターンマッチのコンパイル | PatternMatchCompilation.fs, CheckPatterns.fs |
| Optimization | インライン化・lambda lifting | Optimizer.fs, InnerLambdasToTopLevelFuncs.fs |
| IL Generation | F#コードからILへの変換 | IlxGen.fs, EraseClosures.fs, EraseUnions.fs |
| Language Service | IDE統合・インクリメンタル解析 | service.fs, BackgroundCompiler.fs |

### パッケージ構造

```
src/
├── Compiler/                      # FSharp.Compiler.Service
│   ├── Utilities/                 # 汎用ユーティリティ
│   ├── Facilities/                # コンパイラ基盤機能
│   ├── AbstractIL/                # .NET IL操作
│   ├── SyntaxTree/                # 構文解析・AST
│   ├── TypedTree/                 # 型付き構文木
│   ├── Checking/                  # 型検査
│   │   └── Expressions/           # 式の型検査
│   ├── Optimize/                  # 最適化
│   ├── CodeGen/                   # コード生成
│   ├── Driver/                    # ドライバー
│   │   └── GraphChecking/         # 並列型検査用グラフ
│   ├── Symbols/                   # シンボルAPI
│   ├── Service/                   # 言語サービス
│   ├── Interactive/               # F# Interactive
│   ├── DependencyManager/         # 依存関係管理
│   └── Legacy/                    # レガシー互換
├── FSharp.Core/                   # F#コアライブラリ
├── FSharp.Build/                  # MSBuildタスク
├── FSharp.Compiler.LanguageServer/ # Language Server
├── FSharp.DependencyManager.Nuget/ # NuGet依存関係
├── fsc/                           # コンパイラ実行ファイル
└── fsi/                           # F# Interactive実行ファイル
```

### コンポーネント依存関係

FSharp.Compiler.Serviceは以下の主要コンポーネント間依存を持つ：

- **fsc** (コンパイラ実行ファイル) → FSharp.Compiler.Service
- **fsi** (F# Interactive) → FSharp.Compiler.Service
- **FSharp.Editor** (VS拡張) → FSharp.Compiler.Service
- **FSharp.Compiler.LanguageServer** → FSharp.Compiler.Service
- **FSharp.Compiler.Service** → FSharp.Core, FSharp.DependencyManager.Nuget

## ミドルウェア構成

### データベース

本プロジェクトはデータベースを使用しない。コンパイル状態はメモリ内キャッシュで管理される。

| 種類 | ミドルウェア | バージョン | 用途 |
| --- | --- | --- | --- |
| - | - | - | 該当なし |

### キャッシュ

| ミドルウェア | バージョン | 用途 | TTL |
| --- | --- | --- | --- |
| インメモリキャッシュ (Caches.fs) | N/A | 型情報・解析結果のキャッシュ | セッション依存 |
| LruCache (LruCache.fs) | N/A | 最近使用されたエントリの保持 | 容量ベース |
| AsyncMemoize (AsyncMemoize.fs) | N/A | 非同期計算結果のメモ化 | 呼び出し依存 |

### メッセージキュー

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| - | - | 該当なし |

### 検索エンジン

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| - | - | 該当なし |

### その他ミドルウェア

| ミドルウェア | バージョン | 用途 |
| --- | --- | --- |
| System.Reflection.Metadata | SDK依存 | .NETメタデータ読み取り |
| System.Reflection.Emit | SDK依存 | 動的コード生成（F# Interactive） |
| System.Collections.Immutable | SDK依存 | 不変コレクション |

## データフロー

### リクエスト処理の流れ

コンパイル処理（fsc）の同期フロー：

1. **入力受付**: ソースファイル（.fs/.fsi）とコマンドライン引数を受け取る
2. **字句解析（Lexing）**: lex.fslで定義されたトークナイザがトークンストリームを生成
3. **空白文字感知変換（LexFilter）**: F#のオフサイドルールに基づきトークンを補正
4. **構文解析（Parsing）**: pars.fsyで定義された文法に基づきAST（SyntaxTree）を生成
5. **参照解決**: 外部アセンブリのメタデータを読み込み
6. **型検査（Type Checking）**: ASTからTypedTreeを生成、型推論・制約解決を実行
7. **パターンマッチコンパイル**: パターンマッチ式を低レベル表現に変換
8. **最適化（Optimization）**: インライン化、lambda lifting等の最適化を適用
9. **コード生成（Code Generation）**: TypedTreeからAbstract ILを生成
10. **IL出力（IL Emit）**: Abstract ILから.NETアセンブリ（.dll/.exe）を出力

### 非同期処理の流れ

F# Interactive (fsi) およびLanguage Serviceの非同期フロー：

1. **入力受付**: REPLコマンドまたはエディタからの解析要求を受信
2. **インクリメンタル解析**: 変更されたファイルのみを再解析（BackgroundCompiler）
3. **依存グラフ更新**: ファイル間依存関係を更新（GraphChecking）
4. **型検査**: 差分型検査を実行
5. **結果キャッシュ**: 解析結果をAsyncMemoizeでキャッシュ
6. **応答返却**: 補完候補、診断情報などをクライアントに返却

### データ永続化の流れ

本システムはステートレスであり、永続化は以下に限定される：

1. **出力アセンブリ**: コンパイル結果の.dll/.exeファイル
2. **PDBファイル**: デバッグ情報
3. **XMLドキュメント**: ドキュメントコメントの出力

## 横断的関心事

### 認証・認可

| 方式 | 実装箇所 | 対象 |
| --- | --- | --- |
| 該当なし | - | コンパイラはローカル実行であり認証不要 |

### ロギング・監査

| 種類 | 実装方式 | 保存先 |
| --- | --- | --- |
| コンパイラ診断 | DiagnosticsLogger.fs | 標準出力/エラー出力 |
| パフォーマンス計測 | Activity.fs (System.Diagnostics.Activity) | 診断リスナー |
| 言語サービスログ | FSharpLanguageServer.fs | Language Server Protocol経由 |

### エラーハンドリング

コンパイラエラーは階層的に処理される：

| エラー種別 | ハンドリング方式 | レスポンス |
| --- | --- | --- |
| 構文エラー | ParseHelpers.fs で検出、即座に診断生成 | エラー位置とメッセージ |
| 型エラー | ConstraintSolver.fs/CheckExpressions.fs で検出 | 型不一致の詳細情報 |
| 名前解決エラー | NameResolution.fs で検出 | 候補の提案を含む診断 |
| 内部エラー | 例外キャッチ、DiagnosticsLoggerで報告 | 内部エラーとして報告 |

### トランザクション管理

| 範囲 | 管理方式 | 分離レベル |
| --- | --- | --- |
| 該当なし | - | コンパイラはトランザクション不要 |

## 設計原則・コーディング規約

### 適用している設計原則

| 原則 | 適用箇所 | 実装例 |
| --- | --- | --- |
| 関数型設計 | 全体 | 不変データ構造、純粋関数の多用 |
| 段階的変換 | コンパイルパイプライン | AST → TypedTree → AbstractIL の段階的変換 |
| 関心の分離 | レイヤー構成 | 各フェーズの独立モジュール化 |
| 型駆動開発 | 全体 | 判別共用体による状態・エラー表現 |
| インターフェース分離 | Service層 | .fsiファイルによる公開APIの明示的定義 |

### コーディング規約

- **命名規則**: F# Style Guideに準拠、略語は避ける（例: `bodyTy` ではなく `bodyType`）
- **インデント**: F#のオフサイドルールに従う
- **ティック識別子の回避**: デバッガでの視認性のため `body'` より `bodyR` を使用
- **List.iter/Array.iterの回避**: デバッグ容易性のため `for ... do ...` ループを使用
- **シグネチャファイル**: 公開APIは.fsiファイルで明示的に定義
- **自動フォーマット**: Fantomas使用（.fantomasignore/.editorconfig参照）

## 備考

### ブートストラップ

F#コンパイラはブートストラップされている。既存のF#コンパイラを使用して「proto」コンパイラをビルドし、その「proto」コンパイラで自身をコンパイルして「final」コンパイラを生成する。

### 主要な外部依存

- **.NET SDK**: 10.0.101（global.json参照）
- **Microsoft.DotNet.Arcade.Sdk**: 10.0.0-beta.26110.1
- **FsLex/FsYacc**: buildtools/配下のカスタムビルド

### 関連ドキュメント

- [Compiler Documentation](https://fsharp.github.io/fsharp-compiler-docs/)
- [F# Language Specification](https://fsharp.org/specs/language-spec/)
- [DEVGUIDE.md](../../DEVGUIDE.md)
- [TESTGUIDE.md](../../TESTGUIDE.md)
