# 画面設計書 4-シグネチャヘルプ

## 概要

本ドキュメントは、Lua Language Serverの「シグネチャヘルプ」機能の設計を記載したものである。LSP（Language Server Protocol）の `textDocument/signatureHelp` メソッドに対応し、関数呼び出し時に引数情報をポップアップ表示する機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：
関数を呼び出す際、引数の順序・型・意味を正確に把握することは重要である。本機能は、関数呼び出しの括弧内でカーソルを移動するたびに、現在入力中の引数がどの引数に対応するかを視覚的に示す。これにより、関数のドキュメントを参照することなく、正確な引数を素早く入力できる。

**画面へのアクセス方法**：
エディタ（VS Code等）上でLuaファイルを開き、関数呼び出しの `(` を入力するか、引数入力中に `,` を入力することで自動的にシグネチャヘルプが表示される。また、Ctrl+Shift+Space で手動トリガーも可能。

**主要な操作・処理内容**：
1. エディタからLSPサーバーへ `textDocument/signatureHelp` リクエストを送信
2. カーソル位置から最も近い関数呼び出しを検出
3. 関数の定義情報とオーバーロードを取得
4. 現在の引数インデックスを計算
5. シグネチャラベル、パラメータ範囲、ドキュメントを構築
6. シグネチャ情報をエディタへ返却
7. エディタがシグネチャヘルプポップアップを表示

**画面遷移**：
- 遷移元：エディタのコード編集画面（関数呼び出し入力）
- 遷移先：なし（ポップアップ表示のみ）
- 関連遷移：引数入力完了後、ポップアップが自動的に閉じる

**権限による表示制御**：
本機能に権限による表示制御はない。ただし、`Lua.signatureHelp.enable` 設定により機能全体の有効/無効を切り替えることができる。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | シグネチャヘルプ (textDocument/signatureHelp) | 主機能 | 関数呼び出し時の引数情報を表示する主処理 |
| 52 | 型推論 (Type Inference) | 補助機能 | 引数の型情報を推論 |

## 画面種別

情報表示（ポップアップ）

## URL/ルーティング

LSPメソッド: `textDocument/signatureHelp`

**リクエストパラメータ**:
```json
{
  "textDocument": {
    "uri": "file:///path/to/file.lua"
  },
  "position": {
    "line": 10,
    "character": 15
  }
}
```

**Capability**:
```json
{
  "signatureHelpProvider": {
    "triggerCharacters": ["(", ","]
  }
}
```

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument.uri | string | Yes | 対象ファイルのURI |
| position.line | integer | Yes | カーソル位置の行番号（0始まり） |
| position.character | integer | Yes | カーソル位置の列番号（0始まり） |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| signatures | SignatureInformation[] | シグネチャ情報のリスト |
| signatures[].label | string | 関数シグネチャのラベル（例: `function foo(x: number, y: string)`） |
| signatures[].parameters | ParameterInformation[] | パラメータ情報のリスト |
| signatures[].parameters[].label | [number, number] | パラメータのラベル位置（開始、終了） |
| signatures[].activeParameter | integer | 現在アクティブなパラメータのインデックス |
| signatures[].documentation | MarkupContent | 関数のドキュメント |

## 表示項目

### シグネチャヘルプポップアップ表示内容

| 表示項目 | 形式 | 説明 |
|---------|------|------|
| シグネチャラベル | テキスト | 関数シグネチャ全体（例: `function foo(x: number, y: string)`） |
| アクティブパラメータ | ハイライト | 現在入力中のパラメータがハイライト表示 |
| ドキュメント | Markdown | 関数の説明文 |
| オーバーロード切替 | UI | 複数のオーバーロードがある場合、切替UI |

## イベント仕様

### 1-シグネチャヘルプリクエスト処理

1. エディタが `(` または `,` を検出し、LSPサーバーへ `textDocument/signatureHelp` リクエストを送信
2. `provider.lua` の `textDocument/signatureHelp` ハンドラが呼び出される
3. `Lua.signatureHelp.enable` 設定を確認、無効の場合は `nil` を返却
4. ワークスペースの準備状態を確認
5. `core/signature.lua` の関数を呼び出し
6. `findNearCall` で最も近い関数呼び出しを検出
7. `makeSignatures` でシグネチャ情報を構築
8. 引数インデックスを計算し、`activeParameter` を設定
9. レスポンスとしてエディタへ返却

### 2-引数インデックス計算

1. 関数呼び出しの `args` から引数リストを取得
2. `self` 引数を除外
3. 各引数の位置とカーソル位置を比較
4. カーソル位置に対応する引数インデックスを特定
5. 可変長引数（`...`）の場合、最後の引数として扱う

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

本機能はデータベース操作を行わない（読み取り専用）。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| WINDOW_PROCESSING_SIGNATURE | 情報 | 処理中表示 | シグネチャ処理実行中 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイルが存在しない | `nil` を返却 |
| `Lua.signatureHelp.enable` が `false` | `nil` を返却 |
| 関数呼び出しが見つからない | `nil` を返却 |
| シグネチャ情報なし | `nil` を返却 |

## 備考

- オーバーロード関数の場合、複数のシグネチャが返却される
- シグネチャはパラメータ数でソートされる（少ない順）
- イベント引数のマッチングにより、不一致のオーバーロードは除外される
- OOP（`:`）呼び出しの場合、`self` パラメータは自動的に除外される

---

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

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

### 推奨読解順序

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

シグネチャヘルプで扱うデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parser/guide.lua | `script/parser/guide.lua` | 関数呼び出し（call）ノードの構造 |

**読解のコツ**: `call` ノードには `node`（呼び出される関数）と `args`（引数リスト）がある。

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

処理の起点となるプロバイダーファイルを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | provider.lua | `script/provider/provider.lua` | LSPメソッドの登録とリクエスト処理 |

**主要処理フロー**:
1. **773-823行目**: `textDocument/signatureHelp` ハンドラの定義
2. **783行目**: `Lua.signatureHelp.enable` 設定チェック
3. **793行目**: `core.signature` モジュールの呼び出し
4. **794行目**: シグネチャ取得
5. **798-818行目**: レスポンス構築

#### Step 3: コアシグネチャロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | signature.lua | `script/core/signature.lua` | シグネチャ処理のメインロジック |

**主要処理フロー（signature.lua）**:
- **8-42行目**: `findNearCall` - 最も近い関数呼び出しを検出
- **45-94行目**: `makeOneSignature` - 単一シグネチャの構築
- **96-130行目**: `isEventNotMatch` - イベント引数のマッチング
- **133-204行目**: `makeSignatures` - 全シグネチャの構築
- **207-227行目**: メイン関数 - エントリーポイント

#### Step 4: 補助モジュールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | hover/label.lua | `script/core/hover/label.lua` | シグネチャラベルの構築 |
| 4-2 | hover/description.lua | `script/core/hover/description.lua` | ドキュメントの構築 |
| 4-3 | look-backward.lua | `script/core/look-backward.lua` | 後方参照ユーティリティ |

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

```
textDocument/signatureHelp (provider.lua:773)
    │
    ├─ config.get('Lua.signatureHelp.enable')
    │
    ├─ workspace.awaitReady(uri)
    │
    ├─ files.getState(uri)
    │
    └─ core.signature(uri, pos)
           │
           ├─ lookback.skipSpace()
           │
           ├─ findNearCall(uri, state, pos)
           │      └─ guide.eachSourceContain()
           │
           └─ makeSignatures(text, call, pos)
                  │
                  ├─ 引数インデックス計算
                  │
                  ├─ vm.compileNode(func)
                  │
                  └─ makeOneSignature(src, oop, index)
                         │
                         ├─ hoverLabel(source, oop)
                         │
                         ├─ パラメータ範囲計算
                         │
                         └─ hoverDesc(source)
```

### データフロー図

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

textDocument.uri    ───▶ files.getState(uri)     ───▶  AST State
position            ───▶ converter.unpackPosition ───▶  内部位置
                         │
                         ▼
                    findNearCall()                ───▶  Call Node
                         │
                         ▼
                    引数インデックス計算           ───▶  activeParameter
                         │
                         ▼
                    vm.compileNode()              ───▶  Function Definitions
                         │
                         ▼
                    makeOneSignature()            ───▶  SignatureInfo[]
                         │
                         ▼
                    ソート(パラメータ数順)         ───▶  Sorted Signatures
                         │
                         ▼
                    response構築                  ───▶  LSP Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPプロバイダー・エントリーポイント |
| signature.lua | `script/core/signature.lua` | ソース | シグネチャ処理のメインロジック |
| hover/label.lua | `script/core/hover/label.lua` | ソース | ラベル構築 |
| hover/description.lua | `script/core/hover/description.lua` | ソース | ドキュメント構築 |
| look-backward.lua | `script/core/look-backward.lua` | ソース | 後方参照ユーティリティ |
| vm/init.lua | `script/vm/init.lua` | ソース | 型推論エンジン |
| converter.lua | `script/proto/converter.lua` | ソース | LSP位置変換 |
