# 画面設計書 52-コンパイラ切り替え（served/switchCompiler）

## 概要

本ドキュメントは、serve-d LSPサーバーが提供するカスタムリクエスト `served/switchCompiler` の設計を記述する。このリクエストは、DUBプロジェクトで使用するコンパイラを指定されたものに切り替える。

### 本画面の処理概要

このカスタムリクエストは、エディタ（LSPクライアント）からの要求に応じて、アクティブなDUBプロジェクトのビルドに使用するコンパイラを切り替える処理である。

**業務上の目的・背景**：D言語の開発では dmd、ldc2、gdc 等の複数のコンパイラが利用可能であり、プロジェクトの要件や開発フェーズに応じてコンパイラを動的に切り替える必要がある。例えばデバッグ時にはdmdを、リリースビルド時にはldc2を使用するといった使い分けが行われる。エディタからシームレスにコンパイラを切り替えることで、開発者の生産性を向上させる。

**画面へのアクセス方法**：LSPクライアント（エディタ）が `served/switchCompiler` メソッドをJSON-RPCリクエストとして送信することでアクセスする。通常はエディタのコマンドパレットやステータスバーのドロップダウンから選択する操作を契機として呼び出される。

**主要な操作・処理内容**：
1. クライアントからJSON-RPCリクエスト `served/switchCompiler` を受信する
2. リクエストパラメータからコンパイラ名を取得する
3. アクティブなワークスペースインスタンスおよびDubComponentの存在を確認する
4. DubComponentのsetCompilerメソッドを呼び出してコンパイラを切り替える
5. 切り替え結果（成功/失敗）をbool値で返却する

**画面遷移**：DUB設定管理フローの一部として動作する。切り替え後は `served/getCompiler` で現在の設定を確認できる。コンパイラ切り替え後の設定反映は extension.d の changedConfig に類似した処理パスを通る。

**権限による表示制御**：特になし。LSPプロトコル上の認証・認可機構は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 51 | コンパイラ切り替え (served/switchCompiler) | 主機能 | DUBのコンパイラを切り替える |

## 画面種別

カスタムLSPリクエスト（設定変更）

## URL/ルーティング

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

## 入出力項目

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

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| value | string | はい | 切り替え先のコンパイラ名（例: "dmd", "ldc2", "gdc"）。SwitchCompilerParams構造体またはstring直接指定 |

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

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | bool | 切り替え成功時true、失敗時false |

## 表示項目

LSPリクエスト応答のため、直接的な画面表示項目はない。エディタ側でコンパイラ切り替え結果が反映される。

## イベント仕様

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

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

1. `SwitchCompilerParams` としてパラメータをデシリアライズする（構造体 `{"value": "dmd"}` またはstring直接 `"dmd"` の両形式に対応）
2. `activeInstance` がnullでないか確認する
3. `activeInstance` に `DubComponent` が存在するか確認する
4. 条件を満たさない場合は `false` を返却する
5. 条件を満たす場合は `DubComponent.setCompiler(value)` を呼び出し、結果を返却する

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| コンパイラ切り替え | (なし) | UPDATE相当 | DubComponentのインメモリ状態を更新 |

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

データベースへの更新は発生しない。DubComponentのインメモリ状態のみ変更される。

## メッセージ仕様

| メッセージID | 種別 | 条件 | メッセージ内容 |
|-------------|------|------|---------------|
| (なし) | - | - | 本リクエスト自体ではユーザー向けメッセージは発生しない |

## 例外処理

| 条件 | 動作 | 返却値 |
|------|------|--------|
| activeInstanceがnull | 正常返却 | false |
| DubComponentが存在しない | 正常返却 | false |
| setCompilerが失敗 | 正常返却 | false |

## 備考

- SwitchCompilerParamsは `SingleValueParams!string` mixinを使用しており、JSON-RPCで `"dmd"` のようなstring直接指定と `{"value": "dmd"}` のような構造体指定の両方をサポートする
- `served/getCompiler` と対になるセッター操作
- 設定変更通知（No.7）と連動して、エディタ側のConfiguration.D.dubCompilerも更新されることが期待される

---

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

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

### 推奨読解順序

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

まず、リクエストパラメータの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protoext.d | `source/served/lsp/protoext.d` | SwitchCompilerParams構造体（519-523行目）とSingleValueParams mixinの仕組み（422-488行目）を確認 |
| 1-2 | types.d | `source/served/types.d` | activeInstance、DubComponent等のグローバル変数を確認 |

**読解のコツ**: `SingleValueParams!string` mixinにより、構造体とstring直接値の両方のデシリアライズが可能になっている。D言語のmixin機構に慣れていない場合は422-488行目のテンプレート実装を重点的に読むこと。

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

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

**主要処理フロー**:
1. **124行目**: `@protocolMethod("served/switchCompiler")` UDAでLSPメソッドとして登録
2. **125行目**: `bool switchCompiler(SwitchCompilerParams value)` - パラメータ受取、bool返却
3. **127行目**: `if (!activeInstance || !activeInstance.has!DubComponent)` - ガード条件
4. **128行目**: 条件を満たさない場合 `return false`
5. **129行目**: `return activeInstance.get!DubComponent.setCompiler(value)` - コンパイラ切り替え実行

#### Step 3: パラメータデシリアライズを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | protoext.d | `source/served/lsp/protoext.d` | SingleValueParams mixin（422-488行目）のデシリアライズロジック |

**主要処理フロー**:
- **440行目**: IonTypeCode.struct_の場合は構造体としてデシリアライズ
- **482行目**: それ以外の場合は直接T型（string）としてデシリアライズ

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

```
LSPクライアント (エディタ)
    |
    |  served/switchCompiler (JSON-RPC request)
    v
switchCompiler(SwitchCompilerParams) [source/served/commands/dub.d:125]
    |
    +-- activeInstance [source/served/types.d:471]
    |       |
    |       +-- has!DubComponent
    |
    +-- activeInstance.get!DubComponent.setCompiler(value)
            |
            +-- DubComponent.setCompiler() (workspace-d API)
```

### データフロー図

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

JSON-RPC Request    --->  switchCompiler()             --->  bool (成功/失敗)
  value: string              |                                |
  ("dmd" 等)                 +-- activeInstance確認            +-- true (成功)
                             +-- DubComponent取得              +-- false (失敗)
                             +-- setCompiler呼び出し
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| dub.d | `source/served/commands/dub.d` | ソース | switchCompiler関数の実装（124-130行目） |
| protoext.d | `source/served/lsp/protoext.d` | ソース | SwitchCompilerParams構造体定義（519-523行目）、SingleValueParams mixin（422-488行目） |
| types.d | `source/served/types.d` | ソース | activeInstance、Configuration等のグローバル定義 |
| extension.d | `source/served/extension.d` | ソース | LSPメソッドディスパッチ基盤 |
