# 機能設計書 79-Dietテンプレート処理

## 概要

本ドキュメントは、serve-dにおけるDietテンプレート処理ユーティリティの設計を記述する。vibe.d dietテンプレートファイルに対するコード補完・シグネチャヘルプ用のDコード抽出処理を提供するユーティリティモジュールである。

### 本機能の処理概要

**業務上の目的・背景**：vibe.dフレームワークはdietテンプレートエンジンを使用してHTMLテンプレートを記述する。dietテンプレート内にはD言語の式やコードが埋め込まれるため、これらに対するコード補完やシグネチャヘルプを提供するには、テンプレートからD言語コードを抽出する必要がある。本ユーティリティはdietテンプレートのパース、D言語コード抽出、コンテキスト解決を行う。

**機能の利用シーン**：エディタでdietテンプレートファイル（.dt拡張子）を編集中にコード補完やシグネチャヘルプが要求された際に、テンプレート内のD言語コード部分を抽出してDCDに渡すための前処理として使用される。

**主要な処理内容**：
1. Dietファイルキャッシュ管理（dietFileCache）：パース済みDietテンプレートのキャッシュ
2. DietComplete更新（updateDietFile）：テンプレートのパースと補完エンジンの構築
3. コンテキスト付きDコード抽出（contextExtractD）：テンプレートのコンテキストコメントに基づくD言語コード抽出
4. CompletionType変換（mapToCompletionItemKind）：DietCompletionTypeからLSPのCompletionItemKindへの変換
5. Dietテンプレート使用箇所検索（searchDietTemplateUsage）：D言語ソース内でのテンプレート使用位置を特定

**関連システム・外部連携**：dietcライブラリ（DietComplete、lexer、parser）に依存。vibe.dフレームワークのdietテンプレートシステムを対象とする。

**権限による制御**：なし

## 関連画面

本ユーティリティは直接的に画面と関連しない。コード補完（画面No.17）やシグネチャヘルプ（画面No.29）がdietテンプレートを処理する際に間接的に使用される。

## 機能種別

ユーティリティ / テンプレート解析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| file (updateDietFile) | string | Yes | Dietテンプレートファイルのパス | - |
| content (updateDietFile) | string | Yes | テンプレートファイルの内容 | - |
| completion (contextExtractD) | DietComplete | Yes | パース済みDiet補完オブジェクト | - |
| offset (contextExtractD) | size_t | Yes | カーソル位置のオフセット | - |
| extractContext | bool | Yes | コンテキスト抽出を行うかどうか | - |
| type (mapToCompletionItemKind) | CompletionType | Yes | DietCompletionType列挙値 | - |

### 入力データソース

- エディタで開かれているdietテンプレートファイル（.dtファイル）
- テンプレートマネージャのドキュメントストア

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DietComplete | object | パース済みのDiet補完オブジェクト |
| code (contextExtractD) | string | 抽出されたD言語コード |
| dOffset (contextExtractD) | size_t | D言語コード内でのカーソル位置 |
| CompletionItemKind | enum | LSPのCompletionItemKind列挙値 |

### 出力先

serve-dのコード補完・シグネチャヘルプモジュール

## 処理フロー

### 処理シーケンス

```
1. Dietファイル更新リクエスト
   └─ updateDietFileでファイルをパース/再パース
2. キャッシュ確認
   └─ dietFileCacheに既存エントリがあれば再パース、なければ新規作成
3. コンテキスト抽出
   └─ テンプレート先頭の//- context=xxx コメントからコンテキストファイルを特定
4. コンテキストファイル検索
   └─ ドキュメントストアからコンテキストファイルを検索し、テンプレート使用位置を特定
5. Dコード抽出
   └─ コンテキストのプレフィックスとテンプレート内のD式を結合
6. 補完候補生成
   └─ 抽出されたDコードに基づいてDCDで補完候補を取得
```

### フローチャート

```mermaid
flowchart TD
    A[Diet テンプレート編集] --> B{キャッシュにあり?}
    B -->|Yes| C[reparse]
    B -->|No| D[新規 DietComplete 作成]
    C --> E[contextExtractD]
    D --> E
    E --> F{context= コメントあり?}
    F -->|Yes| G[コンテキストファイル検索]
    F -->|No| H[直接 extractD]
    G --> I[テンプレート使用位置特定]
    I --> J[プレフィックスコード抽出]
    J --> H
    H --> K[D言語コード + オフセット]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-79-01 | キャッシュ管理 | dietFileCacheにファイルパスをキーとしてパース結果をキャッシュし、再編集時はreparseで更新 | updateDietFile呼び出し時 |
| BR-79-02 | コンテキスト解決 | テンプレート先頭に`//- context=filename.d`コメントがある場合、そのD言語ファイルの内容をプレフィックスとして抽出 | contextExtractDでextractContext=true時 |
| BR-79-03 | テンプレート使用位置検索 | コンテキストファイル内でdietテンプレートのファイル名が文字列リテラルとして使用されている位置を検索 | コンテキスト解決時 |
| BR-79-04 | CompletionType変換 | DietのCompletionTypeをLSPのCompletionItemKindにマッピング（tag→keyword、attribute→property等） | 補完候補生成時 |

### 計算ロジック

searchDietTemplateUsage関数：
1. D言語ソース内でdietテンプレートのファイル名文字列を検索
2. その直後が`"`または`` ` ``で終わっていることを確認
3. 直前の`!(` or `;`までさかのぼり、テンプレート呼び出しの開始位置を特定
4. さらに直前の`;`/改行まで戻り、関数定義の先頭を返す

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

本機能ではデータベース操作は行わない。dietFileCacheはインメモリ連想配列。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ログ警告 | コンテキストファイルが見つからない場合 | infoログを出力し、プレフィックスなしで続行 |
| - | 戻り値-2 | dietテンプレートファイル名がD言語ソース内に見つからない場合 | 負値を返却、呼び出し元がフォールバック |
| - | 戻り値-3 | テンプレートファイル名の後に引用符がない場合 | 負値を返却 |
| - | 戻り値-4 | テンプレート呼び出しの開始位置が特定できない場合 | 負値を返却 |

### リトライ仕様

リトライは行わない。コンテキスト解決に失敗した場合はプレフィックスなしでDコード抽出を続行する。

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

不要。

## パフォーマンス要件

dietFileCacheにより、同一ファイルの繰り返しパースを回避する。reparseは差分更新で効率的に行われる。

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

特になし（ローカルファイルのテンプレート処理のみ）。

## 備考

- dietテンプレートはvibe.dフレームワーク固有の機能であり、D言語Webアプリケーション開発で使用される
- `DietComplete.defaultFileProvider`はdietテンプレートのinclude/extends解決に使用される
- コンテキスト解決機能により、テンプレート内で使用可能な変数・関数の補完が可能になる

---

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

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

### 推奨読解順序

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

dietcライブラリの型とキャッシュ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | diet.d | `source/served/utils/diet.d` | `dietFileCache`連想配列（17行目）、インポートされるdietcライブラリの型（3-5行目） |

**読解のコツ**: `DietComplete`はdietcライブラリのクラスで、テンプレートのパース結果と補完エンジンを保持する。`CompletionType`はdietc.completeモジュールの列挙型で、tag/attribute/value/d等の補完種別を表す。

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

主要なパブリック関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | diet.d | `source/served/utils/diet.d` | `updateDietFile`関数（19-35行目）: キャッシュ管理とパース |
| 2-2 | diet.d | `source/served/utils/diet.d` | `contextExtractD`関数（62-118行目）: コンテキスト付きDコード抽出 |
| 2-3 | diet.d | `source/served/utils/diet.d` | `mapToCompletionItemKind`関数（37-60行目）: CompletionType変換 |

**主要処理フロー**:
1. **19-35行目**: `updateDietFile`でキャッシュにあればreparse、なければ新規DietComplete作成
2. **62-118行目**: `contextExtractD`でテンプレート先頭のHiddenComment（`//-`コメント）から`context=`指定を取得
3. **79-81行目**: コンテキスト指定からファイル名を抽出し、`.d`拡張子を付加
4. **92-101行目**: ドキュメントストアからコンテキストファイルを検索し、`searchDietTemplateUsage`で使用位置を特定
5. **117行目**: `extractD`でD言語コードとオフセットを抽出

#### Step 3: テンプレート使用箇所検索を理解する

D言語ソース内でのdietテンプレート使用位置特定ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | diet.d | `source/served/utils/diet.d` | `searchDietTemplateUsage`関数（120-134行目）: テンプレート使用位置の特定 |

**主要処理フロー**:
- **122行目**: D言語ソース内でdietテンプレートファイル名を文字列検索
- **126-127行目**: ファイル名直後が`"`または`` ` ``であることを確認
- **129行目**: 直前の`;!(` をさかのぼって関数呼び出しの開始位置を特定
- **133行目**: さらに直前の`;\r\n`まで戻って関数定義の先頭を返す

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

```
serve-d 補完/シグネチャヘルプモジュール
    │
    ├─ updateDietFile (19行目)
    │      ├─ DietComplete.reparse (既存キャッシュ)
    │      └─ new DietComplete (新規作成)
    │
    ├─ contextExtractD (62行目)
    │      ├─ HiddenComment解析 (context= 取得)
    │      ├─ documents.documentStore 走査
    │      ├─ searchDietTemplateUsage (120行目)
    │      └─ extractD (dietcライブラリ)
    │
    └─ mapToCompletionItemKind (37行目)
```

### データフロー図

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

.dt ファイル ──────────▶ updateDietFile ──────────▶ DietComplete (キャッシュ)
カーソル位置 ──────────▶ contextExtractD ─────────▶ D言語コード + オフセット
context= 指定 ────────▶ searchDietTemplateUsage ──▶ プレフィックスコード
CompletionType ───────▶ mapToCompletionItemKind ──▶ CompletionItemKind
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| diet.d | `source/served/utils/diet.d` | ソース | Dietテンプレート処理の全実装 |
| complete.d | `source/served/commands/complete.d` | ソース | コード補完モジュール（Dietテンプレート補完の呼び出し元） |
| calltips.d | `source/served/commands/calltips.d` | ソース | シグネチャヘルプモジュール（Dietテンプレートのシグネチャヘルプ呼び出し元） |
| textdocumentmanager.d | `lsp/source/served/lsp/textdocumentmanager.d` | ソース | documents.documentStoreの提供元 |
