# 機能設計書 44-clj-kondo統合

## 概要

本ドキュメントは、clojure-lspの「clj-kondo統合」機能の設計を詳細に記載する。この機能は、clj-kondoによる静的解析結果をLSP診断として表示する中核機能である。

### 本機能の処理概要

**業務上の目的・背景**：Clojure開発において、コンパイル前にコードの問題を検出することは生産性向上に不可欠である。clj-kondoはClojure/ClojureScript向けの高速な静的解析ツールであり、未解決シンボル、型不一致、非推奨API使用などを検出する。clojure-lspはclj-kondoを内蔵し、その解析結果をリアルタイムでエディタに表示する。

**機能の利用シーン**：開発者がコードを編集するたびに自動的に実行され、問題のある箇所にエディタ上で警告やエラーを表示する。ファイル保存時やプロジェクト読み込み時にも全体解析が実行される。

**主要な処理内容**：
1. ファイル変更時にclj-kondo解析を実行
2. 解析結果（findings）を正規化
3. LSP診断形式に変換
4. エディタに診断を発行

**関連システム・外部連携**：clj-kondoライブラリ、LSP診断プロトコル。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | エディタ | 主画面 | 診断結果の表示（波線、問題パネル等） |

## 機能種別

静的解析 / 診断

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| uri | String | Yes | 解析対象ファイルURI | 有効なファイルURI |
| text | String | Yes | ファイルの内容 | N/A |

### 入力データソース

- エディタから送信されるファイル内容（didOpen, didChange イベント）
- プロジェクトのclj-kondo設定（.clj-kondo/config.edn）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| diagnostics | Array | LSP診断オブジェクトの配列 |
| diagnostics[].range | Range | 問題箇所の範囲 |
| diagnostics[].severity | Number | 重大度（1:Error, 2:Warning, 3:Information, 4:Hint） |
| diagnostics[].code | String | 診断コード |
| diagnostics[].source | String | "clj-kondo" |
| diagnostics[].message | String | 診断メッセージ |
| diagnostics[].tags | Array | タグ（1:Unnecessary, 2:Deprecated） |

### 出力先

- LSP textDocument/publishDiagnostics 通知

## 処理フロー

### 処理シーケンス

```
1. ファイル変更イベント受信
   └─ didOpen, didChange, didChangeWatchedFiles
2. clj-kondo解析実行
   └─ kondo/run-kondo-on-text! または run-kondo-on-paths!
   └─ 設定ファイル、キャッシュを使用
3. 解析結果の正規化
   └─ normalize 関数で findings を URI 別にグループ化
   └─ 要素にURIとbucketを付加
4. データベース更新
   └─ db-with-results で :diagnostics :clj-kondo に格納
5. 診断変換
   └─ kondo-finding->diagnostic で LSP 形式に変換
6. 診断発行
   └─ publish-diagnostics! で textDocument/publishDiagnostics 送信
```

### フローチャート

```mermaid
flowchart TD
    A[ファイル変更] --> B{ignore-path?}
    B -->|はい| C[空の診断返却]
    B -->|いいえ| D[clj-kondo実行]
    D --> E[findings取得]
    E --> F[正規化]
    F --> G[DB更新]
    G --> H[LSP形式変換]
    H --> I[診断発行]
    I --> J[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | レベルフィルタ | :linters :clj-kondo :level が :off なら診断を出力しない | 常時 |
| BR-02 | 名前空間除外 | :ns-exclude-regex にマッチする名前空間は除外 | 設定時 |
| BR-03 | タグ付与 | unnecessary系診断にはtag=1、deprecated系にはtag=2 | 常時 |
| BR-04 | ソース識別 | clojure-lsp/unused-public-varは"clojure-lsp"、それ以外は"clj-kondo" | 常時 |

### 計算ロジック

診断タイプとタグの対応：
```clojure
(def diagnostic-types-of-unnecessary-type
  #{:clojure-lsp/unused-public-var
    :redefined-var
    :redundant-do
    :redundant-expression
    :redundant-let
    :unused-binding
    :unreachable-code
    :unused-import
    :unused-namespace
    :unused-private-var
    :unused-referred-var})

(def deprecated-diagnostic-types
  #{:deprecated-var})
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 診断格納 | :diagnostics :clj-kondo | UPDATE | URI毎のfindings配列を格納 |
| 解析結果格納 | :analysis | MERGE | clj-kondoの解析結果をマージ |

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

#### :diagnostics :clj-kondo

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| UPDATE | uri -> [findings] | clj-kondoのfindings配列 | URI毎に上書き |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | 解析エラー | clj-kondo実行時例外 | エラーログ出力、空の結果返却 |

### リトライ仕様

リトライなし（次回ファイル変更時に再実行）

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

アトム操作による排他制御（swap!）。

## パフォーマンス要件

- 単一ファイル解析: 100ms以内（通常）
- プロジェクト全体解析: バッチサイズ120ファイルで分割実行
- キャッシュ使用による高速化

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

- clj-kondo設定ファイルの検証（任意コード実行防止）

## 備考

- clj-kondoバージョンは `CLJ_KONDO_VERSION` リソースファイルで管理
- 設定ファイルは .clj-kondo/config.edn または ~/.config/clj-kondo/config.edn

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | kondo.clj | `lib/src/clojure_lsp/kondo.clj` | clj-kondoの結果構造とnormalize関数を理解 |
| 1-2 | diagnostics.clj | `lib/src/clojure_lsp/feature/diagnostics.clj` | LSP診断形式への変換を理解 |

**読解のコツ**: clj-kondoはfindingsとanalysisの2種類のデータを返す。findingsが診断、analysisがシンボル情報。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | file_management.clj | `lib/src/clojure_lsp/feature/file_management.clj` | did-open, did-change がclj-kondo解析をトリガー |

**主要処理フロー**:
- ファイル変更 -> analyze-changes -> kondo/run-kondo-on-text!

#### Step 3: clj-kondo実行を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | kondo.clj | `lib/src/clojure_lsp/kondo.clj` | run-kondo-on-text!, run-kondo-on-paths! |

**主要処理フロー**:
- **340-366行目**: `config-for-single-file` - 単一ファイル解析設定
- **427-436行目**: `run-kondo-on-text!` - stdin経由の解析
- **379-390行目**: `run-kondo-on-paths!` - パス指定解析
- **200-248行目**: `normalize` - 結果の正規化

#### Step 4: 診断変換を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | diagnostics.clj | `lib/src/clojure_lsp/feature/diagnostics.clj` | kondo-finding->diagnostic, find-diagnostics |

**主要処理フロー**:
- **36-64行目**: `kondo-finding->diagnostic` - LSP形式への変換
- **78-87行目**: `kondo-findings->diagnostics` - URI毎の診断取得
- **115-129行目**: `find-diagnostics` - 全診断源の統合

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

```
handlers/did-open, did-change
    │
    └─ f.file-management/analyze-changes
           │
           └─ kondo/run-kondo-on-text!
                  │
                  ├─ config-for-single-file (設定生成)
                  ├─ run-kondo! (clj-kondo実行)
                  └─ normalize-for-file (結果正規化)
                         │
                         └─ normalize
                                │
                                ├─ normalize-analysis
                                └─ findings->analysis

kondo/db-with-results
    │
    ├─ db-with-analysis (解析結果格納)
    └─ update :diagnostics :clj-kondo (診断格納)

f.diagnostic/publish-diagnostics!
    │
    ├─ find-diagnostics
    │      └─ kondo-findings->diagnostics
    │             └─ kondo-finding->diagnostic
    └─ diagnostics-chan へ送信
```

### データフロー図

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

text ─────────────▶ with-in-str ───▶ kondo/run!
                           │
                           ▼
                 {:findings [...], :analysis {...}}
                           │
                           ▼
                    normalize
                           │
                    ┌──────┴──────┐
                    │             │
               findings      analysis
                    │             │
                    ▼             ▼
          :diagnostics      :analysis
          :clj-kondo        (merge)
                    │
                    ▼
    kondo-finding->diagnostic
                    │
                    ▼
        LSP Diagnostic ───▶ textDocument/publishDiagnostics
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| kondo.clj | `lib/src/clojure_lsp/kondo.clj` | ソース | clj-kondo実行と結果正規化 |
| diagnostics.clj | `lib/src/clojure_lsp/feature/diagnostics.clj` | ソース | 診断変換と発行 |
| file_management.clj | `lib/src/clojure_lsp/feature/file_management.clj` | ソース | ファイル変更イベント処理 |
| db.clj | `lib/src/clojure_lsp/db.clj` | ソース | データベース構造定義 |
| settings.clj | `lib/src/clojure_lsp/settings.clj` | ソース | 設定管理 |
