# 画面設計書 54-インポートパス更新（served/updateImports）

## 概要

本ドキュメントは、serve-d LSPサーバーが提供するカスタムリクエスト `served/updateImports` の設計を記述する。このリクエストは、DUB依存関係をリフレッシュし、DCDのインポートパスを更新する処理を実行する。

### 本画面の処理概要

このカスタムリクエストは、DUBプロジェクトの依存関係情報を再読み込みし、DCD（D Completion Daemon）のインポートパスを最新状態に同期させる重要な更新処理である。

**業務上の目的・背景**：DUBプロジェクトの依存関係が変更された場合（パッケージの追加・削除・更新等）、DCDのインポートパスが古くなり、コード補完やシンボル解決が正しく機能しなくなる。この問題を解決するために、依存関係の変更後にインポートパスを明示的に更新する必要がある。本リクエストは依存関係インストール（No.58）、依存関係更新（No.59）、依存関係削除（No.60）等の操作後に自動的に呼び出されるほか、ユーザーが手動で実行することも可能である。

**画面へのアクセス方法**：LSPクライアントが `served/updateImports` メソッドをJSON-RPCリクエストとして送信する。他のDUB操作（依存関係管理等）から内部的に呼び出されることも多い。

**主要な操作・処理内容**：
1. クライアントからJSON-RPCリクエスト `served/updateImports` を受信する
2. 進捗状況をクライアントに通知する（reportProgress）
3. DubComponentの依存関係を更新する（dub.update）
4. 更新成功時にcoded/updateDubTree通知を送信する
5. DCDComponentのインポートパスをリフレッシュする
6. バックグラウンドインデックスを実行する
7. 処理完了を進捗通知する

**画面遷移**：DUB依存関係管理フローの一部として動作する。依存関係インストール/更新/削除の後処理として呼び出される。完了後はcoded/updateDubTree通知によりDUBツリー更新通知（No.13）が発生する。

**権限による表示制御**：特になし。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 54 | インポート更新 (served/updateImports) | 主機能 | DUB依存関係をファイルシステムからリフレッシュしDCDのインポートパスを更新する |

## 画面種別

カスタムLSPリクエスト（更新処理）

## URL/ルーティング

LSPカスタムメソッド: `served/updateImports`

## 入出力項目

### 入力（リクエスト）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| reportProgress | bool | いいえ | UI向け進捗更新を送信するかどうか（デフォルト: true） |

### 出力（レスポンス）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | bool | DubComponentの更新が成功した場合true、失敗または存在しない場合false |

## 表示項目

進捗通知としてクライアントに送信される情報：

| 項目 | 表示形式 | 説明 |
|------|----------|------|
| dubReload進捗 | 数値（0/5） | DUB依存関係リロード開始 |
| importReload進捗 | 数値（4/5, 5/5） | インポートパスリロード進捗 |

## イベント仕様

### 1-リクエスト受信

クライアントから `served/updateImports` リクエストを受信すると、以下の処理が実行される：

1. `UpdateImportsParams` からパラメータをデシリアライズする
2. `activeInstance` を取得する
3. `reportProgress` がtrueの場合、`dubReload` 進捗（0/5）を通知する
4. `DubComponent` が存在する場合：
   - `DubComponent.update` を非同期実行（getYield）する
   - 成功時に `coded/updateDubTree` 通知をクライアントに送信する
5. `reportProgress` がtrueの場合、`importReload` 進捗（4/5）を通知する
6. `DCDComponent` が存在する場合、`refreshImports()` を呼び出す
7. `backgroundIndex()` を実行してバックグラウンドインデックスを更新する
8. `reportProgress` がtrueの場合、`importReload` 進捗（5/5）を通知する
9. DubComponent更新の成否をboolで返却する

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| DUB依存関係更新 | (なし) | UPDATE相当 | DubComponentのインメモリ依存関係情報を再読み込み |
| DCDインポートパスリフレッシュ | (なし) | UPDATE相当 | DCDサーバーのインポートパスキャッシュを更新 |
| バックグラウンドインデックス | (なし) | UPDATE相当 | ワークスペースのモジュールインデックスを再構築 |

### テーブル別更新項目詳細

物理データベースへの更新は発生しない。全てインメモリ状態の更新。

## メッセージ仕様

| メッセージID | 種別 | 条件 | メッセージ内容 |
|-------------|------|------|---------------|
| coded/updateDubTree | 通知 | DubComponent更新成功時 | DUBツリー更新通知（クライアントがツリー表示を更新する契機） |

## 例外処理

| 条件 | 動作 | 返却値 |
|------|------|--------|
| DubComponentが存在しない | DUB更新をスキップ、DCDリフレッシュは試行 | false |
| DCDComponentが存在しない | DCDリフレッシュをスキップ | (DUB更新結果に依存) |
| DubComponent.updateが失敗 | coded/updateDubTree通知をスキップ | false |

## 備考

- `DubComponent.update` は `getYield` で非同期実行され、完了を待機する
- 依存関係インストール（No.58）、更新（No.59）、削除（No.60）の各操作後に `updateImports(UpdateImportsParams(false))` として内部呼び出しされる（進捗通知なし）
- DUBレシピファイル保存時（textDocument/didSave）にも間接的に呼び出される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protoext.d | `source/served/lsp/protoext.d` | UpdateImportsParams構造体（251-255行目）のフィールド定義を確認 |
| 1-2 | progress.d | `source/served/utils/progress.d` | ProgressType列挙型（16-45行目）のdubReload、importReloadを確認 |

**読解のコツ**: `@serdeOptional bool reportProgress = true` はクライアントからのリクエストでは通常省略されtrue（進捗通知あり）となるが、内部呼び出し時は明示的にfalseが指定される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | dub.d | `source/served/commands/dub.d` | updateImports関数（212-232行目）がエントリーポイント |

**主要処理フロー**:
1. **212行目**: `@protocolMethod("served/updateImports")` UDAでLSPメソッドとして登録
2. **213行目**: `bool updateImports(UpdateImportsParams params)` - bool返却
3. **218行目**: `reportProgress(params.reportProgress, ProgressType.dubReload, 0, 5, ...)` - 進捗通知開始
4. **222行目**: `success = instance.get!DubComponent.update.getYield` - DUB依存関係の非同期更新
5. **224行目**: `rpc.notifyMethod("coded/updateDubTree")` - ツリー更新通知
6. **226行目**: `reportProgress(params.reportProgress, ProgressType.importReload, 4, 5, ...)` - インポートリロード進捗
7. **228行目**: `instance.get!DCDComponent.refreshImports()` - DCDインポートパスリフレッシュ
8. **229行目**: `backgroundIndex()` - バックグラウンドインデックス実行
9. **230行目**: `reportProgress(params.reportProgress, ProgressType.importReload, 5, 5, ...)` - 完了通知

#### Step 3: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dub.d | `source/served/commands/dub.d` | installDependency（574-586行目）、updateDependency（588-604行目）、uninstallDependency（606-621行目）からの内部呼び出しパターンを確認 |
| 3-2 | dub.d | `source/served/commands/dub.d` | onDidSaveDubRecipe（234-325行目）からの間接呼び出しを確認 |

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

```
LSPクライアント / 内部呼び出し
    |
    |  served/updateImports (JSON-RPC request) or 直接呼び出し
    v
updateImports(UpdateImportsParams) [source/served/commands/dub.d:213]
    |
    +-- reportProgress() [source/served/utils/progress.d:47]
    |       +-- dubReload (0/5)
    |
    +-- DubComponent.update.getYield
    |       |
    |       +-- (workspace-d API: DUB依存関係リフレッシュ)
    |
    +-- rpc.notifyMethod("coded/updateDubTree")
    |
    +-- reportProgress()
    |       +-- importReload (4/5)
    |
    +-- DCDComponent.refreshImports()
    |       +-- (DCD API: インポートパス更新)
    |
    +-- backgroundIndex()
    |
    +-- reportProgress()
            +-- importReload (5/5)
```

### データフロー図

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

JSON-RPC Request   --->  updateImports()                --->  bool (成功/失敗)
  reportProgress          |                                    |
                          +-- DubComponent.update              +-- coded/updateDubTree通知
                          |   (依存関係リフレッシュ)              |  (成功時のみ)
                          +-- DCDComponent.refreshImports      +-- 進捗通知
                          |   (インポートパス更新)               |  (reportProgress=true時)
                          +-- backgroundIndex
                              (インデックス再構築)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dub.d | `source/served/commands/dub.d` | ソース | updateImports関数の実装（212-232行目）、呼び出し元の各関数 |
| protoext.d | `source/served/lsp/protoext.d` | ソース | UpdateImportsParams構造体定義（251-255行目） |
| progress.d | `source/served/utils/progress.d` | ソース | ProgressType定義、reportProgress関数 |
| types.d | `source/served/types.d` | ソース | activeInstance、backend等のグローバル定義 |
| extension.d | `source/served/extension.d` | ソース | LSPメソッドディスパッチ基盤、backgroundIndex関数 |
