# 機能設計書 24-@babel/plugin-transform-template-literals

## 概要

本ドキュメントは、`@babel/plugin-transform-template-literals` プラグインの機能設計を記載したものである。このプラグインは、ES2015（ES6）のテンプレートリテラル構文をES5互換のコードに変換するBabelプラグインである。

### 本機能の処理概要

**業務上の目的・背景**：ES2015で導入されたテンプレートリテラル（バッククォート文字列）は、文字列補間やタグ付きテンプレートなどの機能を提供する。古いJavaScript環境ではこの構文がサポートされていないため、文字列連結やヘルパー関数を使用した従来の方法に変換する必要がある。

**機能の利用シーン**：このプラグインは以下のような場面で利用される。
- `` `Hello, ${name}!` `` のようなテンプレートリテラルの変換
- `` tag`template` `` のようなタグ付きテンプレートリテラルの変換
- 複数行文字列の変換

**主要な処理内容**：
1. TemplateLiteralを検出し、文字列連結に変換
2. TaggedTemplateExpressionを検出し、ヘルパー関数を使用した変換
3. `ignoreToPrimitiveHint` assumptionに基づく最適化（`+`演算子 vs `.concat()`）
4. `mutableTemplateObject` assumptionに基づくタグ付きテンプレートの最適化
5. rawプロパティとcookedプロパティの適切な処理

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

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loose | boolean | No | looseモードの有効化。`ignoreToPrimitiveHint`と`mutableTemplateObject`を有効にする | - |

### 入力データソース

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

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化
   └─ オプション（loose）の読み込み
   └─ assumption設定の解決（ignoreToPrimitiveHint, mutableTemplateObject）
   └─ ヘルパー名の決定（taggedTemplateLiteral / taggedTemplateLiteralLoose）

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

3. TaggedTemplateExpression処理
   └─ quasisからstringsとrawsを構築
   └─ stringsとrawsが同一かどうかを判定
   └─ 一時変数を生成してテンプレートオブジェクトをキャッシュ
   └─ ヘルパー関数呼び出しに変換

4. TemplateLiteral処理
   └─ TSLiteralType内の場合はスキップ
   └─ quasisとexpressionsを順に処理
   └─ ignoreToPrimitiveHint: `+`演算子で連結
   └─ それ以外: `.concat()`メソッドで連結
```

### フローチャート

```mermaid
flowchart TD
    A[AST走査開始] --> B{ノードタイプ判定}
    B -->|TaggedTemplateExpression| C[strings/raws配列構築]
    C --> D{strings === raws?}
    D -->|Yes| E[raws引数を省略]
    D -->|No| F[raws引数を追加]
    E --> G[一時変数生成]
    F --> G
    G --> H[ヘルパー呼び出しに変換]

    B -->|TemplateLiteral| I{TSLiteralType内?}
    I -->|Yes| Z[処理スキップ]
    I -->|No| J[nodes配列構築]
    J --> K{先頭が文字列?}
    K -->|No| L[空文字列を先頭に追加]
    K -->|Yes| M{ignoreToPrimitiveHint?}
    L --> M
    M -->|Yes| N[+演算子で連結]
    M -->|No| O[.concat()で連結]
    N --> P[AST置換]
    O --> P
    H --> P
    P --> Q[次のノードへ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | プリミティブヒント | strictモードでは`.concat()`で正確なToPrimitive評価順序を保持 | ignoreToPrimitiveHintがfalse |
| BR-002 | テンプレートオブジェクトキャッシュ | タグ付きテンプレートのstrings配列はプログラムスコープでキャッシュ | TaggedTemplateExpression |
| BR-003 | raw/cooked比較 | rawとcookedが全て同一の場合、raw引数を省略可能 | TaggedTemplateExpression |
| BR-004 | 先頭要素保証 | 結果が文字列になるよう、必要に応じて空文字列を先頭に追加 | TemplateLiteral |

### 計算ロジック

**テンプレートリテラルの変換例（strictモード）**：
```javascript
// 入力
const str = `Hello, ${name}!`;

// 出力
const str = "Hello, ".concat(name, "!");
```

**テンプレートリテラルの変換例（looseモード）**：
```javascript
// 入力
const str = `Hello, ${name}!`;

// 出力
const str = "Hello, " + name + "!";
```

**タグ付きテンプレートの変換例**：
```javascript
// 入力
const result = tag`Hello, ${name}!`;

// 出力
var _templateObject;
const result = tag(
  _templateObject || (_templateObject = _taggedTemplateLiteral(["Hello, ", "!"]))
, name);
```

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

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

## エラー処理

### エラーケース一覧

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

本プラグインは通常のテンプレートリテラルに対してエラーを発生させない。

### リトライ仕様

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

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

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

## パフォーマンス要件

- AST走査は1パスで完了すること
- タグ付きテンプレートのキャッシュにより実行時パフォーマンスを最適化

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

- ソースコードの変換のみを行い、外部リソースへのアクセスは行わない
- テンプレートリテラルのエスケープ処理は正確に保持される

## 備考

- ES2015のテンプレートリテラルはTC39によって標準化されている
- looseモードでは`+`演算子を使用するため、非プリミティブ値のToPrimitive評価順序が変わる可能性がある
- タグ付きテンプレートでは、同一のテンプレートリテラルは同一のstringsオブジェクトを受け取ることがES仕様で保証されている

---

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

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

### 推奨読解順序

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

まず、プラグインのオプションとassumption設定を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-transform-template-literals/src/index.ts` | Options型定義（4-6行目）とassumption設定（11-14行目） |

**読解のコツ**: `ignoreToPrimitiveHint`はES仕様の厳密なToPrimitive評価順序を無視するかどうかを制御。

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-transform-template-literals/src/index.ts` | visitorオブジェクト（58-150行目） |

**主要処理フロー**:
1. **59-105行目**: TaggedTemplateExpressionの処理
2. **107-149行目**: TemplateLiteralの処理

#### Step 3: ヘルパー関数を理解する

変換に使用されるヘルパー関数を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-plugin-transform-template-literals/src/index.ts` | buildConcatCallExpressions関数（34-53行目） |

**主要処理フロー**:
- **buildConcatCallExpressions**: 複数のconcat呼び出しを構築して評価順序を保持

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

```
index.ts (エントリーポイント)
    │
    ├─ visitor.TaggedTemplateExpression
    │      ├─ quasi.quasisの走査
    │      │    └─ strings/raws配列構築
    │      ├─ isStringsRawEqual判定
    │      ├─ scope.generateUidIdentifier: 一時変数生成
    │      ├─ scope.getProgramParent().push: キャッシュ変数登録
    │      └─ path.replaceWith: ヘルパー呼び出しに置換
    │
    └─ visitor.TemplateLiteral
           ├─ parent.type === "TSLiteralType"チェック
           ├─ quasis/expressionsの走査
           │    └─ nodes配列構築
           ├─ 先頭要素チェック
           ├─ ignoreToPrimitiveHint判定
           │    ├─ true: +演算子連結
           │    └─ false: buildConcatCallExpressions
           └─ path.replaceWith: 連結式に置換
```

### データフロー図

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

JavaScriptソース ───▶ @babel/parser ───▶ AST
                                           │
                                           ▼
                              ┌─────────────────────────┐
                              │  transform-template-literals │
                              │  ビジター               │
                              │    │                    │
                              │    ├─ Tagged処理        │
                              │    │   ├─ strings構築   │
                              │    │   ├─ raws構築      │
                              │    │   └─ ヘルパー呼び出し│
                              │    │                    │
                              │    └─ TemplateLiteral処理│
                              │        ├─ nodes構築     │
                              │        └─ 連結式生成    │
                              └─────────────────────────┘
                                           │
                                           ▼
                              変換後AST ───▶ @babel/generator ───▶ ES5コード
```

### 関連ファイル一覧

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