# 機能設計書 7-ワークスペースシンボル検索

## 概要

本ドキュメントは、Clojure LSP サーバーにおけるワークスペースシンボル検索機能の設計仕様を記載する。この機能は LSP プロトコルの `workspace/symbol` リクエストに対応し、プロジェクト全体からシンボルを検索する。

### 本機能の処理概要

**業務上の目的・背景**：大規模なプロジェクトにおいて、特定の関数や名前空間を素早く見つけることは開発効率の向上に直結する。本機能は、クエリ文字列に基づいてプロジェクト内の全てのシンボル（名前空間定義、変数定義、defmethod）をファジー検索し、マッチするシンボルの一覧を返却する。エディタのシンボル検索機能（Cmd+T、Ctrl+P等）と連携して使用される。

**機能の利用シーン**：開発者がエディタのシンボル検索パレットを開き、関数名や名前空間名の一部を入力すると、本機能がリアルタイムでマッチするシンボルを返却する。インクリメンタルサーチにより、タイプするごとに候補が絞り込まれる。

**主要な処理内容**：
1. クエリ文字列を受信
2. プロジェクト内の全シンボル定義を取得
3. ファジーマッチングでフィルタリング
4. スコア順にソート
5. SymbolInformation 配列として返却

**関連システム・外部連携**：clj-flx ライブラリ（ファジーマッチング）

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| query | string | Yes | 検索クエリ文字列 | - |

### 入力データソース

- clj-kondo による静的解析結果（db の :analysis）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (配列) | SymbolInformation[] | シンボル情報のリスト |
| [].name | string | シンボル名 |
| [].kind | integer | シンボルの種類（Function, Variable, Namespace 等） |
| [].location | Location | シンボル位置（uri, range） |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ handlers/workspace-symbols が workspace/symbol を受信

2. 全シンボル定義取得
   └─ q/find-all-element-definitions で全定義を取得

3. ファジーフィルタリング
   └─ fuzzy-filter でクエリにマッチするシンボルを抽出

4. シンボル変換
   └─ element->workspace-symbol で SymbolInformation に変換

5. URI でグループ化
   └─ 同一ファイルのシンボルをまとめて返却

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

### フローチャート

```mermaid
flowchart TD
    A[workspace/symbol リクエスト受信] --> B[find-all-element-definitions]
    B --> C{query が空?}
    C -->|Yes| D[全シンボル返却]
    C -->|No| E[fuzzy-filter]
    D --> F[element->workspace-symbol]
    E --> F
    F --> G[URI でグループ化]
    G --> H[フラット化]
    H --> I[SymbolInformation 配列返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ファジーマッチ | clj-flx によるファジーマッチングを使用 | query が空でない場合 |
| BR-02 | 全件返却 | query が空白の場合は全シンボルを返却 | query が空白 |
| BR-03 | スコア順ソート | ファジーマッチスコアの降順でソート | ファジーマッチ時 |
| BR-04 | 内部シンボルのみ | プロジェクト内（internal）のシンボルのみ検索 | 全検索 |
| BR-05 | URI グループ化 | スコア順を維持しつつ同一 URI のシンボルをグループ化 | 全結果 |

### 計算ロジック

- ファジーマッチスコア: clj-flx/score によりクエリとシンボル名のマッチ度を計算
- シンボル種別: q/element->symbol-kind により要素から LSP SymbolKind を決定

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| シンボル検索 | db :analysis | SELECT | 全シンボル定義を取得 |

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

#### db :analysis

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| SELECT | :namespace-definitions | internal-analysis から取得 | 名前空間定義 |
| SELECT | :var-definitions | internal-analysis から取得 | 変数定義 |
| SELECT | :var-usages | :defmethod フラグ付きを抽出 | defmethod |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 空配列返却 | マッチするシンボルがない | 空配列を返却 |

### リトライ仕様

リトライは行わない。

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

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

## パフォーマンス要件

- 応答時間: 通常 100ms 以内
- 大規模プロジェクトでも高速なファジーマッチングを実現

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

- 外部ネットワーク通信なし
- プロジェクト内のシンボル情報のみを返却

## 備考

- defmethod は :defmethod フラグで識別され、dispatch-val-str が名前に追加される
- deprecated シンボルは tags に 1 が追加される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | workspace_symbols.clj | `lib/src/clojure_lsp/feature/workspace_symbols.clj` | element->workspace-symbol（27-31行目）で出力データ構造を確認 |

**読解のコツ**: SymbolInformation は name, kind, location の3要素で構成される。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | handlers.clj | `lib/src/clojure_lsp/handlers.clj` | workspace-symbols 関数（342-345行目）が LSP リクエストのエントリーポイント |
| 2-2 | workspace_symbols.clj | `lib/src/clojure_lsp/feature/workspace_symbols.clj` | workspace-symbols 関数（33-51行目）がメインロジック |

**主要処理フロー**:
1. **33-35行目**: find-all-element-definitions で全定義取得
2. **36行目**: fuzzy-filter でファジーマッチング
3. **37行目**: element->workspace-symbol で変換
4. **38-50行目**: reduce で URI ごとにグループ化
5. **51行目**: reduce into で最終的にフラット化

#### Step 3: ファジーマッチングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | workspace_symbols.clj | `lib/src/clojure_lsp/feature/workspace_symbols.clj` | fuzzy-search（11-19行目）でファジーマッチングのロジックを確認 |
| 3-2 | workspace_symbols.clj | `lib/src/clojure_lsp/feature/workspace_symbols.clj` | fuzzy-filter（21-25行目）でフィルタリング処理を確認 |

**主要処理フロー**:
- **12行目**: query を小文字に変換
- **14行目**: flx/score でスコア計算
- **18行目**: :score の降順でソート

#### Step 4: シンボル定義の収集を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | queries.clj | `lib/src/clojure_lsp/queries.clj` | find-all-element-definitions（744-754行目）で全定義取得を確認 |
| 4-2 | document_symbol.clj | `lib/src/clojure_lsp/feature/document_symbol.clj` | element->name（10-12行目）でシンボル名生成を確認 |

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

```
handlers/workspace-symbols
    │
    └─ f.workspace-symbols/workspace-symbols
           │
           ├─ q/find-all-element-definitions
           │      └─ internal-analysis
           │             ├─ namespace-definitions
           │             ├─ var-definitions
           │             └─ var-usages (defmethod)
           │
           ├─ fuzzy-filter
           │      └─ fuzzy-search
           │             └─ flx/score
           │
           ├─ element->workspace-symbol
           │      ├─ f.document-symbol/element->name
           │      └─ q/element->symbol-kind
           │
           └─ [URI グループ化・フラット化]
```

### データフロー図

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

workspace/symbol ──▶ handlers/workspace-symbols ──▶ SymbolInformation[]
  - query                    │
                             ▼
                       workspace-symbols
                             │
                             ├──▶ find-all-element-definitions
                             │      └─ db :analysis (internal)
                             │
                             ├──▶ fuzzy-filter
                             │      └─ flx/score
                             │
                             ├──▶ element->workspace-symbol
                             │
                             └──▶ URI グループ化 & フラット化
                                    │
                                    ▼
                               SymbolInformation[]
                                 {name, kind, location}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| workspace_symbols.clj | `lib/src/clojure_lsp/feature/workspace_symbols.clj` | ソース | ワークスペースシンボル検索のメインロジック |
| handlers.clj | `lib/src/clojure_lsp/handlers.clj` | ソース | LSP リクエストハンドラー |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | シンボル定義の収集、種別判定 |
| document_symbol.clj | `lib/src/clojure_lsp/feature/document_symbol.clj` | ソース | シンボル名生成 |
| workspace_symbols_test.clj | `lib/test/clojure_lsp/feature/workspace_symbols_test.clj` | テスト | ユニットテスト |
