# 機能設計書 95-名前解決

## 概要

本ドキュメントは、F#コンパイラにおける名前解決（Name Resolution）機能について記述する。名前解決は、ソースコード内の識別子を型、値、モジュール、名前空間等の具体的な定義に関連付けるプロセスであり、型チェックの基盤となる重要な機能である。

### 本機能の処理概要

**業務上の目的・背景**：F#プログラムでは、識別子（変数名、関数名、型名等）が様々なスコープで使用される。名前解決は、これらの識別子が参照する具体的な定義を特定するプロセスである。openディレクティブ、モジュール修飾、型推論等の複雑な要素を考慮しながら、正しい解決先を決定する。

**機能の利用シーン**：
- 型チェック時の識別子解決
- IDEでのIntelliSense（コード補完）
- Go to Definition機能
- Find All References機能
- リファクタリング（名前変更等）

**主要な処理内容**：
1. 名前解決環境（NameResolutionEnv）の構築と管理
2. 修飾名と非修飾名の解決
3. openディレクティブによる名前空間/モジュールのインポート処理
4. オーバーロード解決（複数の候補がある場合）
5. 拡張メンバーの解決
6. アクティブパターンの解決

**関連システム・外部連携**：構文木（SyntaxTree）から識別子を受け取り、型チェッカー（CheckExpressions）に解決結果を提供する。また、FSharp.Compiler.Serviceを通じてIDE機能に解決情報を提供する。

**権限による制御**：アクセシビリティ（public/internal/private）に基づく解決制御

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | IDE統合 | 参照画面 | IntelliSense、Go to Definition |

## 機能種別

名前解決 / シンボル解決

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| nenv | NameResolutionEnv | Yes | 名前解決環境 | - |
| id | Ident | Yes | 解決対象の識別子 | - |
| fullyQualifiedFlag | FullyQualifiedFlag | No | 完全修飾のみを検索するか | - |

### 入力データソース

構文木からの識別子、型チェッカーからの解決要求

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Item | Item | 解決された項目（Value, Type, Module等） |
| ItemWithInst | ItemWithInst | 型パラメータのインスタンス化情報付きの項目 |

### 出力先

型チェッカー、IDE機能

## 処理フロー

### 処理シーケンス

```
1. 識別子の分類
   ├─ 非修飾名（例：x）
   ├─ 修飾名（例：List.map）
   └─ 完全修飾名（例：Microsoft.FSharp.Collections.List.map）

2. 解決環境の検索
   ├─ ローカルスコープ（letバインディング、パターン変数）
   ├─ 現在のモジュール/名前空間
   ├─ openされた名前空間/モジュール
   └─ 自動オープンされた名前空間

3. 候補の選択
   ├─ 単一候補: そのまま返却
   ├─ 複数候補: オーバーロード解決
   └─ 候補なし: エラー報告

4. アクセシビリティチェック
   ├─ public: アクセス可能
   ├─ internal: 同一アセンブリからアクセス可能
   └─ private: 同一モジュールからのみアクセス可能
```

### フローチャート

```mermaid
flowchart TD
    A[識別子入力] --> B{修飾名?}
    B -->|Yes| C[モジュール/名前空間解決]
    B -->|No| D[ローカルスコープ検索]
    C --> E[メンバー解決]
    D --> F{見つかった?}
    F -->|No| G[open名前空間検索]
    F -->|Yes| H[アクセシビリティチェック]
    G --> F
    E --> H
    H --> I{アクセス可能?}
    I -->|Yes| J[Item返却]
    I -->|No| K[エラー: アクセス不可]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-95-1 | シャドウイング | 内側のスコープが外側を隠す | 同名の定義がある場合 |
| BR-95-2 | open優先度 | 後のopenが優先される | 複数のopenで同名がある場合 |
| BR-95-3 | RequireQualifiedAccess | 完全修飾が必要 | 属性が付与されている場合 |
| BR-95-4 | AutoOpen | 自動的にopenされる | 属性が付与されている場合 |

### 計算ロジック

**解決優先度**：
```
1. ローカル変数/パターン変数
2. 現在のモジュールのメンバー
3. open された名前空間/モジュール（後のopenが優先）
4. 自動オープンされた名前空間
5. 拡張メンバー
```

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| FS0039 | UndefinedValue | 識別子が見つからない | 識別子を定義するか、openを追加 |
| FS0072 | AmbiguousOverload | 複数の候補があいまい | 型注釈を追加 |
| FS0491 | AccessibilityError | アクセス不可 | アクセス修飾子を変更 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

大規模プロジェクト（数千ファイル）でもIntelliSenseは100ms以内で応答すること

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

該当なし

## 備考

名前解決環境はイミュータブルであり、openディレクティブやletバインディングごとに新しい環境が作成される。

---

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

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

### 推奨読解順序

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

名前解決で使用される主要な型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NameResolution.fs | `src/Compiler/Checking/NameResolution.fs` | NameResolutionEnv型、Item型の定義 |

**主要な型定義**:
- **43-62行目**: NameResolver - 名前解決のコンテキストを保持するクラス
- **140-252行目**: Item - 解決結果を表す判別共用体（Value, UnionCase, Type等）
- **393-475行目**: NameResolutionEnv - 名前解決環境

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

名前解決の主要な関数を確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NameResolution.fs | `src/Compiler/Checking/NameResolution.fs` | ResolveLongIdentAsModuleOrNamespace等の解決関数 |

**主要処理フロー**:
- **68-105行目**: ActivePatternElemsOfValRef - アクティブパターン要素の取得
- **341-375行目**: ExtensionMember - 拡張メンバーの定義
- **459-475行目**: NameResolutionEnv.Empty - 空の名前解決環境

#### Step 3: 呼び出し元を理解する

名前解決がどこから使われるかを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CheckExpressions.fs | `src/Compiler/Checking/CheckExpressions.fs` | 型チェックからの名前解決呼び出し |

**読解のコツ**:
- NameResolutionEnvは複数のマップ（eUnqualifiedItems, eModulesAndNamespaces等）を持つ
- 解決順序は内側から外側へ、後のopenが優先という原則を理解する
- Item判別共用体の各ケースが何を表すか把握する

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

```
CheckExpressions.fs
    │
    └─ NameResolution.fs
           │
           ├─ NameResolver
           │      ├─ g: TcGlobals
           │      ├─ amap: ImportMap
           │      ├─ InfoReader: InfoReader
           │      └─ InstantiationGenerator
           │
           ├─ NameResolutionEnv
           │      ├─ eUnqualifiedItems: 非修飾項目マップ
           │      ├─ eModulesAndNamespaces: モジュール/名前空間マップ
           │      ├─ eTyconsByAccessNames: 型マップ
           │      ├─ eFieldLabels: フィールドラベルマップ
           │      └─ eIndexedExtensionMembers: 拡張メンバーマップ
           │
           └─ Item（解決結果）
                  ├─ Value: 値/関数
                  ├─ UnionCase: 判別共用体ケース
                  ├─ ExnCase: 例外
                  ├─ RecdField: レコードフィールド
                  ├─ Types: 型
                  └─ ModuleOrNamespaces: モジュール/名前空間
```

### データフロー図

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

識別子 ───▶ NameResolution ───▶ Item
(Ident)          │               │
                 ▼               │
          NameResolutionEnv      ▼
          ┌────────────────┐   ┌──────────┐
          │ eUnqualifiedItems │→ │ Value    │
          │ eModulesAndNamespaces│→│ Type    │
          │ eTyconsByAccessNames │→│ Module  │
          │ eFieldLabels      │→ │ Field   │
          └────────────────┘   └──────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NameResolution.fs | `src/Compiler/Checking/NameResolution.fs` | ソース | 名前解決の実装 |
| NameResolution.fsi | `src/Compiler/Checking/NameResolution.fsi` | ソース | 公開シグネチャ |
| CheckExpressions.fs | `src/Compiler/Checking/CheckExpressions.fs` | ソース | 主要な呼び出し元 |
| AccessibilityLogic.fs | `src/Compiler/Checking/AccessibilityLogic.fs` | ソース | アクセシビリティチェック |
| InfoReader.fs | `src/Compiler/Checking/InfoReader.fs` | ソース | 型情報の読み取り |
