# 機能設計書 85-プロジェクトツリー表示

## 概要

本ドキュメントは、clojure-lspのプロジェクトツリー表示機能の設計書である。エディタのカスタム拡張機能として、プロジェクト構造を階層的に表示する。

### 本機能の処理概要

この機能は、LSPプロトコルのカスタム拡張として、プロジェクトのソースパス、名前空間、変数定義、外部依存関係などを階層的なツリー構造で表示する。エディタ側のクライアントがこの機能をサポートしている場合に利用可能。

**業務上の目的・背景**：大規模なClojureプロジェクトでは、多数のファイルと名前空間が存在し、プロジェクト構造の把握が困難になることがある。本機能により、プロジェクトの論理的な構造をツリー形式で視覚化し、開発者のナビゲーションと理解を支援する。

**機能の利用シーン**：
- プロジェクト構造の全体把握
- 特定の名前空間や関数の探索
- 外部依存関係のブラウジング
- JARファイル内のクラスやソースの確認
- 新規参加メンバーへのコードベース説明

**主要な処理内容**：
1. クライアントからのノード要求の受信
2. ノードタイプに応じた子ノードの生成
3. ツリー構造データの返却

**関連システム・外部連携**：
- LSPクライアント: ツリー表示UI
- clj-kondo: 解析データの提供

**権限による制御**：権限による制御は行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | 該当なし | 該当なし | エディタのサイドパネルとして表示（LSP拡張機能） |

## 機能種別

表示機能 / カスタムLSP拡張

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| current-node | Map | No | 現在のノード情報（nilの場合はルートノード） | - |
| current-node.name | String | No | ノード名 | - |
| current-node.type | Keyword | No | ノードタイプ | :project, :source-path, :library, :jar, :ns のいずれか |
| current-node.uri | String | No | ノードのURI | - |
| current-node.id | Keyword | No | 特殊ノードの識別子 | - |

### 入力データソース

- clj-kondo解析結果（名前空間定義、変数定義）
- プロジェクト設定（ソースパス）
- 外部依存関係情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| name | String | ノード名 |
| type | Keyword | ノードタイプ |
| nodes | Vector | 子ノードのリスト |
| uri | String | ファイルURI（存在する場合） |
| range | Map | 位置範囲（存在する場合） |
| final | Boolean | 末端ノードかどうか |
| detail | String | 追加情報（存在する場合） |

### ノードタイプ

| タイプ | 説明 | 子ノード |
|--------|------|---------|
| :project | プロジェクトルート | source-path, library |
| :source-path | ソースディレクトリ | ns |
| :library | 外部依存関係コンテナ | jar |
| :jar | JARファイル | ns, class |
| :ns | 名前空間 | function, variable, keyword |
| :class | Javaクラス | なし（final） |
| :function | 関数定義 | なし（final） |
| :variable | 変数定義 | なし（final） |

### 出力先

- LSPレスポンス: JSON形式のノードデータ

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ clojure/workspace/projectTree/nodes

2. ノードタイプ判定
   └─ current-node の type を確認

3. 子ノード生成
   └─ タイプに応じた処理関数を呼び出し

4. レスポンス返却
   └─ ノードデータをJSON形式で返却
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B{current-node is nil?}
    B -->|Yes| C[root-node 生成]
    B -->|No| D{type判定}
    D -->|:source-path| E[source-path-node 生成]
    D -->|:library + external-dependencies| F[external-dependencies-node 生成]
    D -->|:jar| G[jar-node 生成]
    D -->|:ns| H[ns-node 生成]
    C --> I[レスポンス返却]
    E --> I
    F --> I
    G --> I
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-85-1 | ルートノード | current-node が nil の場合はプロジェクトルートを返す | 初回リクエスト時 |
| BR-85-2 | ソースパス表示 | 設定の :source-paths からソースディレクトリを列挙 | root-node 生成時 |
| BR-85-3 | 外部依存関係 | "External dependencies" として JAR ファイルを列挙 | root-node 生成時 |
| BR-85-4 | 名前空間ソート | 名前空間はアルファベット順にソート | ns ノード生成時 |

### 計算ロジック

ノード生成ロジック:
1. root-node: source-paths + "External dependencies"
2. source-path-node: パス内の全名前空間定義
3. external-dependencies-node: 全JARファイル
4. jar-node: JAR内の名前空間定義 + Javaクラス定義
5. ns-node: 変数定義 + キーワード定義

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

該当なし（ファイルシステムのみ操作）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ノード未発見 | 指定されたタイプが不正 | nil を返却 |

### リトライ仕様

リトライは行わない。

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

該当なし（読み取り専用処理）

## パフォーマンス要件

- 各ノード要求は遅延評価される（展開時のみ子ノードを取得）
- 大量のJARファイルがある場合、外部依存関係の展開に時間がかかる可能性

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

- 読み取り専用操作のためセキュリティリスクは低い
- プロジェクト構造情報が外部に露出する可能性がある

## 備考

- この機能はLSPの実験的（experimental）機能として提供される
- クライアントが :experimental :project-tree をサポートしている必要がある

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ノード構造 | `lib/src/clojure_lsp/feature/project_tree.clj` | ノードのデータ構造（name, type, nodes, uri など） |

**読解のコツ**: ファイル末尾のコメントにノード構造の例が記載されている（112-166行目）

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | server.clj | `cli/src/clojure_lsp/server.clj` | LSPリクエストハンドラの登録 |

**主要処理フロー**:
1. **243-248行目**: `clojure/workspace/projectTree/nodes` メソッドの登録
2. ハンドラから `handler/project-tree-nodes` を呼び出し

#### Step 3: ハンドラ層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | handlers.clj | `lib/src/clojure_lsp/handlers.clj` | project-tree-nodes 関数 |

**主要処理フロー**:
- **541-544行目**: `project-tree-nodes` 関数 - ツリーノード取得処理

#### Step 4: 機能実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | project_tree.clj | `lib/src/clojure_lsp/feature/project_tree.clj` | ノード生成の詳細実装 |

**主要処理フロー**:
- **7-21行目**: `root-node` - ルートノードの生成
- **23-34行目**: `source-path-node` - ソースパスノードの生成
- **36-51行目**: `external-dependencies-node` - 外部依存関係ノードの生成
- **53-74行目**: `jar-node` - JARノードの生成
- **76-92行目**: `ns-node` - 名前空間ノードの生成
- **94-110行目**: `nodes` - メインディスパッチ関数

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

```
jsonrpc.server/receive-request "clojure/workspace/projectTree/nodes"
    │
    └─ handler/project-tree-nodes
           │
           └─ f.project-tree/nodes
                  │
                  ├─ (nil) ──────────▶ root-node
                  │
                  ├─ :source-path ───▶ source-path-node
                  │
                  ├─ :library ───────▶ external-dependencies-node
                  │
                  ├─ :jar ───────────▶ jar-node
                  │
                  └─ :ns ────────────▶ ns-node
```

### データフロー図

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

current-node ─────▶ nodes ディスパッチ ──▶ ノードタイプ判定
                          │
                          ▼
                    ノード生成関数
                          │
                          ├─ q/find-all-path-namespace-definitions
                          ├─ q/find-var-definitions
                          ├─ q/find-keyword-definitions
                          └─ q/external-analysis
                          │
                          ▼
                    ノードマップ ────────▶ LSPレスポンス
                    {:name ...
                     :type ...
                     :nodes [...]}
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| project_tree.clj | `lib/src/clojure_lsp/feature/project_tree.clj` | ソース | ツリーノード生成 |
| handlers.clj | `lib/src/clojure_lsp/handlers.clj` | ソース | LSPハンドラー |
| server.clj | `cli/src/clojure_lsp/server.clj` | ソース | LSPサーバー |
| clojure_coercer.clj | `cli/src/clojure_lsp/clojure_coercer.clj` | ソース | 型変換 |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | データ検索 |
