# 機能設計書 76-参照取得

## 概要

本ドキュメントは、clojure-lsp の API として提供される `references` 関数の機能設計を記述する。この関数はシンボルの全参照箇所をプロジェクト全体および依存関係から検索する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Clojure プロジェクトでコードを理解・メンテナンスする際、特定のシンボル（変数、関数等）がどこで使用されているかを把握することが重要である。この機能はシンボルの全参照箇所を網羅的に検索し、影響範囲の分析やリファクタリングの事前調査に役立つ。

**機能の利用シーン**：リファクタリング前の影響調査、コードレビュー時の使用箇所確認、未使用コードの特定などで利用される。

**主要な処理内容**：
1. 対象シンボルの定義位置を特定
2. プロジェクトおよび依存関係から全参照箇所を検索
3. 参照情報のコレクションを返却

**関連システム・外部連携**：なし（解析済みデータベースの参照のみ）。

**権限による制御**：呼び出し元プロセスのファイルシステム権限に依存。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | 該当なし | 該当なし | 本プロジェクトは LSP サーバー実装であり UI 画面は存在しない |

## 機能種別

データ取得 / 検索

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| :project-root | java.io.File | No | プロジェクトルートディレクトリ | nil または存在する File |
| :from | Symbol | Yes | 検索対象の完全修飾シンボル | symbol?、qualified-symbol? |
| :analysis | Map | No | 解析タイプ設定 | :type (:project-only, :project-and-shallow-analysis, :project-and-full-dependencies) |
| :settings | Map | No | clojure-lsp 設定マップ | nil または map? |

### 入力データソース

- 解析データベース（シンボル定義・参照情報）
- ファイルシステム（必要に応じて）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| :result-code | Integer | 0: 成功、1: シンボル未検出 |
| :message-fn | Function | 結果を文字列化する関数 |
| :references | Collection | 参照情報のコレクション |

### 参照情報の構造

| フィールド | 型 | 説明 |
|-----------|-----|------|
| :uri | String | ファイル URI |
| :name | Symbol | シンボル名 |
| :name-row | Integer | 行番号 |
| :name-col | Integer | 列番号 |
| :name-end-row | Integer | 終了行番号 |
| :name-end-col | Integer | 終了列番号 |
| :from | Symbol | 参照元の名前空間 |
| :to | Symbol | 参照先の名前空間 |

### 出力先

- 戻り値として参照情報を返却

## 処理フロー

### 処理シーケンス

```
1. パラメータバリデーション
   └─ :from の事前条件チェック（qualified-symbol?）
2. プロジェクト解析
   └─ :analysis :type に応じた解析実行
3. シンボル定義の検索
   └─ q/find-element-from-sym で定義位置を特定
4. 参照検索
   └─ q/find-references で全参照箇所を取得
5. 結果返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{パラメータ有効?}
    B -->|No| C[AssertionError]
    B -->|Yes| D[API セットアップ]
    D --> E[プロジェクト解析]
    E --> F[シンボル定義検索]
    F --> G{シンボル見つかった?}
    G -->|No| H[Symbol not found エラー]
    G -->|Yes| I[参照検索実行]
    I --> J[参照コレクション返却]
    H --> K[終了]
    J --> K
    C --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-76-1 | 完全修飾必須 | :from は qualified-symbol である必要がある | 常時 |
| BR-76-2 | 解析タイプ選択 | :analysis :type で解析範囲を制御可能 | 常時 |
| BR-76-3 | デフォルト解析 | :analysis 未指定時は :project-and-full-dependencies | 常時 |
| BR-76-4 | 定義を含む | 参照には定義位置自体も含まれる | 常時 |

### 計算ロジック

解析タイプ：
- `:project-only`: プロジェクトソースのみ
- `:project-and-shallow-analysis`: プロジェクト + 浅い依存解析
- `:project-and-full-dependencies`: プロジェクト + 全依存解析（デフォルト）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | 該当なし | 該当なし | RDB は使用しない |

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

atom によるインメモリデータベースを参照。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AssertionError | バリデーションエラー | :from が qualified-symbol でない | 完全修飾シンボルを指定 |
| result-code: 1 | シンボル未検出 | :from のシンボルが見つからない | 正しいシンボル名を指定 |

### リトライ仕様

リトライ機構は実装されていない。

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

RDB を使用しないため、トランザクション管理は不要。

## パフォーマンス要件

- 解析タイプにより処理時間が変動
- プロジェクトサイズと依存関係数に依存

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

- ファイルシステムアクセスはプロセス権限に依存

## 備考

- 外部依存からの参照を含めるには :project-and-full-dependencies が必要
- message-fn は改行区切りの URI:行:列 形式を返す

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | queries.clj | `lib/src/clojure_lsp/queries.clj` | 参照データの構造 |

**読解のコツ**: find-references の戻り値構造を理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | api.clj | `lib/src/clojure_lsp/api.clj` | references 関数定義 |

**主要処理フロー**:
1. **249-291行目**: `references` 関数定義、docstring と事前条件

#### Step 3: 内部 API 実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | internal_api.clj | `lib/src/clojure_lsp/internal_api.clj` | references* の実装 |

**主要処理フロー**:
- **438-454行目**: references* で定義検索、参照取得、結果生成
- **440行目**: dynamic-setup-project-analysis! で解析タイプ選択
- **448行目**: q/find-references で参照取得

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

```
api/references
    |
    +-- internal-api/references
            |
            +-- build-components
            |
            +-- references*
                    |
                    +-- setup-api!
                    |
                    +-- dynamic-setup-project-analysis!
                    |
                    +-- q/find-element-from-sym (シンボル定義検索)
                    |
                    +-- q/find-references (参照検索)
                    |
                    +-- element->string (結果文字列化)
```

### データフロー図

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

{:from 'ns/sym}          api/references                       {:result-code 0/1
        |                |                                     :message-fn fn
        v                v                                     :references [...]}
        +-----------> q/find-element-from-sym                   |
                        |                                       |
                        v                                       |
                   シンボル定義                                 |
                        |                                       |
                        v                                       |
                   q/find-references                            |
                        |                                       |
                        v                                       |
                   [{:uri ... :name-row ...}] ----------------> 結果返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| api.clj | `lib/src/clojure_lsp/api.clj` | ソース | 公開 API 定義 |
| internal_api.clj | `lib/src/clojure_lsp/internal_api.clj` | ソース | 内部実装 |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | シンボル検索 |
| api_test.clj | `lib/test/clojure_lsp/api_test.clj` | テスト | API テスト |
