# 機能設計書 28-@babel/plugin-transform-async-generator-functions

## 概要

本ドキュメントは、`@babel/plugin-transform-async-generator-functions` プラグインの機能設計を記載したものである。このプラグインは、ES2018のasyncジェネレーター関数とfor-await-of文をES2015のジェネレーター関数に変換するBabelプラグインである。

### 本機能の処理概要

**業務上の目的・背景**：ES2018で導入されたasyncジェネレーター関数（`async function*`）とfor-await-of文は、非同期イテレーションを可能にする機能である。ES2015/ES2017環境ではこれらの構文がサポートされていないため、通常のジェネレーター関数とヘルパー関数を組み合わせて同等の動作を再現する必要がある。

**機能の利用シーン**：このプラグインは以下のような場面で利用される。
- `async function* gen() { yield await promise; }` のようなasyncジェネレーター関数の変換
- `for await (const item of asyncIterable) {}` のようなfor-await-of文の変換
- `yield* asyncIterable` のようなasync yield delegationの変換

**主要な処理内容**：
1. for-await-of文の検出と変換（最初に処理）
2. asyncジェネレーター関数の検出
3. `yield*`のasyncイテレーター対応変換
4. `@babel/helper-remap-async-to-generator`を使用した変換
5. `wrapAsyncGenerator`と`awaitAsyncGenerator`ヘルパーでラップ

**関連システム・外部連携**：
- `@babel/core`：Babelのコア機能との連携
- `@babel/helper-plugin-utils`：プラグインユーティリティの利用
- `@babel/helper-remap-async-to-generator`：async関数のジェネレーター変換
- `@babel/traverse`：ビジター構築ユーティリティ

**権限による制御**：特になし。ビルド時に実行されるトランスパイル処理のため、権限による制御は不要。

## 関連画面

本プラグインはビルドツールとして動作するため、直接的な関連画面はない。

## 機能種別

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

## 入力仕様

### 入力パラメータ

本プラグインはオプションパラメータを持たない。

### 入力データソース

- JavaScriptソースコード（AST形式）
- Babelの設定ファイル（babel.config.js, .babelrc等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| transformedAST | AST | 変換後のAST |

### 出力先

変換されたASTは@babel/generatorによってJavaScriptコードとして出力される。

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化
   └─ ビジターの構築（environmentVisitor使用）

2. Program走査開始
   └─ path.traverseでFunction/ForOfStatementを走査

3. for-await-of文処理（先に実行）
   └─ forAwaitVisitorでfor-await-of文を検出
   └─ rewriteForAwaitで変換
   └─ try-finally構造でイテレーター処理

4. yield* delegation処理
   └─ yieldStarVisitorでyield*を検出
   └─ asyncIteratorとasyncGeneratorDelegateヘルパーでラップ

5. asyncジェネレーター関数処理
   └─ async generatorを検出
   └─ remapAsyncToGeneratorを適用
   └─ wrapAsyncGeneratorとawaitAsyncGeneratorでラップ
```

### フローチャート

```mermaid
flowchart TD
    A[Program検出] --> B[path.traverse開始]
    B --> C[Function検出]

    C --> D{async関数?}
    D -->|No| Z[処理スキップ]
    D -->|Yes| E[forAwaitVisitor適用]

    E --> F{for-await-of含む?}
    F -->|Yes| G[rewriteForAwait]
    G --> H[try-finally構造生成]
    F -->|No| I{generator?}

    H --> I
    I -->|No| Z
    I -->|Yes| J[yieldStarVisitor適用]

    J --> K{yield* delegation含む?}
    K -->|Yes| L[asyncGeneratorDelegate変換]
    K -->|No| M[remapAsyncToGenerator]

    L --> M
    M --> N[wrapAsyncGenerator適用]
    N --> O[awaitAsyncGenerator適用]
    O --> P[AST置換]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | for-await優先処理 | for-await-ofはasync-to-generatorより先に処理 | async関数内 |
| BR-002 | yield* delegation | yield*のasyncイテレーター対応 | asyncジェネレーター内 |
| BR-003 | アロー関数スキップ | ビジター内でアロー関数をスキップ | 環境ビジター |
| BR-004 | データ設定 | 変換済みフラグをパスデータに設定 | 二重変換防止 |

### 計算ロジック

**asyncジェネレーター関数の変換例**：
```javascript
// 入力
async function* gen() {
  yield await promise;
}

// 出力
function gen() {
  return _wrapAsyncGenerator(function* () {
    yield _awaitAsyncGenerator(promise);
  })();
}
```

**for-await-of文の変換例**：
```javascript
// 入力
async function fn() {
  for await (const item of asyncIterable) {
    console.log(item);
  }
}

// 出力
async function fn() {
  var _iteratorAbruptCompletion = false;
  var _didIteratorError = false;
  var _iteratorError;
  try {
    for (var _iterator = _asyncIterator(asyncIterable), _step;
         _iteratorAbruptCompletion = !(_step = await _iterator.next()).done;
         _iteratorAbruptCompletion = false) {
      const item = _step.value;
      console.log(item);
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (_iteratorAbruptCompletion && _iterator.return != null) {
        await _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }
}
```

**yield* delegationの変換例**：
```javascript
// 入力
async function* gen() {
  yield* otherAsyncGen();
}

// 出力
function gen() {
  return _wrapAsyncGenerator(function* () {
    yield* _asyncGeneratorDelegate(_asyncIterator(otherAsyncGen()));
  })();
}
```

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

本プラグインはデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | - | - |

本プラグインは通常のasyncジェネレーター/for-await-ofに対してエラーを発生させない。

### リトライ仕様

ビルドプロセスのため、リトライは不要。

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

該当なし。ビルドプロセスはトランザクション管理を行わない。

## パフォーマンス要件

- for-await-ofの変換は通常のfor-ofより先に実行
- AST走査は効率的に行う（不要なトラバースを避ける）

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

- ソースコードの変換のみを行い、外部リソースへのアクセスは行わない
- 非同期イテレーターのエラーハンドリングは適切に保持される

## 備考

- ES2018のasyncジェネレーターはTC39によって標準化されている
- for-await-ofの変換にはawait式が使用されるため、async-to-generatorより先に処理が必要
- ランタイムでのPromiseとSymbol.asyncIteratorサポートが必要

---

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

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

### 推奨読解順序

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

まず、プラグインの構造と使用するビジターを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-transform-async-generator-functions/src/index.ts` | yieldStarVisitor（11-27行目）とforAwaitVisitor（29-67行目） |

**読解のコツ**: `visitors.environmentVisitor`はFunction/Classの境界を超えないビジターを生成する。

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

処理の起点となるビジターパターンを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-transform-async-generator-functions/src/index.ts` | visitor.Programとvisitor.Function（69-110行目） |

**主要処理フロー**:
1. **71行目**: async関数かどうかを確認
2. **73行目**: forAwaitVisitorでfor-await-of文を処理
3. **75行目**: generatorかどうかを確認
4. **77行目**: yieldStarVisitorでyield*を処理
5. **79-82行目**: 変換済みフラグの設定
6. **86-89行目**: remapAsyncToGenerator呼び出し

#### Step 3: for-await-of変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | for-await.ts | `packages/babel-plugin-transform-async-generator-functions/src/for-await.ts` | rewriteForAwait関数（32-84行目） |

**主要処理フロー**:
- **3-30行目**: buildForAwaitテンプレート（try-finally構造）
- **38-53行目**: 左辺の変換（変数宣言/代入式）
- **54-64行目**: テンプレート適用
- **70-76行目**: ラベル付き文の処理

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

```
index.ts (エントリーポイント)
    │
    └─ visitor.Program
           └─ path.traverse(visitor, state)
                  │
                  └─ visitor.Function
                         │
                         ├─ forAwaitVisitor（先に実行）
                         │      └─ ForOfStatement
                         │             └─ rewriteForAwait (for-await.ts)
                         │                    ├─ buildForAwait
                         │                    ├─ 変数宣言処理
                         │                    └─ ラベル処理
                         │
                         ├─ yieldStarVisitor
                         │      └─ YieldExpression
                         │             ├─ asyncIteratorヘルパー
                         │             └─ asyncGeneratorDelegateヘルパー
                         │
                         └─ remapAsyncToGenerator
                                ├─ wrapAsyncGeneratorヘルパー
                                └─ awaitAsyncGeneratorヘルパー
```

### データフロー図

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

JavaScriptソース ───▶ @babel/parser ───▶ AST
                                           │
                                           ▼
                              ┌─────────────────────────┐
                              │  transform-async-generator-functions │
                              │  Program.traverse       │
                              │    │                    │
                              │    ├─ async関数検出     │
                              │    │                    │
                              │    ├─ for-await-of変換  │
                              │    │   ├─ asyncIterator │
                              │    │   └─ try-finally   │
                              │    │                    │
                              │    ├─ yield* delegation │
                              │    │   └─ asyncGeneratorDelegate│
                              │    │                    │
                              │    └─ async generator変換│
                              │        ├─ wrapAsyncGenerator│
                              │        └─ awaitAsyncGenerator│
                              └─────────────────────────┘
                                           │
                                           ▼
                              変換後AST ───▶ @babel/generator ───▶ ES2015コード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-transform-async-generator-functions/src/index.ts` | ソース | プラグインエントリーポイント |
| for-await.ts | `packages/babel-plugin-transform-async-generator-functions/src/for-await.ts` | ソース | for-await-of変換ロジック |
| package.json | `packages/babel-plugin-transform-async-generator-functions/package.json` | 設定 | パッケージ定義、依存関係 |
| test/fixtures/ | `packages/babel-plugin-transform-async-generator-functions/test/fixtures/` | テスト | テストフィクスチャ |
