# 機能設計書 48-@babel/plugin-transform-regenerator

## 概要

本ドキュメントは、Babelプラグインであるジェネレータ関数と非同期関数のES5互換コードへの変換機能について記述する。

### 本機能の処理概要

**業務上の目的・背景**：
ジェネレータ関数（function*）と非同期関数（async function）はES2015以降の機能であり、古いブラウザやJavaScript環境ではサポートされていない。本プラグインは、これらの関数をステートマシンベースのES5互換コードに変換し、レガシー環境でも同等の機能を実現する。

**機能の利用シーン**：
- IE11等のレガシーブラウザ対応
- 古いNode.jsバージョンでのジェネレータ/async関数サポート
- @babel/preset-envを通じた自動的な利用
- イテレータプロトコルを使用するライブラリ開発

**主要な処理内容**：
1. ジェネレータ関数（function*）のステートマシンへの変換
2. 非同期関数（async function）のPromiseベース関数への変換
3. 非同期ジェネレータ（async function*）の変換
4. yield/await式の状態遷移コードへの変換
5. try/catch/finallyブロックの適切な処理
6. thisとargumentsの保持
7. function.sentメタプロパティのサポート

**関連システム・外部連携**：
Babelヘルパー関数（regenerator、regeneratorAsync、regeneratorAsyncGen）を使用。内部のEmitterクラスで状態遷移コードを生成。

**権限による制御**：
プラグインオプション（generators、async、asyncGenerators）による個別の有効/無効化が可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はCLI/APIから利用されるプラグインのため、直接の画面関連なし |

## 機能種別

データ変換（AST変換）/ ランタイムコード生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| generators | boolean | No | ジェネレータ関数を変換（デフォルト: true） | - |
| async | boolean | No | 非同期関数を変換（デフォルト: true） | - |
| asyncGenerators | boolean | No | 非同期ジェネレータを変換（デフォルト: true） | - |

### 入力データソース

ジェネレータ関数または非同期関数を含むJavaScriptソースコード（AST形式）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| transformedAST | t.Program | ステートマシンベースのES5互換AST |
| helperCalls | t.CallExpression | regeneratorヘルパー呼び出し |

### 出力先

変換されたAST（@babel/coreに返却）

## 処理フロー

### 処理シーケンス

```
1. Methodビジター
   └─ shouldRegenerate()でジェネレータ/async判定
   └─ 関数本体をIIFEでラップ
   └─ メソッドのgenerator/asyncフラグをfalseに
   └─ 関数環境のアンラップ
2. Function.exitビジター
   └─ shouldRegenerate()でジェネレータ/async判定
   └─ ObjectMethodの場合ObjectPropertyに変換
   └─ contextIdとargsIdを生成
   └─ functionSentVisitorでfunction.sentを変換
   └─ 変数のホイスト
   └─ argumentsThisVisitorでarguments/thisを処理
   └─ Emitterでステートマシンコード生成
   └─ regeneratorヘルパー呼び出し生成
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{Method?}
    B -->|Yes| C{shouldRegenerate?}
    C -->|Yes| D[本体をIIFEでラップ]
    D --> E[generator/async=false]
    E --> F[関数環境アンラップ]
    B -->|No| G{Function.exit?}
    G -->|Yes| H{shouldRegenerate?}
    H -->|Yes| I[contextId生成]
    I --> J[変数ホイスト]
    J --> K[arguments/this処理]
    K --> L[Emitter.explode]
    L --> M[ステートマシン生成]
    M --> N{generator?}
    N -->|Yes| O[regenerator.m呼び出し]
    N -->|No| P{async?}
    P -->|Yes & generator| Q[regeneratorAsyncGen呼び出し]
    P -->|Yes & !generator| R[regeneratorAsync呼び出し]
    C -->|No| S[終了]
    H -->|No| S
    F --> S
    O --> S
    Q --> S
    R --> S
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-48-01 | ジェネレータ変換 | function*をステートマシンに変換 | generators=true時 |
| BR-48-02 | async変換 | async functionをPromiseベースに変換 | async=true時 |
| BR-48-03 | asyncGenerator変換 | async function*を両方の機能で変換 | asyncGenerators=true時 |
| BR-48-04 | this保持 | this参照を変数に保存して内部で使用 | this使用時 |
| BR-48-05 | arguments保持 | arguments参照を変数に保存して内部で使用 | arguments使用時 |
| BR-48-06 | try/catch/finally | tryLocationリストで例外処理を管理 | 例外処理存在時 |
| BR-48-07 | function.sent | context.vに変換 | function.sent使用時 |

### 計算ロジック

ステートマシン変換の概念:
```javascript
// 入力
function* gen() {
  yield 1;
  yield 2;
}

// 出力（概念）
var _marked = regenerator.m(gen);
function gen() {
  return regenerator.w(function gen$(_context) {
    while (1) switch (_context.prev = _context.next) {
      case 0:
        _context.next = 2;
        return 1;
      case 2:
        _context.next = 4;
        return 2;
      case 4:
      case "end":
        return _context.stop();
    }
  }, _marked);
}
```

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

該当なし（ファイルシステム操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| （なし） | - | 本プラグインは構文エラーを送出しない | - |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

特定のパフォーマンス要件なし（変換処理は同期的に実行）

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

- 変換後のコードはステートマシンベースのため、元のコードより複雑になる
- デバッグ時にはソースマップの利用を推奨

## 備考

- regeneratorRuntime（グローバル）は不要になり、ヘルパー関数として注入される
- Babel 8では内部実装がリファクタリングされ、外部のregenerator-transformパッケージへの依存がなくなった
- ジェネレータのマーキング（regenerator.m）は、Symbolサポートのためのプロトタイプ設定を行う

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-transform-regenerator/src/index.ts` | プラグイン定義（4-12行目） |

**読解のコツ**: index.tsはgetVisitor()を呼び出すだけのシンプルな構造。

#### Step 2: ビジター定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | visit.ts | `packages/babel-plugin-transform-regenerator/src/regenerator/visit.ts` | getVisitor関数（11-230行目） |

**主要処理フロー**:
- **11-38行目**: Methodビジター（メソッドのジェネレータ/async処理）
- **39-229行目**: Function.exitビジター（メイン変換処理）
- **233-249行目**: shouldRegenerate関数（変換対象判定）

#### Step 3: 変換判定ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | visit.ts | `packages/babel-plugin-transform-regenerator/src/regenerator/visit.ts` | shouldRegenerate関数（233-249行目） |

**主要処理フロー**:
- **234-237行目**: async generatorの判定
- **238-241行目**: plain generatorの判定
- **242-245行目**: async functionの判定

#### Step 4: Emitterを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | emit.ts | `packages/babel-plugin-transform-regenerator/src/regenerator/emit.ts` | Emitterクラス |

**主要処理フロー**:
- Emitterクラスはステートマシンコードの生成を担当
- explode()メソッドで関数本体をステートマシンに変換
- getContextFunction()で変換結果を取得

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

```
@babel/plugin-transform-regenerator/src/index.ts
    │
    └─ ./regenerator/visit.ts
           │
           ├─ ./hoist.ts
           │      └─ hoist() - 変数ホイスト
           │
           ├─ ./emit.ts
           │      └─ Emitter - ステートマシン生成
           │
           ├─ ./replaceShorthandObjectMethod.ts
           │      └─ ObjectMethod→ObjectProperty変換
           │
           └─ ./util.ts
                  └─ isReference() - 参照チェック
```

### データフロー図

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

ジェネレータ/async関数  ──▶  Parser (AST生成)
                              │
                              ▼
                     shouldRegenerate判定
                              │
                     ┌────────┼────────┐
                     ▼        ▼        ▼
              変数ホイスト this/args  Emitter
                          保存
                     │        │        │
                     └────────┼────────┘
                              │
                              ▼
                     ステートマシンコード
                              │
                              ▼
                     regeneratorヘルパー呼び出し
                              │
                              ▼
                       変換済みAST ──▶ Generator ──▶ ES5コード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-transform-regenerator/src/index.ts` | ソース | エントリーポイント |
| visit.ts | `packages/babel-plugin-transform-regenerator/src/regenerator/visit.ts` | ソース | ビジター定義（372行） |
| emit.ts | `packages/babel-plugin-transform-regenerator/src/regenerator/emit.ts` | ソース | ステートマシン生成 |
| hoist.ts | `packages/babel-plugin-transform-regenerator/src/regenerator/hoist.ts` | ソース | 変数ホイスト処理 |
| util.ts | `packages/babel-plugin-transform-regenerator/src/regenerator/util.ts` | ソース | ユーティリティ関数 |
| package.json | `packages/babel-plugin-transform-regenerator/package.json` | 設定 | 依存関係・メタデータ |
