# 機能設計書 48-ビルドタイプ切り替え (served/switchBuildType)

## 概要

本ドキュメントは、serve-d LSPサーバーが提供するカスタムLSPメソッド `served/switchBuildType` の機能設計を記述する。このメソッドは、DUBのビルドタイプを指定されたタイプに切り替える。

### 本機能の処理概要

**業務上の目的・背景**：DUBプロジェクトでは、debug・release・unittest等のビルドタイプによってコンパイルフラグやバージョン識別子が異なる。ビルドタイプを切り替えることで、serve-dが参照するインポートパスやバージョン条件が更新され、コード補完や静的解析がビルドタイプに応じた正しい結果を返すようになる。

**機能の利用シーン**：エディタのステータスバーやコマンドパレットからビルドタイプを変更する際に呼び出される。No.47（ビルドタイプ一覧取得）で取得した一覧から選択されたビルドタイプ名を送信する。

**主要な処理内容**：
1. アクティブなワークスペースインスタンスとDubComponentの有効性確認
2. 指定されたビルドタイプの妥当性確認
3. ビルドタイプの切り替えとインポートパスの更新

**関連システム・外部連携**：workspace-dサブパッケージのDubComponentを介してDUBのビルドタイプを変更する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 49 | ビルドタイプ切り替え（served/switchBuildType） | 主画面 | DUBのビルドタイプを切り替える |

## 機能種別

設定変更（UPDATE）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| value | SwitchBuildTypeParams (string) | Yes | 切り替え先のビルドタイプ名。JSON文字列またはオブジェクト形式に対応 | buildTypesに含まれるビルドタイプ名であること |

### 入力データソース

LSPクライアントからの `served/switchBuildType` リクエスト。SwitchBuildTypeParams型はSingleValueParams!stringミキシンにより柔軟なデシリアライズに対応。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (戻り値) | bool | ビルドタイプ切り替えが成功した場合true、失敗した場合false |

### 出力先

LSPクライアントへのJSON-RPCレスポンスとして返却。

## 処理フロー

### 処理シーケンス

```
1. アクティブインスタンスの確認
   └─ activeInstanceがnullの場合、falseを返却して終了
2. DubComponentの有効性確認
   └─ activeInstance.has!DubComponentがfalseの場合、falseを返却して終了
3. ビルドタイプの切り替え
   └─ DubComponent.setBuildType(value)を呼び出し
      ├─ 指定タイプがbuildTypesに含まれるか確認
      ├─ 含まれない場合falseを返却
      ├─ _buildTypeに新しいタイプを保存
      └─ updateImportPaths(false)でインポートパスを再計算
4. 結果の返却
   └─ bool値をクライアントに返却
```

### フローチャート

```mermaid
flowchart TD
    A[served/switchBuildType リクエスト受信] --> B{activeInstance が有効か?}
    B -->|No| C[false を返却]
    B -->|Yes| D{DubComponent が有効か?}
    D -->|No| C
    D -->|Yes| E[DubComponent.setBuildType 呼び出し]
    E --> F{タイプがbuildTypesに存在するか?}
    F -->|No| C
    F -->|Yes| G[_buildType を更新]
    G --> H[updateImportPaths で再計算]
    H --> I[結果を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-48-01 | アクティブインスタンス必須 | アクティブなワークスペースインスタンスが存在しない場合はfalseを返す | 常時 |
| BR-48-02 | DubComponent必須 | DubComponentがロードされていない場合はfalseを返す | 常時 |
| BR-48-03 | ビルドタイプの妥当性確認 | 指定されたビルドタイプがbuildTypes（定義済み+カスタム）に含まれていること | setBuildType呼び出し時 |
| BR-48-04 | インポートパス自動更新 | ビルドタイプ切り替え後、updateImportPaths(false)が自動的に呼び出される | 切り替え成功時 |

### 計算ロジック

特別な計算ロジックはない。

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 暗黙的エラー | activeInstanceがnull | falseを返却 |
| - | 暗黙的エラー | DubComponentが未ロード | falseを返却 |
| - | 検証エラー | 指定ビルドタイプがbuildTypesに存在しない | falseを返却 |

### リトライ仕様

リトライ処理はない。

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

トランザクション制御はない。設定変更は即時反映される。

## パフォーマンス要件

設定変更後にupdateImportPathsが呼び出されるため、プロジェクト規模に応じた遅延が発生する可能性がある。

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

特になし。

## 備考

- _buildTypeの初期値は "debug" である（dub.d 840行目）。
- setBuildTypeはbuildTypesプロパティ（定義済み12種 + カスタムタイプ）にcanFindで存在確認を行う。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protoext.d | `source/served/lsp/protoext.d` | SwitchBuildTypeParams構造体（514-517行目）- SingleValueParams!stringミキシン |

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

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

**主要処理フロー**:
1. **100行目**: `@protocolMethod("served/switchBuildType")` でLSPメソッドとして登録
2. **101行目**: 引数として `SwitchBuildTypeParams value` を受け取る
3. **103-104行目**: activeInstanceとDubComponentの存在確認
4. **105行目**: `DubComponent.setBuildType(value)` を呼び出し

#### Step 3: DubComponent.setBuildTypeの実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | dub.d | `workspace-d/source/workspaced/com/dub.d` | setBuildType関数（641-652行目） |
| 3-2 | dub.d | `workspace-d/source/workspaced/com/dub.d` | _buildTypeフィールド（840行目）の宣言と初期値 |

**主要処理フロー**:
- **643行目**: `buildTypes.canFind(type)` でビルドタイプの妥当性を検証
- **645行目**: `_buildType = type` で内部状態を更新
- **646行目**: `updateImportPaths(false)` でインポートパスを再計算
- **650行目**: 存在しないビルドタイプの場合はfalseを返却

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

```
served/switchBuildType (LSPリクエスト)
    │
    └─ switchBuildType(SwitchBuildTypeParams) [source/served/commands/dub.d:101-106]
           │
           ├─ activeInstance チェック
           ├─ has!DubComponent チェック
           │
           └─ DubComponent.setBuildType(string) [workspace-d/source/workspaced/com/dub.d:641-652]
                  │
                  ├─ buildTypes.canFind(type) (妥当性検証)
                  ├─ _buildType = type (内部状態更新)
                  └─ updateImportPaths(false) (インポートパス再計算)
```

### データフロー図

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

SwitchBuildTypeParams ───> switchBuildType() ───> bool (成否)
  (ビルドタイプ名)               │
                            DubComponent
                            .setBuildType()
                                 │
                            buildTypes.canFind
                                 │
                            updateImportPaths()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dub.d | `source/served/commands/dub.d` | ソース | LSPメソッドのエントリーポイント（switchBuildType関数） |
| dub.d | `workspace-d/source/workspaced/com/dub.d` | ソース | DubComponent.setBuildTypeの実装 |
| protoext.d | `source/served/lsp/protoext.d` | ソース | SwitchBuildTypeParams型定義 |
| types.d | `source/served/types.d` | ソース | activeInstance等のグローバル状態管理 |
| extension.d | `source/served/extension.d` | ソース | コマンドモジュールのpublic import |
