# 機能設計書 37-Bladeコンパイラ

## 概要

本ドキュメントは、Laravel Frameworkにおけるブレードコンパイラ（Blade Compiler）機能の設計書である。BladeテンプレートをPHPコードに変換するコンパイラであり、ディレクティブ、エコー、コンポーネント等の構文を解析し、実行可能なPHPファイルを生成する。

### 本機能の処理概要

**業務上の目的・背景**：
生のPHPテンプレートは冗長で可読性が低い。Bladeテンプレートエンジンは、`@if`、`@foreach`、`{{ }}`等の簡潔な構文を提供し、開発者の生産性を向上させる。BladeCompilerはこれらの構文を解析し、標準的なPHPコードに変換することで、高いパフォーマンスを維持しながら開発体験を改善する。

**機能の利用シーン**：
- Bladeテンプレートのコンパイル
- カスタムディレクティブの登録
- カスタム条件ディレクティブの登録
- コンポーネントエイリアスの登録
- コンポーネント名前空間の登録
- インラインBladeコードのレンダリング

**主要な処理内容**：
1. テンプレートコンパイル（`compile`, `compileString`メソッド）
2. ディレクティブ処理（`@if`, `@foreach`, `@include`等の変換）
3. エコー処理（`{{ }}`, `{!! !!}`, `{{{ }}}`の変換）
4. コンポーネントタグ処理（`<x-component>`タグの変換）
5. カスタムディレクティブ登録（`directive`メソッド）
6. カスタム条件登録（`if`メソッド）
7. コンポーネント登録（`component`, `componentNamespace`メソッド）
8. プリコンパイラ登録（`precompiler`メソッド）

**関連システム・外部連携**：
- Filesystem: テンプレートファイルの読み書き
- ComponentTagCompiler: コンポーネントタグのコンパイル
- ViewFactory: 名前空間登録との連携

**権限による制御**：
本機能自体は権限制御を行わない。`@can`ディレクティブは認可を確認するが、コンパイラは構文変換のみを担当する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 全Blade画面 | 主処理 | 全てのBladeテンプレートで使用 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| path | string | No | コンパイル対象のファイルパス | 存在するファイル |
| value | string | Yes（compileString時） | コンパイル対象のBlade文字列 | - |

### 入力データソース

- Bladeテンプレートファイル（.blade.php）
- インライン文字列

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| compiled | string | コンパイル後のPHPコード |
| compiledPath | string | コンパイル結果の保存パス |

### 出力先

- コンパイルキャッシュディレクトリ（storage/framework/views）
- 戻り値として呼び出し元に返却

## 処理フロー

### 処理シーケンス

```
1. コンパイル開始（compile呼び出し）
   └─ パスを設定
   └─ ファイル内容を読み込み

2. プリプロセス
   └─ prepareStringsForCompilationUsing コールバック実行
   └─ verbatimブロックとphpブロックを一時保存

3. コンポーネントタグコンパイル
   └─ ComponentTagCompilerでx-タグを変換
   └─ コメント処理

4. プリコンパイラ実行
   └─ 登録済みプリコンパイラを順次実行

5. トークン処理
   └─ token_get_all()でPHPトークン化
   └─ T_INLINE_HTMLトークンを処理
   └─ Extensions → Statements → Echosの順でコンパイル

6. 後処理
   └─ rawブロックを復元
   └─ フッター追加（@endonce等）
   └─ ファイルパスコメント追加

7. 保存
   └─ コンパイルディレクトリにファイル書き込み
   └─ ハッシュ比較で変更がある場合のみ書き込み
```

### フローチャート

```mermaid
flowchart TD
    A[compile呼び出し] --> B[ファイル読み込み]
    B --> C[prepareStringsForCompilation]
    C --> D[storeUncompiledBlocks]
    D --> E[compileComponentTags]
    E --> F[プリコンパイラ実行]
    F --> G[token_get_all]
    G --> H[トークンループ]
    H --> I{T_INLINE_HTML?}
    I -->|Yes| J[compileExtensions]
    J --> K[compileStatements]
    K --> L[compileEchos]
    L --> M[次のトークン]
    I -->|No| M
    M --> H
    H --> N[rawブロック復元]
    N --> O[フッター追加]
    O --> P[ファイルパス追加]
    P --> Q{ハッシュ変更?}
    Q -->|Yes| R[ファイル書き込み]
    Q -->|No| S[スキップ]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | コンパイル順序 | Extensions → Statements → Echosの順で処理 | 常時 |
| BR-37-02 | Verbatimブロック | @verbatim〜@endverbatim内はコンパイルしない | verbatim使用時 |
| BR-37-03 | PHPブロック | @php〜@endphp内はそのまま出力 | php使用時 |
| BR-37-04 | エスケープエコー | `{{ }}`は`e()`でHTMLエスケープ | 通常エコー時 |
| BR-37-05 | ハッシュ比較 | xxh128ハッシュで変更検出、変更時のみ書き込み | 常時 |

### 計算ロジック

**コンパイルパス生成**:
```php
$compiledPath = $cachePath . '/' . hash('xxh128', $relative ? $basePath . $path : $path) . '.' . $extension;
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | InvalidArgumentException | 無効なディレクティブ名 | 英数字とアンダースコアのみ使用 |
| - | ParseError | 不正なPHP構文 | テンプレートを修正 |
| - | RuntimeException | キャッシュディレクトリ書き込み不可 | パーミッション確認 |

### リトライ仕様

本機能にリトライ機能は含まれない。

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

該当なし

## パフォーマンス要件

- コンパイル結果はファイルキャッシュされ、変更がない限り再コンパイルしない
- xxh128ハッシュ（高速ハッシュアルゴリズム）で変更検出
- コンパイル済みファイルの有効期限確認は設定可能（`check_cache_timestamps`）

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

- `{{ }}`はデフォルトでHTMLエスケープ（XSS対策）
- `{!! !!}`は生出力のため、信頼できないデータには使用禁止
- ディレクティブ名は英数字とアンダースコアのみ（インジェクション対策）
- コンポーネントクラス名の検証

## 備考

- `ReflectsClosures`トレイトでクロージャの引数情報を取得
- `withoutComponentTags()`でコンポーネントタグ処理を無効化可能
- `render()`静的メソッドでインライン文字列を直接レンダリング可能

---

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

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

### 推奨読解順序

#### Step 1: 基底クラスを理解する

まず、コンパイラの共通機能を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Compiler.php | `src/Illuminate/View/Compilers/Compiler.php` | 基底クラス、パス管理 |
| 1-2 | CompilerInterface.php | `src/Illuminate/View/Compilers/CompilerInterface.php` | コンパイラ契約 |

#### Step 2: BladeCompilerクラスを理解する

コンパイラの中核機能を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BladeCompiler.php | `src/Illuminate/View/Compilers/BladeCompiler.php` | メインコンパイラ |

**主要処理フロー**:
- **91-96行目**: `$compilers`配列 - コンパイル処理の種類
- **103行目**: `$rawTags` - 生出力タグ `{!! !!}`
- **110行目**: `$contentTags` - 通常エコータグ `{{ }}`
- **117行目**: `$escapedTags` - エスケープエコータグ `{{{ }}}`
- **181-210行目**: `compile()` - メインコンパイルメソッド
- **275-322行目**: `compileString()` - 文字列コンパイル
- **332-358行目**: `render()` - 静的レンダリング
- **390-401行目**: `storeUncompiledBlocks()` - verbatim/php保存
- **448-457行目**: `compileComponentTags()` - コンポーネント変換
- **505-516行目**: `parseToken()` - トークン処理
- **539-585行目**: `compileStatements()` - ディレクティブ処理
- **654-667行目**: `compileStatement()` - 単一ディレクティブ処理
- **729-755行目**: `if()` - カスタム条件登録
- **983-991行目**: `directive()` - カスタムディレクティブ登録

**読解のコツ**: BladeCompilerはConcernsトレイトで機能を分割している。各ディレクティブの実装は対応するConcernsファイルを参照。

#### Step 3: ディレクティブConcernsを理解する

個別ディレクティブの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CompilesConditionals.php | `src/Illuminate/View/Compilers/Concerns/CompilesConditionals.php` | if/else等 |
| 3-2 | CompilesLoops.php | `src/Illuminate/View/Compilers/Concerns/CompilesLoops.php` | foreach/for等 |
| 3-3 | CompilesEchos.php | `src/Illuminate/View/Compilers/Concerns/CompilesEchos.php` | エコー処理 |
| 3-4 | CompilesComponents.php | `src/Illuminate/View/Compilers/Concerns/CompilesComponents.php` | コンポーネント |

#### Step 4: ComponentTagCompilerを理解する

コンポーネントタグの変換を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ComponentTagCompiler.php | `src/Illuminate/View/Compilers/ComponentTagCompiler.php` | x-タグのコンパイル |

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

```
BladeCompiler::compile($path)
    │
    ├─ setPath($path) ... パス設定
    │
    ├─ files->get($path) ... ファイル読み込み
    │
    └─ compileString($contents)
           │
           ├─ prepareStringsForCompilationUsing
           │      └─ 登録済みコールバック実行
           │
           ├─ storeUncompiledBlocks()
           │      ├─ storeVerbatimBlocks()
           │      └─ storePhpBlocks()
           │
           ├─ compileComponentTags()
           │      └─ ComponentTagCompiler::compile()
           │
           ├─ プリコンパイラ実行
           │
           ├─ token_get_all($value)
           │
           └─ parseToken() ループ
                  │
                  ├─ compileExtensions() ... カスタム拡張
                  │
                  ├─ compileStatements() ... ディレクティブ
                  │      └─ compileStatement($match)
                  │             ├─ カスタムディレクティブ確認
                  │             └─ compile{Name}() 呼び出し
                  │
                  └─ compileEchos() ... エコー処理
                         ├─ compileRawEchos()      ... {!! !!}
                         ├─ compileEscapedEchos()  ... {{{ }}}
                         └─ compileRegularEchos()  ... {{ }}
```

### データフロー図

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

Bladeテンプレート ─────────▶ BladeCompiler::compile()
                               │
                         ファイル読み込み
                               │
                         verbatim/php保存
                               │
                         コンポーネントタグ変換
                               │
                         token_get_all
                               │
                         ┌─────┴─────┐
                         │           │
                     T_INLINE_HTML   その他
                         │           │
                    コンパイル処理   スルー
                         │
                    rawブロック復元
                         │
                    フッター追加
                         │
                    PHPコード ──────────────────────────▶ キャッシュファイル
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BladeCompiler.php | `src/Illuminate/View/Compilers/BladeCompiler.php` | ソース | Bladeコンパイラ主実装 |
| Compiler.php | `src/Illuminate/View/Compilers/Compiler.php` | ソース | 基底クラス |
| CompilerInterface.php | `src/Illuminate/View/Compilers/CompilerInterface.php` | インターフェース | コンパイラ契約 |
| ComponentTagCompiler.php | `src/Illuminate/View/Compilers/ComponentTagCompiler.php` | ソース | コンポーネントタグ変換 |
| CompilesAuthorizations.php | `src/Illuminate/View/Compilers/Concerns/CompilesAuthorizations.php` | ソース | 認可ディレクティブ |
| CompilesConditionals.php | `src/Illuminate/View/Compilers/Concerns/CompilesConditionals.php` | ソース | 条件ディレクティブ |
| CompilesEchos.php | `src/Illuminate/View/Compilers/Concerns/CompilesEchos.php` | ソース | エコー処理 |
| CompilesLoops.php | `src/Illuminate/View/Compilers/Concerns/CompilesLoops.php` | ソース | ループディレクティブ |
| CompilesComponents.php | `src/Illuminate/View/Compilers/Concerns/CompilesComponents.php` | ソース | コンポーネントディレクティブ |
| CompilesIncludes.php | `src/Illuminate/View/Compilers/Concerns/CompilesIncludes.php` | ソース | includeディレクティブ |
| CompilesLayouts.php | `src/Illuminate/View/Compilers/Concerns/CompilesLayouts.php` | ソース | レイアウトディレクティブ |
