# 機能設計書 45-コード生成（Codegen）

## 概要

本ドキュメントは、Vue 3テンプレートコンパイラのコード生成（Codegen）機能について記述する。トランスフォーム済みのASTからレンダリング関数のJavaScriptコードを生成する。

### 本機能の処理概要

コード生成は、テンプレートコンパイルパイプラインの最終段階であり、トランスフォーム済みAST（codegenNode付き）を入力として受け取り、JavaScriptのレンダリング関数コードを文字列として出力する。静的ホイスティング、ソースマップ生成、モジュール/関数モード切り替えなどの最適化機能を含む。

**業務上の目的・背景**：Vueテンプレートは最終的にJavaScriptのレンダリング関数に変換される必要がある。Codegenはこの変換を担い、VNodeの生成コード、ブロックツリー最適化、ランタイムヘルパーの参照などを含む実行可能なJavaScriptコードを生成する。

**機能の利用シーン**：`baseCompile()` 関数内でtransform処理の後、最終段階として呼び出される。ビルドツール（Vite, webpack）、SFCコンパイラ、ブラウザ内コンパイラなどで使用される。

**主要な処理内容**：
1. CodegenContextの作成（ソースマップ、インデント、ヘルパー参照管理）
2. プリアンブル生成（import文またはconst宣言、静的ホイスト変数）
3. レンダリング関数シグネチャの生成
4. ASTノードの再帰的なコード生成（VNodeCall, 条件式, ループ等）
5. ソースマップのマッピング生成

**関連システム・外部連携**：source-map-jsによるソースマップ生成、@vue/runtime-coreのランタイムヘルパー

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 4 | Index（メイン画面） | 主機能 | ASTからレンダリング関数JavaScriptコードを生成し右パネルに表示 |
| 5 | Options Panel（コンパイルオプション） | API連携 | コンパイルオプション変更に基づくコード再生成トリガー |

## 機能種別

テンプレートコンパイル（コード生成）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ast | RootNode | Yes | トランスフォーム済みAST | なし |
| options | CodegenOptions | No | コード生成オプション | なし |

### CodegenOptionsの主要プロパティ

| パラメータ名 | 型 | デフォルト | 説明 |
|-------------|-----|-----------|------|
| mode | 'function' \| 'module' | 'function' | 出力モード |
| prefixIdentifiers | boolean | modeに依存 | 識別子プレフィックス |
| sourceMap | boolean | false | ソースマップ生成 |
| filename | string | 'template.vue.html' | ソースマップ用ファイル名 |
| scopeId | string \| null | null | SFCスコープID |
| ssr | boolean | false | SSRモード |
| isTS | boolean | false | TypeScript出力 |
| inline | boolean | false | setup()インラインモード |

### 入力データソース

baseParse() + transform() によって処理されたAST。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| code | string | 生成されたJavaScriptコード |
| preamble | string | インラインモード時のプリアンブルコード |
| ast | RootNode | 入力AST（参照） |
| map | RawSourceMap \| undefined | ソースマップ |

### 出力先

`baseCompile()` の戻り値として呼び出し元に返却される。

## 処理フロー

### 処理シーケンス

```
1. CodegenContext の作成
   └─ createCodegenContext(ast, options)
   └─ ソースマップ生成器の初期化（sourceMap有効時）
2. プリアンブル生成
   └─ module モード: genModulePreamble（import文生成）
   └─ function モード: genFunctionPreamble（const宣言生成）
   └─ 静的ホイスト変数の生成（genHoists）
3. レンダリング関数の生成
   └─ 関数シグネチャ: render(_ctx, _cache) / ssrRender(...)
   └─ with ブロック（非prefixIdentifiersモード）
   └─ アセット解決文（components, directives）
4. VNodeツリーの生成
   └─ genNode(ast.codegenNode) による再帰的コード生成
5. 関数クロージング
   └─ with ブロック閉じ + 関数閉じ
6. 結果の返却
   └─ CodegenResult: { code, preamble, ast, map }
```

### フローチャート

```mermaid
flowchart TD
    A[generate入力: AST + Options] --> B[CodegenContext作成]
    B --> C{mode?}
    C -->|module| D[genModulePreamble: import文]
    C -->|function| E[genFunctionPreamble: const宣言]
    D --> F[レンダリング関数シグネチャ]
    E --> F
    F --> G{useWithBlock?}
    G -->|Yes| H[with _ctx ブロック開始]
    G -->|No| I[直接コード生成]
    H --> J[アセット解決文生成]
    I --> J
    J --> K[genNode: codegenNode再帰生成]
    K --> L[関数クロージング]
    L --> M[CodegenResult返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-45-01 | withブロック | 非prefixIdentifiers かつ functionモード時にwith(_ctx)で包む | mode === 'function' && !prefixIdentifiers |
| BR-45-02 | 静的ホイスト | hoists配列の要素を関数外のconst変数として宣言 | hoists.length > 0 |
| BR-45-03 | PUREアノテーション | Tree-shaking用の/*@__PURE__*/アノテーション付与 | pure === true時 |
| BR-45-04 | PatchFlagコメント | DEVモードではpatchFlagに人間可読なコメントを付与 | __DEV__有効時 |
| BR-45-05 | SSR関数名 | SSRモードではrender関数名がssrRenderになる | ssr === true時 |

### 計算ロジック

ソースマップのマッピングは、各ASTノードの位置情報（loc.start, loc.end）に基づいて、入力テンプレートと出力JavaScriptの対応を記録する。

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

データベース操作は存在しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | アサーション（DEVのみ） | codegenNodeがnullの場合 | transform処理が正しく実行されているか確認 |
| - | アサーション（DEVのみ） | 未処理のノードタイプが検出された場合 | 対応するtransformを追加 |

### リトライ仕様

リトライ仕様は存在しない。

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

トランザクション処理は存在しない。

## パフォーマンス要件

- AST走査は1パスで完了
- ソースマップ生成は非ブラウザビルドでのみ有効（ブラウザビルドでの軽量化）
- 静的ホイスティングにより、再レンダリング時のVNode生成コストを削減

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

- 生成されたコードはeval/new Functionで実行される可能性があるため、テンプレート入力の検証が重要
- CSP（Content Security Policy）環境ではランタイムコンパイルが制限される

## 備考

- `PURE_ANNOTATION` (`/*@__PURE__*/`)はバンドラーのTree-shakingを支援する
- `aliasHelper` はランタイムヘルパーのエイリアス（例: `createVNode: _createVNode`）を生成する
- インラインモード（inline: true）ではアロー関数として生成される
- キャッシュ式（CacheExpression）はv-once, v-memoの最適化に使用される

---

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

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

### 推奨読解順序

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

コード生成に関わる型定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | codegen.ts | `packages/compiler-core/src/codegen.ts` | CodegenResult型（108-113行目）: code, preamble, ast, map |
| 1-2 | codegen.ts | `packages/compiler-core/src/codegen.ts` | CodegenContext型（122-139行目）: push, indent, deindent等のメソッド |
| 1-3 | codegen.ts | `packages/compiler-core/src/codegen.ts` | NewlineType列挙型（115-120行目）: Start, End, None, Unknown |

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

generate()関数の処理フローを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | codegen.ts | `packages/compiler-core/src/codegen.ts` | generate関数（283-406行目）: メインエントリーポイント |
| 2-2 | codegen.ts | `packages/compiler-core/src/codegen.ts` | createCodegenContext関数（141-281行目）: コンテキスト初期化 |

**主要処理フロー**:
1. **289行目**: createCodegenContext(ast, options)でコンテキスト作成
2. **314-318行目**: モジュール/関数モードに応じたプリアンブル生成
3. **320-329行目**: レンダリング関数シグネチャ生成
4. **338-349行目**: withブロックとヘルパー宣言
5. **353-364行目**: アセット解決文（components, directives）
6. **386-390行目**: genNode(ast.codegenNode)による本体コード生成
7. **400-405行目**: CodegenResult返却

#### Step 3: ノード別コード生成を理解する

genNode()のswitch文による各ノードタイプのコード生成を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | codegen.ts | `packages/compiler-core/src/codegen.ts` | genNode関数（650-745行目）: ノードタイプ別の分岐 |
| 3-2 | codegen.ts | `packages/compiler-core/src/codegen.ts` | genVNodeCall関数（817-878行目）: VNode生成コード |
| 3-3 | codegen.ts | `packages/compiler-core/src/codegen.ts` | genConditionalExpression関数（979-1013行目）: 条件式 |
| 3-4 | codegen.ts | `packages/compiler-core/src/codegen.ts` | genFunctionExpression関数（934-977行目）: 関数式 |

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

```
generate(ast, options)
    │
    ├─ createCodegenContext(ast, options)
    │      └─ SourceMapGenerator（sourceMap有効時）
    │
    ├─ genModulePreamble / genFunctionPreamble
    │      └─ genHoists(ast.hoists)
    │             └─ genNode (各hoist)
    │
    ├─ genAssets (components, directives)
    │
    └─ genNode(ast.codegenNode) 再帰
           ├─ genVNodeCall → VNODE_CALL
           ├─ genText → TEXT
           ├─ genExpression → SIMPLE_EXPRESSION
           ├─ genInterpolation → INTERPOLATION
           ├─ genCompoundExpression → COMPOUND_EXPRESSION
           ├─ genComment → COMMENT
           ├─ genCallExpression → JS_CALL_EXPRESSION
           ├─ genObjectExpression → JS_OBJECT_EXPRESSION
           ├─ genArrayExpression → JS_ARRAY_EXPRESSION
           ├─ genFunctionExpression → JS_FUNCTION_EXPRESSION
           ├─ genConditionalExpression → JS_CONDITIONAL_EXPRESSION
           └─ genCacheExpression → JS_CACHE_EXPRESSION
```

### データフロー図

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

トランスフォーム済みAST ──▶ generate()                   ──▶ CodegenResult
                            │                                  ├─ code: string
                            ├─ プリアンブル生成                  ├─ preamble: string
                            ├─ 関数シグネチャ                    ├─ ast: RootNode
                            ├─ genNode (再帰)                   └─ map?: RawSourceMap
                            └─ ソースマップ生成
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| codegen.ts | `packages/compiler-core/src/codegen.ts` | ソース | generate()とコード生成関数群の実装（1119行） |
| runtimeHelpers.ts | `packages/compiler-core/src/runtimeHelpers.ts` | ソース | ランタイムヘルパーのシンボルと名前マッピング |
| ast.ts | `packages/compiler-core/src/ast.ts` | ソース | AST型定義（VNodeCall等） |
| compile.ts | `packages/compiler-core/src/compile.ts` | ソース | baseCompile()からgenerate()を呼び出す |
