# 画面設計書 7-実装へ移動

## 概要

本ドキュメントは、Lua Language Serverの「実装へ移動」機能の設計を記載したものである。LSP（Language Server Protocol）の `textDocument/implementation` メソッドに対応し、インターフェースや抽象定義の実装位置へジャンプする機能を提供する。

### 本画面の処理概要

**業務上の目的・背景**：
オブジェクト指向プログラミングにおいて、インターフェースや抽象クラスの実装位置を特定することは重要である。本機能により、シンボルの参照元のうち、代入や設定を行っている箇所（実装）へジャンプできる。これにより、フィールドやメソッドがどこで具体的に実装されているかを素早く確認できる。

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

**主要な操作・処理内容**：
1. エディタからLSPサーバーへ `textDocument/implementation` リクエストを送信
2. カーソル位置からソースオブジェクトを特定
3. `vm.getRefs` で全参照を取得
4. `guide.isAssign` で代入箇所のみをフィルタリング
5. 結果をソート・フィルタリング
6. Location または LocationLink 形式でエディタへ返却
7. エディタが実装位置へジャンプ

**画面遷移**：
- 遷移元：エディタのコード編集画面
- 遷移先：実装位置のファイル（同一ファイルまたは別ファイル）
- 関連遷移：定義へ移動、参照検索

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | 実装へ移動 (textDocument/implementation) | 主機能 | インターフェースの実装位置へジャンプする主処理 |

## 画面種別

ナビゲーション

## URL/ルーティング

LSPメソッド: `textDocument/implementation`

**リクエストパラメータ**:
```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/implementation` リクエストを送信
2. `provider.lua` の `textDocument/implementation` ハンドラが呼び出される
3. ワークスペースの準備状態を確認
4. `core/implementation.lua` の関数を呼び出し
5. `findSource` でカーソル位置のソースオブジェクトを特定
6. `vm.getRefs` でシンボルの全参照を取得
7. 以下の条件でフィルタリング：
   - `guide.isAssign(src)` が true である（代入箇所）
   - `global` タイプではない
   - `self` ではない
   - `doc.type.*` や `doc.class`, `doc.alias`, `doc.enum` ではない
8. 結果をソート
9. `jumpSource` でジャンプ先を調整
10. `convertDefinitionResult` で LSP 形式に変換
11. レスポンスとしてエディタへ返却

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

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

## メッセージ仕様

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

## 例外処理

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

## 備考

- `guide.isAssign` により、単純な参照ではなく代入・定義箇所のみが結果に含まれる
- LuaDoc定義（`doc.type.function` 等）は実装とはみなされない
- 通常の「定義へ移動」との違いは、全ての代入箇所を含む点
- 共通の `convertDefinitionResult` 関数を使用してレスポンスを構築

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parser/guide.lua | `script/parser/guide.lua` | `isAssign` 関数の定義 |
| 1-2 | vm/init.lua | `script/vm/init.lua` | `getRefs` 関数の動作 |

**読解のコツ**: `isAssign` が true を返すノード種類を確認する。

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

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

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

**主要処理フロー**:
1. **470-493行目**: `textDocument/implementation` ハンドラの定義
2. **477行目**: `workspace.awaitReady` でワークスペース準備待ち
3. **484行目**: `core.implementation` モジュールの呼び出し
4. **486行目**: 実装検索実行
5. **490行目**: `convertDefinitionResult` で結果変換

#### Step 3: コア実装検索ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | implementation.lua | `script/core/implementation.lua` | 実装検索のメインロジック |

**主要処理フロー（implementation.lua）**:
- **7-31行目**: `sortResults` - 結果のソートとフィルタリング
- **33-56行目**: `accept` テーブル - 処理対象ノード種類の定義
- **58-77行目**: `convertIndex` - インデックスアクセスの変換
- **79-170行目**: メイン関数 - 実装検索のエントリーポイント
- **93行目**: `vm.getRefs` で参照取得
- **97-98行目**: `guide.isAssign` チェック

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

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

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

```
textDocument/implementation (provider.lua:470)
    │
    ├─ workspace.awaitReady(uri)
    │
    ├─ files.getState(uri)
    │
    ├─ converter.unpackPosition()
    │
    └─ core.implementation(uri, pos)
           │
           ├─ findSource(ast, offset, accept)
           │
           ├─ convertIndex(source)
           │
           ├─ vm.getRefs(source)
           │
           ├─ フィルタリング
           │      ├─ guide.isAssign(src) == true
           │      ├─ src.type != 'global'
           │      ├─ src.type != 'self'
           │      └─ doc.* 型を除外
           │
           ├─ sortResults(results)
           │
           └─ jumpSource(results)
```

### データフロー図

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

textDocument.uri    ───▶ files.getState(uri)     ───▶  AST State
position            ───▶ converter.unpackPosition ───▶  内部位置
                         │
                         ▼
                    findSource()                  ───▶  Source Object
                         │
                         ▼
                    vm.getRefs()                  ───▶  Reference List
                         │
                         ▼
                    isAssign フィルタ             ───▶  Implementations
                         │
                         ▼
                    sortResults()                 ───▶  Sorted List
                         │
                         ▼
                    jumpSource()                  ───▶  Adjusted List
                         │
                         ▼
                   convertDefinitionResult()      ───▶  LSP Response
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPプロバイダー・エントリーポイント |
| implementation.lua | `script/core/implementation.lua` | ソース | 実装検索のメインロジック |
| find-source.lua | `script/core/find-source.lua` | ソース | ソースオブジェクト検索 |
| jump-source.lua | `script/core/jump-source.lua` | ソース | ジャンプ先調整 |
| guide.lua | `script/parser/guide.lua` | ソース | isAssign判定 |
| vm/init.lua | `script/vm/init.lua` | ソース | 参照検索エンジン |
| converter.lua | `script/proto/converter.lua` | ソース | LSP位置変換 |
