# 機能設計書 68-@babel/plugin-bugfix-safari-class-field-initializer-scope

## 概要

本ドキュメントは、Safariのクラスフィールド初期化子のスコープに関するバグを修正するプラグイン `@babel/plugin-bugfix-safari-class-field-initializer-scope` の機能設計を定義する。

### 本機能の処理概要

本プラグインは、Safari（WebKit）に存在するバグ（[webkit.org/b/236843](https://webkit.org/b/236843)）に対するワークアラウンドを提供する。このバグは、クラスフィールドの初期化子内で外部スコープの変数を参照した場合に発生するスコープ解決の問題である。

**業務上の目的・背景**：Safariの特定バージョンでは、クラスフィールドの初期化子が外部スコープの変数を正しく参照できない場合がある。例えば、`class A { x = someVar }` のようなコードで、`someVar`が正しく解決されないことがある。本プラグインは、このようなパターンを検出し、IIFEでラップすることで問題を回避する。

**機能の利用シーン**：
- Safariをサポートする必要があるウェブアプリケーション
- @babel/preset-envのtargets設定でSafariが含まれる場合
- クラスフィールド初期化子で外部変数を参照するコード

**主要な処理内容**：
1. ClassPropertyまたはClassPrivatePropertyを検出
2. 初期化子（value）がラップを必要とするか判定
3. 必要な場合、初期化子をアロー関数でラップして即時実行

**関連システム・外部連携**：`@babel/core`のAST変換機能を利用する。

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

## 関連画面

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

## 機能種別

バグ修正処理（AST変換）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | 本プラグインにはオプションパラメータはない | - |

### 入力データソース

- ソースコードからのASTノード（ClassProperty、ClassPrivateProperty）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| transformedAST | AST Node | 変換後のAST（IIFEでラップされた初期化子） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. ClassProperty/ClassPrivateProperty訪問
   └─ wrapInitializer関数を呼び出し
2. needsWrapping判定
   └─ 初期化子の各ノードを再帰的に検査
   └─ ラップが必要な式（識別子、複雑な式）を検出
3. ラップ不要の判定
   └─ リテラル、関数式、クラス式、thisはラップ不要
4. ラップ実行
   └─ アロー関数でラップして即時実行
   └─ (() => value)() 形式に変換
```

### フローチャート

```mermaid
flowchart TD
    A[ClassProperty/ClassPrivateProperty検出] --> B[wrapInitializer呼び出し]
    B --> C{value が存在?}
    C -->|No| Z[処理スキップ]
    C -->|Yes| D[needsWrapping判定]
    D --> E{ラップが必要?}
    E -->|No| Z
    E -->|Yes| F[アロー関数でラップ]
    F --> G[即時実行形式に変換]
    G --> H[path.node.value を更新]
    H --> I[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | リテラル除外 | リテラル値（テンプレートリテラル以外）はラップ不要 | t.isLiteral かつ !t.isTemplateLiteral |
| BR-02 | 関数式除外 | 関数式、アロー関数、クラス式はラップ不要 | t.isFunctionExpression等 |
| BR-03 | this除外 | thisExpression はラップ不要 | t.isThisExpression |
| BR-04 | CallExpression再帰判定 | CallExpression は callee と arguments を再帰的に判定 | t.isCallExpression |
| BR-05 | MemberExpression再帰判定 | MemberExpression は object と property を再帰的に判定 | t.isMemberExpression |
| BR-06 | 識別子はラップ必要 | 識別子やその他の式はラップが必要 | 上記以外 |

### 計算ロジック

- ラップ変換: `class A { x = someVar }` → `class A { x = (() => someVar)() }`
- ラップ不要: `class A { x = 42 }` → 変換なし
- 複雑な式: `class A { x = fn(someVar) }` → `class A { x = (() => fn(someVar))() }`

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | - | 通常のエラー処理はない（変換のみ） |

### リトライ仕様

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

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

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

## パフォーマンス要件

- 初期化子の再帰的な検査は軽量
- ラップが必要な場合のみ変換を実行

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

- ソースコード変換のため、実行時のセキュリティリスクは限定的
- バグ修正により予期しない動作を防止

## 備考

- WebKitバグ: [webkit.org/b/236843](https://webkit.org/b/236843)
- @babel/preset-envで自動的に適用される
- Safari 15以降で修正済みの可能性あり

---

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

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

### 推奨読解順序

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

クラスフィールドの変換では、ClassPropertyとClassPrivatePropertyが主要なデータ構造となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-bugfix-safari-class-field-initializer-scope/src/index.ts` | needsWrapping関数のパターンマッチング |

**読解のコツ**: `needsWrapping`関数は再帰的に呼び出され、各ノードタイプごとに異なる判定を行う。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-bugfix-safari-class-field-initializer-scope/src/index.ts` | ClassProperty/ClassPrivatePropertyのvisitor |

**主要処理フロー**:
1. **85-86行目**: assertVersionで互換性チェック
2. **91-97行目**: ClassProperty/ClassPrivatePropertyのvisitor
3. **72-83行目**: wrapInitializer関数でラップ処理

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-plugin-bugfix-safari-class-field-initializer-scope/src/index.ts` | needsWrapping関数（5-70行目） |

**主要処理フロー**:
- **6-8行目**: リテラル判定（テンプレートリテラル以外）
- **10-16行目**: CallExpression/NewExpression判定
- **18-20行目**: TemplateLiteral判定
- **22-24行目**: TaggedTemplateExpression判定
- **26-28行目**: ArrayExpression判定
- **30-43行目**: ObjectExpression判定
- **45-50行目**: MemberExpression/OptionalMemberExpression判定
- **52-58行目**: 関数式/クラス式判定
- **60-62行目**: thisExpression判定
- **64-66行目**: SequenceExpression判定
- **69行目**: その他（識別子等）はtrue

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

```
@babel/core (transform)
    │
    └─ @babel/plugin-bugfix-safari-class-field-initializer-scope/src/index.ts
           │
           ├─ ClassProperty visitor
           │      └─ wrapInitializer
           │             │
           │             ├─ needsWrapping (再帰判定)
           │             │      ├─ t.isLiteral
           │             │      ├─ t.isCallExpression → 再帰
           │             │      ├─ t.isMemberExpression → 再帰
           │             │      ├─ t.isObjectExpression → 再帰
           │             │      └─ その他 → true
           │             │
           │             └─ t.callExpression + t.arrowFunctionExpression
           │
           └─ ClassPrivateProperty visitor
                  └─ wrapInitializer（同上）
```

### データフロー図

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

ClassProperty              needsWrapping判定                 ClassProperty
class A {                  ───▶                              class A {
  x = someVar                   再帰的ノード検査               x = (() => someVar)()
}                              ラップ生成                   }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-bugfix-safari-class-field-initializer-scope/src/index.ts` | ソース | プラグインエントリーポイント、判定・変換ロジック |
| package.json | `packages/babel-plugin-bugfix-safari-class-field-initializer-scope/package.json` | 設定 | パッケージ定義・依存関係 |
