# 機能設計書 24-リネーム (textDocument/rename)

## 概要

本ドキュメントは、serve-d LSPサーバーにおけるリネーム機能（textDocument/rename）の設計を記述する。カーソル位置のシンボルを新しい名前にリネームするためのWorkspaceEditを返却する機能である。

### 本機能の処理概要

**業務上の目的・背景**：変数名・関数名・クラス名等のリネームは、コードの可読性向上やドメイン用語の統一において重要なリファクタリング操作である。手動でのリネームは変更漏れやミスのリスクがあるため、LSPサーバーによる自動リネームが不可欠である。

**機能の利用シーン**：開発者がエディタ上でシンボルを選択して「名前の変更」（F2等）コマンドを実行し、新しい名前を入力した際に呼び出される。

**主要な処理内容**：
1. ドキュメントハイライト機能（No.22）のdocumentHighlightImplを内部利用して、シンボルのローカル使用箇所を取得する
2. 最初のハイライトがwrite種別（宣言箇所）であることを確認し、リネーム可能と判定する
3. 全ハイライト箇所に対して新しい名前への置換テキスト編集を生成する
4. WorkspaceEditとして返却する

**関連システム・外部連携**：DCDComponent（documentHighlightImpl経由で使用）、ドキュメントハイライト機能（No.22）

**権限による制御**：特になし。DCDのfindLocalUseが成功し、宣言箇所が検出された場合のみリネームが実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 28 | リネーム（textDocument/rename） | 主画面 | カーソル位置のシンボルを新しい名前にリネームするためのWorkspaceEditを返却する |
| 28 | リネーム（textDocument/rename） | 補助機能 | リネーム準備（prepareRename）によるリネーム可能性の事前判定 |

## 機能種別

リファクタリング（シンボルリネーム）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| textDocument.uri | DocumentUri | Yes | 対象ドキュメントのURI | 有効なドキュメントURIであること |
| position | Position | Yes | リネーム対象のカーソル位置（行・列） | ドキュメント範囲内であること |
| newName | string | Yes | 新しいシンボル名 | - |

### 入力データソース

- LSPクライアントからのtextDocument/renameリクエストのRenameParams

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| changes | TextEditCollection[DocumentUri] | ドキュメントURIをキーとした、テキスト編集のマップ。現在の実装ではカレントドキュメントのみ |
| changes[uri] | TextEdit[] | 各テキスト編集（範囲と新しいテキスト）。開始位置の降順でソートされる |

### 出力先

LSPクライアント（JSON-RPCレスポンスとして返却。Nullable!WorkspaceEdit型でリネーム不可時はnull）

## 処理フロー

### 処理シーケンス

```
1. textDocument/renameリクエスト受信
   └─ RenameParamsからURI・位置・新名前を取得
2. ドキュメントのimmutableクローン取得
   └─ cast(immutable)documents[uri].clone()
3. カーソル位置をバイトオフセットに変換
   └─ document.positionToBytes(params.position)
4. documentHighlightImplを呼び出し
   └─ ドキュメントハイライト機能のDCD実装を直接利用
5. リネーム可能性判定
   └─ highlight.length > 0 かつ highlight[0].kind == write
6. テキスト編集の生成
   └─ 各ハイライト箇所に対してTextEdit(range, newName)を作成
   └─ 最初の要素と重複するrangeは除外
7. 編集の降順ソート
   └─ 開始位置の降順でソート（後方から適用するため）
8. WorkspaceEditとして返却
   └─ 単一ドキュメントのchangesを設定
```

### フローチャート

```mermaid
flowchart TD
    A[rename リクエスト受信] --> B[ドキュメントimmutableクローン取得]
    B --> C[カーソル位置をバイトオフセットに変換]
    C --> D[documentHighlightImpl呼び出し]
    D --> E{結果あり and 最初がwrite種別?}
    E -->|No| F[Nullable.init返却 リネーム不可]
    E -->|Yes| G[各ハイライト箇所にTextEdit生成]
    G --> H[重複range除外]
    H --> I[開始位置の降順ソート]
    I --> J[WorkspaceEdit構築]
    J --> K[Nullable WorkspaceEdit 返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-24-01 | 宣言箇所必須 | 最初のハイライトがwrite種別（宣言箇所）でない場合はリネーム不可 | リネーム可能性判定時 |
| BR-24-02 | 重複排除 | 宣言箇所と使用箇所のrangeが一致する場合、重複を排除する | テキスト編集生成時（23行目） |
| BR-24-03 | 降順ソート | テキスト編集を開始位置の降順でソートする（後方から適用するため） | WorkspaceEdit構築前 |
| BR-24-04 | ローカルスコープ限定 | DCDのfindLocalUseに基づくため、現在のドキュメント内のローカルスコープに限定される | 常に |

### 計算ロジック

特になし。

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

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

データベース操作は行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | リネーム不可 | ハイライト結果が空の場合 | Nullable.init（null）を返却 |
| - | リネーム不可 | 最初のハイライトがwrite種別でない場合 | Nullable.init（null）を返却 |

### リトライ仕様

リトライは不要。

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

トランザクションは使用しない。テキスト編集はクライアント側でアトミックに適用される。

## パフォーマンス要件

- documentHighlightImplに依存するため、DCDのfindLocalUseのレスポンス時間に比例する
- ローカルスコープのみの検索のため、一般的に高速

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

特になし。

## 備考

- 本機能は現在ローカルスコープ内のリネームのみに対応している。クロスファイルリネームには対応していない（DCDのfindLocalUseの制約）
- テキスト編集を降順ソートするのは、クライアントが前方から適用した場合にオフセットがずれないようにするためのLSP仕様への対応である
- リネーム準備機能（No.25）と密接に連携しており、同じdocumentHighlightImplを使用してリネーム可能性の事前判定を行う

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | types.d | `source/served/types.d` | WorkspaceEdit, TextEdit, TextRange, DocumentHighlightKindの型定義 |

**読解のコツ**: Nullable!WorkspaceEditはD言語の`Nullable`テンプレートで、値が存在しない場合のnull表現を型安全に行う。`typeof(return).init`はnull相当を返す。

#### Step 2: 前提機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | highlight.d | `source/served/commands/highlight.d` | documentHighlightImpl関数（26-58行目）がリネームの基盤。packageスコープで公開されている |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | rename.d | `source/served/commands/rename.d` | provideRename関数（12-32行目）がLSPプロトコルメソッドのエントリーポイント |

**主要処理フロー**:
1. **15行目**: `cast(immutable)documents[...].clone()` ドキュメントのimmutableクローン取得
2. **16行目**: `document.positionToBytes` バイトオフセット変換
3. **18行目**: `documentHighlightImpl(document, currOffset)` ハイライト機能の呼び出し
4. **19行目**: `highlight[0].kind == DocumentHighlightKind.write` 宣言箇所の確認
5. **22-24行目**: 各ハイライト箇所のTextEdit生成（重複排除付き）
6. **26行目**: `edits.sort!"a.range.start>b.range.start"` 降順ソート
7. **27行目**: `edit.changes[params.textDocument.uri] = edits` WorkspaceEdit構築

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

```
provideRename (rename.d:13)
    |
    +-- documentHighlightImpl (highlight.d:26) [package]
    |       |
    |       +-- DCDComponent.findLocalUse
    |       +-- Document.wordRangeAt
    |       +-- Document.nextPositionBytes
    |
    +-- TextEdit生成 (各ハイライト箇所)
    +-- edits.sort (降順ソート)
    +-- WorkspaceEdit構築
```

### データフロー図

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

RenameParams --------------> provideRename --------------------> Nullable!WorkspaceEdit
  (uri, position, newName)         |
                                   v
                            documentHighlightImpl
                                   |
                                   v
                            DocumentHighlight[] (宣言+使用箇所)
                                   |
                                   v
                            TextEdit[] 生成 (range -> newName)
                                   |
                                   v
                            降順ソート -> WorkspaceEdit構築
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| rename.d | `source/served/commands/rename.d` | ソース | リネームのメイン実装（provideRename: 12-32行目, prepareRename: 34-45行目） |
| highlight.d | `source/served/commands/highlight.d` | ソース | documentHighlightImpl関数（packageスコープ）の提供元 |
| types.d | `source/served/types.d` | ソース | LSP型定義（WorkspaceEdit, TextEdit, RenameParams等） |
| dcd.d (workspaced) | `workspace-d/source/workspaced/com/dcd.d` | ソース | DCDComponent.findLocalUse APIの実装 |
