# 画面設計書 36-DUBビルドリント

## 概要

本ドキュメントは、serve-d LSPサーバーが提供するDUBビルドリント機能の画面設計書である。ファイル保存時にDUBビルドを実行し、コンパイルエラー・警告・非推奨の診断情報をクライアントに配信する機能を定義する。

### 本画面の処理概要

本機能は、D言語ソースファイルの保存時にDUBビルドを実行し、コンパイラが出力するエラー・警告・非推奨メッセージを解析して、エディタ上に診断情報として表示する。

**業務上の目的・背景**：D言語の開発において、コンパイルエラーをリアルタイムに把握することは開発効率に直結する。本機能はファイル保存時にDUBビルドを自動実行し、コンパイラの出力をパースして診断情報に変換することで、エディタ上でインラインにエラー位置を表示する。補足的なエラー情報（テンプレートインスタンス化元等）もrelatedInformationとして関連付けられる。前回のビルド時間を記録し、次回ビルドが長時間化した場合は以前の診断を自動クリアする機能も備える。

**画面へのアクセス方法**：ファイル保存時（`textDocument/didSave`）に自動的にトリガーされる。

**主要な操作・処理内容**：
1. ファイル保存をトリガーとして受信
2. DubComponentの利用可能性を確認
3. リント設定（enableLinting, enableDubLinting）の有効性を確認
4. ビルド設定の有効性を確認（isValidBuildConfiguration）
5. DubComponentの `build` メソッドでビルド実行
6. ビルド結果のBuildIssueをDiagnosticに変換
7. ファイルパスの正規化（fixPath）を実施
8. エラー範囲の拡張（extendErrorRange）を実施
9. 補足情報（supplemental）のrelatedInformation設定
10. "instantiated from here" エラーの特別処理
11. 診断マネージャ経由でクライアントに配信

**画面遷移**：診断結果に対してコードアクションを要求すると、コードアクション画面（No.19）が呼び出される。

**権限による表示制御**：設定値（`d.enableLinting`, `d.enableDubLinting`）による有効/無効制御。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 36 | DUBビルド診断 | 主機能 | ファイル保存時にDUBビルドを実行しコンパイルエラー・警告を診断結果として返却する |
| 38 | 診断マネージャ | 補助機能 | DUBビルド診断結果を診断マネージャ経由でクライアントに配信する |
| 10 | ドキュメント保存 (textDocument/didSave) | 補助機能 | テキスト保存時にDUBビルドリントがトリガーされる |

## 画面種別

LSP通知（診断情報配信）

## URL/ルーティング

`textDocument/publishDiagnostics` 通知として配信

## 入出力項目

### 入力

| 項目名 | 型 | 必須 | 説明 |
|--------|------|------|------|
| document | Document | Yes | 解析対象ドキュメント |

### 出力（診断情報）

| 項目名 | 型 | 説明 |
|--------|------|------|
| uri | DocumentUri | 診断対象ファイルのURI |
| diagnostics[].range | TextRange | エラー箇所の範囲 |
| diagnostics[].severity | DiagnosticSeverity | 重大度（error/warning/information） |
| diagnostics[].source | string | "DUB" 固定 |
| diagnostics[].message | string | コンパイラ出力メッセージ |
| diagnostics[].tags | DiagnosticTag[] | タグ（deprecated_等） |
| diagnostics[].relatedInformation | DiagnosticRelatedInformation[] | 補足エラー情報 |

## 表示項目

| 表示項目 | 説明 |
|----------|------|
| エラー波線 | コンパイルエラー箇所に赤い波線 |
| 警告波線 | 警告箇所に黄色い波線 |
| 非推奨マーク | Deprecation箇所に取り消し線 |
| 問題パネル | Problemsパネルに診断一覧 |

## イベント仕様

### 1-DUB build lint実行

1. `lint(Document document)` 関数が呼び出される
2. `backend.getBestInstance!DubComponent` でインスタンス取得
3. `enableLinting` && `enableDubLinting` 設定確認
4. `isValidBuildConfiguration` チェック（ビルド不可なパッケージはスキップ）
5. dubLintRunning フラグチェック（二重実行防止、再試行フラグ設定）
6. `currentBuildToken` インクリメント（長時間ビルド時の診断クリア用タイマー設定）
7. `DubComponent.build` 呼び出し（getYield で同期的に結果取得）
8. ビルド結果ループ:
   - BuildIssueのファイルパスを `fixPath` で正規化
   - 行・列からTextRange作成（1始まり→0始まりに変換）
   - `applyDubLintType` でseverityとtags設定
   - supplemental（続行エラー）を relatedInformation に変換
   - `extendErrorRange` でエラー範囲をワード単位に拡張
   - "instantiated from here" エラーをプロジェクト内ファイルに限り追加診断として登録
9. 結果をDiagnosticSlot=1に格納
10. `updateDiagnostics` で配信
11. `retryDubAtEnd` フラグが立っていれば再実行

## データベース更新仕様

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

本機能はデータベースへの更新を行わない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| lint実行 | なし | SELECT/実行 | DUBビルド実行とドキュメント読み取り |

## メッセージ仕様

| メッセージ種別 | 条件 | メッセージ内容 |
|---------------|------|---------------|
| error | コンパイルエラー | コンパイラ出力のエラーメッセージ |
| warning | 警告 | コンパイラ出力の警告メッセージ |
| information | 非推奨 | Deprecationメッセージ（deprecated タグ付き） |

## 例外処理

| 例外条件 | 処理内容 |
|----------|----------|
| DubComponentが利用不可 | 空診断を設定してリターン |
| enableLinting/enableDubLintingが無効 | 空診断を設定してリターン |
| isValidBuildConfigurationがfalse | 空診断を設定してリターン |
| 二重実行時 | retryDubAtEndフラグを設定して現在の実行完了を待機 |

## 備考

- DiagnosticSlot = 1（DUBビルドは診断スロット1を使用）
- 二重実行防止機構：dubLintRunningフラグとretryDubAtEndフラグによるdo-whileループ
- ビルド時間追跡：lastDubDuration変数で前回ビルド時間を記録し、次回ビルドの長時間化判定に使用
- fixPath関数：-mixin-接尾辞の除去、絶対パス/相対パスの正規化、stringImportPaths経由の検索
- ErrorType.Deprecation → DiagnosticSeverity.information + DiagnosticTag.deprecated_ のマッピング
- 複数ファイルにまたがる診断をPublishDiagnosticsParams[]で管理

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | dub.d | `source/served/linters/dub.d` | DiagnosticSlot=1（行25）、DubDiagnosticSource定数（行27）、状態管理変数（行90-92） |
| 1-2 | dub.d (workspaced) | workspacedサブパッケージ | BuildIssue, ErrorType の型定義 |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dub.d | `source/served/linters/dub.d` | `lint` 関数（行94-232）の全体フロー |

**主要処理フロー**:
1. **行102-104**: DubComponent取得、なければ空診断
2. **行107**: enableLinting/enableDubLinting設定確認
3. **行110-113**: 二重実行防止
4. **行124-129**: isValidBuildConfiguration確認
5. **行131-132**: currentBuildToken更新、タイマー設定
6. **行144-145**: DubComponent.build実行
7. **行165-226**: 結果ループ（fixPath, applyDubLintType, relatedInformation, extendErrorRange, "instantiated from here"処理）

#### Step 3: パス正規化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dub.d | `source/served/linters/dub.d` | `fixPath` 関数（行29-68）。-mixin-接尾辞の除去、パス解決ロジック |

#### Step 4: エラー範囲拡張を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | dub.d | `source/served/linters/dub.d` | `extendErrorRange` 関数（行234-256）。resolveDiagnosticRangeまたはwordRangeAtによる範囲拡張 |

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

```
lint (dub.d:94)
    |
    +-- backend.getBestInstance!DubComponent
    +-- config(document.uri) 設定取得
    +-- [二重実行チェック]
    +-- isValidBuildConfiguration チェック
    +-- setTimeout (長時間ビルド診断クリア)
    +-- DubComponent.build (workspaced)
    +-- [各issue]
    |   +-- fixPath (dub.d:29) パス正規化
    |   +-- applyDubLintType (dub.d:83) severity設定
    |   +-- extendErrorRange (dub.d:234) 範囲拡張
    |       +-- DubComponent.resolveDiagnosticRange
    |       +-- document.wordRangeAt (フォールバック)
    +-- diagnostics[DiagnosticSlot] 格納
    +-- updateDiagnostics 配信
```

### データフロー図

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

Document          --->  lint関数                       --->  publishDiagnostics通知
  .uri                   |                                    (複数ファイル対応)
                         +-- 設定/状態確認                     .uri
                         +-- DUBビルド実行                     .diagnostics[]
                         +-- BuildIssue→Diagnostic変換           .range
                         +-- fixPath パス正規化                  .severity
                         +-- extendErrorRange 範囲拡張           .source ("DUB")
                         +-- relatedInformation設定              .message
                         +-- 診断マネージャ配信                  .relatedInformation
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dub.d | `source/served/linters/dub.d` | ソース | DUBビルドリント本体（263行） |
| diagnosticmanager.d | `source/served/linters/diagnosticmanager.d` | ソース | 診断マネージャ |
| extension.d | `source/served/extension.d` | ソース | グローバル変数、workspaceIndex |
| types.d | `source/served/types.d` | ソース | Diagnostic等のLSP型定義 |
| code_actions.d | `source/served/commands/code_actions.d` | ソース | DUBビルド診断に基づくコードアクション |
