# 画面設計書 6-型定義へ移動

## 概要

本ドキュメントは、Lua Language Serverの「型定義へ移動」機能の設計を記載したものである。LSP（Language Server Protocol）の `textDocument/typeDefinition` メソッドに対応し、変数の型が定義されている位置へジャンプする機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：
通常の「定義へ移動」では変数の宣言位置へジャンプするが、「型定義へ移動」では変数の型（クラス・インターフェース等）が定義されている位置へジャンプする。例えば、`local obj = MyClass.new()` という変数上で実行すると、`MyClass` の定義位置へジャンプする。これにより、オブジェクトの構造やメソッドを確認する際の効率が向上する。

**画面へのアクセス方法**：
エディタ（VS Code等）上でLuaファイルを開き、変数名上で以下の操作を行う：
- 右クリックメニューから「型定義へ移動」を選択
- コマンドパレットから「Go to Type Definition」を実行

**主要な操作・処理内容**：
1. エディタからLSPサーバーへ `textDocument/typeDefinition` リクエストを送信
2. カーソル位置からソースオブジェクトを特定
3. `require` 文字列の場合、モジュールファイルを検索
4. `vm.getDefs` で定義を取得
5. 型定義（`doc.class.name`, `doc.alias.name`, `function` 等）のみをフィルタリング
6. 結果をソート・フィルタリング
7. Location または LocationLink 形式でエディタへ返却
8. エディタが型定義位置へジャンプ

**画面遷移**：
- 遷移元：エディタのコード編集画面
- 遷移先：型定義位置のファイル（同一ファイルまたは別ファイル）
- 関連遷移：定義へ移動（通常の定義移動）

**権限による表示制御**：
本機能に権限による表示制御はない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | 型定義へ移動 (textDocument/typeDefinition) | 主機能 | 変数の型定義位置へジャンプする主処理 |
| 52 | 型推論 (Type Inference) | 補助機能 | 変数の型を推論して定義位置を特定 |

## 画面種別

ナビゲーション

## URL/ルーティング

LSPメソッド: `textDocument/typeDefinition`

**リクエストパラメータ**:
```json
{
  "textDocument": {
    "uri": "file:///path/to/file.lua"
  },
  "position": {
    "line": 10,
    "character": 15
  }
}
```

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument.uri | string | Yes | 対象ファイルのURI |
| position.line | integer | Yes | カーソル位置の行番号（0始まり） |
| position.character | integer | Yes | カーソル位置の列番号（0始まり） |

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (配列) | Location[] または LocationLink[] | 型定義位置のリスト |
| [].uri | string | 型定義位置のファイルURI |
| [].range | Range | 型定義位置の範囲 |

## 表示項目

### 型定義移動結果

| 表示項目 | 形式 | 説明 |
|---------|------|------|
| ジャンプ先 | エディタ表示 | 型定義位置が1つの場合、直接ジャンプ |
| ピークビュー | ポップアップ | 型定義位置が複数の場合、選択リスト表示 |

## イベント仕様

### 1-型定義移動リクエスト処理

1. エディタからLSPサーバーへ `textDocument/typeDefinition` リクエストを送信
2. `provider.lua` の `textDocument/typeDefinition` ハンドラが呼び出される
3. ワークスペースの準備状態を確認
4. `core/type-definition.lua` の関数を呼び出し
5. `findSource` でカーソル位置のソースオブジェクトを特定
6. `checkRequire` で require 文字列の場合、モジュールファイルを検索
7. `vm.getDefs` でシンボルの定義を取得
8. 以下の型定義のみを結果に含める：
   - `doc.class.name`
   - `doc.alias.name`
   - `doc.type.function`
   - `doc.type.array`
   - `doc.type.table`
   - `function`
9. 結果をソート
10. `jumpSource` で関数本体へのジャンプを調整
11. `convertDefinitionResult` で LSP 形式に変換
12. レスポンスとしてエディタへ返却

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

本機能はデータベース操作を行わない（読み取り専用）。

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| WINDOW_PROCESSING_TYPE_DEFINITION | 情報 | 処理中表示 | 型定義検索実行中 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイルが存在しない | `nil` を返却 |
| カーソル位置にシンボルがない | `nil` を返却 |
| 型定義が見つからない | `nil` を返却 |

## 備考

- 「定義へ移動」との違いは、変数宣言位置ではなく型の定義位置へジャンプする点
- プリミティブ型（number, string等）の場合、型定義は見つからない
- LuaDocで `---@class` や `---@alias` で定義された型へジャンプ可能
- 共通の `convertDefinitionResult` 関数を使用してレスポンスを構築

---

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

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

### 推奨読解順序

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

型定義移動で扱うデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parser/guide.lua | `script/parser/guide.lua` | ASTノードの種類と構造 |
| 1-2 | vm/init.lua | `script/vm/init.lua` | `getDefs` 関数の動作 |

**読解のコツ**: 「定義へ移動」との違いは、フィルタリング条件にある。

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

処理の起点となるプロバイダーファイルを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | provider.lua | `script/provider/provider.lua` | LSPメソッドの登録とリクエスト処理 |

**主要処理フロー**:
1. **445-468行目**: `textDocument/typeDefinition` ハンドラの定義
2. **452行目**: `workspace.awaitReady` でワークスペース準備待ち
3. **459行目**: `core.type-definition` モジュールの呼び出し
4. **461行目**: 型定義検索実行
5. **465行目**: `convertDefinitionResult` で結果変換

#### Step 3: コア型定義検索ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | type-definition.lua | `script/core/type-definition.lua` | 型定義検索のメインロジック |

**主要処理フロー（type-definition.lua）**:
- **9-33行目**: `sortResults` - 結果のソートとフィルタリング
- **35-58行目**: `accept` テーブル - 処理対象ノード種類の定義
- **60-85行目**: `checkRequire` - require文字列の解決
- **87-106行目**: `convertIndex` - インデックスアクセスの変換
- **108-176行目**: メイン関数 - 型定義検索のエントリーポイント
- **153-163行目**: 型定義フィルタリング条件

#### Step 4: 補助モジュールを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | find-source.lua | `script/core/find-source.lua` | ソースオブジェクト検索 |
| 4-2 | jump-source.lua | `script/core/jump-source.lua` | ジャンプ先調整 |

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

```
textDocument/typeDefinition (provider.lua:445)
    │
    ├─ workspace.awaitReady(uri)
    │
    ├─ files.getState(uri)
    │
    ├─ converter.unpackPosition()
    │
    └─ core.type-definition(uri, pos)
           │
           ├─ findSource(ast, offset, accept)
           │
           ├─ convertIndex(source)
           │
           ├─ checkRequire(source)
           │      └─ rpath.findUrisByRequireName()
           │
           ├─ vm.getDefs(source)
           │
           ├─ 型定義フィルタリング
           │      (doc.class.name, doc.alias.name,
           │       doc.type.function, function, etc.)
           │
           ├─ sortResults(results)
           │
           └─ jumpSource(results)
```

### データフロー図

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

textDocument.uri    ───▶ files.getState(uri)     ───▶  AST State
position            ───▶ converter.unpackPosition ───▶  内部位置
                         │
                         ▼
                    findSource()                  ───▶  Source Object
                         │
                         ├──▶ checkRequire()     ───▶  Module URIs
                         │
                         └──▶ vm.getDefs()       ───▶  Definition List
                                   │
                                   ▼
                              型定義フィルタ      ───▶  Type Definitions
                                   │
                                   ▼
                              sortResults()       ───▶  Sorted List
                                   │
                                   ▼
                              jumpSource()        ───▶  Adjusted List
                                   │
                                   ▼
                         convertDefinitionResult() ───▶  LSP Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPプロバイダー・エントリーポイント |
| type-definition.lua | `script/core/type-definition.lua` | ソース | 型定義検索のメインロジック |
| definition.lua | `script/core/definition.lua` | ソース | 参考：通常の定義検索 |
| find-source.lua | `script/core/find-source.lua` | ソース | ソースオブジェクト検索 |
| jump-source.lua | `script/core/jump-source.lua` | ソース | ジャンプ先調整 |
| require-path.lua | `script/workspace/require-path.lua` | ソース | requireパス解決 |
| vm/init.lua | `script/vm/init.lua` | ソース | 型推論・定義検索エンジン |
| converter.lua | `script/proto/converter.lua` | ソース | LSP位置変換 |
