# バッチ設計書 13-app

## 概要

本ドキュメントは、serve-dプロジェクトにおけるDML補完データ生成ツール `workspace-d/dml_gen/source/app.d` のバッチ設計書である。DML（DlangUI Markup Language）の定義ファイルからD言語の補完モジュールを自動生成する。

### 本バッチの処理概要

本バッチは、DlangUI向けのDML補完データを定義テキストファイルからD言語ソースコードとして自動生成するコード生成ツールである。

**業務上の目的・背景**：serve-dはD言語のLanguage Server Protocol（LSP）実装であり、DlangUIフレームワークのDML記法に対するコード補完機能を提供する。DMLのウィジェットクラスやenum型、プロパティの一覧はviews/dml-completion.txtに定義されており、これをD言語の補完データ配列として自動生成することで、手動でのデータ管理を排除し、定義の一元管理と保守性の向上を実現する。

**バッチの実行タイミング**：開発者がDML補完定義を変更した際に手動で実行する。`dub run :dml` コマンドにより実行される。定義ファイル（views/dml-completion.txt）の変更後に実行することで、生成済みのD言語ソースファイルを更新する。

**主要な処理内容**：
1. 組み込みのユニットテスト（test関数）を実行して、パーサーの動作を検証する
2. views/dml-completion.txt ファイルを読み込み、DML定義テキストを取得する
3. lookupgenモジュールのgenerateCompletions関数を使用して、DML定義テキストをパースし、CompletionLookup配列を生成する
4. 生成された補完データを文字列化し、モジュール宣言とインポート文のプレフィックスと結合する
5. 結果をsource/workspaced/completion/dml.dに書き込む

**前後の処理との関連**：生成されたdml.dモジュールは、serve-dのDML補完機能（workspaced.com.dlangui）から参照される。DML定義ファイルの変更時には本バッチを再実行し、生成結果をバージョン管理にコミットする必要がある。

**影響範囲**：serve-dのDML補完機能に直接影響する。生成ファイル（source/workspaced/completion/dml.d）は「DO NOT EDIT」コメント付きの自動生成ファイルであり、手動編集は禁止されている。

## バッチ種別

コード生成 / ソースコード自動生成

## 実行スケジュール

| 項目 | 内容 |
|-----|------|
| 実行頻度 | 随時（DML定義変更時） |
| 実行時刻 | 指定なし |
| 実行曜日 | 指定なし |
| 実行日 | 指定なし |
| トリガー | 手動（`dub run :dml` コマンド） |

## 実行条件

### 前提条件

| 条件 | 説明 |
|-----|------|
| dubパッケージマネージャ | dubが利用可能であること |
| peggedライブラリ | PEGパーサージェネレータ pegged ~>0.3.3 がdubにより取得可能であること |
| dunitライブラリ | ユニットテストフレームワーク dunit ~>1.0.14 がdubにより取得可能であること |
| views/dml-completion.txt | DML補完定義ファイルが所定のパスに存在すること |
| 出力先ディレクトリ | source/workspaced/completion/ ディレクトリが存在すること |

### 実行可否判定

特別な実行可否判定ロジックは存在しない。ただし、実行時にユニットテスト（test関数）が最初に実行され、テストが失敗した場合はアサーションエラーで処理が中断される。

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | デフォルト値 | 説明 |
|-------------|-----|-----|-------------|------|
| なし | - | - | - | コマンドライン引数は取らない |

### 入力データソース

| データソース | 形式 | 説明 |
|-------------|------|------|
| views/dml-completion.txt | テキスト（独自DML定義形式） | DlangUIのウィジェットクラス、enum型、プロパティの補完定義。enum定義、class定義、include指定、型指定（bool/color/number/rect/string）、ドキュメンテーション（`---`区切り）を含む |

## 出力仕様

### 出力データ

| 出力先 | 形式 | 説明 |
|-------|------|------|
| source/workspaced/completion/dml.d | D言語ソースファイル | 自動生成された補完データモジュール。`dmlCompletions` enum配列を含む |

### 出力ファイル仕様

| 項目 | 内容 |
|-----|------|
| ファイル名 | dml.d |
| 出力先 | source/workspaced/completion/ |
| 文字コード | UTF-8 |
| 区切り文字 | D言語ソースコード形式 |

出力ファイルの構造：

```d
//
// DO NOT EDIT
//
// This module has been generated automatically from views/dml-completions.txt using `dub run :dml`
//
//
module workspaced.completion.dml;

import workspaced.com.dlangui;

enum dmlCompletions = [CompletionLookup(...), ...];
```

## 処理フロー

### 処理シーケンス

```
1. ユニットテスト実行
   └─ test()関数を呼び出し、lookupgenモジュールのパース・生成ロジックの動作を検証
2. プレフィックス文字列の準備
   └─ モジュール宣言（module workspaced.completion.dml）とインポート文を含むヘッダーを定義
3. DML定義ファイルの読み込み
   └─ views/dml-completion.txt をreadTextで読み込む
4. 補完データの生成
   └─ generateCompletions関数でDML定義をパースし、CompletionLookup配列を生成
5. D言語ソースコードの組み立て
   └─ CompletionLookup配列を文字列化し、"enum dmlCompletions = [...];" 形式に整形
6. ファイル出力
   └─ source/workspaced/completion/dml.d にプレフィックスと補完データを書き込み
```

### フローチャート

```mermaid
flowchart TD
    A[バッチ開始] --> B[test関数によるユニットテスト実行]
    B --> C{テスト成功か}
    C -->|No| D[アサーションエラーで中断]
    C -->|Yes| E[プレフィックス文字列の定義]
    E --> F[views/dml-completion.txt 読み込み]
    F --> G[generateCompletions でパース・変換]
    G --> H[CompletionLookup配列を文字列化]
    H --> I[enum dmlCompletions = 配列 形式に整形]
    I --> J[source/workspaced/completion/dml.d に書き込み]
    J --> K[バッチ終了]
```

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

### 操作別データベース影響一覧

本バッチはデータベース操作を行わない。

| 処理 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| なし | なし | なし | データベース操作なし |

### テーブル別操作詳細

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AssertionError | ユニットテスト失敗 | test関数内のテストケースが期待結果と一致しない場合 | lookupgen.dのパーサーロジックを確認する |
| AssertionError | パースエラー | DML定義テキストの文法が不正な場合（tree.successfulがfalse） | views/dml-completion.txtの文法を確認する |
| AssertionError | 型定義エラー | 未定義の型名がclass定義内で使用された場合 | DML定義内のenum/class宣言順序と型名を確認する |
| AssertionError | 循環参照エラー | include指定が50回以上のイテレーションで解決しない場合 | class間のinclude依存関係に循環がないか確認する |
| FileException | ファイル読み込みエラー | views/dml-completion.txt が存在しない場合 | 入力ファイルのパスと存在を確認する |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0回（リトライなし） |
| リトライ間隔 | なし |
| リトライ対象エラー | なし（入力データの問題であり、リトライでは解決しない） |

### 障害時対応

- パースエラーの場合は、views/dml-completion.txtの文法をDML定義形式（enum/class/include構文）に従って修正する
- 循環参照エラーの場合は、classのinclude指定を見直し、循環依存を解消する
- 出力先ディレクトリが存在しない場合は、ディレクトリを作成してから再実行する

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

| 項目 | 内容 |
|-----|------|
| トランザクション範囲 | なし（データベース操作なし） |
| コミットタイミング | なし |
| ロールバック条件 | なし（ファイル書き込みはアトミックではないが、生成ファイルはバージョン管理されているため、復旧可能） |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定処理件数 | 1ファイル（DML定義ファイルから1つの生成ファイルを出力） |
| 目標処理時間 | 数秒以内 |
| メモリ使用量上限 | 特になし（PEGパーサーのメモリ使用量に依存するが、入力ファイルが小規模のため問題にならない） |

## 排他制御

排他制御は不要。開発者が手動で実行するツールであり、同時実行は想定されていない。出力ファイルはバージョン管理（Git）により保護される。

## ログ出力

| ログ種別 | 出力タイミング | 出力内容 |
|---------|--------------|---------|
| エラーログ | テスト失敗時 | アサーションエラーの詳細メッセージ |
| エラーログ | パースエラー時 | パーサーのエラー情報 |

本バッチは正常終了時にはログを出力しない。

## 監視・アラート

| 監視項目 | 閾値 | アラート先 |
|---------|-----|----------|
| なし | なし | 開発者のローカル環境で手動実行されるため、監視・アラート設定は不要 |

## 備考

- 本ツールは `dub run :dml` コマンドで実行する。dub.jsonでサブパッケージ名が "dml" として定義されている
- 依存ライブラリとして pegged（PEGパーサージェネレータ、~>0.3.3）と dunit（ユニットテストフレームワーク、~>1.0.14）を使用する
- lookupgen.dモジュールがDML定義のパースロジックの中核を担い、PEG文法によりDML構文（enum/class/include/型定義/ドキュメンテーション）を解析する
- 生成されるdml.dファイルの先頭には「DO NOT EDIT」コメントが付与され、自動生成ファイルであることが明示される
- DML定義ファイルではenum型（FontFamily, Visibility, Align, State, TextFlag等）とwidgetクラス（Widget, Button, EditBox等）の階層構造が定義されており、include構文によるクラス継承の表現をサポートする
- CompletionType列挙型として Undefined, Class, String, Number, Color, EnumDefinition, EnumValue, Rectangle, Boolean の9種類のが定義されている
