# 機能設計書 6-参照検索

## 概要

本ドキュメントは、Clojure LSP サーバーにおける参照検索機能の設計仕様を記載する。この機能は LSP プロトコルの `textDocument/references` リクエストに対応し、シンボルの全参照箇所を検索する。

### 本機能の処理概要

**業務上の目的・背景**：変数、関数、名前空間、キーワードなどのシンボルがプロジェクト内のどこで使用されているかを把握することは、リファクタリングや影響範囲の調査において不可欠である。本機能は、カーソル位置のシンボルを参照している全ての箇所を検索し、一覧表示することで、効率的なコード調査を支援する。

**機能の利用シーン**：開発者がシンボルの使用箇所を調べたい場合、または関数の変更による影響範囲を事前に確認したい場合に本機能を使用する。「すべての参照を検索」コマンドを実行すると、プロジェクト全体から該当シンボルの参照箇所が一覧表示される。

**主要な処理内容**：
1. カーソル位置のシンボル要素を特定
2. 要素の種類（名前空間、変数、キーワード、ローカル等）に応じた参照検索
3. オプションで定義位置も結果に含める
4. 全参照位置を Location 配列として返却

**関連システム・外部連携**：特になし

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | 本プロジェクトは LSP サーバー実装であり、UI 画面は存在しない。エディタの参照検索機能から呼び出される。 |

## 機能種別

データ検索処理 / ナビゲーション処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| text-document.uri | string | Yes | 対象ドキュメントの URI | 有効な file:// URI |
| position.line | integer | Yes | カーソル行位置（0-indexed） | 0 以上 |
| position.character | integer | Yes | カーソル列位置（0-indexed） | 0 以上 |
| context.include-declaration | boolean | No | 定義位置を結果に含めるか | デフォルト: false |

### 入力データソース

- clj-kondo による静的解析結果（db の :analysis）
- 依存グラフ（:dep-graph）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (配列) | Location[] | 参照位置のリスト |
| [].uri | string | 参照位置のドキュメント URI |
| [].range | Range | 参照位置の範囲 |

### 出力先

LSP プロトコルを通じてエディタクライアントへ Location 配列として返却

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ handlers/references が textDocument/references を受信

2. カーソル位置の全要素特定
   └─ q/find-all-elements-under-cursor でカーソル下の全要素を取得

3. 参照検索
   └─ q/find-references (multimethod) で要素種別に応じた検索

4. 結果のマージ・重複除去
   └─ 全要素の参照を統合し重複を除去

5. 位置変換
   └─ 各要素を element->location で Location に変換

6. レスポンス返却
   └─ Location 配列を返却
```

### フローチャート

```mermaid
flowchart TD
    A[references リクエスト受信] --> B[find-all-elements-under-cursor]
    B --> C{要素あり?}
    C -->|No| D[空配列返却]
    C -->|Yes| E[各要素に find-references]
    E --> F{要素の bucket?}
    F -->|namespace-definitions| G[namespace-usages + keywords 検索]
    F -->|var-definitions| H[var-usages + symbols 検索]
    F -->|keywords| I[keyword-usages 検索]
    F -->|locals/local-usages| J[locals + local-usages 検索]
    F -->|その他| K[element をそのまま返却]
    G --> L[結果マージ・重複除去]
    H --> L
    I --> L
    J --> L
    K --> L
    L --> M[mapv element->location]
    M --> N[Location 配列返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 定義含む | include-declaration が true の場合、定義位置も結果に含める | context パラメータ |
| BR-02 | 複数要素対応 | カーソル下に複数要素がある場合、全ての参照を統合 | 複数要素検出時 |
| BR-03 | 重複除去 | uri, name, row, col で重複を除去 | 全結果 |
| BR-04 | defrecord 名 | defrecord は ->Name, map->Name も参照として扱う | var-definitions + defrecord |
| BR-05 | EDN 対応 | EDN ファイル内のシンボルも参照検索対象 | symbols bucket |

### 計算ロジック

- 参照検索: find-references マルチメソッドにより、要素の :bucket に応じた検索を実行
- 検索範囲: ns-and-dependents-analysis により、対象名前空間とその依存者を検索

## データベース操作仕様

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 要素検索 | db :analysis | SELECT | カーソル位置の要素を検索 |
| 参照検索 | db :analysis | SELECT | 依存者を含む広範囲から参照を検索 |

### テーブル別操作詳細

#### db :analysis

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | :namespace-usages | :name でマッチング | 名前空間参照検索 |
| SELECT | :var-usages | :to, :name でマッチング | 変数参照検索 |
| SELECT | :keyword-usages | :ns, :name でマッチング | キーワード参照検索 |
| SELECT | :local-usages | :id でマッチング | ローカル変数参照検索 |
| SELECT | :symbols | :to, :name でマッチング | EDN シンボル参照検索 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 空配列返却 | カーソル位置に要素がない | 空配列を返却 |
| - | element のみ返却 | 参照が見つからない | 元の element を返却 |

### リトライ仕様

リトライは行わない。

## トランザクション仕様

本機能は読み取り専用であり、トランザクション管理は不要。

## パフォーマンス要件

- 応答時間: 通常 200ms 以内
- 依存者全体を検索するため、大規模プロジェクトでは時間がかかる可能性あり

## セキュリティ考慮事項

- 外部ネットワーク通信なし
- ファイルシステムアクセスは解析対象ファイルのみ

## 備考

- var-usages からの参照検索は、対応する var-definitions として検索を委譲
- namespace-usages からの参照検索は、namespace-definitions として検索を委譲

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | queries.clj | `lib/src/clojure_lsp/queries.clj` | find-references defmulti（476-480行目）で参照検索の分岐を確認 |

**読解のコツ**: :bucket の値に応じて異なる検索ロジックが適用される。:locals と :local-usages は :local として共通処理される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | handlers.clj | `lib/src/clojure_lsp/handlers.clj` | references 関数（312-318行目）が LSP リクエストのエントリーポイント |

**主要処理フロー**:
1. **314-315行目**: position を row, col に変換
2. **317行目**: q/find-references-from-cursor を呼び出し（include-declaration を渡す）
3. **318行目**: mapv で各要素を element->location に変換

#### Step 3: 参照検索のマルチメソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | queries.clj | `lib/src/clojure_lsp/queries.clj` | find-references defmulti（476-480行目）で分岐ポイントを確認 |
| 3-2 | queries.clj | `lib/src/clojure_lsp/queries.clj` | namespace-definitions の参照検索（483-506行目） |
| 3-3 | queries.clj | `lib/src/clojure_lsp/queries.clj` | var-definitions の参照検索（534-548行目） |
| 3-4 | queries.clj | `lib/src/clojure_lsp/queries.clj` | keywords の参照検索（550-560行目） |
| 3-5 | queries.clj | `lib/src/clojure_lsp/queries.clj` | local の参照検索（562-569行目） |
| 3-6 | queries.clj | `lib/src/clojure_lsp/queries.clj` | symbols の参照検索（583-614行目） |

**主要処理フロー**:
- **483-506行目**: namespace-definitions は namespace-usages とキーワードを検索
- **534-548行目**: var-definitions は var-usages と symbols を検索、defrecord は派生名も検索
- **562-569行目**: local は同一ファイル内の locals と local-usages を検索

#### Step 4: 複数要素からの参照検索を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | queries.clj | `lib/src/clojure_lsp/queries.clj` | find-references-from-cursor（664-674行目）で複数要素の統合を確認 |

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

```
handlers/references
    │
    ├─ shared/position->row-col
    │
    └─ q/find-references-from-cursor
           │
           ├─ q/find-all-elements-under-cursor
           │
           └─ [各要素に対して]
                  │
                  └─ q/find-references (multimethod)
                         │
                         ├─ :namespace-definitions
                         │      └─ namespace-usages + keywords
                         │
                         ├─ :namespace-usages
                         │      └─ namespace-definitions として再帰
                         │
                         ├─ :namespace-alias
                         │      └─ 同一ファイル内の var-usages + keywords
                         │
                         ├─ :var-usages
                         │      └─ var-definitions として再帰
                         │
                         ├─ :var-definitions
                         │      └─ var-usages + symbols
                         │
                         ├─ :keywords
                         │      └─ keyword-usages
                         │
                         ├─ :local
                         │      └─ locals + local-usages
                         │
                         ├─ :protocol-impls
                         │      └─ var-usages
                         │
                         ├─ :symbols
                         │      └─ symbols + var-usages
                         │
                         └─ :default
                                └─ element 返却
```

### データフロー図

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

textDocument/references ──▶ handlers/references ──▶ Location[]
  - uri                          │
  - position (line, char)        ▼
  - include-declaration     find-references-from-cursor
                                 │
                                 ├──▶ find-all-elements-under-cursor
                                 │      └─ db :analysis[uri]
                                 │
                                 ├──▶ find-references (multimethod)
                                 │      └─ ns-and-dependents-analysis
                                 │         (各種バケット)
                                 │
                                 ├──▶ 重複除去
                                 │
                                 └──▶ mapv element->location
                                        │
                                        ▼
                                   Location[] {uri, range}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| handlers.clj | `lib/src/clojure_lsp/handlers.clj` | ソース | LSP リクエストハンドラー（references 関数） |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | 参照検索のマルチメソッド（find-references） |
| dep_graph.clj | `lib/src/clojure_lsp/dep_graph.clj` | ソース | 依存グラフによる検索範囲計算 |
| shared.clj | `lib/src/clojure_lsp/shared.clj` | ソース | 位置変換ユーティリティ |
| references_test.clj | `cli/integration-test/integration/api/references_test.clj` | テスト | 統合テスト |
