# 機能設計書 64-@babel/plugin-proposal-function-bind

## 概要

本ドキュメントは、Babelの関数バインド演算子（`::`）を変換する提案プラグイン `@babel/plugin-proposal-function-bind` の機能設計を定義する。

### 本機能の処理概要

本プラグインは、TC39で提案されている関数バインド演算子（`::`）をES5互換のコードに変換する機能を提供する。関数バインド演算子は、`this`のバインディングを簡潔に記述するための構文糖であり、`Function.prototype.bind`や`Function.prototype.call`の呼び出しに変換される。

**業務上の目的・背景**：JavaScriptでは関数の`this`コンテキストの管理が煩雑になりがちである。例えば `obj.method.bind(obj)` や `method.call(obj, ...args)` のような記述が頻繁に必要となる。関数バインド演算子を使用することで、`obj::method` のように簡潔に記述でき、コードの可読性が向上する。

**機能の利用シーン**：
- メソッド抽出時のthisバインド: `const fn = obj::obj.method`
- メソッド借用: `::console.log` でconsoleにバインドされたlogを取得
- 仮想メソッド呼び出し: `obj::method(args)` でobjをthisとしてmethod呼び出し

**主要な処理内容**：
1. BindExpressionノードを検出し、バインドコンテキストを推論
2. CallExpression内のBindExpressionを`.call`呼び出しに変換
3. 単独のBindExpressionを`.bind`呼び出しに変換
4. 静的コンテキストの場合は一時変数を生成せず直接バインド

**関連システム・外部連携**：`@babel/core`のAST変換機能を利用する。パーサープラグイン`functionBind`を有効化する。

**権限による制御**：特にロールや権限による制御はない。Babel設定ファイルでのプラグイン有効化により機能する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はCLIツールまたはビルドプロセスで使用され、GUI画面との関連はない |

## 機能種別

コード変換処理（AST変換）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | 本プラグインにはオプションパラメータはない | - |

### 入力データソース

- ソースコードからのASTノード（BindExpressionノード、CallExpressionノード）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| transformedAST | AST Node | 変換後のAST（CallExpression） |

### 出力先

- 変換後のJavaScriptコード（Babelのパイプライン出力）

## 処理フロー

### 処理シーケンス

```
1. CallExpression訪問
   └─ calleeがBindExpressionの場合、.call変換を実行
2. BindExpression訪問
   └─ .bind変換を実行
3. コンテキスト推論
   └─ getStaticContext で静的コンテキストを取得
   └─ 静的でない場合は一時変数を生成
4. 変換実行
   └─ CallExpression: method.call(context, ...args)
   └─ BindExpression: method.bind(context)
```

### フローチャート

```mermaid
flowchart TD
    A[ノード検出] --> B{CallExpression?}
    B -->|Yes| C{callee が BindExpression?}
    C -->|Yes| D[inferBindContext]
    C -->|No| Z1[処理スキップ]
    D --> E[.call変換]
    E --> F[context を第一引数に追加]
    B -->|No| G{BindExpression?}
    G -->|Yes| H[inferBindContext]
    H --> I[.bind変換]
    G -->|No| Z2[処理スキップ]
    I --> J[path.replaceWith]
    F --> K[終了]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | CallExpression変換 | BindExpressionを含むCallExpressionは.call形式に変換 | callee === BindExpression |
| BR-02 | BindExpression変換 | 単独のBindExpressionは.bind形式に変換 | BindExpression検出時 |
| BR-03 | 静的コンテキスト最適化 | コンテキストが静的な場合は一時変数を生成しない | scope.isStatic(object) === true |
| BR-04 | Super対応 | superがオブジェクトの場合はthisExpressionに変換 | t.isSuper(object) |
| BR-05 | 一時変数生成 | 動的コンテキストの場合は一時変数で値を保持 | 静的でない場合 |

### 計算ロジック

- CallExpression変換: `obj::method(a, b)` → `method.call(obj, a, b)`
- BindExpression変換: `obj::method` → `method.bind(obj)`
- 動的コンテキスト: `(getObj())::method(a)` → `(_ctx = getObj(), method.call(_ctx, a))`

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 構文エラー | 関数バインド演算子の構文が不正 | ソースコードを修正する |

### リトライ仕様

リトライ処理は不要（コンパイル時のエラーはリトライ対象外）

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

トランザクション管理は不要（ファイル変換処理のため）

## パフォーマンス要件

- シンプルな変換処理のため、パフォーマンス上の懸念は少ない
- 大規模コードベースでも数秒以内で変換完了すること

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

- ソースコード変換のため、実行時のセキュリティリスクは限定的
- 生成されるコードはオリジナルと同等のセキュリティ特性を持つ

## 備考

- TC39 Stage 0 提案（長期間進展なし）
- `::` 演算子は左辺にオブジェクト、右辺に関数を取る
- 左辺を省略した場合（`::obj.method`）は右辺のオブジェクトがコンテキストになる

---

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

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

### 推奨読解順序

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

関数バインド演算子の変換では、BindExpressionノードが主要なデータ構造となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-proposal-function-bind/src/index.ts` | BindExpressionの構造（object、callee プロパティ） |

**読解のコツ**: `BindExpression`には`object`（左辺）と`callee`（右辺）があり、`object`がnullの場合は`callee`のオブジェクトがコンテキストになる。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-proposal-function-bind/src/index.ts` | CallExpressionとBindExpressionの2つのvisitor |

**主要処理フロー**:
1. **54行目**: manipulateOptionsでfunctionBindパーサープラグインを追加
2. **57-64行目**: CallExpressionのvisitor（.call変換）
3. **66-75行目**: BindExpressionのvisitor（.bind変換）

#### Step 3: コンテキスト推論処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-plugin-proposal-function-bind/src/index.ts` | getTempId、getObject、getStaticContext、inferBindContext関数 |

**主要処理フロー**:
- **7-13行目**: getTempId - 一時変数の生成と再利用
- **15-21行目**: getObject - BindExpressionからオブジェクトを取得
- **23-29行目**: getStaticContext - 静的コンテキストの判定
- **31-50行目**: inferBindContext - コンテキストの推論と一時変数への代入

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

```
@babel/core (transform)
    │
    └─ @babel/plugin-proposal-function-bind/src/index.ts
           │
           ├─ CallExpression visitor
           │      │
           │      ├─ t.isBindExpression (callee判定)
           │      │
           │      ├─ inferBindContext
           │      │      ├─ getStaticContext
           │      │      │      └─ getObject
           │      │      └─ getTempId (動的時)
           │      │
           │      └─ node変換 (.call追加)
           │
           └─ BindExpression visitor
                  │
                  ├─ inferBindContext
                  │
                  └─ t.callExpression (.bind生成)
```

### データフロー図

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

BindExpression             コンテキスト推論                  CallExpression
obj::method(a)    ───▶     getStaticContext          ───▶   method.call(obj, a)
                           inferBindContext

obj::method       ───▶     getStaticContext          ───▶   method.bind(obj)
                           inferBindContext
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-proposal-function-bind/src/index.ts` | ソース | プラグインエントリーポイント、変換ロジック |
| package.json | `packages/babel-plugin-proposal-function-bind/package.json` | 設定 | パッケージ定義・依存関係 |
