# 機能設計書 73-clangd

## 概要

本ドキュメントは、LLVM/Clangプロジェクトにおける言語サーバー「clangd」の機能設計書である。Language Server Protocol（LSP）を実装し、IDEやエディタにC/C++のスマートな編集支援機能を提供する。

### 本機能の処理概要

clangdは、C/C++開発のためのLanguage Serverである。ソースコードをインクリメンタルに解析し、コード補完、定義ジャンプ、リファクタリング、診断などの機能をLSP経由でエディタに提供する。

**業務上の目的・背景**：モダンな開発環境では、IDEによるコード補完、定義ジャンプ、リアルタイムエラー検出が生産性向上に不可欠である。clangdは、Clangの正確な意味解析をベースに、これらの機能を任意のLSP対応エディタで利用可能にする。

**機能の利用シーン**：
- VS Code、Vim、Emacs、Sublime TextなどでのC/C++開発
- リアルタイムのコード補完とシグネチャヘルプ
- 定義・宣言・参照箇所へのナビゲーション
- コードリファクタリング（リネーム、extract function等）
- インクリメンタルなコンパイルエラー検出

**主要な処理内容**：
1. LSPメッセージの受信: JSON-RPCでエディタからのリクエストを受信
2. ソースコードの解析: TUSchedulerによる非同期AST構築とキャッシュ管理
3. インデックス構築: シンボルインデックスによる高速検索
4. 機能の提供: 補完、ホバー、ナビゲーション、リファクタリング等

**関連システム・外部連携**：LSP対応エディタ/IDE、compile_commands.json、clang-tidy（診断統合）、clang-format（フォーマット）

**権限による制御**：特になし（ファイルシステムへの読み取り権限が必要）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エディタUI | 主画面 | LSP経由でエディタの補完ポップアップ、ホバー情報、診断マーカー等を制御 |

## 機能種別

言語サーバー / コード補完 / コードナビゲーション / リファクタリング / 診断

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --compile-commands-dir | string | No | compile_commands.jsonの検索ディレクトリ | 有効なディレクトリ |
| --background-index | flag | No | バックグラウンドインデックス有効化 | - |
| --clang-tidy | flag | No | clang-tidy診断の有効化 | - |
| --completion-style | enum | No | 補完スタイル（bundled/detailed） | bundled/detailed |
| --header-insertion | enum | No | ヘッダー自動挿入の設定 | iwyu/never |
| --limit-results | int | No | 結果数の上限 | 正の整数 |
| --log | enum | No | ログレベル | error/info/verbose |
| --pch-storage | enum | No | PCHの保存先 | disk/memory |
| -j | int | No | ワーカースレッド数 | 正の整数 |

### 入力データソース

- LSPメッセージ（JSON-RPC over stdio/socket）
- C/C++ソースファイル
- コンパイルデータベース（compile_commands.json）
- 設定ファイル（.clangd）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| LSPレスポンス | JSON-RPC | 補完候補、ホバー情報、診断、ナビゲーション結果 |
| ログ出力 | text | デバッグ・診断情報 |

### 出力先

- 標準出力（LSPメッセージ）
- 標準エラー出力（ログ）

## 処理フロー

### 処理シーケンス

```
1. 初期化
   └─ コンパイルデータベースの検出、ワーカースレッドの起動

2. initialize リクエスト処理
   └─ クライアント機能のネゴシエーション、サーバー機能の通知

3. ドキュメントオープン/変更
   └─ TUSchedulerにAST構築をスケジュール

4. 機能リクエスト処理
   └─ 補完/ホバー/定義/参照などのリクエストに応答

5. バックグラウンドインデックス更新
   └─ ファイル変更の検出とインデックス再構築

6. シャットダウン
   └─ リソースの解放、ワーカースレッドの終了
```

### フローチャート

```mermaid
flowchart TD
    A[開始: clangd] --> B[初期化]
    B --> C[CDB読み込み]
    C --> D[initialize リクエスト待機]
    D --> E{LSPリクエスト受信}
    E --> F{リクエスト種別}
    F -->|textDocument/completion| G[コード補完処理]
    F -->|textDocument/definition| H[定義ジャンプ処理]
    F -->|textDocument/hover| I[ホバー情報取得]
    F -->|textDocument/didOpen| J[ドキュメント登録]
    F -->|textDocument/didChange| K[AST再構築スケジュール]
    F -->|shutdown| L[シャットダウン]
    G --> M[レスポンス送信]
    H --> M
    I --> M
    J --> M
    K --> M
    M --> E
    L --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-73-01 | Preambleキャッシュ | ヘッダー部分をキャッシュして再解析を高速化 | 常時 |
| BR-73-02 | フォールバック | compile_commands.json不在時はデフォルトフラグで解析 | CDB未検出時 |
| BR-73-03 | 診断遅延 | 変更後一定時間待機してから診断を送信（デバウンス） | ドキュメント変更時 |
| BR-73-04 | インデックス永続化 | バックグラウンドインデックスをディスクに保存 | --background-index有効時 |

### 計算ロジック

コード補完のスコアリングは、シンボルの種類、スコープの近さ、使用頻度、型の一致度などを考慮して計算される。

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

シンボルインデックスはLLVMビットコード形式でディスクに永続化される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パースエラー | ソースコードの構文エラー | 診断として通知、部分的な機能提供を継続 |
| - | CDBエラー | compile_commands.jsonの読み込み失敗 | フォールバックフラグで継続 |
| - | インデックスエラー | インデックス破損 | 再構築を実行 |

### リトライ仕様

AST構築失敗時は古いASTを使用して部分的な機能を提供。

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

該当なし。各リクエストは独立して処理され、ファイル変更は非同期にスケジュールされる。

## パフォーマンス要件

- コード補完: 100ms以内の応答を目標
- 診断更新: 変更後500msのデバウンス後に実行
- バックグラウンドインデックス: アイドル時に段階的に構築

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

- clangdはソースコードを解析するが、コードの実行は行わない
- ローカルファイルシステムへのアクセスのみ

## 備考

- clangdは常駐プロセスとして動作し、エディタとの接続が切れると終了
- 複数のワークスペースを同時に扱うことが可能

---

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

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

### 推奨読解順序

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

LSPプロトコルのデータ構造とclangd内部の主要構造体を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Protocol.h | `clang-tools-extra/clangd/Protocol.h` | LSPメッセージの構造体定義 |
| 1-2 | ParsedAST.h | `clang-tools-extra/clangd/ParsedAST.h` | 解析済みASTの表現 |

**読解のコツ**: Protocol.hはLSP仕様に対応した構造体を定義。JSON変換のためにllvm::json::Value との変換関数が多数存在する。

#### Step 2: サーバーコアを理解する

ClangdServerがリクエストを処理する仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ClangdServer.cpp | `clang-tools-extra/clangd/ClangdServer.cpp` | サーバーのメイン実装 |
| 2-2 | ClangdServer.h | `clang-tools-extra/clangd/ClangdServer.h` | 公開インターフェース |

**主要処理フロー**:
1. **214-281行目**: コンストラクタ、インデックス・スケジューラの初期化
2. **297-320行目**: addDocument関数、ドキュメントの登録と解析スケジュール
3. **421-494行目**: codeComplete関数、コード補完処理
4. **802-812行目**: locateSymbolAt関数、定義ジャンプ処理

#### Step 3: 非同期スケジューリングを理解する

TUSchedulerによる非同期処理の仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | TUScheduler.h | `clang-tools-extra/clangd/TUScheduler.h` | スケジューラインターフェース |

**読解のコツ**: runWithASTとrunWithPreambleの違いを理解する。前者は完全なAST、後者はプリアンブルのみで高速。

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

各LSP機能の実装詳細を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CodeComplete.cpp | `clang-tools-extra/clangd/CodeComplete.cpp` | 補完処理の実装 |
| 4-2 | XRefs.cpp | `clang-tools-extra/clangd/XRefs.cpp` | 定義・参照検索の実装 |
| 4-3 | Hover.cpp | `clang-tools-extra/clangd/Hover.cpp` | ホバー情報の生成 |

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

```
main (ClangdMain.cpp)
    │
    ├─ ClangdServer初期化
    │      ├─ TUScheduler
    │      │      └─ ワーカースレッド群
    │      │
    │      ├─ FileIndex (動的インデックス)
    │      │
    │      └─ BackgroundIndex (バックグラウンドインデックス)
    │
    └─ ClangdLSPServer
           │
           └─ JSONTransport
                  │
                  └─ LSPリクエスト/レスポンス処理
                         │
                         ├─ textDocument/completion
                         │      └─ ClangdServer::codeComplete()
                         │             └─ clangd::codeComplete()
                         │
                         ├─ textDocument/definition
                         │      └─ ClangdServer::locateSymbolAt()
                         │             └─ clangd::locateSymbolAt()
                         │
                         └─ textDocument/hover
                                └─ ClangdServer::findHover()
                                       └─ clangd::getHover()
```

### データフロー図

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

エディタ ─────────▶ JSON-RPC ─────────▶ ClangdLSPServer
                                              │
                                              ▼
                                       ClangdServer
                                              │
              ┌───────────────────────────────┼───────────────────────────────┐
              │                               │                               │
              ▼                               ▼                               ▼
      TUScheduler                      FileIndex                    BackgroundIndex
              │                               │                               │
              ▼                               ▼                               ▼
        ParsedAST ◀──────────────────▶ シンボル検索 ◀──────────────────▶ ディスクインデックス
              │
              ▼
       機能実装
     (CodeComplete,
      XRefs, Hover)
              │
              ▼
       LSPレスポンス ─────────▶ JSON-RPC ─────────▶ エディタ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ClangdServer.cpp | `clang-tools-extra/clangd/ClangdServer.cpp` | ソース | サーバーコア実装 |
| ClangdServer.h | `clang-tools-extra/clangd/ClangdServer.h` | ヘッダ | サーバーインターフェース |
| Protocol.h | `clang-tools-extra/clangd/Protocol.h` | ヘッダ | LSPデータ構造 |
| TUScheduler.h | `clang-tools-extra/clangd/TUScheduler.h` | ヘッダ | 非同期スケジューラ |
| CodeComplete.cpp | `clang-tools-extra/clangd/CodeComplete.cpp` | ソース | 補完処理 |
| XRefs.cpp | `clang-tools-extra/clangd/XRefs.cpp` | ソース | 定義・参照検索 |
| Hover.cpp | `clang-tools-extra/clangd/Hover.cpp` | ソース | ホバー情報 |
| JSONTransport.cpp | `clang-tools-extra/clangd/JSONTransport.cpp` | ソース | JSON-RPC通信 |
| GlobalCompilationDatabase.cpp | `clang-tools-extra/clangd/GlobalCompilationDatabase.cpp` | ソース | CDB管理 |
| IncludeCleaner.cpp | `clang-tools-extra/clangd/IncludeCleaner.cpp` | ソース | インクルード解析 |
