# 画面設計書 8-参照検索

## 概要

本ドキュメントは、Lua Language Serverの「参照検索」機能の設計を記載したものである。LSP（Language Server Protocol）の `textDocument/references` メソッドに対応し、シンボルの全参照箇所を一覧表示する機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：
大規模なコードベースにおいて、変数・関数・クラスなどがどこで使用されているかを把握することは、リファクタリングや影響調査において重要である。本機能により、シンボルの全ての参照箇所を一覧でき、コードの依存関係を素早く理解できる。

**画面へのアクセス方法**：
エディタ（VS Code等）上でLuaファイルを開き、変数名・関数名などのシンボル上で以下の操作を行う：
- 右クリックメニューから「すべての参照を検索」を選択
- コマンドパレットから「Find All References」を実行
- ショートカットキー（Shift+F12等）を使用

**主要な操作・処理内容**：
1. エディタからLSPサーバーへ `textDocument/references` リクエストを送信
2. カーソル位置からソースオブジェクトを特定
3. `vm.getRefs` で全参照を取得
4. メタファイルからの参照を除外（設定による）
5. `includeDeclaration` パラメータにより宣言の含有を制御
6. 結果をソート・フィルタリング
7. Location 形式でエディタへ返却
8. エディタが参照一覧を表示

**画面遷移**：
- 遷移元：エディタのコード編集画面
- 遷移先：参照一覧パネル（References Peek View）
- 関連遷移：定義へ移動、名前変更

**権限による表示制御**：
本機能に権限による表示制御はない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 16 | 参照検索 (textDocument/references) | 主機能 | シンボルの全参照箇所を検索する主処理 |

## 画面種別

ナビゲーション

## URL/ルーティング

LSPメソッド: `textDocument/references`

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

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument.uri | string | Yes | 対象ファイルのURI |
| position.line | integer | Yes | カーソル位置の行番号（0始まり） |
| position.character | integer | Yes | カーソル位置の列番号（0始まり） |
| context.includeDeclaration | boolean | Yes | 宣言箇所を結果に含めるか |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (配列) | Location[] | 参照位置のリスト |
| [].uri | string | 参照位置のファイルURI |
| [].range | Range | 参照位置の範囲 |

## 表示項目

### 参照検索結果

| 表示項目 | 形式 | 説明 |
|---------|------|------|
| 参照一覧 | リスト表示 | 全参照箇所のファイル・行番号を一覧表示 |
| ピークビュー | ポップアップ | エディタ内で参照箇所をプレビュー |
| サイドパネル | パネル | 参照一覧を専用パネルに表示 |

## イベント仕様

### 1-参照検索リクエスト処理

1. エディタからLSPサーバーへ `textDocument/references` リクエストを送信
2. `provider.lua` の `textDocument/references` ハンドラが呼び出される
3. ワークスペースの準備状態を確認
4. 進捗表示を開始（WINDOW_PROCESSING_REFERENCE）
5. `core/reference.lua` の関数を呼び出し
6. `findSource` でカーソル位置のソースオブジェクトを特定
7. `vm.getRefs` でシンボルの全参照を取得
8. 以下の条件でフィルタリング：
   - メタファイルからの参照を除外（ソースがメタファイルでない場合）
   - `self` をスキップ
   - `includeDeclaration` が false の場合、代入・リテラルをスキップ
   - `doc.generic.name` をスキップ
   - `doc.param` をスキップ
   - インデックスアクセスの場合、リテラルのみ対象
9. `doc.class`, `doc.alias`, `doc.enum` を名前部分へ変換
10. LuaDocの型名は、ソースも型名の場合のみ結果に含める
11. 結果をソート
12. `jumpSource` でジャンプ先を調整
13. `converter.location` で LSP 形式に変換
14. レスポンスとしてエディタへ返却

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

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

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| WINDOW_PROCESSING_REFERENCE | 情報 | 処理中表示 | 参照検索実行中 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイルが存在しない | `nil` を返却 |
| カーソル位置にシンボルがない | `nil` を返却 |
| 参照が見つからない | `nil` を返却 |

## 備考

- `includeDeclaration` により、宣言箇所を含めるかどうかを制御可能
- メタファイル（組み込みAPIの定義ファイル）からの参照は通常除外される
- LuaDocアノテーションの参照も検索対象
- 名前変更（rename）機能の事前処理としても使用される
- コードレンズでの参照数表示にも同じロジックが使用される

---

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

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

### 推奨読解順序

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

参照検索で扱うデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parser/guide.lua | `script/parser/guide.lua` | `isAssign`, `isLiteral` 関数の定義 |
| 1-2 | vm/init.lua | `script/vm/init.lua` | `getRefs` 関数の動作 |

**読解のコツ**: `vm.getRefs` が返す参照の種類を把握する。

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

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

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

**主要処理フロー**:
1. **495-528行目**: `textDocument/references` ハンドラの定義
2. **503行目**: `workspace.awaitReady` でワークスペース準備待ち
3. **504行目**: `progress.create` で進捗表示開始
4. **509行目**: `core.reference` モジュールの読み込み
5. **511行目**: 参照検索実行（includeDeclarationパラメータを渡す）
6. **521-523行目**: `converter.location` で結果変換

#### Step 3: コア参照検索ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | reference.lua | `script/core/reference.lua` | 参照検索のメインロジック |

**主要処理フロー（reference.lua）**:
- **7-31行目**: `sortResults` - 結果のソートとネストフィルタリング
- **33-55行目**: `accept` テーブル - 処理対象ノード種類の定義
- **61-160行目**: メイン関数 - 参照検索のエントリーポイント
- **67行目**: `findSource` でソースオブジェクト検索
- **72行目**: `vm.isMetaFile` でメタファイル判定
- **74行目**: `vm.getRefs` で参照取得
- **83-84行目**: メタファイルからの参照を除外
- **89-94行目**: `includeDeclaration` による宣言フィルタリング
- **111-136行目**: LuaDoc型の特殊処理

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | find-source.lua | `script/core/find-source.lua` | ソースオブジェクト検索 |
| 4-2 | jump-source.lua | `script/core/jump-source.lua` | ジャンプ先調整 |
| 4-3 | vm/ref.lua | `script/vm/ref.lua` | 参照検索エンジンの詳細 |

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

```
textDocument/references (provider.lua:495)
    │
    ├─ workspace.awaitReady(uri)
    │
    ├─ progress.create()
    │
    ├─ files.getState(uri)
    │
    ├─ converter.unpackPosition()
    │
    └─ core.reference(uri, pos, includeDeclaration)
           │
           ├─ findSource(ast, offset, accept)
           │
           ├─ vm.isMetaFile(uri)
           │
           ├─ vm.getRefs(source)
           │
           ├─ フィルタリング
           │      ├─ metaSource チェック
           │      ├─ src.type != 'self'
           │      ├─ includeDeclaration による除外
           │      ├─ インデックスアクセス処理
           │      └─ LuaDoc 型の特殊処理
           │
           ├─ sortResults(results)
           │
           └─ jumpSource(results)
```

### データフロー図

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

textDocument.uri    ───▶ files.getState(uri)     ───▶  AST State
position            ───▶ converter.unpackPosition ───▶  内部位置
includeDeclaration  ───▶ フィルタ条件として使用
                         │
                         ▼
                    findSource()                  ───▶  Source Object
                         │
                         ▼
                    vm.isMetaFile()               ───▶  Meta判定
                         │
                         ▼
                    vm.getRefs()                  ───▶  Reference List
                         │
                         ▼
                    各種フィルタリング            ───▶  Filtered List
                         │
                         ▼
                    sortResults()                 ───▶  Sorted List
                         │
                         ▼
                    jumpSource()                  ───▶  Adjusted List
                         │
                         ▼
                    converter.location()          ───▶  LSP Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPプロバイダー・エントリーポイント |
| reference.lua | `script/core/reference.lua` | ソース | 参照検索のメインロジック |
| find-source.lua | `script/core/find-source.lua` | ソース | ソースオブジェクト検索 |
| jump-source.lua | `script/core/jump-source.lua` | ソース | ジャンプ先調整 |
| guide.lua | `script/parser/guide.lua` | ソース | isAssign, isLiteral判定 |
| vm/init.lua | `script/vm/init.lua` | ソース | 参照検索エンジン |
| vm/ref.lua | `script/vm/ref.lua` | ソース | getRefs の実装 |
| converter.lua | `script/proto/converter.lua` | ソース | LSP位置変換 |
