# 機能設計書 38-import追加提案

## 概要

本ドキュメントは、Clojure LSPの「import追加提案」機能の設計仕様を記載する。この機能は、未解決のJavaクラス参照に対して、適切なimport句の追加を提案・実行するクイックフィックス操作を提供する。

### 本機能の処理概要

**業務上の目的・背景**：ClojureからJavaクラスを使用する際、クラス名を正しくimportする必要がある。特にプロジェクト内で定義されたJavaクラスや、JDKの標準クラスを使用する際に、正しいパッケージ名を調べてimportするのは手間がかかる。本機能は、未解決のクラス名からパッケージを推測し、import句の追加を提案することで、Java連携を効率化する。

**機能の利用シーン**：この機能は以下の場面で利用される：
- 新しいJavaクラスを使用する際のimport句の自動追加
- 未解決クラス名の診断に対するクイックフィックス
- プロジェクト内で定義されたJavaクラスの参照

**主要な処理内容**：
1. 未解決シンボルがJavaクラス名（大文字始まり）か判定
2. clj-kondoデータベースからクラス定義を検索
3. 候補となるimportを生成
4. ns宣言にimport句を追加する編集を生成

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エディタ画面 | 主画面 | クイックフィックスメニューから「Add import」を選択 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | string | Yes | 対象ファイルのURI | 有効なファイルURIであること |
| line | number | Yes | カーソル行（0-indexed） | 0以上の整数 |
| character | number | Yes | カーソル列（0-indexed） | 0以上の整数 |
| import-name | string | No | インポートするクラスの完全修飾名 | 有効なJavaクラス名 |

### 入力データソース

- エディタからのLSP `textDocument/codeAction` リクエスト
- コマンド名: `add-missing-import`

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| edits | vector | ns宣言へのimport追加編集 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. クラス名の特定
   └─ カーソル位置のシンボルを取得
   └─ 大文字始まりか確認

2. クラス定義の検索
   └─ xf-all-java-definitions-by-class-name でクラス定義を検索
   └─ 使用頻度でソート

3. パッケージとクラスの分離
   └─ 完全修飾名からパッケージ名とクラス名を抽出

4. ns宣言への編集
   └─ import句の追加
   └─ 既存のimportがある場合はそれを拡張
```

### フローチャート

```mermaid
flowchart TD
    A[クイックフィックス要求] --> B[シンボル取得]
    B --> C{大文字始まり?}
    C -->|No| D[nil返却]
    C -->|Yes| E[クラス定義検索]
    E --> F{候補あり?}
    F -->|No| D
    F -->|Yes| G[パッケージ抽出]
    G --> H[ns編集生成]
    H --> I[編集返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-38-01 | クラス名判定 | 大文字始まりのシンボルをJavaクラス名と判定 | シンボル解析時 |
| BR-38-02 | ドット呼び出し | `ClassName.`形式のメソッド呼び出しに対応 | ドットで終わるシンボル |
| BR-38-03 | 使用頻度ソート | プロジェクト内で多く使用されているクラスを優先 | 複数候補がある場合 |
| BR-38-04 | パッケージマージ | 既存のパッケージimportがある場合はクラスを追加 | 既存import存在時 |

### 計算ロジック

**クラス名の抽出**：
```clojure
;; 完全修飾名からパッケージとクラスを分離
(let [split (string/split import-name #"\.")
      package-name (string/join "." (drop-last split))
      class-name (last split)])
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 参照 | :analysis | SELECT | Javaクラス定義を検索 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 候補なし | 該当するクラスが見つからない | 空の結果を返却 |

### リトライ仕様

リトライは行わない。

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

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

## パフォーマンス要件

- 応答時間: 100ms以内

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

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

## 備考

- JDKクラス（java.*パッケージ）はclj-kondoの解析対象に含まれている必要がある

---

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

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

### 推奨読解順序

#### Step 1: クラス名の特定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | add_missing_libspec.clj | `lib/src/clojure_lsp/feature/add_missing_libspec.clj` | find-class-name, find-missing-imports |

**主要処理フロー**:
- **92-109行目**: `find-class-name` - シンボルからクラス名を抽出
- **111-117行目**: `find-missing-imports` - クラス定義を検索

#### Step 2: import追加を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | add_missing_libspec.clj | `lib/src/clojure_lsp/feature/add_missing_libspec.clj` | add-missing-import |

**主要処理フロー**:
- **360-369行目**: `add-missing-import` - import追加のメイン処理
- **137-198行目**: `modified-existing-libform` - 既存importの拡張

#### Step 3: ns編集を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | add_missing_libspec.clj | `lib/src/clojure_lsp/feature/add_missing_libspec.clj` | add-to-namespace* |

**主要処理フロー**:
- **200-251行目**: `add-to-namespace*` - ns宣言へのimport追加

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

```
textDocument/codeAction (LSP)
    │
    └─ code-actions/all
           │
           ├─ find-missing-imports
           │     ├─ find-class-name
           │     └─ q/xf-all-java-definitions-by-class-name
           │
           └─ missing-import-actions (コードアクション生成)
                  │
                  └─ [ユーザー選択]
                         │
                         └─ command/run-command :add-missing-import
                               │
                               └─ add-missing-import
                                     ├─ string/split (パッケージ抽出)
                                     └─ add-to-namespace
```

### データフロー図

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

未解決シンボル      ──▶  find-class-name            ──▶  クラス名
                         (クラス名抽出)

クラス名           ──▶  find-missing-imports        ──▶  [{:class, :usages-count}]
                         (クラス検索)

候補              ──▶  missing-import-actions      ──▶  コードアクションリスト
                         (アクション生成)

選択された候補     ──▶  add-missing-import          ──▶  [{:range, :loc}]
                         (ns編集生成)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| add_missing_libspec.clj | `lib/src/clojure_lsp/feature/add_missing_libspec.clj` | ソース | import追加のコアロジック |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | Javaクラス検索 |
| code_actions.clj | `lib/src/clojure_lsp/feature/code_actions.clj` | ソース | コードアクション生成 |
| command.clj | `lib/src/clojure_lsp/feature/command.clj` | ソース | コマンドディスパッチ |
