# 通知設計書 24-served/rescanTests

## 概要

本ドキュメントは、serve-d LSPサーバーにおけるカスタム通知「served/rescanTests」の設計仕様を定義する。本通知はクライアント(エディタ)からサーバーに送信され、プロジェクト内のユニットテストを再スキャンする。

### 本通知の処理概要

本通知は、DUBプロジェクト内のソースファイルを走査し、ユニットテスト定義を検出・更新するものである。

**業務上の目的・背景**：D言語プロジェクトではユニットテストがソースコード内にインラインで定義される。テスト実行のためにはプロジェクト内のテスト一覧を把握する必要があり、本通知はその再スキャンを手動でトリガーする機能を提供する。テストエクスプローラー機能（--provide test-runner）と連携して使用される。

**通知の送信タイミング**：ユーザーがエディタのコマンドパレットから「Rescan Tests」を実行したとき、またはテストエクスプローラーのリフレッシュボタンを押したときにクライアントが送信する。

**通知の受信者**：serve-d LSPサーバープロセスが受信者である。

**通知内容の概要**：RescanTestsParamsをパラメータとして受け取る。URIフィールドで特定のワークスペースのみを再スキャン対象に指定できる。URIが空の場合は全ワークスペースが対象となる。

**期待されるアクション**：サーバーは対象ワークスペースのソースファイルを走査してユニットテストを検出し、coded/pushProjectTests通知でテスト情報をクライアントに送信する。

## 通知種別

LSPカスタム通知（JSON-RPC Notification）。クライアントからサーバーへの方向（C->S）。

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 非同期（JSON-RPC notification） |
| 優先度 | 中 |
| リトライ | なし |

### 送信先決定ロジック

クライアントがserve-d LSPサーバーに直接送信する。

## 通知テンプレート

### メール通知の場合

該当なし。本通知はLSPプロトコル上のJSON-RPCメッセージである。

### 本文テンプレート

```json
{
  "jsonrpc": "2.0",
  "method": "served/rescanTests",
  "params": {
    "uri": "file:///path/to/workspace"
  }
}
```

### 添付ファイル

該当なし。

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| uri | 再スキャン対象のワークスペースURI。空の場合は全ワークスペース | クライアント指定 | No |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| 画面操作 | ユーザーが「Rescan Tests」コマンドを実行 | なし | テストの手動再スキャン |
| 画面操作 | テストエクスプローラーのリフレッシュ | --provide test-runner有効時 | テスト一覧の更新 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| doTrackTests == false | --provide test-runnerが指定されていない場合、テスト追跡は無効（ただし通知自体は受信される） |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[served/rescanTests通知受信] --> B[URI解析]
    B --> C[全backendインスタンスをループ]
    C --> D{URI指定あり?}
    D -->|Yes| E{instance.cwdがURIに一致?}
    D -->|No| F[全インスタンスが対象]
    E -->|Yes| G[rescanProject実行]
    E -->|No| H[スキップ]
    F --> G
    G --> I[DUBビルド設定取得]
    I --> J[全ソースファイルをスキャン]
    J --> K[各ファイルのユニットテスト検出]
    K --> L[coded/pushProjectTests送信]
    L --> M[終了]
    H --> C
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし。

### 更新テーブル一覧

該当なし。インメモリのprojectTests連想配列を更新する。

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| DubComponent未初期化 | DUBプロジェクトでない場合 | 処理をスキップ |
| ファイル読み込み失敗 | FileException | 警告ログを出力してファイルをスキップ |
| 解析失敗 | パースエラー等 | 警告ログを出力してファイルをスキップ |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし。

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

ローカルファイルシステム上のソースコードのみを読み取るため、セキュリティ上の問題は小さい。

## 備考

- rescanProject内部ではDubComponent.rootPackageBuildSettings()でソースファイル一覧を取得
- 各ファイルに対してprovideDocumentSymbolsOldを呼び出し、SymbolKindEx.testのシンボルを検出
- LazyWorkspaceD.LazyInstanceの場合、didCallAccessがtrueのインスタンスのみスキャン対象
- テスト検出結果はprojectTests連想配列に蓄積される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.d | `source/served/types.d` | RescanTestsParams、UnittestProject、UnittestModule、UnittestInfoの定義 |

**読解のコツ**: UnittestProjectはワークスペースURI、名前、テストモジュール配列を持つ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | test_provider.d | `source/served/commands/test_provider.d` | rescanTests関数（L71-92） |

**主要処理フロー**:
1. **L71**: `@protocolNotification("served/rescanTests")` アノテーション
2. **L72**: `void rescanTests(RescanTestsParams params)` シグネチャ
3. **L73**: URI解析（空ならnull）
4. **L75-91**: 全backendインスタンスをループし、条件に一致するものにrescanProject実行

#### Step 3: プロジェクトスキャン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | test_provider.d | `source/served/commands/test_provider.d` | rescanProject関数（L137-194） |

**主要処理フロー**:
- **L142**: DubComponent取得
- **L143**: rootPackageBuildSettings()でビルド設定取得
- **L155-184**: 全ソースファイルをループしてrescanFile実行
- **L186**: coded/pushProjectTests通知送信

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

```
[クライアント] served/rescanTests通知
    |
    +-- RPCProcessor
          |
          +-- rescanTests() [test_provider.d L72]
                |
                +-- backend.instances (全インスタンスループ)
                      |
                      +-- rescanProject() [L137]
                            |
                            +-- DubComponent.rootPackageBuildSettings()
                            |
                            +-- rescanFile() [L94] (各ファイル)
                            |     |
                            |     +-- provideDocumentSymbolsOld()
                            |     |
                            |     +-- UnittestInfo検出
                            |
                            +-- rpc.notifyMethod("coded/pushProjectTests", ...)
```

### データフロー図

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

RescanTestsParams      rescanTests()                   coded/pushProjectTests通知
(uri: optional)  ----> rescanProject()              --> (UnittestProject)
                       rescanFile() x N
                       ユニットテスト検出
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| test_provider.d | `source/served/commands/test_provider.d` | ソース | rescanTests通知ハンドラ、rescanProject、rescanFile |
| symbol_search.d | `source/served/commands/symbol_search.d` | ソース | provideDocumentSymbolsOld（テストシンボル検出） |
| types.d | `source/served/types.d` | ソース | RescanTestsParams、UnittestProject等の型定義 |
| extension.d | `source/served/extension.d` | ソース | モジュール登録 |
