# 画面設計書 1-ホバー情報表示

## 概要

本ドキュメントは、Lua Language Serverの「ホバー情報表示」機能の設計を記載したものである。LSP（Language Server Protocol）の `textDocument/hover` メソッドに対応し、エディタ上で変数・関数にマウスカーソルを置いた際に、型情報やドキュメントをポップアップ表示する機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：
Luaコードを開発する際、変数や関数の型情報、ドキュメントコメントを即座に確認できることで、開発効率が大幅に向上する。特に大規模なコードベースや、外部ライブラリを使用する場合、シンボルの型や使用方法を確認するためにソースコードを探し回る必要がなくなる。本機能は、開発者がコード理解を深め、エラーを未然に防ぐために不可欠な機能である。

**画面へのアクセス方法**：
エディタ（VS Code等）上でLuaファイルを開き、任意の変数名・関数名・クラス名・型名などのシンボル上にマウスカーソルを移動（ホバー）することでアクセスする。キーボードショートカット（通常Ctrl+K Ctrl+I）でも呼び出し可能。

**主要な操作・処理内容**：
1. エディタからLSPサーバーへ `textDocument/hover` リクエストを送信
2. カーソル位置からソースオブジェクトを特定
3. シンボルの定義を取得し、型情報をラベルとして構築
4. LuaDocアノテーションから説明文を抽出
5. Markdown形式でホバー情報を構築しエディタへ返却
6. エディタがポップアップとしてホバー情報を表示

**画面遷移**：
- 遷移元：エディタのコード編集画面（ホバーアクション）
- 遷移先：なし（ポップアップ表示のみ）
- 関連遷移：ホバー情報内のリンクから定義へ移動（Go to Definition）が可能

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | ホバー情報 (textDocument/hover) | 主機能 | 変数・関数へのホバー時に型情報・ドキュメントを表示する主処理 |
| 52 | 型推論 (Type Inference) | 補助機能 | ホバー表示時の型情報を推論 |
| 55 | LuaDoc解析 | 補助機能 | アノテーションコメントから型・説明情報を抽出 |

## 画面種別

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

## URL/ルーティング

LSPメソッド: `textDocument/hover`

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

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument.uri | string | Yes | 対象ファイルのURI |
| position.line | integer | Yes | カーソル位置の行番号（0始まり） |
| position.character | integer | Yes | カーソル位置の列番号（0始まり） |
| level | integer | No | ホバー情報の詳細レベル（デフォルト: 1） |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| contents.value | string | Markdown形式のホバー情報テキスト |
| contents.kind | string | コンテンツ種別（"markdown"） |
| range.start | Position | ホバー対象シンボルの開始位置 |
| range.end | Position | ホバー対象シンボルの終了位置 |
| maxLevel | integer | 取得可能な最大詳細レベル |

## 表示項目

### ホバーポップアップ表示内容

| 表示項目 | 形式 | 説明 |
|---------|------|------|
| ラベル（型情報） | Luaコードブロック | シンボルの型情報（例: `local x: number`） |
| 説明文 | Markdown | LuaDocコメントから抽出された説明 |
| パラメータ情報 | Markdown | 関数の場合、引数の説明 |
| 戻り値情報 | Markdown | 関数の場合、戻り値の説明 |

## イベント仕様

### 1-ホバーリクエスト処理

1. エディタがマウスホバーを検出し、LSPサーバーへ `textDocument/hover` リクエストを送信
2. `provider.lua` の `textDocument/hover` ハンドラが呼び出される
3. `Lua.hover.enable` 設定を確認、無効の場合は `nil` を返却
4. ワークスペースの準備状態を確認、未完了の場合はローディングメッセージを返却
5. `core/hover/init.lua` の `byUri` 関数を呼び出し
6. `findSource` でカーソル位置のソースオブジェクトを特定
7. `getHover` 関数でホバー情報を構築
8. ラベル（型情報）と説明文をMarkdown形式で結合
9. レスポンスとしてエディタへ返却

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| HOVER_WS_LOADING | 情報 | "ワークスペース読み込み中: {count}/{max}" | ワークスペース初期化中にホバーした場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイルが存在しない | `nil` を返却（ポップアップ表示なし） |
| カーソル位置にシンボルがない | `nil` を返却（ポップアップ表示なし） |
| ホバー情報が空 | `nil` を返却（ポップアップ表示なし） |
| `Lua.hover.enable` が `false` | `nil` を返却（機能無効） |

## 備考

- ホバー情報の詳細レベル（level）パラメータにより、表示する情報量を調整可能
- `SHOWSOURCE` フラグが有効な場合、ソース情報がデバッグ用に追加表示される
- `SHOWNODE` フラグが有効な場合、ノード情報がデバッグ用に追加表示される

---

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

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

### 推奨読解順序

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

ホバー機能で扱うデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | proto/define.lua | `script/proto/define.lua` | LSPメッセージの定義を理解 |
| 1-2 | parser/guide.lua | `script/parser/guide.lua` | ASTノードの操作方法を理解 |

**読解のコツ**: Luaのテーブルがオブジェクトとして使われており、`source.type` でノードの種類を判別する。

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

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

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

**主要処理フロー**:
1. **340-385行目**: `textDocument/hover` ハンドラの定義
2. **349行目**: `Lua.hover.enable` 設定チェック
3. **362行目**: `core.hover` モジュールの呼び出し
4. **368行目**: `core.byUri` でホバー情報取得
5. **376-384行目**: レスポンスの構築と返却

#### Step 3: コアホバーロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | hover/init.lua | `script/core/hover/init.lua` | ホバー処理のメインロジック |
| 3-2 | hover/label.lua | `script/core/hover/label.lua` | 型情報ラベルの構築 |
| 3-3 | hover/description.lua | `script/core/hover/description.lua` | 説明文の構築 |

**主要処理フロー（init.lua）**:
- **13-112行目**: `getHover` 関数 - ホバー情報の構築
- **30-54行目**: `addHover` 内部関数 - ラベルと説明を追加
- **37行目**: `getLabel` でラベル取得
- **48行目**: `getDesc` で説明取得
- **135-160行目**: `getHoverByUri` - URIとポジションからホバー情報取得

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | find-source.lua | `script/core/find-source.lua` | カーソル位置のソース特定 |
| 4-2 | vm/init.lua | `script/vm/init.lua` | 型推論エンジン |

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

```
textDocument/hover (provider.lua:340)
    │
    ├─ config.get('Lua.hover.enable')
    │
    ├─ workspace.isReady(uri)
    │      └─ ローディング中: HOVER_WS_LOADING メッセージ返却
    │
    ├─ files.getState(uri)
    │
    ├─ converter.unpackPosition()
    │
    └─ core.hover.byUri(uri, pos, level)
           │
           ├─ files.getState(uri)
           │
           ├─ findSource(ast, position, accept)
           │
           └─ getHover(source, level)
                  │
                  ├─ getLabel(def, oop, level)
                  │      └─ buildName, buildArgs, buildReturn, buildTable
                  │
                  └─ getDesc(def)
                         └─ lookUpDocComments, tryDocComment
```

### データフロー図

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

textDocument.uri    ───▶ files.getState(uri)     ───▶  AST State
position            ───▶ converter.unpackPosition ───▶  内部位置
                         │
                         ▼
                    findSource(ast, pos)          ───▶  Source Object
                         │
                         ▼
                    vm.getDefs(source)            ───▶  Definition List
                         │
                         ▼
                    getLabel() + getDesc()        ───▶  Markdown Content
                         │
                         ▼
                    response構築                   ───▶  LSP Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPプロバイダー・エントリーポイント |
| init.lua | `script/core/hover/init.lua` | ソース | ホバー処理のメインロジック |
| label.lua | `script/core/hover/label.lua` | ソース | 型情報ラベルの構築 |
| description.lua | `script/core/hover/description.lua` | ソース | 説明文の構築 |
| name.lua | `script/core/hover/name.lua` | ソース | シンボル名の取得 |
| args.lua | `script/core/hover/args.lua` | ソース | 関数引数の構築 |
| return.lua | `script/core/hover/return.lua` | ソース | 戻り値情報の構築 |
| table.lua | `script/core/hover/table.lua` | ソース | テーブル型の展開表示 |
| find-source.lua | `script/core/find-source.lua` | ソース | カーソル位置のソース特定 |
| markdown.lua | `script/provider/markdown.lua` | ソース | Markdown構築ユーティリティ |
| converter.lua | `script/proto/converter.lua` | ソース | LSP位置変換 |
