# 機能設計書 64-シンボルハイライト

## 概要

本ドキュメントは、Clojure LSPにおけるシンボルハイライト機能（textDocument/documentHighlight）の設計を定義する。この機能は、同一ファイル内で同じシンボルの全ての出現箇所をハイライト表示するための情報を提供する。

### 本機能の処理概要

**業務上の目的・背景**：開発者がコードを読む際、特定の変数や関数がファイル内でどこで使われているかを素早く把握したいニーズがある。シンボルハイライト機能は、カーソル位置のシンボルと同じシンボルが出現する全ての箇所をハイライト表示することで、コードの理解を支援する。これは一般的なIDEで標準的に提供される機能である。

**機能の利用シーン**：開発者がファイル内の変数や関数名にカーソルを置くと、エディタは自動的にこの機能を呼び出す（通常は遅延あり）。同じシンボルの全ての出現箇所がハイライト表示され、開発者は視覚的にシンボルの使用状況を把握できる。

**主要な処理内容**：
1. 指定されたURI・位置からカーソル下の要素を特定
2. 同一ファイル内で同じシンボルの全参照箇所を検索
3. 各参照箇所の範囲情報をハイライト用に返却

**関連システム・外部連携**：LSPクライアント（エディタ）との通信はJSON-RPC経由で行われる。解析結果は同一ファイル内に限定して検索する。

**権限による制御**：特に権限制御は存在しない。全ユーザーが同等にこの機能を利用できる。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | 該当なし | 該当なし | 本機能はLSPプロトコルを通じてエディタから呼び出される |

## 機能種別

データ取得処理 / 参照検索処理 / LSPレスポンス生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | string | Yes | 対象ファイルのURI | 有効なファイルURIであること |
| position | object | Yes | カーソル位置 | {line, character} 形式 |

### 入力データソース

- LSPクライアントからの textDocument/documentHighlight リクエスト
- 内部DB（解析済みの要素情報）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| DocumentHighlight[] | array | ハイライト対象の範囲リスト |
| range | Range | ハイライト対象の範囲 |

### 出力先

LSPクライアント（JSON-RPC レスポンス）

## 処理フロー

### 処理シーケンス

```
1. LSPクライアントから textDocument/documentHighlight リクエストを受信
   └─ handlers.clj の document-highlight ハンドラが呼び出される
2. 解析データを同一ファイルに限定
   └─ db[:analysis] を対象URIのみにフィルタリング
3. カーソル位置から同一シンボルの全参照を検索
   └─ queries.clj の find-references-from-cursor を使用
4. 各参照箇所を DocumentHighlight 形式に変換
   └─ 範囲情報のみを抽出
5. レスポンスを返却
```

### フローチャート

```mermaid
flowchart TD
    A[textDocument/documentHighlight リクエスト受信] --> B[解析データをファイル内に限定]
    B --> C[find-references-from-cursor で参照検索]
    C --> D{参照が見つかったか?}
    D -->|No| E[空配列を返却]
    D -->|Yes| F[各参照を DocumentHighlight に変換]
    F --> G[配列として返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ファイル限定 | 検索範囲を同一ファイル内に限定 | 常時 |
| BR-02 | 定義を含む | find-references-from-cursor の include-definition を true にして定義も含める | 常時 |
| BR-03 | 変更待機 | エディタの変更が完了するまで待機（process-after-changes） | 常時 |

### 計算ロジック

**ローカルDBの作成**:
- local-db = (update db :analysis select-keys [uri])
- ファイル内の解析データのみを含むDBを作成

**ハイライト範囲の変換**:
- {:range (shared/->range reference)}
- 参照の位置情報をLSP Range形式に変換

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 参照検索 | db[:analysis][uri] | SELECT | 同一ファイル内の参照を検索 |

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

#### db[:analysis][uri]

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 全バケット | uri = 指定URI | find-references-from-cursor 経由 |

## エラー処理

### エラーケース一覧

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

### リトライ仕様

リトライは不要。

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

読み取り専用処理のため、トランザクション管理は不要。

## パフォーマンス要件

- 通常のClojureファイルに対して数十ミリ秒以内で応答
- ファイルサイズが大きい場合でも100ms以内を目標

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

- 特になし（ローカルファイルの読み取り専用）

## 備考

- LSPプロトコル仕様: https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_documentHighlight
- DocumentHighlightKind（Read/Write）は現在未実装で、デフォルト値が使用される

---

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

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

### 推奨読解順序

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

参照検索結果のデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | queries.clj | `lib/src/clojure_lsp/queries.clj` | find-references-from-cursor 関数（664-674行目） |

**読解のコツ**: find-references-from-cursor は全ての参照を返し、各参照は :row, :col, :end-row, :end-col, :name-row, :name-col, :name-end-row, :name-end-col などを持つ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | server.clj | `cli/src/clojure_lsp/server.clj` | textDocument/documentHighlight リクエストハンドラ（382-387行目） |
| 2-2 | handlers.clj | `lib/src/clojure_lsp/handlers.clj` | document-highlight ハンドラ関数（328-340行目） |

**主要処理フロー**:
1. **382-387行目（server.clj）**: LSPリクエストを受信し、ハンドラに委譲
2. **328-340行目（handlers.clj）**:
   - skip-feature-for-uri? でスキップ判定
   - process-after-changes で変更待機
   - local-db を作成（同一ファイル限定）
   - find-references-from-cursor で参照検索
   - mapv で DocumentHighlight に変換

#### Step 3: 補助機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | shared.clj | `lib/src/clojure_lsp/shared.clj` | ->range 関数（範囲変換） |

**読解のコツ**: ->range は clj-kondo の位置情報（1-indexed）をLSP形式（0-indexed）に変換する。

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

```
server.clj (textDocument/documentHighlight リクエスト受信)
    │
    └─ handlers.clj::document-highlight
           │
           ├─ skip-feature-for-uri? (スキップ判定)
           │
           ├─ process-after-changes (変更待機)
           │
           └─ queries.clj::find-references-from-cursor
                  │
                  ├─ find-all-elements-under-cursor
                  │
                  └─ find-references (multimethod)
```

### データフロー図

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

URI + Position  ───▶  document-highlight
                          │
                          ▼
                   local-db = db[:analysis][uri] のみ
                          │
                          ▼
                   find-references-from-cursor
                          │
                          ▼
                   参照リスト
                   [{:row 1 :col 5 :end-row 1 :end-col 10} ...]
                          │
                          ▼
                   mapv {:range (->range reference)}
                          │
                          ▼
                   DocumentHighlight[]  ───▶  LSPクライアント
                   [{:range {:start {...} :end {...}}} ...]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| handlers.clj | `lib/src/clojure_lsp/handlers.clj` | ソース | ハイライト処理のメインロジック |
| server.clj | `cli/src/clojure_lsp/server.clj` | ソース | LSPサーバーエントリーポイント |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | 参照検索クエリ関数群 |
| shared.clj | `lib/src/clojure_lsp/shared.clj` | ソース | 範囲変換ユーティリティ |
