# 機能設計書 75-リネーム実行

## 概要

本ドキュメントは、clojure-lsp の API として提供される `rename!` 関数の機能設計を記述する。この関数はシンボル名（変数、関数、名前空間等）をプロジェクト全体で一括変更する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Clojure プロジェクトでリファクタリングを行う際、シンボル名の変更は頻繁に必要となる。手動での変更は漏れやエラーの原因となるため、プロジェクト全体で参照を含めて一括変更する機能が必要である。

**機能の利用シーン**：変数名や関数名の改善、名前空間の再構成、API 名の変更などのリファクタリング作業で利用される。

**主要な処理内容**：
1. 対象シンボルの定義位置を特定
2. シンボルの全参照箇所を検索
3. 名前空間リネームの場合はファイル名の変更も含む
4. 変更の適用または差分レポート

**関連システム・外部連携**：なし（プロジェクト内のファイル操作のみ）。

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

## 関連画面

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

## 機能種別

ファイル更新 / リファクタリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| :project-root | java.io.File | No | プロジェクトルートディレクトリ | nil または存在する File |
| :from | Symbol | Yes | 変更元の完全修飾シンボル | symbol?、qualified-symbol? または simple-symbol? |
| :to | Symbol | Yes | 変更先の完全修飾シンボル | symbol?、:from と同じ形式（両方 simple または両方 qualified） |
| :dry? | Boolean | No | true の場合はファイル変更せず差分のみ表示 | boolean |
| :settings | Map | No | clojure-lsp 設定マップ | nil または map? |

### 入力データソース

- ファイルシステム（プロジェクトソースファイル）
- 解析データベース（シンボル定義・参照情報）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| :result-code | Integer | 0: 成功、1: エラー/該当なし |
| :message-fn | Function | 結果を文字列化する関数 |
| :edits | Collection | 編集内容のコレクション |

### 出力先

- ファイルシステム（dry? が false の場合）
- 戻り値として差分情報

## 処理フロー

### 処理シーケンス

```
1. パラメータバリデーション
   └─ :from、:to の事前条件チェック
2. プロジェクト解析
   └─ project-only で解析
3. シンボル定義の検索
   └─ q/find-element-from-sym で定義位置を特定
4. リネーム実行
   └─ f.rename/rename-from-position で変更を生成
5. 編集適用または差分生成
   └─ dry? に応じて処理を分岐
```

### フローチャート

```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{変更あり?}
    J -->|No| K[Nothing to rename]
    J -->|Yes| L{dry? モード?}
    L -->|Yes| M[差分を生成し返却]
    L -->|No| N[ファイルに適用]
    N --> O[Renamed X to Y]
    H --> P[終了]
    K --> P
    M --> P
    O --> P
    C --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-75-1 | シンボル形式一致 | :from と :to は両方 simple-symbol または両方 qualified-symbol | 常時 |
| BR-75-2 | 名前空間リネーム | :from が simple-symbol の場合は名前空間リネーム | :from が simple-symbol |
| BR-75-3 | ファイルリネーム | 名前空間リネーム時はファイル名も変更 | 名前空間リネーム時 |
| BR-75-4 | dry モード | :dry? が true の場合はファイル変更せず差分のみ表示 | :dry? が true |

### 計算ロジック

シンボル種別の判定：
- `simple-symbol?` が true: 名前空間リネーム
- `qualified-symbol?` が true: 変数/関数リネーム

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

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

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AssertionError | バリデーションエラー | パラメータ不正 | 有効なパラメータを渡す |
| result-code: 1 | シンボル未検出 | :from のシンボルが見つからない | 正しいシンボル名を指定 |
| result-code: 1 | リネーム不可 | リネーム操作が実行できない | エラーメッセージを確認 |

### リトライ仕様

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

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

RDB を使用しないため、トランザクション管理は不要。複数ファイルの変更は各ファイル単位で実行。

## パフォーマンス要件

- pmap による並列処理で編集サマリーを生成
- プロジェクトサイズと参照数に依存

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

- ファイルシステムアクセスはプロセス権限に依存
- プロジェクト外のファイルは変更されない

## 備考

- 名前空間リネームは関連するファイル名も変更される
- 外部依存からの参照は変更されない（プロジェクト内のみ）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | queries.clj | `lib/src/clojure_lsp/queries.clj` | シンボル検索の構造 |

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

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

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

**主要処理フロー**:
1. **210-247行目**: `rename!` 関数定義、docstring と事前条件

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

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

**主要処理フロー**:
- **403-432行目**: rename!* で定義検索、リネーム実行、結果処理
- **407-411行目**: simple-symbol? でシンボル種別判定
- **412-415行目**: f.rename/rename-from-position でリネーム実行

#### Step 4: リネーム機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | rename.clj | `lib/src/clojure_lsp/feature/rename.clj` | rename-from-position 実装 |

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

```
api/rename!
    |
    +-- internal-api/rename!
            |
            +-- build-components
            |
            +-- rename!*
                    |
                    +-- setup-api!
                    |
                    +-- setup-project-only-analysis!
                    |
                    +-- q/find-element-from-sym (シンボル定義検索)
                    |
                    +-- open-file!
                    |
                    +-- f.rename/rename-from-position
                            |
                            +-- document-changes 生成
                            +-- ファイルリネーム処理（名前空間の場合）
                    |
                    +-- document-change->edit-summary (pmap)
                    |
                    +-- apply-workspace-edit-summary! (dry? が false の場合)
```

### データフロー図

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

{:from 'ns/sym          api/rename!                          {:result-code 0/1
 :to 'ns/new-sym}       |                                     :message-fn fn
        |               v                                     :edits [...]}
        +-----------> q/find-element-from-sym                  |
                        |                                      |
                        v                                      |
                   シンボル定義位置                            |
                        |                                      |
                        v                                      |
                   f.rename/rename-from-position               |
                        |                                      |
                        v                                      |
                   document-changes                            |
                        |                                      |
              +---------+---------+                            |
              |                   |                            |
              v                   v                            |
        dry? = true         dry? = false                       |
              |                   |                            |
              v                   v                            |
        差分生成             ファイル更新 -------------------> 結果返却
```

### 関連ファイル一覧

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