# 機能設計書 23-キーワード自動解決切り替え

## 概要

本ドキュメントは、clojure-lspの「キーワード自動解決切り替え」機能（cycle-keyword-auto-resolveコマンド）の設計仕様を定義する。この機能は、名前空間修飾キーワード（:my-ns/keyword）と自動解決キーワード（::keyword）を相互に変換するリファクタリング機能を提供する。

### 本機能の処理概要

キーワード自動解決切り替え機能は、カーソル位置のキーワードについて、現在の名前空間に基づく自動解決形式（::keyword）と完全修飾形式（:my-ns/keyword）を相互に変換する。同じキーワードが名前空間内で複数使用されている場合、ユーザーに確認の上、すべての使用箇所を一括変換することも可能。

**業務上の目的・背景**：Clojureでは、キーワードの名前空間修飾には2つの方式がある。自動解決（::）は簡潔だが現在の名前空間に依存し、完全修飾（:ns/kw）は冗長だが明示的である。リファクタリングや名前空間の変更時に、これらを切り替える必要が生じることがある。この機能により、キーワードの修飾方式を効率的に変更できる。

**機能の利用シーン**：
- 自動解決キーワードを他の名前空間でも使用するため完全修飾に変更したい場合
- 完全修飾キーワードを簡潔な自動解決形式に変更したい場合
- 名前空間のリファクタリング時にキーワードの修飾を統一したい場合
- コードの可読性向上のために修飾方式を調整したい場合

**主要な処理内容**：
1. カーソル位置のキーワードノードを特定
2. キーワードが自動解決（::で始まる）か完全修飾（:ns/kw）かを判定
3. 現在の名前空間名を取得
4. 変換先の形式でキーワードノードを生成
5. 同じキーワードの他の使用箇所を検索し、一括変換の確認
6. 変換結果を返却

**関連システム・外部連携**：LSPプロトコルを通じてエディタと連携し、コードアクションまたはコマンドとして実行される。ユーザーへの確認ダイアログにはproducerを使用。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 該当なし | - | 本プロジェクトはLSPサーバーであり、UI画面は存在しない。エディタのコードアクションメニューから呼び出される。 |

## 機能種別

リファクタリング（コード変換処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| zloc | zipper location | Yes | カーソル位置のzipperロケーション | キーワードノード上にあること |
| uri | string | Yes | 対象ファイルのURI | 有効なURI形式 |
| db | database | Yes | LSPデータベース | - |
| components | map | Yes | LSPコンポーネント（producer含む） | - |

### 入力データソース

- エディタから送信されるLSPリクエスト
- ドキュメントのパース結果（rewrite-clj zipper）
- clj-kondo解析データ（キーワード使用箇所の検索）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| range | map | 変更対象範囲（:row, :col, :end-row, :end-col） |
| loc | zipper location | 変換後のキーワードノード |

### 出力先

LSPプロトコルを通じてエディタに返却され、テキスト編集として適用される。

## 処理フロー

### 処理シーケンス

```
1. キーワードノードの確認
   └─ n/keyword-node?でキーワードノードかチェック
2. 現在の名前空間を取得
   └─ edit/find-namespaceで名前空間フォームを検索
3. キーワードの種類を判定
   └─ ::で始まる（自動解決）か、ns/kwで始まる（完全修飾）かを判定
4. 変換可能性の確認
   └─ 現在の名前空間と一致する修飾の場合のみ変換可能
5. 同一キーワードの使用箇所を検索
   └─ q/find-keyword-usages-by-keywordで検索
6. ユーザー確認（複数使用箇所がある場合）
   └─ producer/show-message-requestで確認ダイアログ表示
7. キーワードの変換
   └─ n/keyword-nodeで新しいキーワードノードを生成
8. 結果の返却
   └─ 全変換箇所のrangeとlocを返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{キーワードノード?}
    B -->|No| C[nil返却]
    B -->|Yes| D[名前空間を取得]
    D --> E{自動解決?}
    E -->|Yes| F[status = from-auto-resolve-to-namespace]
    E -->|No| G{現在NSと一致?}
    G -->|No| C
    G -->|Yes| H[status = from-namespace-to-auto-resolve]
    F --> I[同一キーワード使用箇所検索]
    H --> I
    I --> J{複数使用箇所?}
    J -->|Yes| K[ユーザー確認ダイアログ]
    J -->|No| L[単一変換]
    K --> M{一括変換?}
    M -->|Yes| N[全箇所変換]
    M -->|No| L
    N --> O[結果返却]
    L --> O
    O --> P[終了]
    C --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | 自動解決→完全修飾 | ::kwを:current-ns/kwに変換 | 自動解決キーワードで、スラッシュを含まない場合 |
| BR-002 | 完全修飾→自動解決 | :current-ns/kwを::kwに変換 | 完全修飾キーワードで、名前空間が現在のNSと一致する場合 |
| BR-003 | 一括変換確認 | 複数使用箇所がある場合、ユーザーに確認を求める | キーワード使用箇所が2以上の場合 |
| BR-004 | エイリアス修飾非対応 | ::alias/kwのような形式は変換対象外 | スラッシュを含む自動解決キーワードの場合 |

### 計算ロジック

特になし。

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

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

本機能はデータベース操作を行わない。clj-kondo解析データの読み取りのみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 暗黙的エラー | キーワードノードでない場合 | nil返却 |
| - | 暗黙的エラー | 変換対象外のキーワード形式 | nil返却 |

### リトライ仕様

リトライは不要。

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

該当なし（メモリ上の操作のみ）。

## パフォーマンス要件

キーワード使用箇所の検索を含め、1秒以内に完了すること。

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

特になし。ローカルファイルの操作のみ。

## 備考

- cycle-keyword-auto-resolve-status関数は変換可能性と変換方向を判定するヘルパー
- 自動解決キーワードの:auto-resolved?プロパティでrewrite-cljノードの種類を判定

---

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

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

### 推奨読解順序

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

キーワードノードの構造とプロパティを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cycle_keyword.clj | `lib/src/clojure_lsp/feature/cycle_keyword.clj` | キーワードの判定ロジック（12-33行目） |

**読解のコツ**: rewrite-cljのn/keyword-node?、z/stringを使ってキーワードノードを判定。::で始まる場合は自動解決キーワード。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | command.clj | `lib/src/clojure_lsp/feature/command.clj` | cycle-keyword-auto-resolveコマンドの定義（161-162行目） |
| 2-2 | code_actions.clj | `lib/src/clojure_lsp/feature/code_actions.clj` | cycle-kwd-actionでUIアクション生成（165-173行目） |

**主要処理フロー**:
1. **161-162行目**: run-commandのcycle-keyword-auto-resolveメソッドがf.cycle-keyword/cycle-keyword-auto-resolveを呼び出し

#### Step 3: 変換処理の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cycle_keyword.clj | `lib/src/clojure_lsp/feature/cycle_keyword.clj` | cycle-keyword-auto-resolve-status（12-33行目）で変換可能性判定 |
| 3-2 | cycle_keyword.clj | `lib/src/clojure_lsp/feature/cycle_keyword.clj` | cycle-keyword-auto-resolve（44-65行目）で変換実行 |

**主要処理フロー**:
- **13-16行目**: edit/find-namespaceで現在の名前空間を取得
- **17行目**: n/keyword-node?でキーワードノードか確認
- **18-20行目**: z/stringでキーワード文字列取得、::判定、/判定
- **21-33行目**: 変換方向を決定（from-auto-resolve-to-namespace or from-namespace-to-auto-resolve）
- **46行目**: q/find-keyword-usages-by-keywordで同一キーワードの使用箇所検索
- **47-54行目**: z/edit->でキーワードノードを置換
- **55-56行目**: 複数使用箇所の場合にユーザー確認

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

```
call-command (command.clj)
    │
    └─ run-command :cycle-keyword-auto-resolve (command.clj:161-162)
           │
           └─ f.cycle-keyword/cycle-keyword-auto-resolve (cycle_keyword.clj:44-65)
                  │
                  ├─ cycle-keyword-auto-resolve-status (cycle_keyword.clj:12-33)
                  │      ├─ edit/find-namespace
                  │      └─ n/keyword-node?
                  │
                  ├─ q/find-keyword-usages-by-keyword (queries.clj)
                  │
                  ├─ ask-to-replace-all-ns-changes (cycle_keyword.clj:35-42)
                  │      └─ producer/show-message-request
                  │
                  └─ z/edit-> z/replace n/keyword-node
```

### データフロー図

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

LSPリクエスト ───▶ zloc取得 ───▶ status判定 ───▶ 使用箇所検索 ───▶ キーワード変換 ───▶ TextEdit
(uri, pos)              │              │
                        └─ NS取得      └─ ユーザー確認（複数箇所時）
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cycle_keyword.clj | `lib/src/clojure_lsp/feature/cycle_keyword.clj` | ソース | キーワード変換処理の実装 |
| command.clj | `lib/src/clojure_lsp/feature/command.clj` | ソース | コマンドディスパッチ |
| code_actions.clj | `lib/src/clojure_lsp/feature/code_actions.clj` | ソース | コードアクションUI生成 |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | キーワード使用箇所の検索 |
| producer.clj | `lib/src/clojure_lsp/producer.clj` | ソース | ユーザー確認ダイアログ表示 |
| cycle_keyword_test.clj | `lib/test/clojure_lsp/feature/cycle_keyword_test.clj` | テスト | キーワード変換のテスト |
