# 機能設計書 73-診断取得

## 概要

本ドキュメントは、clojure-lsp の API として提供される `diagnostics` 関数の機能設計を記述する。この関数はプロジェクト内の全ての診断情報（警告、エラー、情報）を取得する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Clojure プロジェクトのコード品質を維持するため、静的解析による問題の早期発見が重要である。この機能は clj-kondo による標準的な lint チェックに加え、clojure-lsp 独自のカスタム linter（未使用パブリック変数検出等）の結果を統合して提供する。

**機能の利用シーン**：CI/CD パイプラインでのコード品質チェック、IDE 外でのバッチ処理での lint 実行、品質レポート生成などで利用される。

**主要な処理内容**：
1. プロジェクトの解析（未解析の場合）
2. 対象名前空間/ファイルの特定
3. clj-kondo 診断の取得
4. カスタム linter 診断の取得（unused-public-var 等）
5. 診断結果の集約と返却

**関連システム・外部連携**：clj-kondo（静的解析）、カスタム linter API。

**権限による制御**：呼び出し元プロセスのファイルシステム権限に依存。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | 該当なし | 該当なし | 本プロジェクトは LSP サーバー実装であり UI 画面は存在しない |

## 機能種別

データ取得 / 計算処理 / レポート出力

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| :project-root | java.io.File | No | プロジェクトルートディレクトリ | nil または存在する File |
| :namespace | Collection of Symbols | No | 対象名前空間のコレクション | nil または coll? |
| :filenames | Collection of Files | No | 対象ファイルのコレクション | nil または coll? |
| :ns-exclude-regex | Pattern | No | 除外する名前空間の正規表現 | nil または Pattern |
| :output | Map | No | 出力設定 | :canonical-paths (boolean)、:format (:edn/:json) |
| :settings | Map | No | clojure-lsp 設定マップ | nil または map? |

### 入力データソース

- ファイルシステム（プロジェクトソースファイル）
- clj-kondo 解析結果
- カスタム linter 結果

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| :result-code | Integer | 0: 診断なし/情報のみ、2: 警告あり、3: エラーあり |
| :message-fn | Function | 結果を文字列化する関数 |
| :diagnostics | Map | URI をキー、診断リストを値とするマップ |

### 出力先

- 戻り値として返却
- message-fn 実行時に標準出力

## 処理フロー

### 処理シーケンス

```
1. パラメータバリデーション
   └─ :project-root、:namespace、:filenames の事前条件チェック
2. プロジェクト解析
   └─ project-and-shallow-analysis で解析（未解析の場合）
3. 対象 URI の特定
   └─ namespace/filenames から URI リストを生成
4. 診断の取得
   └─ 各 URI に対して f.diagnostic/find-diagnostics を実行
5. 結果の集約
   └─ URI ごとに診断をグループ化
6. 結果コードの決定
   └─ severity に基づいて result-code を決定
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{パラメータ有効?}
    B -->|No| C[AssertionError]
    B -->|Yes| D[API セットアップ]
    D --> E[プロジェクト解析]
    E --> F[対象 URI 特定]
    F --> G[各 URI の診断取得]
    G --> H{診断あり?}
    H -->|No| I[result-code: 0]
    H -->|Yes| J{エラーあり?}
    J -->|Yes| K[result-code: 3]
    J -->|No| L{警告あり?}
    L -->|Yes| M[result-code: 2]
    L -->|No| I
    I --> N[結果返却]
    K --> N
    M --> N
    N --> O[終了]
    C --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-1 | 結果コード決定 | severity 1 (error) があれば 3、severity 2 (warning) があれば 2、それ以外は 0 | 常時 |
| BR-73-2 | 名前空間フィルタ | :namespace 指定時は該当名前空間のみ対象 | :namespace が指定された場合 |
| BR-73-3 | 除外フィルタ | :ns-exclude-regex にマッチする名前空間は除外 | :ns-exclude-regex が指定された場合 |
| BR-73-4 | 浅い解析 | project-and-shallow-analysis タイプで解析 | 常時 |

### 計算ロジック

Severity レベル：
- 1: Error（エラー）
- 2: Warning（警告）
- 3: Information（情報）
- 4: Hint（ヒント）

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 該当なし | 該当なし | 該当なし | RDB は使用しない |

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

atom によるインメモリデータベースから診断情報を取得。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| AssertionError | バリデーションエラー | パラメータ不正 | 有効なパラメータを渡す |

### リトライ仕様

リトライ機構は実装されていない。

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

RDB を使用しないため、トランザクション管理は不要。

## パフォーマンス要件

- 診断取得は pmap による並列処理で実行
- プロジェクトサイズに依存

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

- ファイルシステムアクセスはプロセス権限に依存

## 備考

- clj-kondo の lint 結果とカスタム linter の結果を統合
- unused-public-var はデフォルトで有効

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | coercer.cljc | `lib/src/lsp4clj/coercer.cljc` | 診断データ構造の定義 |

**読解のコツ**: LSP プロトコルの Diagnostic 構造体を理解する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | api.clj | `lib/src/clojure_lsp/api.clj` | diagnostics 関数定義 |

**主要処理フロー**:
1. **128-168行目**: `diagnostics` 関数定義、docstring と事前条件

#### Step 3: 内部 API 実装を理解する

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

**主要処理フロー**:
- **344-354行目**: diagnostics-by-uri で URI ごとの診断取得
- **355-372行目**: diagnostics* で結果コード決定と返却

#### Step 4: 診断機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | diagnostics.clj | `lib/src/clojure_lsp/feature/diagnostics.clj` | find-diagnostics 実装 |

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

```
api/diagnostics
    |
    +-- internal-api/diagnostics
            |
            +-- build-components
            |
            +-- diagnostics*
                    |
                    +-- setup-api!
                    |
                    +-- setup-project-and-clojure-only-deps-analysis!
                    |
                    +-- diagnostics-by-uri
                            |
                            +-- options->uris
                            |
                            +-- f.diagnostic/find-diagnostics
```

### データフロー図

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

{:namespace [...]}       api/diagnostics                     {:result-code 0/2/3
 :filenames [...]}       |                                    :message-fn fn
        |                v                                    :diagnostics {...}}
        +-------------> options->uris                         |
                        |                                     |
                        v                                     |
                   diagnostics-by-uri                         |
                        |                                     |
                        v                                     |
                   f.diagnostic/find-diagnostics              |
                        |                                     |
                        v                                     |
                   {uri: [diag1, diag2, ...]} -------------> 結果返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| api.clj | `lib/src/clojure_lsp/api.clj` | ソース | 公開 API 定義 |
| internal_api.clj | `lib/src/clojure_lsp/internal_api.clj` | ソース | 内部実装 |
| diagnostics.clj | `lib/src/clojure_lsp/feature/diagnostics.clj` | ソース | 診断機能 |
| api_test.clj | `lib/test/clojure_lsp/api_test.clj` | テスト | API テスト |
