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

## 概要

本ドキュメントは、clojure-lspのCLI（コマンドラインインターフェース）から実行するシンボルリネーム機能の設計書である。プロジェクト全体にわたってシンボル名の一括変更を行う。

### 本機能の処理概要

この機能は、CLIコマンド `clojure-lsp rename` を通じて、Clojureプロジェクト内のシンボル（変数、関数、名前空間、キーワードなど）の名前を一括で変更する。全ての参照箇所を自動的に検出し、一貫した変更を適用する。

**業務上の目的・背景**：ソフトウェア開発において、リファクタリングは品質向上と保守性向上の重要な活動である。シンボル名の変更は頻繁に行われるリファクタリング操作の一つであり、手動で行うと見落としや不整合が発生しやすい。本機能により、プロジェクト全体で安全かつ確実にシンボル名を変更できる。

**機能の利用シーン**：
- 関数や変数の名前をより適切なものに変更する場合
- 名前空間のリネーム（ファイル名変更を含む）
- キーワードの名前変更
- スクリプトやCI/CDパイプラインでの自動リファクタリング

**主要な処理内容**：
1. コマンドライン引数の解析（--from: 変更元シンボル、--to: 変更先名前）
2. プロジェクトの解析と参照関係の構築
3. 変更元シンボルの定義と全参照箇所の特定
4. 各参照箇所に対するリネーム変更の生成
5. 変更の適用（dry-runモードの場合はdiff表示のみ）

**関連システム・外部連携**：
- clj-kondo: シンボル解析に使用
- ファイルシステム: 名前空間リネーム時のファイル名変更

**権限による制御**：権限による制御は行わない。ファイルシステムへの書き込み権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | 該当なし | 該当なし | CLIから実行されるため画面は存在しない |

## 機能種別

バッチ処理 / リファクタリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --from | Symbol | Yes | 変更元の完全修飾シンボル名（例: my-project/my-var） | 有効なClojureシンボル形式 |
| --to | Symbol | Yes | 変更先の完全修飾シンボル名 | 有効なClojureシンボル形式 |
| --project-root, -p | Path | No | プロジェクトルートパス | 存在するディレクトリであること |
| --dry | Boolean | No | ドライランモード（デフォルト: false） | - |
| --raw | Boolean | No | 必要最小限の出力（デフォルト: false） | - |
| --settings, -s | EDN | No | 追加設定（EDN形式） | 有効なEDNマップ |

### 入力データソース

- ファイルシステム上のClojureソースファイル
- clj-kondo解析結果（シンボル定義・参照情報）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result-code | Integer | 実行結果コード（0: 成功、1: エラー） |
| message-fn | Function | 結果メッセージを生成する関数 |
| edits | Vector | 適用された編集のリスト |

### 出力先

- 標準エラー出力: 進捗メッセージ
- 標準出力: 結果メッセージ（dry-runモード時はdiff形式）
- ファイルシステム: 変更されたソースファイル、リネームされたファイル

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ --from と --to の必須チェック

2. コンポーネントの初期化
   └─ CLILogger、APIProducerの生成

3. プロジェクト解析の実行
   └─ :project-only タイプで解析

4. シンボルの検索
   └─ from シンボルの定義と参照箇所を特定

5. リネーム変更の生成
   └─ シンボルタイプに応じた変更処理

6. 結果の処理
   └─ dry-run: diff出力、通常: ファイル更新
```

### フローチャート

```mermaid
flowchart TD
    A[開始: rename コマンド実行] --> B[引数解析]
    B --> C{--from, --to あり?}
    C -->|No| D[エラー: 必須オプション不足]
    C -->|Yes| E[コンポーネント初期化]
    E --> F[プロジェクト解析]
    F --> G[シンボル検索]
    G --> H{シンボル見つかった?}
    H -->|No| I[エラー: シンボル未発見]
    H -->|Yes| J[参照箇所の特定]
    J --> K[リネーム変更の生成]
    K --> L{変更あり?}
    L -->|No| M[Nothing to rename 出力]
    L -->|Yes| N{dry-run?}
    N -->|Yes| O[diff形式で出力]
    N -->|No| P[ファイル更新]
    O --> Q[result-code: 0]
    P --> Q
    I --> R[result-code: 1]
    D --> R
    M --> S[result-code: 1]
    Q --> T[終了]
    R --> T
    S --> T
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-82-1 | 名前空間シンボル | 名前空間のみの場合はファイルリネームも実行 | from が simple-symbol? の場合 |
| BR-82-2 | キーワードリネーム | 名前空間付きキーワードのみリネーム可能 | キーワード定義に :ns がある場合 |
| BR-82-3 | defrecord対応 | defrecordのリネームは ->Constructor と map->Constructor も変更 | var-definitions で defrecord の場合 |
| BR-82-4 | エイリアス付きリネーム | replacement-raw に "/" が含まれる場合はエイリアス定義も更新 | var-usages で "/" を含む場合 |

### 計算ロジック

シンボル検索の優先順位:
1. 名前空間のみ指定（simple-symbol?）の場合は名前空間定義を検索
2. namespace/name 形式の場合は var 定義を検索
3. キーワードの場合はキーワード定義を検索

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

該当なし（ファイルシステムのみ操作）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 引数エラー | --from または --to が未指定 | エラーメッセージを表示して終了 |
| 1 | シンボル未発見 | 指定されたシンボルがプロジェクト内に存在しない | エラーメッセージを表示して終了 |
| 1 | 定義なし | シンボルの定義が見つからない | エラーメッセージを表示して終了 |
| 1 | 参照なし | 他の参照箇所が見つからない | エラーメッセージを表示して終了 |
| 1 | source-path無効 | 名前空間リネーム時にsource-pathが無効 | エラーメッセージを表示して終了 |
| 1 | クライアント非対応 | ファイルリネームを実行できない | エラーメッセージを表示して終了 |

### リトライ仕様

リトライは行わない。エラー発生時は即座に終了する。

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

トランザクション管理は行わない。各ファイルは独立して更新される。名前空間リネーム時はファイル名変更を含む複数の操作が実行される。

## パフォーマンス要件

- pmap を使用して変更生成を並列処理
- 名前空間リネームは追加のファイルI/O操作が発生

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

- ファイル書き込みは指定されたプロジェクト内のファイルのみに制限
- 外部ファイルへの変更は行わない

## 備考

- 名前空間リネームではファイル名も自動的に変更される
- defrecord のリネームでは関連するコンストラクタ関数も自動的にリネームされる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cli-spec | `cli/src/clojure_lsp/main.clj` | --from, --to オプションの定義 |
| 1-2 | rename types | `lib/src/clojure_lsp/feature/rename.clj` | リネーム対象のシンボルタイプ |

**読解のコツ**: リネーム対象は bucket キーで区別される（:namespace-definitions, :var-definitions, :keyword-definitions など）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | main.clj | `cli/src/clojure_lsp/main.clj` | renameコマンドの実行フロー |

**主要処理フロー**:
1. **187-192行目**: `with-required-options` で --from, --to の必須チェック
2. **205-208行目**: `"rename"` コマンドで `internal-api/rename!` を呼び出し

#### Step 3: internal-api層を理解する

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

**主要処理フロー**:
- **403-432行目**: `rename!*` 関数 - リネーム処理の本体
- **407-411行目**: シンボルの名前空間と名前を分離
- **412行目**: `q/find-element-from-sym` でシンボルを検索
- **413-415行目**: `f.rename/rename-from-position` でリネーム実行

#### Step 4: リネーム実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | rename.clj | `lib/src/clojure_lsp/feature/rename.clj` | リネーム処理の詳細実装 |

**主要処理フロー**:
- **224-267行目**: `rename-status` - リネーム可否のチェック
- **283-310行目**: `rename-element` - 変更の生成と適用
- **193-222行目**: `rename-changes` - シンボルタイプ別の変更生成

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

```
main/-main
    │
    └─ main/run!
           │
           └─ main/handle-action!
                  │
                  └─ main/with-required-options
                         │
                         └─ internal-api/rename!
                                │
                                ├─ internal-api/build-components
                                │
                                └─ internal-api/rename!*
                                       │
                                       ├─ q/find-element-from-sym
                                       │
                                       └─ f.rename/rename-from-position
                                              │
                                              └─ f.rename/rename-element
                                                     │
                                                     ├─ f.rename/rename-status
                                                     │
                                                     └─ f.rename/rename-changes
```

### データフロー図

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

--from シンボル ──────▶ find-element-from-sym ──▶ element
                               │
                               ▼
プロジェクト解析 ─────▶ find-references ──────▶ references リスト
                               │
                               ▼
--to シンボル ────────▶ rename-changes ────────▶ 変更リスト
                               │
                               ▼
                        dry-run分岐 ──────────▶ diff出力 / ファイル更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| main.clj | `cli/src/clojure_lsp/main.clj` | ソース | CLIエントリーポイント |
| internal_api.clj | `lib/src/clojure_lsp/internal_api.clj` | ソース | CLI用API実装 |
| rename.clj | `lib/src/clojure_lsp/feature/rename.clj` | ソース | リネーム処理実装 |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | シンボル検索クエリ |
| diff.clj | `lib/src/clojure_lsp/diff.clj` | ソース | diff出力生成 |
