# 機能設計書 60-@babel/plugin-proposal-decorators

## 概要

本ドキュメントは、Babelプラグイン `@babel/plugin-proposal-decorators` の機能設計を記載したものである。本プラグインは、TC39提案のデコレータ構文（`@decorator` アノテーション）をES5互換のコードに変換する。

### 本機能の処理概要

**業務上の目的・背景**：デコレータは、クラス、メソッド、プロパティなどに対してメタプログラミングを行うための構文である。`@decorator` 形式でクラスやメンバーを修飾し、振る舞いを拡張・変更できる。TypeScriptやフレームワーク（Angular、MobXなど）で広く使用されている。TC39で複数のバージョンが提案されており、本プラグインは「legacy」版と「2023-11」版の両方をサポートする。

**機能の利用シーン**：
- クラスに横断的関心事（ロギング、認証、キャッシュ）を適用する場合
- メソッドやプロパティの振る舞いを宣言的に変更する場合
- フレームワーク（Angular、Nest.js、MobXなど）でのデコレータ利用
- プロパティのバリデーションやシリアライゼーション

**主要な処理内容**：
1. デコレータ構文の解析（`@babel/plugin-syntax-decorators` を継承）
2. バージョンに応じた変換処理の選択
3. legacy版: クラスデコレータとメンバーデコレータを関数呼び出しに変換
4. 2023-11版: `@babel/helper-create-class-features-plugin` を使用して変換

**関連システム・外部連携**：
- `@babel/plugin-syntax-decorators` でデコレータ構文の解析を有効化
- `@babel/helper-create-class-features-plugin` で2023-11版の変換を実行
- legacy版は独自のVisitor（transformer-legacy.ts）で変換

**権限による制御**：本プラグインに権限制御の概念は存在しない。

## 関連画面

該当なし（CLIツール/ビルドツールとして動作）

## 機能種別

データ変換処理（ASTトランスフォーム）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| version | "legacy" \| "2023-11" | No | デコレータ仕様のバージョン（デフォルト: "2023-11"） | 指定値以外はエラー |
| decoratorsBeforeExport | boolean | No | export宣言の前にデコレータを配置（legacy版で使用） | legacy版でのみ有効 |

### 入力データソース

- Babelコアから渡されるAST（抽象構文木）
- `Decorator` ノードを含むクラス、メソッド、プロパティが処理対象

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 変換後AST | AST Node | デコレータが展開されたコード |

### 出力先

変換されたASTはBabelコアに返され、最終的にJavaScriptコードとして出力される

## 処理フロー

### 処理シーケンス

```
1. プラグイン初期化
   └─ Babelバージョン検証（^7.0.0-0 || ^8.0.0）
   └─ version オプションの取得

2. バージョン判定
   └─ "legacy": legacyVisitor を使用
   └─ "2023-11" (デフォルト): createClassFeaturePlugin を使用

3. Legacy版変換
   └─ デコレータ式を評価順序保証のため変数に格納
   └─ クラスデコレータを適用
   └─ メソッド/プロパティデコレータを適用
   └─ ヘルパー関数を注入

4. 2023-11版変換
   └─ @babel/helper-create-class-features-plugin に委譲
   └─ FEATURES.decorators フラグを使用
```

### フローチャート

```mermaid
flowchart TD
    A[プラグイン初期化] --> B{version?}
    B -->|legacy| C[legacyVisitor]
    B -->|2023-11/undefined| D[createClassFeaturePlugin]
    C --> E[クラスデコレータ処理]
    E --> F[メンバーデコレータ処理]
    F --> G[ヘルパー注入]
    D --> H[helper-create-class-features-plugin]
    G --> I[変換完了]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | バージョン選択 | version オプションで変換方式を選択 | プラグイン設定時 |
| BR-02 | legacy変換 | デコレータを関数呼び出しに変換 | version === "legacy" |
| BR-03 | 2023-11変換 | TC39 2023-11仕様に基づく変換 | version === "2023-11" または未指定 |
| BR-04 | 評価順序保証 | デコレータ式を変数に格納して順序を保証 | legacy版 |
| BR-05 | 計算プロパティ禁止 | 計算プロパティキーへのデコレータはエラー | legacy版 |

### 計算ロジック

Legacy版の変換ロジック：
1. クラスデコレータ: `DECORATOR(CLASS_REF = INNER) || CLASS_REF`
2. メンバーデコレータ: `applyDecoratedDescriptor(target, property, decorators, descriptor)`
3. プロパティデコレータ: `initializerWarningHelper` と `initializerDefineProperty` を使用

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

該当なし（データベース操作は行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | version が無効な値 | "The '.version' option must be one of 'legacy' or '2023-11'." |
| - | BuildCodeFrameError | 計算プロパティへのデコレータ（legacy） | "Computed method/property decorators are not yet supported." |

### リトライ仕様

該当なし

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

該当なし（ステートレスな変換処理）

## パフォーマンス要件

- デコレータの数に応じてヘルパー関数呼び出しが増加
- 評価順序保証のための一時変数が生成される

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

- デコレータ関数は任意のコードを実行できるため、信頼できないデコレータの使用に注意

## 備考

- TC39デコレータ提案をネイティブサポートする環境ではこのプラグインは不要
- TypeScriptのデコレータとは仕様が異なる可能性がある
- legacy版とTypeScriptのデコレータは互換性が高い
- 2023-11版は最新のTC39仕様に基づく

---

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

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

### 推奨読解順序

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

プラグインオプションの型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-plugin-proposal-decorators/src/index.ts` | Options インターフェース（11-15行目） |

**読解のコツ**: `version` は "legacy" または "2023-11" を指定。`loose` オプションは非推奨で、代わりに `constantSuper` assumption を使用。

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

プラグインの初期化とバージョン分岐を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-plugin-proposal-decorators/src/index.ts` | プラグイン本体（19-48行目） |

**主要処理フロー**:
1. **19-20行目**: プラグイン宣言、Babelバージョン検証
2. **24行目**: version オプション取得
3. **26-31行目**: legacy版の場合、legacyVisitorを使用
4. **32-42行目**: 2023-11版の場合、createClassFeaturePluginを使用
5. **43-46行目**: 無効なversionはエラー

#### Step 3: Legacy版の変換ロジックを理解する

Legacy版デコレータの詳細な変換処理を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | transformer-legacy.ts | `packages/babel-plugin-proposal-decorators/src/transformer-legacy.ts` | Legacy版Visitor（301-396行目） |

**主要処理フロー**:
- **6-12行目**: buildClassDecorator テンプレート
- **14-16行目**: buildClassPrototype テンプレート
- **18-23行目**: buildGetDescriptor テンプレート
- **53-89行目**: applyEnsureOrdering（評価順序の保証）
- **95-113行目**: applyClassDecorators（クラスデコレータ適用）
- **123-135行目**: applyMethodDecorators（メソッドデコレータ適用）
- **169-285行目**: applyTargetDecorators（デコレータの実際の適用）
- **301-353行目**: Visitor定義（ExportDefaultDeclaration, ClassDeclaration, ClassExpression, ObjectExpression）

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

```
@babel/plugin-proposal-decorators
    │
    ├─ [version === "legacy"]
    │      │
    │      └─ legacyVisitor
    │             │
    │             ├─ ExportDefaultDeclaration
    │             │      └─ decoratedClassToExpression()
    │             │
    │             ├─ ClassDeclaration
    │             │      └─ decoratedClassToExpression()
    │             │
    │             ├─ ClassExpression
    │             │      ├─ applyEnsureOrdering()
    │             │      ├─ applyClassDecorators()
    │             │      └─ applyMethodDecorators()
    │             │             └─ applyTargetDecorators()
    │             │
    │             └─ ObjectExpression
    │                    └─ applyObjectDecorators()
    │
    └─ [version === "2023-11"]
           │
           └─ createClassFeaturePlugin
                  └─ @babel/helper-create-class-features-plugin
```

### データフロー図

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

@decorator               AST解析  ───▶  Visitor  ───▶  var _class;
class C {                                  │             let C = _class =
  @method                                  │               _decorator(
  foo() {}                                 │                 class C {
}                             applyClassDecorators           foo() {}
                              applyMethodDecorators        }
                              applyTargetDecorators      ) || _class;
                                           │             _applyDecoratedDescriptor(
                                           │               _class.prototype,
                                           │               "foo", [method], ...
                                           │             );
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-plugin-proposal-decorators/src/index.ts` | ソース | プラグインエントリーポイント |
| transformer-legacy.ts | `packages/babel-plugin-proposal-decorators/src/transformer-legacy.ts` | ソース | Legacy版変換ロジック |
| package.json | `packages/babel-plugin-proposal-decorators/package.json` | 設定 | パッケージ定義、依存関係 |
| index.ts | `packages/babel-plugin-syntax-decorators/src/index.ts` | ソース | デコレータ構文解析 |
| index.ts | `packages/babel-helper-create-class-features-plugin/src/index.ts` | ソース | 2023-11版変換ヘルパー |
