# clojure-lsp コードリーディングガイドライン

## はじめに

このガイドラインは、clojure-lspのコードベースを効率的に理解するための手引きです。
Clojure言語に精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- 他言語からの経験者
- コードレビューを行う担当者

---

## 1. 言語基礎

> このセクションでは、Clojureの基本構文と概念を解説します。

### 1.1 プログラム構造

Clojureは関数型プログラミング言語であり、JVM上で動作するLisp方言です。コードは**S式（S-expression）**で記述され、括弧で囲まれた式が基本単位となります。

**名前空間（namespace）の宣言:**

```clojure
;; ファイル: lib/src/clojure_lsp/handlers.clj:1-36
(ns clojure-lsp.handlers
  (:require
   [cheshire.core :as json]
   [clojure-lsp.db :as db]
   [clojure-lsp.dep-graph :as dep-graph]
   [clojure-lsp.feature.call-hierarchy :as f.call-hierarchy]
   [clojure-lsp.feature.clojuredocs :as f.clojuredocs]
   [clojure-lsp.queries :as q]
   [clojure.core.async :as async]))
```

**ポイント:**
- `ns` マクロで名前空間を定義
- `:require` で他の名前空間を読み込み
- `:as` でエイリアス（短縮名）を設定
- ファイルパスと名前空間は対応（`_` はファイル名で `-` に対応）

### 1.2 データ型と変数

Clojureの主要なデータ型:

| データ型 | 構文 | 例 |
|---------|------|-----|
| キーワード | `:keyword` | `:uri`, `:name`, `:bucket` |
| シンボル | `symbol` | `db*`, `zloc`, `handler` |
| ベクター | `[a b c]` | `[:clj :cljs :cljc]` |
| マップ | `{:key val}` | `{:uri "file://..." :name 'foo}` |
| セット | `#{a b}` | `#{:clj :cljs}` |
| リスト | `(a b c)` | `(+ 1 2)` |

**実際の使用例:**

```clojure
;; ファイル: lib/src/clojure_lsp/db.clj:15-21
(def initial-db {:documents {}
                 :dep-graph {}
                 :diagnostics {:clj-kondo nil
                               :clj-depend nil
                               :built-in nil
                               :custom nil}})
```

**変数定義のパターン:**
- `def` - 定数・グローバル変数の定義
- `defonce` - 一度だけ定義（再評価時に値を保持）
- `let` - ローカル変数の束縛
- `atom` - 可変状態を持つ参照型（名前の末尾に `*` を付ける慣例: `db*`）

### 1.3 制御構造

**条件分岐:**

```clojure
;; ファイル: cli/src/clojure_lsp/main.clj:156-180
(cond
  pod?
  {:action "pod" :options options}

  (:help options)
  {:exit-message (help summary) :ok? true}

  (:version options)
  {:exit-message (version) :ok? true}

  errors
  {:exit-message (error-msg errors)}

  :else
  {:exit-message (help summary)})
```

**制御構造の種類:**
- `if` - 二分岐
- `when` - 条件が真の時のみ実行
- `cond` - 複数条件分岐
- `case` - 値によるスイッチ
- `condp` - 述語を使った条件分岐

**ループとイテレーション:**

```clojure
;; ファイル: lib/src/clojure_lsp/handlers.clj:63-96
(loop [immediate? true
       backoff backoff-start
       desired-versions versions]
  (let [db @db*]
    (if-let [processing-versions (seq desired-versions)]
      (do
        (Thread/sleep (long backoff))
        (recur false (min backoff-max (* backoff-mult backoff)) processing-versions))
      {:delay/outcome :immediate})))
```

### 1.4 関数/メソッド定義

**関数定義の基本形:**

```clojure
;; ファイル: lib/src/clojure_lsp/shared.clj:42-57
(defn fast=
  "Faster `=` comparassion for string, symbols and keywords."
  [a b]
  (cond
    (instance? clojure.lang.Symbol b)
    (.equals ^clojure.lang.Symbol b a)

    (instance? String b)
    (.equals ^String b a)

    (instance? clojure.lang.Keyword a)
    (identical? a b)

    :else
    (= a b)))
```

**関数定義のパターン:**
- `defn` - 公開関数
- `defn-` - プライベート関数（`^:private` メタデータ）
- `fn` - 無名関数
- `#()` - 短縮形の無名関数

**マルチメソッド（ポリモーフィズム）:**

```clojure
;; ファイル: lib/src/clojure_lsp/queries.clj:254-256
(defmulti find-definition
  (fn [_db element]
    (:bucket element)))

(defmethod find-definition :var-usages
  [db var-usage]
  ;; 実装
  )
```

### 1.5 モジュール/インポート

**require の形式:**

```clojure
;; ファイル: cli/src/clojure_lsp/server.clj:1-30
(ns clojure-lsp.server
  (:require
   [clojure-lsp.clojure-coercer :as clojure-coercer]
   [clojure-lsp.db :as db]
   [clojure-lsp.handlers :as handler]
   [clojure.core.async :as async]
   [promesa.core :as p])
  (:import
   [io.opentelemetry.sdk.autoconfigure AutoConfiguredOpenTelemetrySdk]
   [java.util.function Function]))
```

**インポートの種類:**
- `:require` - Clojureライブラリの読み込み
- `:import` - Javaクラスのインポート
- `:refer` - 特定の関数を名前空間なしで使用可能に

---

## 2. プロジェクト固有の概念

> このセクションでは、clojure-lsp特有の概念を解説します。

### 2.1 フレームワーク固有の概念

#### LSP（Language Server Protocol）

clojure-lspは[Language Server Protocol](https://microsoft.github.io/language-server-protocol/)を実装したサーバーです。主要な概念:

- **Request/Response**: クライアントからの要求に応答
- **Notification**: 一方向の通知（didOpen, didChangeなど）
- **capabilities**: サーバー/クライアントの機能宣言

**実装例:**

```clojure
;; ファイル: cli/src/clojure_lsp/server.clj:254-258
(defmethod jsonrpc.server/receive-notification "textDocument/didOpen" [_ components params]
  (handler/did-open components (normalize-doc-uri params)))

(defmethod jsonrpc.server/receive-notification "textDocument/didChange" [_ components params]
  (handler/did-change components (normalize-doc-uri params)))
```

#### clj-kondo統合

静的解析にclj-kondoを使用:

```clojure
;; ファイル: lib/src/clojure_lsp/kondo.clj:58-69
(defn db-with-analysis
  "Update `db` with normalized kondo analysis."
  [db {:keys [analysis external?]}]
  (-> db
      (update :analysis merge analysis)
      (dep-graph/refresh-analysis (select-keys (:analysis db) (keys analysis))
                                  analysis
                                  (not external?))))
```

### 2.2 プロジェクト独自のパターン

#### db* アトムパターン

アプリケーション状態をアトムで管理:

```clojure
;; ファイル: lib/src/clojure_lsp/db.clj:21
(defonce db* (atom initial-db))
```

全ての状態は `db*` に集約され、以下の構造を持ちます:

| キー | 説明 |
|-----|------|
| `:documents` | 開いているドキュメントの情報 |
| `:analysis` | clj-kondoの解析結果 |
| `:dep-graph` | 名前空間の依存グラフ |
| `:diagnostics` | 診断情報（エラー、警告） |
| `:settings` | 設定値 |
| `:project-root-uri` | プロジェクトルートのURI |

#### Components パターン

依存性注入のためのコンポーネントマップ:

```clojure
;; ファイル: cli/src/clojure_lsp/server.clj:658-665
(let [components {:db* db*
                  :logger timbre-logger
                  :producer producer
                  :server server
                  :current-changes-chan (async/chan 1)
                  :diagnostics-chan (async/chan 1)
                  :watched-files-chan (async/chan 1)
                  :edits-chan (async/chan 1)}]
  ...)
```

#### スレッドマクロ

データ変換のパイプライン:

```clojure
;; ファイル: cli/src/clojure_lsp/server.clj:271-276
(->> params
     normalize-doc-uri
     (handler/references components)
     (conform-or-log ::coercer/locations-or-error)
     eventually)
```

- `->` (thread-first): 結果を次の式の第1引数に
- `->>` (thread-last): 結果を次の式の最後の引数に
- `some->`: nilなら中断
- `cond->`: 条件付きスレッド

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `feature/*.clj` | LSP機能の実装 | `feature/completion.clj`, `feature/rename.clj` |
| `refactor/*.clj` | リファクタリング機能 | `refactor/transform.clj`, `refactor/edit.clj` |
| `*_test.clj` | テストファイル | `server_test.clj`, `main_test.clj` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `db*` | アトム（可変参照） | `db*`, `cache*` |
| `f.xxx` | feature名前空間のエイリアス | `f.completion`, `f.rename` |
| `r.xxx` | refactor名前空間のエイリアス | `r.transform` |
| `^:private` | プライベート関数 | `(defn ^:private helper ...)` |
| `!` サフィックス | 副作用を持つ関数 | `clean-ns!`, `format!`, `rename!` |
| `?` サフィックス | 述語（真偽値を返す） | `db-exists?`, `can-thread?` |
| `-` プレフィックス | プライベート関数（代替表記） | `(defn- my-fn ...)` |
| `xf-` プレフィックス | トランスデューサー | `xf-analysis->var-definitions` |

### 3.3 名前空間エイリアス規則

```clojure
;; 標準パターン
[clojure-lsp.feature.completion :as f.completion]
[clojure-lsp.feature.rename :as f.rename]
[clojure-lsp.refactor.transform :as r.transform]
[clojure-lsp.queries :as q]
[clojure-lsp.shared :as shared]
[clojure.string :as string]
[medley.core :as medley]
[rewrite-clj.zip :as z]
```

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
clojure-lsp/
├── cli/                          # CLIアプリケーション
│   ├── src/clojure_lsp/
│   │   ├── main.clj             # エントリーポイント
│   │   ├── server.clj           # LSPサーバー実装
│   │   ├── nrepl.clj            # nREPL統合
│   │   └── clojure_coercer.clj  # Clojure用型変換
│   ├── test/                    # CLIのユニットテスト
│   └── integration-test/        # 統合テスト
├── lib/                          # コアライブラリ
│   ├── src/clojure_lsp/
│   │   ├── api.clj              # 公開API
│   │   ├── internal_api.clj     # 内部API
│   │   ├── handlers.clj         # LSPリクエストハンドラ
│   │   ├── queries.clj          # 解析データクエリ
│   │   ├── db.clj               # データベース/状態管理
│   │   ├── kondo.clj            # clj-kondo統合
│   │   ├── shared.clj           # 共通ユーティリティ
│   │   ├── feature/             # LSP機能実装
│   │   │   ├── completion.clj
│   │   │   ├── rename.clj
│   │   │   ├── hover.clj
│   │   │   └── ...
│   │   └── refactor/            # リファクタリング機能
│   │       ├── transform.clj
│   │       └── edit.clj
│   └── test/                    # ライブラリのテスト
├── test-helper/                  # テスト用ヘルパー
├── scripts/                      # ビルド・リリーススクリプト
├── docs/                         # ドキュメント
├── deps.edn                      # プロジェクト依存関係
├── bb.edn                        # Babashkaタスク定義
└── README.md
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `cli/src` | CLIエントリーポイントとサーバー実装 | `main.clj`, `server.clj` |
| `lib/src` | コアライブラリ機能 | `api.clj`, `handlers.clj`, `queries.clj` |
| `lib/src/feature` | 個別のLSP機能 | `completion.clj`, `rename.clj`, `hover.clj` |
| `lib/src/refactor` | コード変換ロジック | `transform.clj`, `edit.clj` |
| `cli/integration-test` | E2E統合テスト | `integration/` 配下 |
| `scripts` | CI/CDスクリプト | `make.clj` |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

clojure-lspはレイヤードアーキテクチャを採用しています:

```
┌─────────────────────────────────────────────────────────────┐
│                      CLI Layer (cli/)                       │
│  main.clj → server.clj → [LSP Protocol Handler]            │
├─────────────────────────────────────────────────────────────┤
│                   Handler Layer (lib/handlers.clj)          │
│  LSPリクエストを受け取り、Feature層に委譲                     │
├─────────────────────────────────────────────────────────────┤
│                   Feature Layer (lib/feature/)              │
│  completion.clj | rename.clj | hover.clj | code_actions.clj │
├─────────────────────────────────────────────────────────────┤
│                   Query Layer (lib/queries.clj)             │
│  解析データへの問い合わせ                                     │
├─────────────────────────────────────────────────────────────┤
│                   Data Layer (lib/db.clj, lib/kondo.clj)    │
│  状態管理、clj-kondo解析                                     │
└─────────────────────────────────────────────────────────────┘
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| CLI | エントリーポイント、LSPプロトコル処理 | `cli/src/clojure_lsp/main.clj`, `server.clj` |
| Handler | リクエストルーティング、応答生成 | `lib/src/clojure_lsp/handlers.clj` |
| Feature | 個別機能の実装 | `lib/src/clojure_lsp/feature/*.clj` |
| Query | 解析データのクエリ | `lib/src/clojure_lsp/queries.clj` |
| Data | 状態管理、解析エンジン | `lib/src/clojure_lsp/db.clj`, `kondo.clj` |

### 5.3 データフロー

```
[Editor/Client]
      │
      ▼ LSP Request (JSON-RPC)
┌─────────────────┐
│   server.clj    │ ← LSPメッセージのデシリアライズ
└────────┬────────┘
         │
         ▼ Clojureデータ構造
┌─────────────────┐
│  handlers.clj   │ ← リクエストタイプに応じた処理
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│  feature/*.clj  │ ← 具体的な機能実装
└────────┬────────┘
         │
         ▼ クエリ
┌─────────────────┐
│   queries.clj   │ ← 解析データの検索
└────────┬────────┘
         │
         ▼ 解析データ
┌─────────────────┐
│   db* (atom)    │ ← 全状態を保持
└─────────────────┘
```

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

**CLIエントリーポイント:**

```clojure
;; ファイル: cli/src/clojure_lsp/main.clj:250-252
(defn -main
  [& args]
  (run args))
```

**サーバー起動フロー:**

```clojure
;; ファイル: cli/src/clojure_lsp/main.clj:194-198
(defn ^:private handle-action!
  [action options]
  (if (= "listen" action)
    (let [finished @(server/run-lsp-io-server! (:trace-level options) (:log-path options))]
      {:result-code (if (= :done finished) 0 1)})
    ...))
```

### 6.2 ビジネスロジック

**機能実装の例（rename）:**

```clojure
;; ファイル: lib/src/clojure_lsp/feature/rename.clj:283-310
(defn rename-element [new-name db element source]
  (let [{:keys [error] :as result} (rename-status db element)]
    (if error
      result
      (let [{:keys [references definition source-path]} result
            replacement (string/replace new-name #".*/([^/]*)$" "$1")
            changes (rename-changes element definition references replacement new-name db)
            doc-changes (->> changes
                             (group-by :text-document)
                             (map (fn [[text-document edits]]
                                    {:text-document text-document
                                     :edits (mapv #(dissoc % :text-document) edits)})))]
        ...))))
```

### 6.3 データアクセス

**解析データへのクエリ:**

```clojure
;; ファイル: lib/src/clojure_lsp/queries.clj:643-648
(defn find-definition-from-cursor [db uri row col]
  (try
    (when-let [element (find-element-under-cursor db uri row col)]
      (find-definition db element))
    (catch Throwable e
      (logger/error e "can't find definition"))))
```

### 6.4 ユーティリティ/共通機能

**共通ユーティリティ関数:**

```clojure
;; ファイル: lib/src/clojure_lsp/shared.clj:59-88
(defn deep-merge
  "Recursively merges maps together."
  ([])
  ([a] a)
  ([a b]
   (when (or a b)
     (letfn [(merge-entry [m e]
               (let [k (key e)
                     v' (val e)]
                 (if (contains? m k)
                   (assoc m k (let [v (get m k)]
                                (cond
                                  (and (map? v) (map? v'))
                                  (deep-merge v v')
                                  ...)))
                   (assoc m k v'))))]
       (reduce merge-entry (or a {}) (seq b))))))
```

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| Threading Macro | データ変換のパイプライン | 高 | 全ファイル |
| Multimethod | バケットによる分岐 | 高 | `queries.clj` |
| Atom State | 可変状態の管理 | 高 | `db.clj`, `server.clj` |
| Channel Pattern | 非同期通信 | 中 | `server.clj`, `handlers.clj` |
| Transducer | 効率的なコレクション変換 | 中 | `queries.clj` |

### 各パターンの詳細

#### パターン1: Threading Macro

**目的:** データ変換のパイプラインを読みやすく表現

**実装例:**
```clojure
;; ファイル: cli/src/clojure_lsp/server.clj:354-359
(->> params
     normalize-doc-uri
     (handler/definition components)
     (conform-or-log ::coercer/location-or-error)
     eventually)
```

**解説:** `params` を入力として、順番に変換関数を適用し、最終結果を返します。

#### パターン2: Multimethod (bucket分岐)

**目的:** 要素の種類（bucket）に応じて処理を切り替え

**実装例:**
```clojure
;; ファイル: lib/src/clojure_lsp/queries.clj:254-309
(defmulti find-definition
  (fn [_db element]
    (:bucket element)))

(defmethod find-definition :namespace-usages
  [db namespace-usage]
  (find-last-order-by-project-analysis
    (comp xf-analysis->namespace-definitions
          (xf-same-name (:name namespace-usage)))
    (db-with-ns-analysis db (:name namespace-usage))))

(defmethod find-definition :var-usages
  [db var-usage]
  (find-last-order-by-project-analysis
    (comp xf-analysis->var-definitions
          (xf-same-fqn (:to var-usage) (:name var-usage)))
    (db-with-ns-analysis db (:to var-usage))))
```

**解説:** `find-definition` は要素の `:bucket` キーの値によって異なる実装を呼び出します。

#### パターン3: Transducer

**目的:** メモリ効率の良いコレクション変換

**実装例:**
```clojure
;; ファイル: lib/src/clojure_lsp/queries.clj:83-94
(def ^:private xf-analysis->by-bucket (map val))
(defn ^:private xf-by-bucket->bucket-elems [bucket-name]
  (mapcat bucket-name))

(def xf-analysis->var-definitions (xf-analysis->bucket-elems :var-definitions))
(def xf-analysis->var-usages (xf-analysis->bucket-elems :var-usages))
```

**解説:** `xf-` プレフィックスのトランスデューサーを組み合わせて、解析データから必要な要素を抽出します。

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: 「定義へ移動」機能

**概要:** カーソル位置のシンボルの定義元に移動する機能

**処理フロー:**
```
LSP Request → server.clj → handlers.clj → queries.clj → db（解析データ）
```

**詳細な追跡:**

1. **LSPリクエスト受信** (`cli/src/clojure_lsp/server.clj:354-359`)
   ```clojure
   (defmethod jsonrpc.server/receive-request "textDocument/definition" [_ components params]
     (->> params
          normalize-doc-uri
          (handler/definition components)
          (conform-or-log ::coercer/location-or-error)
          eventually))
   ```

2. **ハンドラ処理** (`lib/src/clojure_lsp/handlers.clj:288-294`)
   ```clojure
   (defn definition [{:keys [db* producer]} {:keys [text-document position]}]
     (shared/logging-task
       :lsp/definition
       (let [db @db*
             [row col] (shared/position->row-col position)]
         (when-let [definition (q/find-definition-from-cursor db (:uri text-document) row col)]
           (element->location db producer definition)))))
   ```

3. **クエリ実行** (`lib/src/clojure_lsp/queries.clj:643-648`)
   ```clojure
   (defn find-definition-from-cursor [db uri row col]
     (try
       (when-let [element (find-element-under-cursor db uri row col)]
         (find-definition db element))
       (catch Throwable e
         (logger/error e "can't find definition"))))
   ```

4. **マルチメソッドによる定義検索** (`lib/src/clojure_lsp/queries.clj:272-290`)
   ```clojure
   (defmethod find-definition :var-usages
     [db var-usage]
     (or
       (find-last-order-by-project-analysis
         (comp xf-analysis->var-definitions
               (xf-same-fqn (:to var-usage) (:name var-usage))
               (xf-same-lang var-usage))
         (db-with-ns-analysis db (:to var-usage)))
       ;; フォールバック処理
       ...))
   ```

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリングを確認したか
- [ ] 最終的な出力を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要
2. `docs/features.md` - 機能一覧
3. `docs/capabilities.md` - LSP機能対応状況

#### 特定機能を理解したい場合
1. `docs/features.md` - 機能概要
2. `lib/src/clojure_lsp/feature/{機能名}.clj` - 実装コード
3. `lib/test/clojure_lsp/feature/{機能名}_test.clj` - テストケース

#### 改修作業を行う場合
1. `docs/development.md` - 開発環境セットアップ
2. 対象機能のソースコード
3. `cli/integration-test/` - 統合テスト

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | プロジェクト概要 | 初回参照 |
| `docs/features.md` | 機能一覧と使い方 | 機能理解時 |
| `docs/settings.md` | 設定オプション | 設定変更時 |
| `docs/development.md` | 開発ガイド | 開発開始時 |
| `docs/troubleshooting.md` | トラブルシュート | 問題発生時 |
| `CHANGELOG.md` | 変更履歴 | バージョン確認時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: `db*` の中身を確認するには?
A: REPLで `@clojure-lsp.db/db*` を評価するか、`(clojure.pprint/pprint @db*)` で整形表示できます。nREPL接続が可能な開発環境であれば、ホットリロードも可能です。

#### Q: 特定の機能がどこで実装されているか分からない
A: `lib/src/clojure_lsp/feature/` ディレクトリを確認してください。LSP機能名と対応したファイル名になっています。また、`handlers.clj` でリクエストタイプと呼び出し先の対応が分かります。

#### Q: マルチメソッドの実装を全て確認したい
A: `grep -r "defmethod find-definition" lib/src/` のように検索するか、エディタの「実装へ移動」機能を使用してください。

### デバッグのヒント

1. **ログ確認**: `~/.clojure-lsp/clojure-lsp.out` にログが出力されます
2. **REPL接続**: 開発モードではnREPLが起動し、ポートが `db*` に保存されます
3. **トレース有効化**: `--trace-level verbose` オプションでLSPメッセージを詳細表示

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| LSP | Language Server Protocol - エディタとの通信プロトコル |
| clj-kondo | Clojureの静的解析ツール |
| bucket | 解析要素の種類（var-definitions, var-usages等） |
| zloc | rewrite-cljのzipper location |
| db* | アプリケーション状態を保持するアトム |
| namespace | Clojureのモジュール単位 |
| defmulti/defmethod | Clojureのマルチメソッド（ポリモーフィズム） |
| transducer | 合成可能なコレクション変換 |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `cli/src/clojure_lsp/main.clj` | CLIエントリーポイント | コマンドライン解析、起動処理 |
| `cli/src/clojure_lsp/server.clj` | LSPサーバー実装 | リクエストハンドラ登録、サーバー起動 |
| `lib/src/clojure_lsp/api.clj` | 公開API | 外部から呼び出し可能なAPI |
| `lib/src/clojure_lsp/handlers.clj` | リクエストハンドラ | LSPリクエストの処理ロジック |
| `lib/src/clojure_lsp/queries.clj` | 解析クエリ | 定義・参照の検索ロジック |
| `lib/src/clojure_lsp/db.clj` | 状態管理 | アプリケーション状態の定義と永続化 |
| `lib/src/clojure_lsp/kondo.clj` | clj-kondo統合 | 静的解析の実行と結果の正規化 |
| `lib/src/clojure_lsp/shared.clj` | 共通ユーティリティ | 汎用ヘルパー関数 |

### C. 参考資料

- [Clojure公式ドキュメント](https://clojure.org/reference/documentation)
- [Language Server Protocol仕様](https://microsoft.github.io/language-server-protocol/)
- [clj-kondo公式ドキュメント](https://github.com/clj-kondo/clj-kondo)
- [rewrite-clj公式ドキュメント](https://github.com/clj-commons/rewrite-clj)
- [clojure-lsp公式サイト](https://clojure-lsp.io/)
