# 機能設計書 54-インポート更新

## 概要

本ドキュメントは、serve-dのLSPカスタムリクエスト `served/updateImports` の機能設計を記述する。DUB依存関係をファイルシステムからリフレッシュし、DCDのインポートパスを更新する機能である。

### 本機能の処理概要

**業務上の目的・背景**：D言語プロジェクトでDUB依存関係が変更された場合（依存パッケージの追加・更新・削除後）、コード補完やシンボル解決が正しく動作するためにはインポートパスの再読み込みが必要となる。本機能は、DUBの依存関係情報をファイルシステムからリフレッシュし、DCD（D Completion Daemon）のインポートパスを更新し、バックグラウンドインデックスを再構築する一連の処理を行う。

**機能の利用シーン**：依存関係のインストール（No.58）、更新（No.59）、削除（No.60）の各操作後に内部的に呼び出される。また、クライアントから明示的に呼び出すことも可能である。

**主要な処理内容**：
1. クライアントから `served/updateImports` リクエストを受信する
2. 進捗レポートを開始する（オプション）
3. DubComponentの `update` メソッドで依存関係をリフレッシュする
4. 成功時に `coded/updateDubTree` 通知をクライアントに送信する
5. DCDComponentの `refreshImports()` でインポートパスを更新する
6. `backgroundIndex()` でバックグラウンドインデックスを再構築する
7. 進捗レポートを完了する

**関連システム・外部連携**：DubComponent（依存関係リフレッシュ）、DCDComponent（インポートパス更新）、IndexComponent（バックグラウンドインデックス）の3つのコンポーネントと連携する。また、クライアントに `coded/updateDubTree` 通知を送信する。

**権限による制御**：特に権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 54 | インポートパス更新（served/updateImports） | 主画面 | DUB依存関係リフレッシュとDCDインポートパス更新 |
| 58 | 依存関係インストール（served/installDependency） | 呼出元 | 依存関係インストール後にupdateImportsを呼び出す |
| 59 | 依存関係更新（served/updateDependency） | 呼出元 | 依存関係更新後にupdateImportsを呼び出す |
| 60 | 依存関係削除（served/uninstallDependency） | 呼出元 | 依存関係削除後にupdateImportsを呼び出す |

## 機能種別

状態更新処理（DUB依存関係リフレッシュ、DCDインポートパス再読込、インデックス再構築）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| reportProgress | bool | No | trueの場合、UI用の進捗通知を送信する。デフォルトtrue | なし |

### 入力データソース

LSPクライアントからのJSON-RPCリクエスト（UpdateImportsParams構造体）。内部呼び出し時は `UpdateImportsParams(false)` で進捗通知なしで呼び出される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | bool | DUB依存関係の更新成否。trueなら成功 |

### 出力先

- LSPクライアントへのJSON-RPCレスポンス（bool）
- クライアントへの `coded/updateDubTree` 通知（DUB更新成功時）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ UpdateImportsParamsとしてデシリアライズ
2. 進捗レポート開始
   └─ reportProgressがtrueの場合、ProgressType.dubReload (0/5) を報告
3. DUB依存関係リフレッシュ
   └─ DubComponentがある場合、dub.update.getYield で同期的に更新
   └─ 成功時、rpc.notifyMethod("coded/updateDubTree") を送信
4. 進捗レポート中間
   └─ reportProgressがtrueの場合、ProgressType.importReload (4/5) を報告
5. DCDインポートパス更新
   └─ DCDComponentがある場合、refreshImports() でインポートパスをリフレッシュ
6. バックグラウンドインデックス再構築
   └─ backgroundIndex() を呼び出し
7. 進捗レポート完了
   └─ reportProgressがtrueの場合、ProgressType.importReload (5/5) を報告
8. 結果返却
   └─ DUB更新の成否をboolで返却
```

### フローチャート

```mermaid
flowchart TD
    A[served/updateImports リクエスト受信] --> B[進捗レポート開始 0/5]
    B --> C{DubComponent あり?}
    C -->|Yes| D[DubComponent.update.getYield]
    C -->|No| E[進捗レポート 4/5]
    D --> F{更新成功?}
    F -->|Yes| G[coded/updateDubTree 通知送信]
    F -->|No| E
    G --> E
    E --> H{DCDComponent あり?}
    H -->|Yes| I[DCDComponent.refreshImports]
    H -->|No| J[backgroundIndex 呼出]
    I --> J
    J --> K[進捗レポート完了 5/5]
    K --> L[bool を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-54-01 | 進捗通知制御 | reportProgressがtrueの場合のみUI用進捗通知を送信する | 常時 |
| BR-54-02 | DubTree更新通知 | DUB依存関係の更新に成功した場合にのみcoded/updateDubTree通知を送信する | DUB更新成功時 |
| BR-54-03 | DCD更新独立 | DCDのインポートパス更新はDUB更新の成否に関わらず実行する | 常時 |
| BR-54-04 | インデックス再構築 | バックグラウンドインデックスは常に再構築する | 常時 |
| BR-54-05 | 内部呼出時の進捗抑制 | installDependency等からの内部呼出時はreportProgress=falseで進捗通知を抑制する | 内部呼出時 |

### 計算ロジック

特になし。

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

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

本機能はデータベースを使用しない。DUBのパッケージキャッシュ（ファイルシステム上）とインメモリのインポートパス情報を更新する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 暗黙的失敗 | DubComponent.updateが失敗した場合 | successがfalseとなり、そのまま返却される |

### リトライ仕様

リトライは不要。失敗時はクライアントから再度リクエストを送信できる。

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

トランザクション管理は不要。各コンポーネントの更新は独立して実行される。

## パフォーマンス要件

DUB依存関係のリフレッシュはファイルシステムアクセスを伴うため、やや時間がかかる場合がある。進捗通知により経過をクライアントに報告する。`getYield` により非同期処理を同期的に待機する。

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

特になし。

## 備考

- 本機能は依存関係管理の中核的な更新処理であり、No.58/59/60の各操作から内部的に呼び出される
- `getYield` はD言語のファイバー（協調スレッド）を使用した非同期-同期変換機構である
- DUBツリーの更新通知により、クライアント側のDUB依存関係ツリー表示が更新される

---

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

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

### 推奨読解順序

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

UpdateImportsParams構造体と進捗通知の型を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protoext.d | `source/served/lsp/protoext.d` | UpdateImportsParams構造体（251-255行目）。reportProgressフィールドのデフォルト値trueを確認 |
| 1-2 | progress.d | `source/served/utils/progress.d` | ProgressType列挙型（15-45行目）。dubReloadとimportReloadの意味を確認 |

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

updateImports関数の全体処理を把握する。

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

**主要処理フロー**:
1. **212行目**: `@protocolMethod("served/updateImports")` - LSPメソッド登録
2. **213行目**: `bool updateImports(UpdateImportsParams params)` - bool返却
3. **218行目**: `reportProgress(params.reportProgress, ProgressType.dubReload, 0, 5, ...)` - 進捗報告開始
4. **222行目**: `instance.get!DubComponent.update.getYield` - DUB依存関係を同期的に更新
5. **224行目**: `rpc.notifyMethod("coded/updateDubTree")` - DUBツリー更新通知
6. **228行目**: `instance.get!DCDComponent.refreshImports()` - DCDインポートパス更新
7. **229行目**: `backgroundIndex()` - バックグラウンドインデックス再構築
8. **230行目**: 最終進捗報告（5/5）
9. **231行目**: `return success` - 成否返却

#### Step 3: バックグラウンドインデックスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.d | `source/served/commands/index.d` | backgroundIndex関数（16-21行目）。setImmediateで非同期にreindexAllを呼び出す |

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

```
updateImports(UpdateImportsParams) [source/served/commands/dub.d:213]
    |
    +-- reportProgress(...) [source/served/utils/progress.d:47]
    |
    +-- activeInstance [source/served/types.d:471]
    |
    +-- DubComponent.update.getYield [workspace-d API]
    |
    +-- rpc.notifyMethod("coded/updateDubTree") [LSP通知]
    |
    +-- DCDComponent.refreshImports() [workspace-d API]
    |
    +-- backgroundIndex() [source/served/commands/index.d:16]
    |       |
    |       +-- reindexAll() [source/served/commands/index.d:24]
    |
    +-- return bool
```

### データフロー図

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

UpdateImportsParams    -->  updateImports()                        -->  bool (成否)
  reportProgress: bool       |                                          |
                             +-- DubComponent.update (FS refresh)       +-- coded/updateDubTree 通知
                             +-- DCDComponent.refreshImports            +-- 進捗通知
                             +-- 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` | ソース | reportProgress関数とProgressType列挙型 |
| index.d | `source/served/commands/index.d` | ソース | backgroundIndex関数（16-21行目） |
| types.d | `source/served/types.d` | ソース | activeInstanceプロパティ、backend定義 |
| extension.d | `source/served/extension.d` | ソース | LSPプロトコルメソッドのルーティング基盤 |
