# 機能設計書 40-refer-all置換

## 概要

本ドキュメントは、Clojure LSPの「refer-all置換」機能の設計仕様を記載する。この機能は、`:refer :all`形式のrequire句を、具体的なrefer リストまたはエイリアス形式に置換するクイックフィックス操作を提供する。

### 本機能の処理概要

**業務上の目的・背景**：`:refer :all`は便利だが、以下の問題がある：
- どのシンボルが使用されているか不明確
- 名前空間の更新時に予期しないシンボル衝突が発生する可能性
- clj-kondoは`refer-all`として警告を出す

本機能は、実際に使用されているシンボルを検出し、明示的なreferリストに置換するか、エイリアス形式に変更することで、コードの明確性と保守性を向上させる。

**機能の利用シーン**：この機能は以下の場面で利用される：
- clj-kondoの`refer-all`警告の修正
- コードの明確化
- 名前空間のリファクタリング

**主要な処理内容**：
1. `:refer :all`の診断を検出
2. 該当名前空間から使用されているシンボルを検索
3. 2つの置換オプションを提供：
   - 具体的なreferリストに置換
   - エイリアス形式に置換
4. 必要に応じてコード内のシンボル参照を更新

**関連システム・外部連携**：LSPプロトコルを通じてエディタと連携。clj-kondoの診断結果を使用。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エディタ画面 | 主画面 | クイックフィックスメニューから置換オプションを選択 |

## 機能種別

コードアクション（クイックフィックス）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | string | Yes | 対象ファイルのURI | 有効なファイルURIであること |
| line | number | Yes | カーソル行（0-indexed） | 0以上の整数 |
| character | number | Yes | カーソル列（0-indexed） | 0以上の整数 |
| refers | vector | Yes（replace-refer-all-with-refer時） | referするシンボルのリスト | 文字列の配列 |

### 入力データソース

- エディタからのLSP `textDocument/codeAction` リクエスト
- コマンド名: `replace-refer-all-with-refer` または `replace-refer-all-with-alias`

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| edits | vector | ns宣言の更新とシンボル参照の更新編集 |

### 出力先

- LSPレスポンスとしてエディタに返却

## 処理フロー

### 処理シーケンス

```
1. 診断の取得
   └─ refer-all診断から位置と使用シンボルを取得

2. 置換方法の選択
   └─ referリストに置換
   └─ エイリアスに置換

3. referリストに置換の場合
   └─ :refer :all を :refer [symbols...] に変換

4. エイリアスに置換の場合
   └─ :refer :all を :as alias に変換
   └─ コード内のシンボル参照をエイリアス形式に更新

5. 結果の返却
   └─ 編集操作を返却
```

### フローチャート

```mermaid
flowchart TD
    A[クイックフィックス要求] --> B[refer-all診断取得]
    B --> C{置換方法?}
    C -->|referリスト| D[referリスト生成]
    C -->|エイリアス| E[エイリアス生成]
    D --> F[ns編集]
    E --> G[ns編集 + シンボル更新]
    F --> H[編集返却]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-40-01 | referリスト置換 | 使用されているシンボルのみをreferリストに含める | referリスト選択時 |
| BR-40-02 | エイリアス置換 | デフォルトエイリアス名を使用 | エイリアス選択時 |
| BR-40-03 | シンボル更新 | エイリアス置換時は全シンボル参照を更新 | エイリアス選択時 |

### 計算ロジック

**referリストの生成**：
```clojure
;; 診断データから使用シンボルを取得
;; ソートしてベクタに変換
(->> refers
     (mapv #(n/token-node (symbol %)))
     (interpose (n/spaces 1)))
```

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

本機能はclj-kondo解析データベースを参照のみ行う。

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 参照 | :analysis | SELECT | ローカルの名前空間使用を検索 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 操作不可 | refer-all診断でない | 空の結果を返却 |

### リトライ仕様

リトライは行わない。

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

トランザクション管理は不要。

## パフォーマンス要件

- 応答時間: 100ms以内

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

- ファイルシステムへの書き込みは行わない

## 備考

- LSP仕様ではカスタム入力を求める機能がないため、エイリアス名は固定値（an-alias）を使用
- 将来的にはユーザーにエイリアス名を入力させる機能が必要

---

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

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

### 推奨読解順序

#### Step 1: referリスト置換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | replace_refer_all.clj | `lib/src/clojure_lsp/feature/replace_refer_all.clj` | replace-with-refers |

**主要処理フロー**:
- **8-14行目**: `replace-with-refers` - referリストへの置換

#### Step 2: エイリアス置換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | replace_refer_all.clj | `lib/src/clojure_lsp/feature/replace_refer_all.clj` | replace-with-alias |

**主要処理フロー**:
- **16-36行目**: `replace-with-alias` - エイリアスへの置換とシンボル更新

#### Step 3: コードアクションの生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | code_actions.clj | `lib/src/clojure_lsp/feature/code_actions.clj` | replace-refer-all-actions |

**主要処理フロー**:
- **38-57行目**: `replace-refer-all-actions` - コードアクションの生成

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

```
textDocument/codeAction (LSP)
    │
    └─ code-actions/all
           │
           └─ replace-refer-all-actions
                 │
                 └─ [ユーザー選択]
                        │
                        ├─ command/run-command :replace-refer-all-with-refer
                        │     └─ f.replace-refer-all/replace-with-refers
                        │
                        └─ command/run-command :replace-refer-all-with-alias
                              └─ f.replace-refer-all/replace-with-alias
                                    └─ q/find-local-var-usages-to-namespace
```

### データフロー図

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

refer-all診断      ──▶  replace-refer-all-actions  ──▶  コードアクションリスト
                         (アクション生成)

refers リスト      ──▶  replace-with-refers        ──▶  [{:range, :loc}]
                         (referリスト生成)

名前空間           ──▶  replace-with-alias         ──▶  [{:range, :loc}] (複数)
+ シンボル使用         (エイリアス生成 + シンボル更新)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| replace_refer_all.clj | `lib/src/clojure_lsp/feature/replace_refer_all.clj` | ソース | refer-all置換のコアロジック |
| code_actions.clj | `lib/src/clojure_lsp/feature/code_actions.clj` | ソース | コードアクション生成 |
| command.clj | `lib/src/clojure_lsp/feature/command.clj` | ソース | コマンドディスパッチ |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | シンボル使用検索 |
| replace_refer_all_test.clj | `lib/test/clojure_lsp/feature/replace_refer_all_test.clj` | テスト | refer-all置換のテスト |
