# 機能設計書 74-メソッドリフレクション

## 概要

本ドキュメントは、Julia言語におけるメソッドリフレクション機能の設計を記述する。`methods`、`which`、`hasmethod`、`applicable`、`functionloc`、`code_typed`、`code_lowered` などの関数を通じて、ジェネリック関数のメソッド情報の取得を提供する。

### 本機能の処理概要

メソッドリフレクション機能は、Juliaの多重ディスパッチシステムにおけるメソッド情報をプログラム実行時に取得するための関数群を提供する。特定の関数に対して、登録されたメソッドの一覧取得、引数型に対するメソッド解決、メソッドの定義場所の特定、型推論済みIRの取得など、開発・デバッグ・最適化に不可欠な内省機能を備える。

**業務上の目的・背景**：Juliaの多重ディスパッチは言語の中核機能であり、関数に対して複数のメソッドが定義される。開発者がどのメソッドが呼び出されるかを確認したり、型推論の結果を検査したり、メソッドの定義元を特定したりするために、メソッドレベルのリフレクション機能が必要である。これはデバッグ、性能最適化、IDE支援、ドキュメント生成などで広く活用される。

**機能の利用シーン**：REPLでの`methods(f)`によるメソッド一覧確認、`which(f, types)`による実際に呼び出されるメソッドの特定、`@code_typed`での型推論結果の確認、`functionloc`でのメソッド定義ファイルの特定、`hasmethod`によるメソッド存在確認による分岐処理などで使用される。

**主要な処理内容**：
1. `methods(f, types)` - 関数fの引数型typesにマッチするメソッド一覧を取得
2. `which(f, types)` - 特定の引数型に対して呼び出されるメソッドを特定
3. `which(m::Module, s::Symbol)` - シンボルが定義されたモジュールを特定
4. `hasmethod(f, types)` - メソッドの存在確認
5. `hasmethod(f, types, kwnames)` - キーワード引数を含むメソッドの存在確認
6. `applicable(f, args...)` - 引数に適用可能かの確認
7. `functionloc(m::Method)` - メソッドのソースコード位置を取得
8. `code_lowered(f, types)` - 低レベルIR（CodeInfo）を取得
9. `code_typed(f, types)` - 型推論済みIRを取得
10. `code_ircode(f, types)` - 最適化済みIRCode を取得
11. `return_types(f, types)` - 推論される戻り値型を取得

**関連システム・外部連携**：コンパイラモジュール（Compiler/）の型推論エンジンと連携。NativeInterpreterを通じて推論結果を取得する。

**権限による制御**：特別な権限制御はない。ただし、generated functionsの内部からはcode reflectionは使用できない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | ヘルプモード（help?>） | 補助機能 | methods/whichによるメソッド情報取得とドキュメント内でのメソッドシグネチャ表示 |
| 2 | Juliaプロンプト（julia>） | 補助機能 | @code_warntype/@code_llvm/@code_native等の対話的開発ユーティリティをREPLから呼び出し |

## 機能種別

メソッド情報取得・コード内省処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| f | Function/Callable | Yes | 対象の関数 | 呼び出し可能なオブジェクト |
| types | Type{<:Tuple} | No | 引数型のタプル型 | 有効なタプル型 |
| world | UInt | No | ワールドエイジ（デフォルト: 現在） | 有効なワールドカウンタ値 |
| optimize | Bool | No | 最適化の適用（code_typed） | true/false |
| debuginfo | Symbol | No | デバッグ情報レベル | :source / :none |
| interp | AbstractInterpreter | No | 使用する抽象インタプリタ | NativeInterpreter等 |

### 入力データソース

- Juliaプログラムからの直接呼び出し
- REPLマクロ（@which, @code_typed等）からの間接呼び出し
- InteractiveUtils stdlib経由

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| methods_list | MethodList | methods()の結果 |
| method | Method | which()の結果 |
| has_method | Bool | hasmethod()の結果 |
| code_info | Vector{CodeInfo} | code_lowered()の結果 |
| typed_code | Vector{Pair{CodeInfo,Type}} | code_typed()の結果 |
| return_type | Vector{Any} | return_types()の結果 |
| location | Tuple{String,Int} | functionloc()の結果（ファイルパス, 行番号） |

### 出力先

戻り値としてJuliaプログラムに返却

## 処理フロー

### 処理シーケンス

```
1. メソッドリフレクション要求
   └─ methods / which / hasmethod / code_typed 等の呼び出し
2. メソッドマッチング
   └─ _methods_by_ftype でメソッドテーブルを検索
3. メソッドインスタンスの特定
   └─ specialize_method で具体的な MethodInstance を取得
4. [code_typed の場合] 型推論の実行
   └─ Compiler.typeinf_code で型推論とオプションの最適化を実行
5. 結果の整形・返却
   └─ Method / CodeInfo / IRCode 等の適切な形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[メソッドリフレクション要求] --> B{関数の種類}
    B -->|methods| C[_methods_by_ftype]
    B -->|which| D[_findsup - 最適メソッド検索]
    B -->|hasmethod| E[jl_gf_invoke_lookup]
    B -->|code_typed| F[型推論実行]
    C --> G[MethodList返却]
    D --> H[Method返却]
    E --> I[Bool返却]
    F --> J[signature_type構築]
    J --> K[_findall_matches]
    K --> L[typeinf_code]
    L --> M[CodeInfo + rettype返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-74-01 | ワールドエイジ制約 | generated functionsからcode reflectionは使用不可 | world == typemax(UInt) |
| BR-74-02 | メソッド解決順序 | whichは最も特殊なメソッドを返す | 多重ディスパッチルール |
| BR-74-03 | キーワード引数チェック | hasmethod(f,t,kwnames)はkwargsのサブセット判定 | kwnames指定時 |
| BR-74-04 | 可変キーワード | kwargs...を持つメソッドは全てのkwnames検証をパス | kwargs末尾が... |
| BR-74-05 | debuginfo制御 | :noneでデバッグ情報を除去、:sourceで保持 | code_lowered/code_typed |

### 計算ロジック

`which(f, t)` は `signature_type(f, t)` でタプル型シグネチャを構築し、`_findsup` でメソッドテーブルから最も特殊なマッチを検索する。一致するメソッドがない場合は `MethodError` 相当のエラーを投げる。

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

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ErrorException | 例外 | code reflectionをgenerated functionから使用 | generated function外で使用 |
| ErrorException | 例外 | whichでマッチするメソッドがない | 正しい引数型を指定 |
| ErrorException | 例外 | which(m, s)でシンボルが未定義 | 正しいモジュールとシンボルを指定 |
| ArgumentError | 例外 | debuginfoに無効な値を指定 | :source または :none を指定 |

### リトライ仕様

リトライ不要（純粋な計算処理）

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

該当なし

## パフォーマンス要件

- methods()はメソッドテーブルの全走査を伴うため、メソッド数に比例
- which()は最適マッチの検索であり、メソッドテーブルのサイズに依存
- code_typed()は型推論の実行を伴うため、関数の複雑さに依存する計算量
- hasmethod()はlookupのみで推論は行わないため比較的軽量

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

特になし。メソッド情報は公開情報である。

## 備考

- `REFLECTION_COMPILER` グローバル変数で使用するコンパイラモジュールを切り替え可能
- `invoke_in_typeinf_world` で型推論ワールドでコンパイラ関数を呼び出す
- InteractiveUtils stdlib が `@which`, `@code_typed` 等のマクロ版を提供

---

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

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

### 推奨読解順序

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

メソッド情報を表現するデータ型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | boot.jl | `base/boot.jl` | Method, MethodInstance, CodeInfo の型定義。メソッドテーブルの構造 |
| 1-2 | reflection.jl | `base/reflection.jl` | CodegenParams（93-199行目）とEmissionParams（203-209行目）の定義 |

**読解のコツ**: Method構造体のフィールド（name, module, sig, slot_syms, source等）が、各リフレクション関数の返却値の源泉となる。MethodInstanceはMethod + 具体的な型パラメータの組み合わせ。

#### Step 2: メソッド検索APIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | reflection.jl | `base/reflection.jl` | which関数（972-1007行目）: signature_typeでタプル型を構築し、_findsupでメソッドを検索 |
| 2-2 | reflection.jl | `base/reflection.jl` | hasmethod関数（1095-1121行目）: Core._hasmethodまたはjl_gf_invoke_lookupでメソッド存在確認 |

**主要処理フロー**:
1. **972-984行目**: `which(f, t)` - signature_type構築 → _findsup呼び出し → Method返却
2. **1095-1097行目**: `hasmethod(f, t)` - Core._hasmethodで判定
3. **1104-1121行目**: `hasmethod(f, t, kwnames)` - キーワード引数名のサブセット判定を含む

#### Step 3: コード内省APIを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | reflection.jl | `base/reflection.jl` | code_lowered（19-52行目）: 低レベルIRの取得。method_instancesとuncompressed_irを使用 |
| 3-2 | reflection.jl | `base/reflection.jl` | code_typed_by_type（355-387行目）: 型推論済みIRの取得。invoke_interp_compilerでtypeinf_codeを呼び出す |
| 3-3 | reflection.jl | `base/reflection.jl` | return_types（592-599行目）: 戻り値型のリストを取得 |

**主要処理フロー**:
- **355-387行目**: code_typed_by_type - NativeInterpreter構築 → _findall_matches → typeinf_code → CodeInfo + rettype
- **304-317行目**: invoke_default_compiler - REFLECTION_COMPILERを介してコンパイラ関数を呼び出し

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

```
which(f, types)
    │
    ├─ signature_type(f, types)    // Tuple型構築
    └─ invoke_default_compiler(:_findsup, ...)
           └─ Compiler._findsup  // メソッドテーブル検索

code_typed(f, types)
    │
    ├─ signature_type(f, types)
    └─ code_typed_by_type(tt)
           │
           ├─ invoke_default_compiler(:_default_interp, world)
           ├─ invoke_interp_compiler(:_findall_matches, ...)
           └─ invoke_interp_compiler(:typeinf_code, ...)
                  └─ Compiler.typeinf_code  // 型推論実行

hasmethod(f, t)
    └─ Core._hasmethod(signature_type(f, t))

hasmethod(f, t, kwnames)
    │
    ├─ ccall(:jl_gf_invoke_lookup, ...)  // メソッドルックアップ
    └─ issubset(kwnames, kws)            // キーワード引数チェック
```

### データフロー図

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

f + types ───────▶ signature_type()
                         │
                         ▼
                   Tuple{typeof(f), types...}
                         │
         ┌───────────────┼───────────────┐
         ▼               ▼               ▼
    _findsup       _findall_matches   _hasmethod
         │               │               │
         ▼               ▼               ▼
    Method         typeinf_code       Bool
                         │
                         ▼
                   CodeInfo + rettype
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| reflection.jl | `base/reflection.jl` | ソース | メソッドリフレクション関数の主要実装 |
| methodshow.jl | `base/methodshow.jl` | ソース | メソッドの表示・フォーマット |
| boot.jl | `base/boot.jl` | ソース | Method/MethodInstance/CodeInfoの型定義 |
| abstractinterpretation.jl | `Compiler/src/abstractinterpretation.jl` | ソース | 型推論エンジン（code_typedで使用） |
| InteractiveUtils/ | `stdlib/InteractiveUtils/` | ソース | @which, @code_typed等のマクロ版 |
