# 画面設計書 29-シグネチャヘルプ（textDocument/signatureHelp）

## 概要

本ドキュメントは、serve-d LSPサーバーにおける `textDocument/signatureHelp` リクエストの処理仕様を定義する画面設計書である。関数呼び出し時にパラメータ情報を含むシグネチャ（関数署名）をポップアップ表示する機能を記述する。

### 本画面の処理概要

**業務上の目的・背景**：D言語で関数を呼び出す際に、その関数のパラメータ名・型・ドキュメント情報をリアルタイムに表示する機能である。開発者がAPIの使用法を覚えていなくても、エディタ上で直接パラメータ情報を確認でき、開発効率が向上する。複数のオーバーロードがある場合は、現在の引数数に基づいて最適なシグネチャを自動選択する。D言語ソースファイルとdietテンプレートの両方に対応している。

**画面へのアクセス方法**：エディタ上で関数呼び出しの括弧内にカーソルがある場合、またはトリガー文字（`(`, `,`）を入力した際に自動的に `textDocument/signatureHelp` リクエストが送信される。

**主要な操作・処理内容**：
1. DCDExtComponentで関数呼び出しのパラメータ情報（括弧位置、引数リスト等）を抽出する
2. DCDComponentで関数のcalltips（シグネチャ文字列）を取得する
3. calltipsをLSP `SignatureHelp` 形式に変換する（パラメータ情報、DDocドキュメント、アクティブパラメータ含む）
4. テンプレートパラメータとファンクションパラメータを区別して処理する
5. 現在の引数数に基づいて最適なシグネチャを `activeSignature` として選択する

**画面遷移**：本機能は独立した情報提供機能であり、他の画面への遷移は発生しない。シグネチャヘルプはカーソル移動や括弧の閉じで自動的に非表示となる。

**権限による表示制御**：権限による表示制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | シグネチャヘルプ (textDocument/signatureHelp) | 主機能 | 関数呼び出し時にパラメータ情報を含むシグネチャヘルプを提供する |

## 画面種別

情報提供（LSPプロトコルレスポンス）

## URL/ルーティング

- LSPメソッド: `textDocument/signatureHelp`

## 入出力項目

| 項目名 | 型 | 入力/出力 | 必須 | 説明 |
|--------|-----|----------|------|------|
| params.textDocument.uri | DocumentUri | 入力 | Yes | 対象ドキュメントのURI |
| params.position | Position | 入力 | Yes | カーソル位置 |
| SignatureHelp | SignatureHelp | 出力 | - | シグネチャヘルプ情報 |
| SignatureHelp.signatures | SignatureInformation[] | 出力 | - | 利用可能なシグネチャ一覧 |
| SignatureHelp.activeSignature | int | 出力 | - | 現在アクティブなシグネチャのインデックス |
| SignatureHelp.activeParameter | int | 出力 | - | 現在アクティブなパラメータのインデックス |
| SignatureInformation.label | string | 出力 | - | シグネチャのラベル（calltip文字列） |
| SignatureInformation.documentation | MarkupContent | 出力 | - | シグネチャのDDocドキュメント |
| SignatureInformation.parameters | ParameterInformation[] | 出力 | - | パラメータ情報の配列 |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|---------|------|
| シグネチャポップアップ | ツールチップ/ポップアップ | 関数シグネチャとパラメータ情報がカーソル位置の近くにポップアップ表示される |
| アクティブパラメータ | 強調表示 | 現在入力中のパラメータが太字等で強調される |
| パラメータドキュメント | テキスト | 各パラメータのDDoc説明文が表示される |

## イベント仕様

### 1-シグネチャヘルプ取得

関数呼び出し中にトリガーされる処理フロー。

1. ドキュメントを取得する（行124）
2. 言語IDに応じて分岐する（行126-131）:
   - D言語: `provideDSignatureHelp` を呼び出す
   - diet: `provideDietSignatureHelp` を呼び出す
   - その他: `SignatureHelp.init` を返却する

### 2-D言語シグネチャヘルプ（provideDSignatureHelp）

D言語ファイルでのシグネチャヘルプ処理フロー（行134-166）。

1. DCDComponentとDCDExtComponentの存在を確認する（行137-138）
2. カーソル位置をバイトオフセットに変換する（行140）
3. `dcdext.extractCallParameters` で関数呼び出しのパラメータ構造を抽出する（行145）
4. 抽出結果が空（CalltipsSupport.init）の場合はinit値を返却する（行146-147）
5. DCDの `listCompletion` を関数括弧の直後の位置で呼び出し、calltipsを取得する（行149-150）
6. 結果がcalltips型の場合、`convertDCDCalltips` で変換する（行157-159）
7. identifiers型等の場合はinit値を返却する（行163-164）

### 3-DCD calltips変換（convertDCDCalltips）

`convertDCDCalltips` 関数（行25-119）の処理フロー。

1. 各calltip文字列について:
   a. `SignatureInformation` を作成する（行37）
   b. DDocドキュメントをパースして設定する（行39-43）
   c. `dcdext.extractCallParameters` でcalltipからパラメータ情報を抽出する（行45-46）
   d. テンプレートパラメータとファンクションパラメータを区別する（行52-53）
   e. 各パラメータについて `ParameterInformation` を生成する（行59-97）:
      - labelOffsetSupportが有効ならUTF-16オフセットペアを設定（行70-73）
      - そうでなければテキスト範囲を設定（行75）
      - DDocからパラメータのドキュメントを取得する（行77-94）
   f. 可変引数（variadic）の場合はパラメータ数をint.maxとする（行55）
2. 現在入力済みの引数数に基づいて、受入可能なシグネチャをフィルタする（行108-111）
3. `activeParameter` を設定する（行113-114）
4. `activeSignature` を受入可能シグネチャの最初のインデックスに設定する（行116）

### 4-dietテンプレートシグネチャヘルプ（provideDietSignatureHelp）

dietテンプレートファイルでのシグネチャヘルプ処理フロー（行168-200）。

1. `updateDietFile` でdietファイルをパースする（行174）
2. 補完位置でD言語コードを抽出する（行182-183）
3. 抽出されたD言語コードに対してDCDComponent/DCDExtComponentで処理する（行187-196）
4. 結果がcalltips型の場合は `convertDCDCalltips` で変換する

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

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

本機能はデータベースに対する操作を行わない。

## メッセージ仕様

| メッセージ | 条件 | 種別 |
|-----------|------|------|
| `Unexpected result from DCD: {result}` | DCDからcalltips以外の予期しない結果型 | ログ（trace） |

## 例外処理

| 条件 | 挙動 |
|------|------|
| DCDComponent/DCDExtComponentが利用不可 | `SignatureHelp.init` を返却 |
| 関数呼び出し位置でない | `extractCallParameters` がinit値を返し、`SignatureHelp.init` を返却 |
| DCDからcalltips以外の結果型 | traceログ出力後、`SignatureHelp.init` を返却 |
| D言語/diet以外の言語 | `SignatureHelp.init` を返却 |

## 備考

- パラメータラベルはクライアントの `labelOffsetSupport` に応じて、UTF-16オフセットペアまたはテキスト文字列のどちらかで提供される
- テンプレートパラメータ（`!(T)` 等）とファンクションパラメータ（`(args)` 等）は `extractedParams.inTemplateParameters` で区別される
- 可変引数関数の場合、パラメータ数は `int.max` として扱われ、任意の引数数にマッチする
- DDocのパラメータドキュメントは `getParamDocumentation` で取得され、Markdown形式に変換される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protocol.d | `source/served/lsp/protocol.d` | `SignatureHelp`, `SignatureInformation`, `ParameterInformation` の定義を確認 |
| 1-2 | ddoc.d | `source/served/utils/ddoc.d` | `parseDdoc`, `Comment`, DDoc処理ユーティリティの理解 |

**読解のコツ**: `SignatureHelp` は `signatures`（シグネチャ配列）、`activeSignature`（アクティブインデックス）、`activeParameter`（アクティブパラメータインデックス）を持つ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | calltips.d | `source/served/commands/calltips.d` | `provideSignatureHelp` 関数（行121-132）がLSPリクエストハンドラ |

**主要処理フロー**:
1. **行121**: `@protocolMethod("textDocument/signatureHelp")` でバインド
2. **行126-131**: 言語IDに応じた分岐

#### Step 3: D言語処理の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | calltips.d | `source/served/commands/calltips.d` | `provideDSignatureHelp` 関数（行134-166）: D言語のシグネチャヘルプ |
| 3-2 | calltips.d | `source/served/commands/calltips.d` | `convertDCDCalltips` 関数（行25-119）: calltipsからSignatureHelpへの変換 |

**主要処理フロー（convertDCDCalltips）**:
- **行32-103**: 各calltipのSignatureInformation生成
- **行45-46**: extractCallParametersでパラメータ構造を抽出
- **行59-97**: ParameterInformation生成（labelOffset/DDoc含む）
- **行105-116**: activeSignature/activeParameter決定

#### Step 4: dietテンプレート処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | calltips.d | `source/served/commands/calltips.d` | `provideDietSignatureHelp` 関数（行168-200）: dietテンプレートのシグネチャヘルプ |

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

```
textDocument/signatureHelp リクエスト
    |
    +-- provideSignatureHelp (calltips.d:121)
           |
           +-- [D言語] provideDSignatureHelp (calltips.d:134)
           |      |
           |      +-- DCDExtComponent.extractCallParameters (パラメータ構造抽出)
           |      +-- DCDComponent.listCompletion (calltips取得)
           |      +-- convertDCDCalltips (calltips.d:25)
           |             +-- parseDdoc (DDoc処理)
           |             +-- extractCallParameters (calltipパラメータ抽出)
           |             +-- getParamDocumentation (パラメータドキュメント取得)
           |
           +-- [diet] provideDietSignatureHelp (calltips.d:168)
                  |
                  +-- updateDietFile (dietファイルパース)
                  +-- extractD (D言語コード抽出)
                  +-- DCDExtComponent.extractCallParameters
                  +-- DCDComponent.listCompletion
                  +-- convertDCDCalltips
```

### データフロー図

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

TextDocumentPositionParams ---> provideSignatureHelp -------------> SignatureHelp
  textDocument.uri                |
  position                        +-- extractCallParameters
                                  |      --> 括弧位置, 引数リスト, activeParameter
                                  +-- DCDComponent.listCompletion
                                  |      --> calltip文字列[], シンボル情報[]
                                  +-- convertDCDCalltips
                                         --> SignatureInformation[]
                                         --> activeSignature
                                         --> activeParameter
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| calltips.d | `source/served/commands/calltips.d` | ソース | シグネチャヘルプとホバーの主処理 |
| ddoc.d | `source/served/utils/ddoc.d` | ソース | DDocパース・Markdown変換ユーティリティ |
| types.d | `source/served/types.d` | ソース | 共通型定義・capabilities |
| protocol.d | `source/served/lsp/protocol.d` | ソース | LSPプロトコル型定義 |
| diet.d | `source/served/utils/diet.d` | ソース | dietテンプレート処理ユーティリティ |
