# 機能設計書 61-@babel/plugin-proposal-pipeline-operator

## 概要

本ドキュメントは、Babelのパイプライン演算子（`|>`）を変換する提案プラグイン `@babel/plugin-proposal-pipeline-operator` の機能設計を定義する。

### 本機能の処理概要

本プラグインは、TC39で提案されているパイプライン演算子（Pipeline Operator）をES5互換のコードに変換する機能を提供する。パイプライン演算子は関数合成を簡潔に記述するための構文糖であり、左辺の値を右辺の式に渡して連鎖的に処理を行う。

**業務上の目的・背景**：関数型プログラミングスタイルでの関数合成を直感的に記述するため、パイプライン演算子が提案されている。例えば `value |> fn1 |> fn2` のように、データの流れを左から右へ読みやすく記述できる。現在のJavaScript環境ではネイティブサポートがないため、Babelによるトランスパイルが必要である。

**機能の利用シーン**：関数型プログラミングスタイルでコードを記述する際、ネストの深い関数呼び出しを避けて可読性を向上させたい場合に使用される。特にデータ処理パイプラインや変換チェーンを構築する際に有用である。

**主要な処理内容**：
1. BinaryExpression（`|>`演算子）を検出し、指定されたプロポーザルに基づいてVisitorを選択
2. Hack プロポーザル：トピック参照（`#`や`@@`など）を一時変数に置換し、シーケンス式に変換
3. F# プロポーザル：パイプの右辺を関数呼び出しとして解釈し、左辺を引数として渡す形式に変換
4. 最適化処理により、不要な一時変数の生成を回避

**関連システム・外部連携**：`@babel/plugin-syntax-pipeline-operator`と連携してパイプライン演算子の構文解析を有効化する。`@babel/core`のAST変換機能を利用する。

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| proposal | `"hack" \| "fsharp"` | Yes | 使用するパイプライン提案のバリアント | 有効な提案名であること |
| topicToken | `"#" \| "%" \| "@@"` | Hackのみ必須 | Hackパイプラインで使用するトピックトークン | Hackプロポーザル使用時は必須 |

### 入力データソース

- Babel設定ファイル（babel.config.js、.babelrc等）からのプラグインオプション
- ソースコードからのASTノード（BinaryExpressionノード、演算子が`|>`のもの）

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化
   └─ proposalオプションに基づきvisitorを選択（hack or fsharp）
2. BinaryExpression訪問
   └─ 演算子が|>であるノードを検出
3. Hackプロポーザルの場合
   └─ topicReferenceVisitorでトピック参照を収集
   └─ サイドエフェクトの有無を判定
   └─ 一時変数を生成し、トピック参照を置換
   └─ シーケンス式（代入式 + パイプ本体）に変換
4. F#プロポーザルの場合
   └─ 左辺を引数として、右辺を関数呼び出しに変換
   └─ アロー関数の場合は最適化を適用
   └─ シーケンス式に変換
```

### フローチャート

```mermaid
flowchart TD
    A[BinaryExpression検出] --> B{演算子が |> ?}
    B -->|No| Z[処理スキップ]
    B -->|Yes| C{proposal設定}
    C -->|hack| D[hackVisitor実行]
    C -->|fsharp| E[fsharpVisitor実行]
    D --> F[トピック参照収集]
    F --> G{単一トピック参照かつ副作用なし?}
    G -->|Yes| H[直接置換]
    G -->|No| I[一時変数生成・シーケンス式変換]
    E --> J{右辺がAwaitExpression?}
    J -->|Yes| K[await式に変換]
    J -->|No| L[関数呼び出しに変換]
    K --> M[最適化シーケンス式生成]
    L --> M
    H --> N[終了]
    I --> N
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | プロポーザル選択 | proposalオプションで指定されたバリアントのvisitorを使用する | 常時 |
| BR-02 | 単一トピック最適化 | トピック参照が1つで副作用がない場合、一時変数を生成せず直接置換 | Hackプロポーザル |
| BR-03 | アロー関数最適化 | 右辺が単純なアロー関数の場合、関数呼び出しを省略して本体を展開 | F#プロポーザル |
| BR-04 | eval特別処理 | evalの直接呼び出しを避けるため、(0, eval)形式に変換 | F#プロポーザル |

### 計算ロジック

- Hackパイプラインの変換: `x |> # + 1` → `(_ref = x, _ref + 1)`
- F#パイプラインの変換: `x |> fn` → `(_ref = x, fn(_ref))`
- await対応: `x |> await` → `(_ref = x, await _ref)`

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | プロポーザル未指定 | proposalオプションが設定されていない | プラグイン設定でproposalを指定する |
| - | 構文エラー | パイプライン演算子の構文が不正 | ソースコードを修正する |

### リトライ仕様

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

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

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

## パフォーマンス要件

- 大規模コードベースでも数秒以内で変換完了すること
- 一時変数の生成を最小限に抑える最適化を実施

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

- eval呼び出しの特別処理により、意図しないグローバル評価を防止
- ソースコード変換のため、実行時のセキュリティリスクは限定的

## 備考

- TC39 Stage 2 提案
- Hack と F# の2つのバリアントが存在
- 将来的にJavaScript標準に組み込まれる可能性あり

---

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

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

### 推奨読解順序

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

パイプライン演算子の変換では、BinaryExpressionノードとTopicReferenceノードが主要なデータ構造となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-proposal-pipeline-operator/src/index.ts` | プラグインのエントリーポイント、proposalによるvisitor選択 |

**読解のコツ**: `visitorsPerProposal`オブジェクトで`hack`と`fsharp`の2つのvisitorが定義されている点に注目。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-proposal-pipeline-operator/src/index.ts` | declareによるプラグイン定義 |

**主要処理フロー**:
1. **12-14行目**: proposalオプションに基づくvisitor選択
2. **17行目**: syntaxPipelineOperatorを継承してパーサープラグインを有効化
3. **18行目**: 選択されたvisitorを返却

#### Step 3: Hackプロポーザルの変換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | hackVisitor.ts | `packages/babel-plugin-proposal-pipeline-operator/src/hackVisitor.ts` | Hackパイプラインの変換ロジック |

**主要処理フロー**:
- **36-44行目**: BinaryExpressionの`|>`演算子を検出
- **46-52行目**: パイプ本体がトピック参照のみの場合、左辺に置換
- **54-71行目**: トピック参照を収集し、最適化可能か判定
- **73-92行目**: 一時変数を生成し、シーケンス式に変換

#### Step 4: F#プロポーザルの変換処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | fsharpVisitor.ts | `packages/babel-plugin-proposal-pipeline-operator/src/fsharpVisitor.ts` | F#パイプラインの変換ロジック |
| 4-2 | buildOptimizedSequenceExpression.ts | `packages/babel-plugin-proposal-pipeline-operator/src/buildOptimizedSequenceExpression.ts` | シーケンス式の最適化 |

**主要処理フロー**:
- **5-8行目**: BinaryExpressionの`|>`演算子を検出
- **10-15行目**: 右辺がAwaitExpressionかCallExpressionかで分岐
- **16-21行目**: 最適化されたシーケンス式を生成

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

```
@babel/core (transform)
    │
    └─ @babel/plugin-proposal-pipeline-operator/src/index.ts
           │
           ├─ @babel/plugin-syntax-pipeline-operator (構文解析有効化)
           │
           ├─ hackVisitor.ts (proposal: "hack")
           │      └─ topicReferenceVisitor (トピック参照収集)
           │
           └─ fsharpVisitor.ts (proposal: "fsharp")
                  └─ buildOptimizedSequenceExpression.ts (最適化)
```

### データフロー図

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

ソースコード               BinaryExpression検出              変換後AST
(x |> fn(#))    ───▶      トピック参照収集          ───▶   SequenceExpression
                           一時変数生成                      (_ref = x, fn(_ref))
                           シーケンス式変換
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-proposal-pipeline-operator/src/index.ts` | ソース | プラグインエントリーポイント |
| hackVisitor.ts | `packages/babel-plugin-proposal-pipeline-operator/src/hackVisitor.ts` | ソース | Hackパイプライン変換 |
| fsharpVisitor.ts | `packages/babel-plugin-proposal-pipeline-operator/src/fsharpVisitor.ts` | ソース | F#パイプライン変換 |
| buildOptimizedSequenceExpression.ts | `packages/babel-plugin-proposal-pipeline-operator/src/buildOptimizedSequenceExpression.ts` | ソース | シーケンス式最適化 |
| package.json | `packages/babel-plugin-proposal-pipeline-operator/package.json` | 設定 | パッケージ定義・依存関係 |
