# 機能設計書 21-@babel/plugin-transform-destructuring

## 概要

本ドキュメントは、`@babel/plugin-transform-destructuring` プラグインの機能設計を記載したものである。このプラグインは、ES2015（ES6）の分割代入（Destructuring Assignment）構文をES5互換のコードに変換するBabelプラグインである。

### 本機能の処理概要

**業務上の目的・背景**：ES2015で導入された分割代入は、配列やオブジェクトから値を簡潔に取り出すための構文である。しかし、古いブラウザやJavaScript環境ではこの構文がサポートされていないため、互換性を確保するために従来のプロパティアクセスや配列アクセスに変換する必要がある。このプラグインは、モダンなJavaScript構文を使用しながら、幅広い環境での動作を保証するという課題を解決する。

**機能の利用シーン**：このプラグインは以下のような場面で利用される。
- `const { a, b } = obj` のようなオブジェクト分割代入の変換
- `const [x, y] = arr` のような配列分割代入の変換
- `function fn({ name, age }) {}` のような関数パラメータでの分割代入の変換
- `for (const { id } of items) {}` のようなfor文での分割代入の変換
- `try {} catch ({ message }) {}` のようなcatch句での分割代入の変換

**主要な処理内容**：
1. VariableDeclaration（変数宣言）内の分割代入パターンを検出し、個別の変数代入に展開
2. AssignmentExpression（代入式）内の分割代入パターンを検出し、一時変数を使用した代入に変換
3. ForXStatement（for-in/for-of文）の左辺の分割代入パターンを処理
4. CatchClause（catch節）のパラメータの分割代入パターンを処理
5. ExportNamedDeclaration内の分割代入を含む変数宣言を分離処理
6. 配列パターンの最適化（直接配列リテラルからの展開）
7. オブジェクトレストスプレッドとの連携処理

**関連システム・外部連携**：
- `@babel/core`：Babelのコア機能との連携
- `@babel/helper-plugin-utils`：プラグインユーティリティの利用
- `@babel/types`：ASTノードの検証・構築
- `@babel/plugin-transform-object-rest-spread`：オブジェクトレスト構文との連携

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loose | boolean | No | looseモードの有効化。`iterableIsArray`と`objectRestNoSymbols`のassumptionを有効にする | - |
| allowArrayLike | boolean | No | 配列ライクオブジェクトをイテラブルとして扱う | - |
| useBuiltIns | boolean | No | `Object.assign`をネイティブで使用する | デフォルト: false |

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化
   └─ オプション（loose, allowArrayLike, useBuiltIns）の読み込み
   └─ assumption設定の解決（iterableIsArray, arrayLikeIsIterable, objectRestNoSymbols）

2. AST走査開始
   └─ 各ノードタイプに対応するビジターを実行

3. ExportNamedDeclaration処理
   └─ 分割代入を含む変数宣言を検出
   └─ エクスポートと変数宣言を分離

4. ForXStatement処理（for-in/for-of）
   └─ 左辺がパターンの場合、一時変数を生成
   └─ ループ本体の先頭に分割代入処理を挿入

5. CatchClause処理
   └─ パラメータがパターンの場合、一時変数を生成
   └─ catch本体の先頭に分割代入処理を挿入

6. AssignmentExpression処理
   └─ 左辺がパターンの場合、DestructuringTransformerを使用して変換

7. VariableDeclaration処理
   └─ 分割代入パターンを含む宣言を検出
   └─ DestructuringTransformerを使用して変換
```

### フローチャート

```mermaid
flowchart TD
    A[AST走査開始] --> B{ノードタイプ判定}
    B -->|ExportNamedDeclaration| C[エクスポート分離処理]
    B -->|ForXStatement| D[for文左辺処理]
    B -->|CatchClause| E[catch句パラメータ処理]
    B -->|AssignmentExpression| F[代入式処理]
    B -->|VariableDeclaration| G[変数宣言処理]

    D --> H{左辺がパターン?}
    H -->|Yes| I[一時変数生成]
    I --> J[ループ本体先頭に代入挿入]
    H -->|No| K[処理スキップ]

    F --> L{左辺がパターン?}
    L -->|Yes| M[DestructuringTransformer適用]
    L -->|No| K

    G --> N{分割代入パターン含む?}
    N -->|Yes| O[convertVariableDeclaration呼び出し]
    N -->|No| K

    C --> P[AST置換]
    J --> P
    M --> P
    O --> P
    P --> Q[次のノードへ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | パターン検出 | VoidPattern以外のPattern（ArrayPattern, ObjectPattern）を分割代入として処理 | VariableDeclaration, AssignmentExpression等 |
| BR-002 | 配列最適化 | 入力が配列リテラルで、参照の競合がない場合は直接展開 | canUnpackArrayPatternがtrueの場合 |
| BR-003 | 一時変数生成 | 複数回評価される可能性がある式には一時変数を生成 | 式が純粋でない場合 |
| BR-004 | デフォルト値処理 | AssignmentPatternのデフォルト値はundefinedとの比較で適用 | デフォルト値が設定されている場合 |

### 計算ロジック

**配列分割代入の変換例**：
```javascript
// 入力
const [a, b] = arr;

// 出力
var _arr = arr,
    a = _arr[0],
    b = _arr[1];
```

**オブジェクト分割代入の変換例**：
```javascript
// 入力
const { x, y } = obj;

// 出力
var x = obj.x,
    y = obj.y;
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | BuildCodeFrameError | 無効な分割代入パターン | ソースコードの修正 |

### リトライ仕様

ビルドプロセスのため、リトライは不要。エラー発生時はビルドが中断される。

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

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

## パフォーマンス要件

- AST走査は1パスで完了すること
- 大規模ファイルでも線形時間で処理可能であること

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

- ソースコードの変換のみを行い、外部リソースへのアクセスは行わない
- 生成されるコードは入力コードと同等のセキュリティ特性を維持する

## 備考

- ES2015の分割代入構文はTC39によって標準化されている
- looseモードを使用すると、より小さなコードが生成されるが、一部のエッジケースで動作が異なる可能性がある

---

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

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

### 推奨読解順序

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

まず、プラグインのオプションとDestructuringTransformerクラスの構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-transform-destructuring/src/index.ts` | Options型定義（28-33行目）とassumption設定の解決方法 |
| 1-2 | util.ts | `packages/babel-plugin-transform-destructuring/src/util.ts` | DestructuringTransformerクラスの構造（92-128行目）とそのオプション |

**読解のコツ**: `api.assumption()`はBabel 7.13以降で導入されたオプション解決方法。`options.loose`はレガシー設定との互換性のため。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-transform-destructuring/src/index.ts` | visitorオブジェクト（49-177行目）で各ASTノードタイプの処理エントリを確認 |

**主要処理フロー**:
1. **50-61行目**: ExportNamedDeclarationの処理。分割代入を含む変数宣言をエクスポートから分離
2. **62-124行目**: ForXStatementの処理。左辺のパターンを一時変数に変換
3. **126-149行目**: CatchClauseの処理。パラメータのパターンを展開
4. **151-161行目**: AssignmentExpressionの処理
5. **163-176行目**: VariableDeclarationの処理

#### Step 3: DestructuringTransformerクラスを理解する

分割代入の実際の変換ロジックを担当するクラス。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | util.ts | `packages/babel-plugin-transform-destructuring/src/util.ts` | DestructuringTransformerクラス（104-560行目） |

**主要処理フロー**:
- **185-200行目**: push()メソッド - パターンタイプに応じた処理の振り分け
- **251-300行目**: pushAssignmentPattern() - デフォルト値の処理
- **336-398行目**: pushObjectPattern() - オブジェクト分割代入の処理
- **469-542行目**: pushArrayPattern() - 配列分割代入の処理

#### Step 4: ユーティリティ関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | util.ts | `packages/babel-plugin-transform-destructuring/src/util.ts` | convertVariableDeclaration（643-756行目）とconvertAssignmentExpression（758-811行目） |

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

```
index.ts (エントリーポイント)
    │
    ├─ visitor.VariableDeclaration
    │      └─ convertVariableDeclaration (util.ts)
    │             └─ DestructuringTransformer.init
    │                    ├─ pushObjectPattern
    │                    ├─ pushArrayPattern
    │                    └─ pushAssignmentPattern
    │
    ├─ visitor.AssignmentExpression
    │      └─ convertAssignmentExpression (util.ts)
    │             └─ DestructuringTransformer.init
    │
    ├─ visitor.ForXStatement
    │      └─ DestructuringTransformer.init
    │             └─ unshiftForXStatementBody
    │
    └─ visitor.CatchClause
           └─ DestructuringTransformer.init
```

### データフロー図

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

JavaScriptソース ───▶ @babel/parser ───▶ AST
                                           │
                                           ▼
                              ┌─────────────────────────┐
                              │  transform-destructuring │
                              │  ビジター               │
                              │    │                    │
                              │    ▼                    │
                              │  DestructuringTransformer│
                              │    ├─ pushObjectPattern │
                              │    ├─ pushArrayPattern  │
                              │    └─ pushAssignmentPattern│
                              └─────────────────────────┘
                                           │
                                           ▼
                              変換後AST ───▶ @babel/generator ───▶ ES5コード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-transform-destructuring/src/index.ts` | ソース | プラグインエントリーポイント、ビジター定義 |
| util.ts | `packages/babel-plugin-transform-destructuring/src/util.ts` | ソース | DestructuringTransformerクラス、変換ユーティリティ |
| package.json | `packages/babel-plugin-transform-destructuring/package.json` | 設定 | パッケージ定義、依存関係 |
| test/index.js | `packages/babel-plugin-transform-destructuring/test/index.js` | テスト | テストランナー |
| test/fixtures/ | `packages/babel-plugin-transform-destructuring/test/fixtures/` | テスト | テストフィクスチャ |
