# 機能設計書 20-@babel/plugin-transform-classes

## 概要

本ドキュメントは、Babelの@babel/plugin-transform-classesパッケージの機能設計を記述する。@babel/plugin-transform-classesは、ES6のクラス構文をES5互換のコンストラクタ関数とプロトタイプベースの継承に変換するプラグインである。

### 本機能の処理概要

@babel/plugin-transform-classesは、ES6で導入されたclass構文（`class Foo extends Bar {}`）をES5互換のコンストラクタ関数パターンに変換する。継承、メソッド定義、静的メソッド、コンストラクタなどを適切にES5形式に変換する。

**業務上の目的・背景**：クラス構文はES6（ECMAScript 2015）で導入された構文であり、古いブラウザ（IE11など）やJavaScript実行環境ではサポートされていない。レガシー環境でも動作するコードを生成するため、クラス構文をコンストラクタ関数とプロトタイプチェーンに変換する必要がある。

**機能の利用シーン**：レガシーブラウザ対応のWebアプリケーション、古いNode.jsバージョンでの実行、@babel/preset-envの一部として自動適用、React（class component）の変換などで利用される。

**主要な処理内容**：
1. ClassDeclaration/ClassExpressionノードの検出と変換
2. コンストラクタ関数の生成
3. プロトタイプメソッドの定義（createClassヘルパー使用）
4. 静的メソッドの定義
5. 継承関係の処理（inheritsヘルパー使用）
6. super呼び出しの変換
7. ネイティブクラス継承のラッピング（wrapNativeSuperヘルパー）

**関連システム・外部連携**：@babel/helper-plugin-utils、@babel/helper-replace-supers、@babel/helper-annotate-as-pure、@babel/helper-compilation-targets、@babel/helper-globalsと連携。

**権限による制御**：本機能に権限制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | なし | - | CLIおよびAPIとして利用 |

## 機能種別

プラグイン / ES6構文変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| loose | boolean | No | ルーズモード（パフォーマンス優先） | デフォルト: false |

### 入力データソース

- Babel設定ファイル（babel.config.js, .babelrc等）
- API呼び出しのオプション
- api.assumptionによる各種仮定設定

### API Assumption設定

| 仮定名 | 説明 | looseとの関係 |
|--------|------|---------------|
| setClassMethods | メソッドをdefinePropertyではなく代入で設定 | loose: trueで有効 |
| constantSuper | superが定数であると仮定 | loose: trueで有効 |
| superIsCallableConstructor | 親クラスがcallableと仮定 | loose: trueで有効 |
| noClassCalls | classCallCheckを省略 | loose: trueで有効 |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| visitor | object | ClassDeclaration/ClassExpressionを処理するビジターオブジェクト |
| name | string | プラグイン名 "transform-classes" |

### 出力先

Babelコア(@babel/core)のトランスフォームパイプラインにビジターを提供する。

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化
   └─ api.assertVersion(7): バージョン確認
   └─ looseオプションの取得
   └─ 各種仮定（assumption）の取得

2. ビジター登録
   ├─ ExportDefaultDeclaration: export default class の分離
   ├─ ClassDeclaration: クラス宣言の変換
   └─ ClassExpression: クラス式の変換

3. クラス変換処理（transformClass）
   ├─ classState初期化
   ├─ コンストラクタ生成（maybeCreateConstructor）
   ├─ メソッド処理（pushBody）
   │   ├─ ReplaceSupers: super参照の置換
   │   └─ pushMethod: メソッドをディスクリプタに追加
   ├─ 継承処理（pushInheritsToBody）
   └─ ディスクリプタ処理（pushDescriptors）
       └─ createClassヘルパー呼び出し
```

### フローチャート

```mermaid
flowchart TD
    A[ClassDeclaration/ClassExpression検出] --> B{VISITED済み?}
    B -->|Yes| C[処理スキップ]
    B -->|No| D[VISITEDに追加]
    D --> E[transformClass呼び出し]
    E --> F[classState初期化]
    F --> G{継承あり?}
    G -->|Yes| H[superName設定]
    G -->|No| I[コンストラクタ生成]
    H --> J{ネイティブクラス継承?}
    J -->|Yes| K[wrapNativeSuperヘルパー追加]
    J -->|No| L[inheritsヘルパー追加]
    K --> L
    L --> I
    I --> M[メソッド処理]
    M --> N[静的メソッド処理]
    N --> O{noClassCalls仮定?}
    O -->|No| P[classCallCheckヘルパー追加]
    O -->|Yes| Q[ディスクリプタ生成]
    P --> Q
    Q --> R[createClassヘルパー呼び出し]
    R --> S[IIFE生成]
    S --> T[変換完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | use strict | クラスは常にstrictモードで動作 | 常時 |
| BR-02 | 二重変換防止 | WeakSetで処理済みノードを追跡 | 常時 |
| BR-03 | ネイティブ継承 | Array/Error等の継承時はwrapNativeSuper使用 | builtinClasses継承時 |
| BR-04 | Iterator除外 | Iteratorはbuiltinから除外（newできない） | builtinClasses定義 |
| BR-05 | looseモード | パフォーマンス優先の緩い変換 | loose: true |
| BR-06 | export default分離 | export default classは分離してから処理 | ExportDefaultDeclaration |

### 計算ロジック

クラス変換例:
```javascript
// 入力（ES6 クラス）
class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    console.log(`${this.name} makes a sound.`);
  }
  static create(name) {
    return new Animal(name);
  }
}

class Dog extends Animal {
  constructor(name) {
    super(name);
  }
  speak() {
    console.log(`${this.name} barks.`);
  }
}

// 出力（ES5 コンストラクタ関数） - 簡略化
var Animal = /*#__PURE__*/function () {
  function Animal(name) {
    _classCallCheck(this, Animal);
    this.name = name;
  }
  _createClass(Animal, [{
    key: "speak",
    value: function speak() {
      console.log(this.name + " makes a sound.");
    }
  }], [{
    key: "create",
    value: function create(name) {
      return new Animal(name);
    }
  }]);
  return Animal;
}();

var Dog = /*#__PURE__*/function (_Animal) {
  _inherits(Dog, _Animal);
  function Dog(name) {
    _classCallCheck(this, Dog);
    return _possibleConstructorReturn(this, _getPrototypeOf(Dog).call(this, name));
  }
  _createClass(Dog, [{
    key: "speak",
    value: function speak() {
      console.log(this.name + " barks.");
    }
  }]);
  return Dog;
}(Animal);
```

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | AssertionError | Babel 7未満で使用 | Babelをアップグレード |
| - | SyntaxError | 不正なクラス構文 | コードを修正 |
| - | CodeFrameError | クラスプロパティ変換なし | class-propertiesプラグインを追加 |
| - | CodeFrameError | デコレータ順序不正 | decoratorsプラグインをclassesの前に配置 |

### リトライ仕様

本機能にリトライ処理は存在しない。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

- 複雑な変換のため、大規模クラスではオーバーヘッドあり
- looseモードで高速化可能
- WeakSetによる二重処理防止で効率化
- annotateAsPureによるtree-shaking最適化

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

- 入力コードの検証は行わない
- 構文変換のみを実行
- use strictディレクティブを自動挿入

## 備考

- @babel/preset-envで自動的に必要に応じて適用される
- クラスプロパティ（class fields）は別プラグイン（@babel/plugin-transform-class-properties）が必要
- デコレータは別プラグイン（@babel/plugin-proposal-decorators）が必要で、順序に注意
- transformClass.tsは886行に及ぶ大規模な変換ロジック

---

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

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

### 推奨読解順序

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

まず、プラグインのメイン処理を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-transform-classes/src/index.ts` | プラグインのメイン実装 |

**読解のコツ**:
- **1-7行目**: インポート文（declare, isRequired, annotateAsPure, types, globals, transformClass）
- **9-12行目**: builtinClasses Set定義（browser/builtinグローバル）
- **14-19行目**: Iterator除外のコメントと処理
- **21-23行目**: Optionsインターフェース（looseオプション）
- **25-38行目**: declare関数とassumption取得
- **41行目**: VISITEDのWeakSet（二重変換防止）
- **46-51行目**: ExportDefaultDeclarationビジター
- **52-64行目**: ClassDeclarationビジター
- **66-99行目**: ClassExpressionビジター

#### Step 2: ビジターの動作を理解する

各ビジターの処理内容を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-transform-classes/src/index.ts` | 46-99行目のビジター処理 |

**主要処理フロー**:
- **47-51行目**: ExportDefaultDeclaration - export default classの分離
- **52-64行目**: ClassDeclaration - let宣言への変換
- **66-99行目**: ClassExpression - transformClass呼び出しとannotateAsPure

#### Step 3: クラス変換の核心を理解する

transformClass関数の構造を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | transformClass.ts | `packages/babel-plugin-transform-classes/src/transformClass.ts` | クラス変換のメインロジック |

**主要処理フロー**:
- **9-14行目**: ClassAssumptions型定義
- **18-30行目**: buildConstructor関数
- **40-84行目**: State型定義（クラス変換の状態管理）
- **91-98行目**: transformClass関数のシグネチャ
- **99-140行目**: classState初期化
- **152-154行目**: createClassHelper関数
- **159-180行目**: maybeCreateConstructor関数
- **182-196行目**: buildBody関数
- **198-254行目**: pushBody関数（メソッド処理）
- **256-302行目**: pushDescriptors関数
- **304-390行目**: wrapSuperCall関数
- **392-573行目**: verifyConstructor関数（super呼び出し検証）
- **578-622行目**: pushMethod関数
- **624-658行目**: processMethod関数
- **678-707行目**: pushConstructor関数
- **712-730行目**: pushInheritsToBody関数
- **777-882行目**: classTransformer関数（メイン処理）

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

```
@babel/plugin-transform-classes
    │
    ├─ declare (@babel/helper-plugin-utils)
    │      ├─ api.assertVersion(7)
    │      └─ api.assumption(...)
    │           ├─ setClassMethods
    │           ├─ constantSuper
    │           ├─ superIsCallableConstructor
    │           └─ noClassCalls
    │
    ├─ builtinClasses (Set)
    │      ├─ globalsBrowserUpper
    │      └─ globalsBuiltinUpper
    │
    └─ visitor
           │
           ├─ ExportDefaultDeclaration
           │      └─ splitExportDeclaration()
           │
           ├─ ClassDeclaration
           │      └─ variableDeclaration変換
           │
           └─ ClassExpression
                  │
                  ├─ VISITED.has() チェック
                  ├─ ensureFunctionName()
                  │
                  └─ transformClass()
                         │
                         ├─ classState初期化
                         ├─ extractDynamicKeys()
                         ├─ setupClosureParamsArgs()
                         │
                         ├─ buildBody()
                         │      ├─ maybeCreateConstructor()
                         │      ├─ pushBody()
                         │      │      ├─ ReplaceSupers.replace()
                         │      │      ├─ pushConstructor()
                         │      │      └─ pushMethod()
                         │      ├─ verifyConstructor()
                         │      │      └─ wrapSuperCall()
                         │      └─ pushDescriptors()
                         │             └─ createClassHelper()
                         │
                         └─ Helpers
                                ├─ classCallCheck
                                ├─ createClass
                                ├─ inherits / inheritsLoose
                                ├─ possibleConstructorReturn
                                ├─ assertThisInitialized
                                └─ wrapNativeSuper
```

### データフロー図

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

ClassDeclaration/
ClassExpression AST ─────> classState初期化 ─────────────┐
                                                         │
superClass参照 ────────────> isDerived判定 ───────────────┤
                                                         │
builtinClasses ────────────> extendsNative判定 ──────────┤
                                                         │
                                                         └──> buildBody
                                                                   │
                                                         ┌─────────┴─────────┐
                                                         │                   │
                                                    継承あり            継承なし
                                                         │                   │
                                                    inherits            直接構築
                                                    callSuper
                                                         │                   │
                                                         └─────────┬─────────┘
                                                                   │
                                                         createClass / 直接返却
                                                                   │
                                                         IIFE (ArrowFunction)
                                                                   │
                                                         ES5関数 + プロトタイプ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-transform-classes/src/index.ts` | ソース | プラグインメイン実装 |
| transformClass.ts | `packages/babel-plugin-transform-classes/src/transformClass.ts` | ソース | クラス変換のコアロジック |
| inline-callSuper-helpers.ts | `packages/babel-plugin-transform-classes/src/inline-callSuper-helpers.ts` | ソース | callSuperヘルパーのインライン化 |
| package.json | `packages/babel-plugin-transform-classes/package.json` | 設定 | パッケージ設定 |
| test/fixtures | `packages/babel-plugin-transform-classes/test/fixtures/` | テスト | 変換テストケース |
