# 機能設計書 58-呼び出し階層準備

## 概要

本ドキュメントは、clojure-lspにおける呼び出し階層準備（Prepare Call Hierarchy）機能の設計を記述する。この機能はLSPプロトコルの`textDocument/prepareCallHierarchy`リクエストを実装し、コールヒエラルキーの開始点となるシンボル情報を返却する。

### 本機能の処理概要

**業務上の目的・背景**：
コールヒエラルキー機能は、関数の呼び出し関係を階層的に探索するための機能である。prepareCallHierarchyは、その探索の起点となるシンボル情報を取得する最初のステップである。この情報を基に、クライアントはincomingCalls（この関数を呼び出している箇所）やoutgoingCalls（この関数が呼び出している関数）を取得できる。

**機能の利用シーン**：
1. 関数の呼び出し元を調査する際の起点設定
2. 関数が呼び出している他の関数を調査する際の起点設定
3. リファクタリング時の影響範囲調査
4. コードナビゲーション

**主要な処理内容**：
1. カーソル位置の要素情報を取得
2. 要素をCallHierarchyItem形式に変換
3. 結果を配列として返却

**関連システム・外部連携**：
- clj-kondo：シンボル情報の提供
- LSPクライアント（エディタ）：コールヒエラルキーUIの表示

**権限による制御**：
特に権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | エディタ | 主画面 | コールヒエラルキーの開始 |

## 機能種別

情報取得処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| textDocument.uri | string | Yes | 対象ドキュメントのURI | 有効なファイルURI形式 |
| position.line | integer | Yes | カーソル行（0始まり） | 0以上の整数 |
| position.character | integer | Yes | カーソル列（0始まり） | 0以上の整数 |

### 入力データソース

- LSPクライアントからの`textDocument/prepareCallHierarchy`リクエスト
- 解析データ（db.analysis）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| name | string | シンボル名（引数リスト付き） |
| kind | SymbolKind | シンボルの種類 |
| tags | array | タグ（deprecated等） |
| detail | string | 名前空間またはファイルパス |
| uri | string | ファイルURI |
| range | Range | シンボルの範囲 |
| selectionRange | Range | 選択範囲 |

### 出力先

LSPクライアントへのレスポンス（CallHierarchyItem配列）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ textDocument/prepareCallHierarchyを受信
2. 要素検索
   └─ find-element-under-cursorでカーソル位置の要素を取得
3. CallHierarchyItem生成
   └─ element-by-uri->call-hierarchy-itemで変換
4. レスポンス返却
   └─ 配列として返却
```

### フローチャート

```mermaid
flowchart TD
    A[prepareCallHierarchy受信] --> B[カーソル位置取得]
    B --> C[find-element-under-cursor]
    C --> D{要素取得成功?}
    D -->|No| E[空配列返却]
    D -->|Yes| F[element-by-uri->call-hierarchy-item]
    F --> G[CallHierarchyItem配列返却]
    E --> H[終了]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-58-01 | 名前表示 | arglist-strsがあれば名前に引数リストを付加 | 関数の場合 |
| BR-58-02 | 詳細表示 | 名前空間があれば名前空間、なければファイルパスを表示 | 常時 |
| BR-58-03 | 非推奨タグ | :deprecatedがtrueの場合はtag 1を追加 | 非推奨シンボル |
| BR-58-04 | 単一要素返却 | 準備段階ではカーソル位置の要素1つのみを返却 | 常時 |

### 計算ロジック

**名前の生成**:
```clojure
(if arglist-strs
  (str (name el-name) " " (string/join " " (remove nil? arglist-strs)))
  (name el-name))
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 要素検索 | db.analysis | SELECT | カーソル位置の要素を検索 |

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

#### db.analysis

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | 各bucket | uri, row, col | カーソル位置の要素 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 要素未検出 | カーソル位置にシンボルがない | 空配列返却 |

### リトライ仕様

リトライは行わない。

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

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

## パフォーマンス要件

- 通常数十ミリ秒以内

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

- 特になし

## 備考

- `call-hierarchy-provider: true`でこの機能を有効化

---

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

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

### 推奨読解順序

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

CallHierarchyItemのデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | call_hierarchy.clj | `lib/src/clojure_lsp/feature/call_hierarchy.clj` | **17-30行目**: element-by-uri->call-hierarchy-item |

**読解のコツ**: CallHierarchyItemはname, kind, tags, detail, uri, range, selectionRangeを持つ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | server.clj | `cli/src/clojure_lsp/server.clj` | **403-408行目**: prepareCallHierarchyハンドラ |
| 2-2 | handlers.clj | `lib/src/clojure_lsp/handlers.clj` | **479-484行目**: prepare-call-hierarchy関数 |

**主要処理フロー**:
1. **403-408行目**: `textDocument/prepareCallHierarchy`リクエストを受信
2. **481行目**: `f.call-hierarchy/prepare`を呼び出し

#### Step 3: 準備処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | call_hierarchy.clj | `lib/src/clojure_lsp/feature/call_hierarchy.clj` | **32-37行目**: `prepare`関数 |

**主要処理フロー**:
- **33行目**: `q/find-element-under-cursor`でカーソル位置の要素を取得
- **34-37行目**: 要素をCallHierarchyItemに変換して配列で返却

#### Step 4: CallHierarchyItem変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | call_hierarchy.clj | `lib/src/clojure_lsp/feature/call_hierarchy.clj` | **17-30行目**: `element-by-uri->call-hierarchy-item` |

**主要処理フロー**:
- **19行目**: 親要素から必要な情報を抽出
- **20-23行目**: 名前を生成（arglist-strsがあれば付加）
- **24行目**: `q/element->symbol-kind`でシンボル種別を取得
- **25行目**: deprecated判定でタグを設定
- **27行目**: 名前空間またはファイルパスを詳細として設定
- **28-30行目**: uri, range, selectionRangeを設定

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

```
textDocument/prepareCallHierarchy (server.clj:403-408)
    │
    ├─ handler/prepare-call-hierarchy (handlers.clj:479-484)
    │      │
    │      └─ f.call-hierarchy/prepare (call_hierarchy.clj:32-37)
    │             │
    │             ├─ q/find-element-under-cursor
    │             │
    │             └─ element-by-uri->call-hierarchy-item (call_hierarchy.clj:17-30)
    │                    │
    │                    ├─ q/element->symbol-kind
    │                    │
    │                    └─ shared/->range
    │
    └─ conform-or-log
```

### データフロー図

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

prepareCallHierarchy       ┌──────────────────────────────────┐
Request                    │                                  │
  ├─ uri ─────────────────►│  prepare                         │
  └─ position ────────────►│                                  │
       ├─ line             │    ├─ find-element-under-cursor  │
       └─ character        │    │                             │
                           │    └─ element-by-uri->...        │
db.analysis                │         ├─ name生成              │         CallHierarchyItem[]
  └─ 各bucket ────────────►│         ├─ kind取得              │────────►  ├─ name
                           │         ├─ tags設定              │           ├─ kind
                           │         ├─ detail設定            │           ├─ tags
                           │         ├─ uri設定               │           ├─ detail
                           │         ├─ range設定             │           ├─ uri
                           │         └─ selectionRange設定   │           ├─ range
                           │                                  │           └─ selectionRange
                           └──────────────────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| server.clj | `cli/src/clojure_lsp/server.clj` | ソース | LSPサーバーハンドラ定義 |
| handlers.clj | `lib/src/clojure_lsp/handlers.clj` | ソース | 各機能のハンドラ実装 |
| call_hierarchy.clj | `lib/src/clojure_lsp/feature/call_hierarchy.clj` | ソース | コールヒエラルキーの実装 |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | 要素検索クエリ |
| call_hierarchy_test.clj | `lib/test/clojure_lsp/feature/call_hierarchy_test.clj` | テスト | コールヒエラルキーのテスト |
