# 画面設計書 12-ドキュメントシンボル

## 概要

本ドキュメントは、Lua Language Serverの「ドキュメントシンボル（textDocument/documentSymbol）」機能の画面設計書である。この機能は、ファイル内のシンボル（変数、関数、クラス等）を階層構造で一覧表示するアウトライン機能を提供する。

### 本画面の処理概要

この機能では、指定されたドキュメント内のすべてのシンボルを解析し、階層構造（親子関係）を持つシンボルツリーとして返却する。エディタはこの情報を使用してアウトラインビュー、ブレッドクラム、シンボル検索などの機能を提供する。

**業務上の目的・背景**：大規模なLuaファイルでは、関数やクラスの定義が多数存在し、コードの全体像を把握することが困難になる。ドキュメントシンボル機能により、ファイル内の構造を視覚的に把握でき、目的の定義箇所への素早いナビゲーションが可能となる。これにより、コードの理解とメンテナンス効率が大幅に向上する。

**画面へのアクセス方法**：エディタのアウトラインパネルを開く、またはシンボル検索コマンド（Ctrl+Shift+O等）を実行することで、この機能が呼び出される。VS Codeでは、サイドバーの「アウトライン」ビューやブレッドクラムナビゲーションで表示される。

**主要な操作・処理内容**：
1. ドキュメントのASTを取得し、すべてのソース要素を走査する
2. 各ソース要素からシンボル情報（名前、種類、範囲）を抽出する
3. シンボルを階層構造（ネスト関係）に整理する
4. LSP形式のDocumentSymbol配列として返却する

**画面遷移**：アウトラインビューでシンボルをクリックすると、そのシンボルの定義位置にジャンプする。また、シンボルから「定義へ移動」や「参照検索」などの機能に遷移できる。

**権限による表示制御**：特になし。LSPプロトコルレベルでの認証・権限管理は行わない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 20 | ドキュメントシンボル (textDocument/documentSymbol) | 主機能 | ファイル内のシンボル一覧を階層的に表示する主処理 |

## 画面種別

LSP機能（一覧）

## URL/ルーティング

LSPメソッド: `textDocument/documentSymbol`

## 入出力項目

### 入力項目（リクエストパラメータ）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument | TextDocumentIdentifier | Yes | 対象ドキュメントのURI |

### 出力項目（レスポンス）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| symbols | DocumentSymbol[] | シンボル配列（階層構造） |

### DocumentSymbol構造

| 項目名 | 型 | 説明 |
|--------|-----|------|
| name | string | シンボル名 |
| detail | string | 詳細情報（値のプレビュー等） |
| kind | SymbolKind | シンボル種別（Function, Variable等） |
| range | Range | シンボル全体の範囲 |
| selectionRange | Range | 選択時にハイライトする範囲 |
| children | DocumentSymbol[] | 子シンボル（ネストされたシンボル） |

## 表示項目

| 表示項目 | 説明 |
|---------|------|
| シンボル名 | 変数名、関数名、テーブルフィールド名等 |
| シンボルアイコン | SymbolKindに応じたアイコン |
| 詳細情報 | 値のプレビュー（関数パラメータ、テーブル内容等） |
| 階層構造 | 親子関係を持つツリー表示 |

## イベント仕様

### 1-documentSymbolリクエスト処理

1. クライアントからtextDocument/documentSymbolリクエストを受信
2. ドキュメントURIから対象ファイルのASTを取得
3. makeSymbol関数ですべてのソース要素を走査し、シンボル情報を収集
4. packSymbols関数でシンボルを階層構造に整理
5. LSP形式に変換してレスポンスを返却

## データベース更新仕様

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

この機能はデータベース操作を行わない。ファイルシステム上のソースコードを読み取るのみで、変更は行わない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| documentSymbolリクエスト | なし | SELECT（読み取り） | ソースコードの解析のみ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| WINDOW_PROCESSING_SYMBOL | 進捗 | 処理中表示 | シンボル解析処理中 |
| - | 成功 | （シンボル配列返却） | シンボルが見つかった場合 |
| - | 成功 | null | シンボルが見つからない場合 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイルが見つからない | nullを返却 |
| ASTの取得に失敗 | nullを返却 |
| シンボルが存在しない | nullを返却 |

## 備考

- シンボルはネスト構造を持ち、関数内のローカル変数や、テーブル内のフィールドは子シンボルとして表現される
- SymbolKindは以下を含む: Function, Variable, Method, Field, Class, Module, Property, Boolean, Number, String, Array, Object, Constant, Package
- 空の名前を持つシンボルは、表示上はスペースに置換される
- 匿名関数やreturn文の関数もシンボルとして抽出される
- if/while/for等の制御構造もPackageタイプのシンボルとして抽出される

---

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

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

### 推奨読解順序

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

まず、DocumentSymbolの構造とSymbolKindの定義を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | define.lua | `script/proto/define.lua` | SymbolKindの定義（Function=12, Variable=13等） |
| 1-2 | converter.lua | `script/proto/converter.lua` | Range変換処理（packRange） |

**読解のコツ**: SymbolKindはLSP仕様で定義された数値コードで、エディタ側でアイコンと対応付けられる。

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

処理の起点となるプロバイダー登録を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | provider.lua | `script/provider/provider.lua` | textDocument/documentSymbolの登録（825-875行目） |

**主要処理フロー**:
1. **825行目**: `m.register 'textDocument/documentSymbol'`でハンドラー登録
2. **832-833行目**: ワークスペース準備待機とファイル状態取得
3. **839行目**: `core/document-symbol`モジュールを呼び出し
4. **846-866行目**: convert関数でシンボルをLSP形式に変換
5. **869-871行目**: 全シンボルを変換してレスポンス返却

#### Step 3: コア処理を理解する

シンボル抽出とパッキングのコアロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | document-symbol.lua | `script/core/document-symbol.lua` | シンボル抽出の全体構造 |
| 3-2 | document-symbol.lua | `script/core/document-symbol.lua` (100-210行目) | buildValue関数 - 値からシンボル構築 |
| 3-3 | document-symbol.lua | `script/core/document-symbol.lua` (212-265行目) | buildAnonymous関数 - 匿名関数のシンボル構築 |
| 3-4 | document-symbol.lua | `script/core/document-symbol.lua` (267-312行目) | buildBlock関数 - 制御構造のシンボル構築 |
| 3-5 | document-symbol.lua | `script/core/document-symbol.lua` (337-357行目) | makeSymbol関数 - 全ソース要素走査 |
| 3-6 | document-symbol.lua | `script/core/document-symbol.lua` (359-399行目) | packSymbols関数 - 階層構造への整理 |

**主要処理フロー**:
- **18-41行目**: buildName関数 - シンボル名の構築
- **43-60行目**: buildFunctionParams関数 - 関数パラメータの構築
- **100-210行目**: buildValue関数 - 変数宣言、フィールド設定からシンボル情報抽出
- **359-399行目**: packSymbols関数 - シンボルを位置でソートし、ネスト構造に整理

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

```
textDocument/documentSymbol (provider.lua:825-875)
    |
    +-- files.getRealUri (ファイルURI正規化)
    |
    +-- workspace.awaitReady (ワークスペース準備待機)
    |
    +-- files.getState (AST取得)
    |
    +-- core/document-symbol (document-symbol.lua:402-411)
           |
           +-- makeSymbol (337-357行目)
           |      |
           |      +-- guide.eachSource (全ソース走査)
           |      |
           |      +-- buildSource (314-334行目)
           |             |
           |             +-- buildValue (100-210行目)
           |             +-- buildAnonymous (212-265行目)
           |             +-- buildBlock (267-312行目)
           |
           +-- packSymbols (389-399行目)
                  |
                  +-- table.sort (位置でソート)
                  |
                  +-- packChild (359-386行目)
                         |
                         +-- 階層構造構築（再帰）
```

### データフロー図

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

DocumentSymbolParams           provider.lua                        DocumentSymbol[]
+------------------+           +------------------+                 +------------------+
| textDocument.uri |  ------>  | ファイル状態取得   |                 | name             |
+------------------+           | AST解析          |                 | detail           |
                               +------------------+                 | kind             |
                                      |                             | range            |
                                      v                             | selectionRange   |
                               document-symbol.lua                  | children[]       |
                               +------------------+                 +------------------+
                               | makeSymbol       |
                               |   eachSource     |  ------------>
                               |   buildValue     |
                               |   buildAnonymous |
                               | packSymbols      |
                               |   packChild      |
                               +------------------+
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPメソッドハンドラー登録 |
| document-symbol.lua | `script/core/document-symbol.lua` | ソース | シンボル抽出・構造化コアロジック |
| substring.lua | `script/core/substring.lua` | ソース | 部分文字列抽出ユーティリティ |
| define.lua | `script/proto/define.lua` | ソース | SymbolKind定義 |
| converter.lua | `script/proto/converter.lua` | ソース | Range変換処理 |
| files.lua | `script/files.lua` | ソース | ファイル管理・AST取得 |
| guide.lua | `script/parser/guide.lua` | ソース | AST操作ユーティリティ |
