# F# Compiler (dotnet/fsharp) コードリーディングガイドライン

## はじめに

このガイドラインは、F#コンパイラ（dotnet/fsharp）のコードベースを効率的に理解するための手引きです。
F#に精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

**プロジェクト概要:**
このリポジトリはF#コンパイラ、F#コアライブラリ、およびF#エディタツールを含む.NET Foundation配下のオープンソースプロジェクトです。

---

## 1. 言語基礎

> このセクションでは、F#の基本構文と概念を解説します。

### 1.1 プログラム構造

F#は関数型言語であり、モジュールベースの構造を持ちます。各ファイルはモジュールとして扱われ、`module`キーワードで明示的に宣言できます。

**実例 (`src/Compiler/Driver/fsc.fs:12`)**
```fsharp
module internal FSharp.Compiler.Driver

open System
open System.Collections.Generic
open System.Diagnostics
open System.Globalization
open System.IO
```

- `module internal` は内部（internal）アクセス修飾子付きのモジュール宣言
- `open` は他のモジュールや名前空間のインポート
- `internal` キーワードはアセンブリ内部からのみアクセス可能であることを示す

### 1.2 データ型と変数

F#は強い型付け言語であり、判別共用体(Discriminated Union)やレコード型を多用します。

**判別共用体の例 (`src/Compiler/TypedTree/TypedTree.fs:43-58`)**
```fsharp
[<RequireQualifiedAccess>]
type ValInline =
    /// Indicates the value is inlined but the .NET IL code for the function still exists
    | Always
    /// Indicates the value may optionally be inlined by the optimizer
    | Optional
    /// Indicates the value must never be inlined by the optimizer
    | Never

    member x.ShouldInline =
        match x with
        | ValInline.Always -> true
        | ValInline.Optional | ValInline.Never -> false
```

- `type` キーワードで型を定義
- `|` で各ケース（バリアント）を区切る
- `member` でメンバー関数を定義
- `match ... with` でパターンマッチング

**レコード型の例 (`src/Compiler/Optimize/Optimizer.fs:98-99`)**
```fsharp
type ValInfo =
    { ValMakesNoCriticalTailcalls: bool }
```

- 波括弧 `{ }` でレコード型のフィールドを定義
- フィールド名: 型 の形式で定義

### 1.3 制御構造

F#ではパターンマッチングが主要な制御構造として使われます。

**パターンマッチングの例 (`src/Compiler/Driver/fsc.fs:77-97`)**
```fsharp
override x.DiagnosticSink(diagnostic) =
    let tcConfig = TcConfig.Create(tcConfigB, validate = false)

    match diagnostic.AdjustSeverity(tcConfig.diagnosticsOptions) with
    | FSharpDiagnosticSeverity.Error ->
        if errors >= tcConfig.maxErrors then
            x.HandleTooManyErrors(FSComp.SR.fscTooManyErrors ())
            exiter.Exit 1

        x.HandleIssue(tcConfig, diagnostic, FSharpDiagnosticSeverity.Error)
        errors <- errors + 1

    | FSharpDiagnosticSeverity.Hidden -> ()
    | s -> x.HandleIssue(tcConfig, diagnostic, s)
```

- `match ... with` でパターンマッチング
- `|` で各パターンを区切る
- `->` の後にそのパターンに対する処理を記述
- `()` は unit型（何もしない）

### 1.4 関数/メソッド定義

F#では `let` キーワードで関数を定義します。

**関数定義の例 (`src/Compiler/Driver/fsc.fs:100-111`)**
```fsharp
/// Create an error logger that counts and prints errors
let ConsoleDiagnosticsLogger (tcConfigB: TcConfigBuilder, exiter: Exiter) =
    { new DiagnosticsLoggerUpToMaxErrors(tcConfigB, exiter, "ConsoleDiagnosticsLogger") with

        member _.HandleTooManyErrors(text: string) =
            DoWithDiagnosticColor FSharpDiagnosticSeverity.Warning (fun () -> Printf.eprintfn "%s" text)

        member _.HandleIssue(tcConfig, diagnostic, severity) =
            DoWithDiagnosticColor severity (fun () ->
                writeViaBuffer stderr (fun buf -> diagnostic.Output(buf, tcConfig, severity))
                stderr.WriteLine())
    }
    :> DiagnosticsLogger
```

- `let` で関数定義
- `///` で XML ドキュメントコメント
- `{ new ... with }` でオブジェクト式（インターフェース実装）
- `:>` でアップキャスト

### 1.5 モジュール/インポート

F#では `open` キーワードでモジュールや名前空間をインポートします。

**インポートの例 (`src/Compiler/SyntaxTree/SyntaxTree.fs:1-11`)**
```fsharp
namespace rec FSharp.Compiler.Syntax

open System
open System.Diagnostics
open FSharp.Compiler.Syntax
open FSharp.Compiler.Text
open FSharp.Compiler.Text.Range
open FSharp.Compiler.Xml
open FSharp.Compiler.SyntaxTrivia
```

- `namespace rec` は再帰的な名前空間宣言
- `open` でモジュールを現在のスコープに取り込む

---

## 2. プロジェクト固有の概念

> このセクションでは、当プロジェクト特有の概念を解説します。

### 2.1 コンパイラパイプラインの主要フェーズ

F#コンパイラは以下の主要フェーズで構成されています：

1. **字句解析（Lexing）** - ソースコードをトークン列に変換
2. **構文解析（Parsing）** - トークン列を抽象構文木（AST）に変換
3. **型チェック（Type Checking）** - 型推論と型検査
4. **最適化（Optimization）** - コードの最適化
5. **コード生成（Code Generation）** - ILコードの生成
6. **バイナリ出力（Emit）** - 実行可能ファイルの生成

### 2.2 主要なデータ表現

| データ形式 | 説明 | 主要ファイル |
|-----------|------|-------------|
| AST (Abstract Syntax Tree) | パース後の未型付き構文木 | `SyntaxTree/SyntaxTree.fs` |
| Typed Tree | 型チェック後の型付き構文木 | `TypedTree/TypedTree.fs` |
| Abstract IL | .NET IL の抽象表現 | `AbstractIL/il.fs` |

**AST の例 (`src/Compiler/SyntaxTree/SyntaxTree.fs:13-24`)**
```fsharp
[<Struct; NoEquality; NoComparison; DebuggerDisplay("{idText}")>]
type Ident(text: string, range: range) =
    member _.idText = text
    member _.idRange = range

    member x.MakeSynthetic() =
        if range.IsSynthetic then
            x
        else
            Ident(text, range.MakeSynthetic())

    override _.ToString() = text
```

### 2.3 TcGlobals と環境オブジェクト

コンパイラ全体で共有される重要なオブジェクト：

- **TcGlobals (g)**: グローバルな型チェック情報
- **TcConfig**: コンパイラ設定
- **TcEnv**: 型チェック環境（スコープ内の名前など）

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `*.fs` | F#ソースファイル | `fsc.fs`, `Optimizer.fs` |
| `*.fsi` | F#シグネチャファイル（インターフェース定義） | `fsc.fsi`, `Optimizer.fsi` |
| `*.fsl` | FsLex字句解析器定義 | `lex.fsl` |
| `*.fsy` | FsYacc構文解析器定義 | `pars.fsy` |
| `PascalCase` | ディレクトリ名 | `SyntaxTree`, `TypedTree`, `Checking` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `Tc` | Type Checker関連 | `TcConfig`, `TcEnv`, `TcGlobals` |
| `Syn` | Syntax Tree関連 | `SynExpr`, `SynType`, `SynPat` |
| `IL` / `Ilx` | Abstract IL関連 | `ILModuleDef`, `IlxGen` |
| `ty` / `tys` | 型（Type） | `argty`, `tys` |
| `m` | ソースコード範囲（Range） | `m`, `mExpr` |
| `g` | TcGlobals インスタンス | `g.int_ty` |
| `env` | 環境オブジェクト | `env`, `tcEnv` |
| `cenv` | コンパイル環境 | `cenv` |
| `info` | メタデータオブジェクト | `minfo`, `pinfo`, `einfo` |
| `ref` | 参照オブジェクト | `vref`, `tcref`, `ucref` |
| `mk` | 生成関数（Make） | `mkSynId`, `mkTyparTy` |

### 3.3 一般的な略語一覧

| 略語 | 意味 |
|-----|------|
| `amap` | Assembly map（アセンブリマップ） |
| `ccu` | Compilation Unit（コンパイル単位、F# DLL参照） |
| `css` | Constraint Solver State（制約ソルバー状態） |
| `denv` | Display Environment（表示環境） |
| `lid` | Long Identifier（長い識別子） |
| `pat` | Pattern（パターン） |
| `rfref` | Record Field Reference（レコードフィールド参照） |
| `tau` | 型理論における型（forallノードを除いた型） |
| `tinst` | Type Instantiation（型インスタンス化） |
| `tpenv` | Type Parameter Environment（型パラメータ環境） |
| `typar` | Type Parameter（型パラメータ） |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
fsharp-main/
├── src/
│   ├── Compiler/                    # F#コンパイラサービス本体
│   │   ├── AbstractIL/              # Abstract IL 処理
│   │   ├── Checking/                # 型チェック
│   │   │   └── Expressions/         # 式の型チェック
│   │   ├── CodeGen/                 # ILコード生成
│   │   ├── DependencyManager/       # 依存関係管理
│   │   ├── Driver/                  # コンパイラドライバ
│   │   │   └── GraphChecking/       # 並列型チェック
│   │   ├── Facilities/              # コンパイラ機能
│   │   ├── Interactive/             # F# Interactive
│   │   ├── Optimize/                # 最適化
│   │   ├── Service/                 # コンパイラサービスAPI
│   │   ├── Symbols/                 # シンボルAPI
│   │   ├── SyntaxTree/              # 構文木
│   │   ├── TypedTree/               # 型付き構文木
│   │   └── Utilities/               # ユーティリティ
│   ├── FSharp.Core/                 # F#コアライブラリ
│   ├── FSharp.Build/                # MSBuildタスク
│   ├── fsc/                         # コンパイラ実行ファイル
│   └── fsi/                         # F# Interactive実行ファイル
├── tests/                           # テストスイート
├── vsintegration/                   # Visual Studio統合
├── docs/                            # ドキュメント
└── buildtools/                      # ビルドツール（fslex, fsyacc）
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `src/Compiler/AbstractIL/` | .NET IL の読み書き | `il.fs`, `ilread.fs`, `ilwrite.fs` |
| `src/Compiler/SyntaxTree/` | 構文解析、AST定義 | `SyntaxTree.fs`, `LexHelpers.fs` |
| `src/Compiler/TypedTree/` | 型付き構文木定義 | `TypedTree.fs`, `TypedTreeOps.fs` |
| `src/Compiler/Checking/` | 型チェックロジック | `CheckDeclarations.fs`, `ConstraintSolver.fs` |
| `src/Compiler/Optimize/` | 最適化パス | `Optimizer.fs`, `InnerLambdasToTopLevelFuncs.fs` |
| `src/Compiler/CodeGen/` | ILコード生成 | `IlxGen.fs`, `EraseClosures.fs` |
| `src/Compiler/Driver/` | コンパイラ起動、設定 | `fsc.fs`, `CompilerConfig.fs` |
| `src/Compiler/Service/` | エディタサービスAPI | `service.fs`, `IncrementalBuild.fs` |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

F#コンパイラはパイプラインアーキテクチャを採用しており、各フェーズが順次データを変換していきます。

```mermaid
flowchart TD
    subgraph Input["入力"]
        Source["ソースファイル (.fs, .fsx)"]
        Refs["参照アセンブリ"]
    end

    subgraph Lexing["字句解析"]
        BasicLex["基本字句解析"]
        WhitespaceLex["空白感知字句解析"]
    end

    subgraph Parsing["構文解析"]
        Parser["パーサー"]
        AST["AST"]
    end

    subgraph TypeChecking["型チェック"]
        Import["インポート"]
        Check["型チェック"]
        Constraint["制約ソルバー"]
        TypedTree["Typed Tree"]
    end

    subgraph Optimization["最適化"]
        Optimizer["オプティマイザー"]
        TLF["トップレベル関数変換"]
    end

    subgraph CodeGen["コード生成"]
        IlxGen["ILX生成"]
        Erase["クロージャ/共用体消去"]
        AbstractIL["Abstract IL"]
    end

    subgraph Emit["出力"]
        Binary["バイナリ出力"]
        Output["実行ファイル/DLL"]
    end

    Source --> BasicLex
    BasicLex --> WhitespaceLex
    WhitespaceLex --> Parser
    Parser --> AST
    Refs --> Import
    Import --> Check
    AST --> Check
    Check --> Constraint
    Constraint --> TypedTree
    TypedTree --> Optimizer
    Optimizer --> TLF
    TLF --> IlxGen
    IlxGen --> Erase
    Erase --> AbstractIL
    AbstractIL --> Binary
    Binary --> Output
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| Driver | コンパイラ起動、オプション処理、フェーズ調整 | `fsc.fs`, `CompilerOptions.fs` |
| Service | IDE連携、インクリメンタルビルド | `service.fs`, `IncrementalBuild.fs` |
| Checking | 型チェック、制約解決 | `CheckDeclarations.fs`, `ConstraintSolver.fs` |
| SyntaxTree | 構文解析、AST定義 | `SyntaxTree.fs`, `pars.fsy` |
| TypedTree | 型付きツリー、型操作 | `TypedTree.fs`, `TypedTreeOps.fs` |
| Optimize | 最適化パス | `Optimizer.fs` |
| CodeGen | IL生成 | `IlxGen.fs` |
| AbstractIL | IL読み書き | `il.fs`, `ilread.fs`, `ilwrite.fs` |
| Utilities | 共通ユーティリティ | `lib.fs`, `range.fs` |

### 5.3 データフロー

1. **ソースファイル** -> **トークン列** (Lexing)
2. **トークン列** -> **AST** (Parsing)
3. **AST** + **参照アセンブリ** -> **Typed Tree** (Type Checking)
4. **Typed Tree** -> **最適化されたTyped Tree** (Optimization)
5. **最適化されたTyped Tree** -> **Abstract IL** (Code Generation)
6. **Abstract IL** -> **.NET バイナリ** (Emit)

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

**コンパイラのメインエントリーポイント (`src/Compiler/Driver/fsc.fs:140-167`)**
```fsharp
let TypeCheck
    (ctok, tcConfig, tcImports, tcGlobals, diagnosticsLogger: DiagnosticsLogger, assemblyName, tcEnv0, openDecls0, inputs, exiter: Exiter)
    =
    try
        if isNil inputs then
            error (Error(FSComp.SR.fscNoImplementationFiles (), rangeStartup))

        let ccuName = assemblyName

        let tcInitialState =
            GetInitialTcState(rangeStartup, ccuName, tcConfig, tcGlobals, tcImports, tcEnv0, openDecls0)

        let eagerFormat (diag: PhasedDiagnostic) = diag.EagerlyFormatCore true

        CheckClosedInputSet(
            ctok,
            (fun () -> diagnosticsLogger.CheckForRealErrorsIgnoringWarnings),
            tcConfig,
            tcImports,
            tcGlobals,
            None,
            tcInitialState,
            eagerFormat,
            inputs
        )
    with exn ->
        errorRecovery exn rangeStartup
        exiter.Exit 1
```

### 6.2 型チェック（Checking）

型チェックは `src/Compiler/Checking/` ディレクトリで行われます。

**制約ソルバーの例 (`src/Compiler/Checking/ConstraintSolver.fs:85-100`)**
```fsharp
let NewCompGenTypar (kind, rigid, staticReq, dynamicReq, error) =
    Construct.NewTypar(kind, rigid, SynTypar(compgenId, staticReq, true), error, dynamicReq, [], false, false)

let AnonTyparId m = mkSynId m unassignedTyparName

let NewAnonTypar (kind, m, rigid, var, dyn) =
    Construct.NewTypar (kind, rigid, SynTypar(AnonTyparId m, var, true), false, dyn, [], false, false)

let NewNamedInferenceMeasureVar (_m, rigid, var, id) =
    Construct.NewTypar(TyparKind.Measure, rigid, SynTypar(id, var, false), false, TyparDynamicReq.No, [], false, false)

let NewInferenceMeasurePar () =
    NewCompGenTypar (TyparKind.Measure, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, false)

let NewErrorTypar () =
    NewCompGenTypar (TyparKind.Type, TyparRigidity.Flexible, TyparStaticReq.None, TyparDynamicReq.No, true)
```

### 6.3 最適化（Optimization）

**オプティマイザーのデータ構造 (`src/Compiler/Optimize/Optimizer.fs:55-97`)**
```fsharp
type TypeValueInfo =
  | UnknownTypeValue

/// Partial information about an expression.
type ExprValueInfo =
  | UnknownValue
  | SizeValue of size: int * ExprValueInfo
  | ValValue of ValRef * ExprValueInfo
  | TupleValue of ExprValueInfo[]
  | RecdValue of TyconRef * ExprValueInfo[]
  | UnionCaseValue of UnionCaseRef * ExprValueInfo[]
  | ConstValue of Const * TType
  | CurriedLambdaValue of id: Unique * arity: int * size: int * lambdaExpr: Expr * lambdaExprTy: TType
  | ConstExprValue of size: int * value: Expr
```

### 6.4 コード生成（CodeGen）

コード生成は `src/Compiler/CodeGen/` ディレクトリで行われます。主要ファイル：

- `IlxGen.fs` - Typed Tree から Abstract IL への変換
- `EraseClosures.fs` - クロージャの消去
- `EraseUnions.fs` - 共用体の消去

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| 判別共用体 | データの多様性を型で表現 | 高 | `TypedTree.fs`, `SyntaxTree.fs` |
| パターンマッチング | 条件分岐とデータ抽出 | 高 | 全体 |
| オブジェクト式 | インターフェースのインライン実装 | 中 | `fsc.fs` |
| 計算式（Computation Expression） | モナディックな処理 | 中 | `BuildGraph.fs` |
| アクティブパターン | カスタムパターンマッチング | 中 | `TypedTreeOps.fs` |

### 各パターンの詳細

#### パターン1: 判別共用体

**目的:** コンパイラ内のさまざまな構文要素や状態を型安全に表現する

**実装例:**
```fsharp
// ファイル: src/Compiler/TypedTree/TypedTree.fs:70-73
type ValMutability =
    | Immutable
    | Mutable
```

**解説:** F#では値の可変性を判別共用体で表現します。これにより、パターンマッチングで網羅的なケース処理が保証されます。

#### パターン2: オブジェクト式

**目的:** インターフェースやクラスをインラインで実装する

**実装例:**
```fsharp
// ファイル: src/Compiler/Driver/fsc.fs:100-111
let ConsoleDiagnosticsLogger (tcConfigB: TcConfigBuilder, exiter: Exiter) =
    { new DiagnosticsLoggerUpToMaxErrors(tcConfigB, exiter, "ConsoleDiagnosticsLogger") with
        member _.HandleTooManyErrors(text: string) =
            DoWithDiagnosticColor FSharpDiagnosticSeverity.Warning (fun () -> Printf.eprintfn "%s" text)
        member _.HandleIssue(tcConfig, diagnostic, severity) =
            DoWithDiagnosticColor severity (fun () ->
                writeViaBuffer stderr (fun buf -> diagnostic.Output(buf, tcConfig, severity))
                stderr.WriteLine())
    }
    :> DiagnosticsLogger
```

**解説:** `{ new ... with }` 構文でクラスを継承し、必要なメソッドをオーバーライドします。

#### パターン3: ビットフラグによる効率的な状態管理

**目的:** 複数のフラグを単一の整数値で効率的に管理する

**実装例:**
```fsharp
// ファイル: src/Compiler/TypedTree/TypedTree.fs:100-145
[<Struct>]
type ValFlags(flags: int64) =
    new (recValInfo, baseOrThis, isCompGen, inlineInfo, ...) =
        let flags =
            (match baseOrThis with
                | BaseVal ->        0b00000000000000000000L
                | CtorThisVal ->    0b00000000000000000010L
                | NormalVal ->      0b00000000000000000100L
                | MemberThisVal ->  0b00000000000000000110L) |||
            (if isCompGen then      0b00000000000000001000L
             else                   0b000000000000000000000L) |||
            ...
        ValFlags flags

    member x.IsCompilerGenerated = (flags &&& 0b00000000000000001000L) <> 0x0L
```

**解説:** パフォーマンスが重要な箇所では、ビット演算を使って複数のブール値を1つの整数にパックします。

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定（`fsc.fs` または `service.fs`）
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認（AST -> Typed Tree -> IL）
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: ソースファイルからAST生成まで

**概要:** F#ソースファイルがどのように抽象構文木に変換されるかを追跡

**処理フロー:**
```
ソースファイル → 字句解析 (lex.fsl) → 構文解析 (pars.fsy) → AST (SyntaxTree.fs)
```

**詳細な追跡:**

1. **字句解析器の定義** (`src/Compiler/lex.fsl`)
   - FsLexツールで字句解析器を生成
   - トークンを定義

2. **構文解析器の定義** (`src/Compiler/pars.fsy`)
   - FsYaccツールで構文解析器を生成
   - 文法規則を定義

3. **AST定義** (`src/Compiler/SyntaxTree/SyntaxTree.fs:13-24`)
   ```fsharp
   [<Struct; NoEquality; NoComparison; DebuggerDisplay("{idText}")>]
   type Ident(text: string, range: range) =
       member _.idText = text
       member _.idRange = range
   ```

#### 例2: 型チェックの流れ

**概要:** ASTがどのように型付きツリーに変換されるかを追跡

**処理フロー:**
```
AST → CheckDeclarations → ConstraintSolver → Typed Tree
```

**詳細な追跡:**

1. **宣言のチェック** (`src/Compiler/Checking/CheckDeclarations.fs`)
   - モジュール、型、値の宣言をチェック

2. **制約ソルバー** (`src/Compiler/Checking/ConstraintSolver.fs`)
   - 型の等式や包含関係を解決

3. **型付きツリーの生成** (`src/Compiler/TypedTree/TypedTree.fs`)
   - 型情報が付与されたツリーを構築

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要
2. `docs/index.md` - コンパイラドキュメントインデックス
3. `docs/overview.md` - アーキテクチャ概要

#### 特定機能を理解したい場合
1. `docs/index.md` - 該当機能へのリンク
2. 該当ディレクトリの `.fsi` ファイル（インターフェース定義）
3. 該当ディレクトリの `.fs` ファイル（実装）

#### 改修作業を行う場合
1. `DEVGUIDE.md` - 開発ガイド
2. `TESTGUIDE.md` - テストガイド
3. `docs/coding-standards.md` - コーディング規約

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | プロジェクト概要、ビルド方法 | 最初 |
| `DEVGUIDE.md` | 開発環境セットアップ、ワークフロー | 開発開始時 |
| `TESTGUIDE.md` | テスト実行方法 | テスト時 |
| `docs/index.md` | コンパイラドキュメントインデックス | 詳細理解時 |
| `docs/overview.md` | アーキテクチャ概要 | 全体理解時 |
| `docs/coding-standards.md` | コーディング規約、略語一覧 | コーディング時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: 略語が多くて読みにくい
A: `docs/coding-standards.md` に主要な略語一覧があります。`ty`=Type, `m`=Range, `g`=TcGlobals などが頻出します。

#### Q: どこから読み始めればよいか
A: `src/Compiler/Driver/fsc.fs` がコンパイラのメインエントリーポイントです。ここから処理の流れを追うとよいでしょう。

#### Q: 型定義がどこにあるかわからない
A: 主要な型は以下のファイルにあります：
- AST関連: `src/Compiler/SyntaxTree/SyntaxTree.fs`
- 型付きツリー: `src/Compiler/TypedTree/TypedTree.fs`
- IL関連: `src/Compiler/AbstractIL/il.fs`

#### Q: `.fsi` ファイルと `.fs` ファイルの違いは？
A: `.fsi` はシグネチャファイル（インターフェース定義）、`.fs` は実装ファイルです。まず `.fsi` で公開APIを確認し、詳細を知りたい場合に `.fs` を読むとよいでしょう。

### デバッグのヒント

1. **Visual Studio / Rider**: ブレークポイントを設定してデバッグ実行
2. **fantomas-tools**: AST をブラウザで可視化 (https://fsprojects.github.io/fantomas-tools/)
3. **sharplab.io**: 生成されるILを確認
4. **ログ出力**: `--times` オプションでフェーズごとの時間を確認

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| AST | Abstract Syntax Tree - 抽象構文木 |
| CCU | Compiled Compilation Unit - コンパイル済みコンパイル単位 |
| Typed Tree | 型情報が付与された構文木 |
| Abstract IL | .NET IL の抽象表現 |
| FCS | FSharp.Compiler.Service の略 |
| FSI | F# Interactive の略 |
| SRTP | Statically Resolved Type Parameters - 静的に解決される型パラメータ |

### B. ファイル一覧（主要）

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `src/Compiler/Driver/fsc.fs` | コンパイラドライバ | メインエントリーポイント |
| `src/Compiler/SyntaxTree/SyntaxTree.fs` | AST定義 | 構文要素の型定義 |
| `src/Compiler/TypedTree/TypedTree.fs` | 型付きツリー定義 | 型情報付き構文要素 |
| `src/Compiler/Checking/CheckDeclarations.fs` | 宣言チェック | モジュール/型の型チェック |
| `src/Compiler/Checking/ConstraintSolver.fs` | 制約ソルバー | 型の等式/包含の解決 |
| `src/Compiler/Optimize/Optimizer.fs` | オプティマイザー | インライン化、不要コード削除 |
| `src/Compiler/CodeGen/IlxGen.fs` | IL生成 | Typed Tree から IL への変換 |
| `src/Compiler/AbstractIL/il.fs` | Abstract IL定義 | .NET IL の型定義 |
| `src/Compiler/Service/service.fs` | コンパイラサービス | IDE連携API |

### C. 参考資料

- [F# Language Specification](https://fsharp.org/specs/language-spec/) - F#言語仕様
- [F# Compiler Guide](https://fsharp.github.io/fsharp-compiler-docs/) - コンパイラドキュメント
- [FsLexYacc](http://fsprojects.github.io/FsLexYacc/) - 字句解析/構文解析ツール
- [F# for Fun and Profit](https://fsharpforfunandprofit.com/) - F#学習リソース
- [Microsoft F# Documentation](https://learn.microsoft.com/dotnet/fsharp/) - 公式ドキュメント
