# 機能設計書 31-@babel/plugin-transform-class-properties

## 概要

本ドキュメントは、Babelの変換プラグイン「@babel/plugin-transform-class-properties」の機能設計を記述する。本プラグインはES2022のクラスプロパティ構文（クラスフィールド）を、古いJavaScript環境でも動作する形式に変換する。

### 本機能の処理概要

本プラグインは、クラス内で宣言されたパブリックおよびプライベートなクラスフィールド（プロパティ初期化子構文）を、コンストラクタ内での代入文やWeakMapを用いた実装に変換する機能を提供する。

**業務上の目的・背景**：ES2022で正式に仕様化されたクラスフィールド構文は、クラスのプロパティをより簡潔に宣言できる新しい構文である。しかし、古いブラウザやNode.jsバージョンではこの構文をサポートしていないため、トランスパイルが必要となる。本プラグインにより、開発者は最新の構文を使用しながらも、幅広い環境での互換性を確保できる。

**機能の利用シーン**：
- レガシーブラウザをサポートする必要があるWebアプリケーション開発
- 古いNode.jsバージョンをサポートするライブラリ開発
- `@babel/preset-env`の一部として自動的に適用される場合

**主要な処理内容**：
1. クラス宣言/式内のクラスフィールド宣言を検出
2. パブリックフィールドをコンストラクタ内での代入または`Object.defineProperty`呼び出しに変換
3. プライベートフィールドをWeakMapを用いた実装に変換（looseモードでは異なる実装）
4. 静的フィールドをクラス定義後の代入文に変換
5. フィールド初期化子の評価順序を仕様通りに維持

**関連システム・外部連携**：
- `@babel/helper-create-class-features-plugin`: クラス機能の変換ロジックを提供する共有ヘルパー
- `@babel/helper-plugin-utils`: プラグインユーティリティ
- `@babel/core`: Babelコアとの統合

**権限による制御**：特になし。変換はビルド時に実行される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIまたはビルドツール経由で使用されるため、画面との関連なし |

## 機能種別

コード変換処理 / AST操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loose | boolean | No | trueの場合、仕様準拠よりもパフォーマンスを優先した簡易な変換を行う | boolean型であること |

### 入力データソース

- Babelによってパースされたソースコード（AST形式）
- 特にClassDeclaration、ClassExpression内のClassPropertyノード

## 出力仕様

### 出力データ

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

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化
   └─ createClassFeaturePlugin関数を呼び出し、FEATURESにfieldsを指定

2. クラスノード（ClassDeclaration/ClassExpression）の訪問
   └─ helper-create-class-features-plugin内のビジターが処理

3. クラスフィールドの検出と分類
   ├─ パブリック静的フィールド
   ├─ パブリックインスタンスフィールド
   ├─ プライベート静的フィールド
   └─ プライベートインスタンスフィールド

4. 変換処理の実行
   ├─ looseモード: Object.definePropertyではなく単純代入を使用
   └─ 標準モード: 仕様準拠の変換（definePropertyを使用）

5. 初期化コードの生成
   └─ コンストラクタへの挿入またはクラス定義後のコード生成
```

### フローチャート

```mermaid
flowchart TD
    A[クラスノードの訪問] --> B{クラスフィールドあり?}
    B -->|No| Z[変換なし]
    B -->|Yes| C{フィールドの種類}
    C -->|パブリック静的| D[クラス定義後に代入文を追加]
    C -->|パブリックインスタンス| E[コンストラクタに初期化を追加]
    C -->|プライベート| F{looseモード?}
    F -->|Yes| G[簡易実装で変換]
    F -->|No| H[WeakMapを使用した変換]
    D --> I[変換完了]
    E --> I
    G --> I
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-31-01 | 初期化順序の維持 | フィールド初期化子は宣言順に評価される | 常時 |
| BR-31-02 | looseモード動作 | looseモードでは単純代入を使用し、Object.definePropertyを回避 | loose=true |
| BR-31-03 | プライベートフィールドの隠蔽 | プライベートフィールドは外部からアクセス不可 | プライベートフィールド使用時 |

### 計算ロジック

特になし（構文変換のため）

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

該当なし（コンパイル時変換のため）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | SyntaxError | 不正なクラスフィールド構文 | パーサーレベルでエラー |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 変換処理は同期的に実行される
- 大規模プロジェクトでもビルド時間に大きな影響を与えない設計

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

- プライベートフィールドの変換では、実行時にも外部からアクセスできない実装を維持

## 備考

- 本プラグインは`@babel/preset-env`に含まれており、ターゲット環境に応じて自動的に適用される
- デコレータとの併用時は、デコレータプラグインとの実行順序に注意が必要

---

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

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

### 推奨読解順序

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

本プラグインはクラスフィールド関連のASTノード（ClassProperty、ClassPrivateProperty）を変換対象とする。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-transform-class-properties/src/index.ts` | プラグインのエントリーポイント。Optionsインターフェースでlooseオプションを定義 |

**読解のコツ**: `createClassFeaturePlugin`関数に委譲する構造のため、実際の変換ロジックは`@babel/helper-create-class-features-plugin`パッケージにある。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-transform-class-properties/src/index.ts` | declare関数でプラグインを定義し、createClassFeaturePluginを呼び出す |

**主要処理フロー**:
1. **3-7行目**: 必要なモジュールのインポート
2. **9-11行目**: Optionsインターフェースの定義（looseオプション）
3. **13-14行目**: APIバージョンの検証
4. **16-22行目**: createClassFeaturePluginの呼び出し、FEATURES.fieldsを指定

#### Step 3: ヘルパープラグインを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | helper-create-class-features-plugin | `packages/babel-helper-create-class-features-plugin/src/` | 実際のクラスフィールド変換ロジックを含む |

**主要処理フロー**:
- FEATURESオブジェクトでサポートする機能フラグを定義
- クラスノードのビジターで各種フィールドを検出・変換

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

```
@babel/plugin-transform-class-properties/src/index.ts
    │
    └─ createClassFeaturePlugin (from @babel/helper-create-class-features-plugin)
           │
           ├─ ClassDeclaration/ClassExpression visitor
           │      └─ transformClassFields
           │
           └─ buildFieldsInitialization
                  └─ generateFieldInitialization
```

### データフロー図

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

クラスフィールド付き  ─▶  @babel/helper-create       ─▶  コンストラクタ内
ソースコード(AST)         -class-features-plugin          初期化コード(AST)
                                 │
                                 ├─ フィールド検出
                                 ├─ 初期化コード生成
                                 └─ AST置換
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-transform-class-properties/src/index.ts` | ソース | プラグインエントリーポイント |
| package.json | `packages/babel-plugin-transform-class-properties/package.json` | 設定 | パッケージ依存関係定義 |
| test/index.js | `packages/babel-plugin-transform-class-properties/test/index.js` | テスト | テストランナー設定 |
| fixtures/ | `packages/babel-plugin-transform-class-properties/test/fixtures/` | テスト | テストケース群 |
