# 画面設計書 35-FFIメタデータ再読込

## 概要

本ドキュメントは、Lua Language ServerのLSPコマンド「FFIメタデータ再読込（lua.reloadFFIMeta）」の画面設計書です。

### 本画面の処理概要

この画面（LSPコマンド）は、LuaJIT FFI（Foreign Function Interface）のメタデータを再読み込みする機能を提供します。

**業務上の目的・背景**：
LuaJIT開発者がffi.cdef()を使用してC言語の型定義を行う場合、Language Serverはこれらの定義を解析してIntelliSense機能を提供します。しかし、ffi.cdef()の内容は動的に変更されることがあり、Language Serverが保持するメタデータが古くなる場合があります。本コマンドは、プロジェクト内のffi.cdef()呼び出しを再スキャンし、メタデータを更新することで、最新のC型定義に基づいたコード補完と型チェックを可能にします。

**画面へのアクセス方法**：
本コマンドは、以下の方法でトリガーされます：
- LSPクライアントからの `workspace/executeCommand` リクエストで `lua.reloadFFIMeta` コマンドを実行
- VS Codeのコマンドパレットから「Lua: Reload FFI Metadata」を選択
- FFI関連ファイルの編集後に自動または手動でトリガー

**主要な操作・処理内容**：
1. ランタイムバージョンがLuaJITかを確認
2. ワークスペースの準備完了を待機
3. メタデータ出力ディレクトリを作成
4. ffi.cdef()の参照箇所を検索
5. 各参照箇所からCコードを抽出
6. FFIメタデータをビルドしてファイルに出力
7. 新規ディレクトリの場合、workspace.libraryに追加

**画面遷移**：
- 入力元：コマンドパレット、エディタコマンド
- 出力先：メタデータ生成後、処理完了

**権限による表示制御**：
Lua.runtime.versionが「LuaJIT」でない場合、処理は実行されません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 78 | FFIサポート | 主機能 | FFIメタデータを再読み込みするコマンド処理 |

## 画面種別

LSPコマンド（非同期処理）

## URL/ルーティング

- LSPコマンド名: `lua.reloadFFIMeta`
- プロトコル: `workspace/executeCommand`
- ハンドラファイル: `script/core/command/reloadFFIMeta.lua`

## 入出力項目

### 入力パラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| uri | uri | Yes | 対象ファイルのURI（スコープ特定用） |

### 出力

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (ファイル出力) | file | FFIメタデータファイル（METAPATHディレクトリ内） |

## 表示項目

本機能はコマンド処理であり、直接的なUI表示項目はありません。

## イベント仕様

### 1-FFIメタデータ再読込実行

1. **リクエスト受信**: uriパラメータを受信
2. **バージョン確認**: Lua.runtime.versionがLuaJITかを確認
3. **ワークスペース待機**: ws.awaitReady()で準備完了を待機
4. **ディレクトリ作成**: createDir()でメタデータ出力先を作成
5. **参照検索**: cdefRerence()でffi.cdef()の参照箇所を取得
6. **コード検索**: searchCode()で各参照箇所からCコードを抽出
7. **メタデータビルド**: ffi.build_single()でメタデータを生成
8. **ライブラリ追加**: 新規ディレクトリの場合、workspace.libraryに追加

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

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

本機能はデータベースを使用しませんが、以下への影響があります：

| 操作（イベント） | 対象 | 操作種別 | 概要 |
|----------------|------|---------|------|
| メタデータ出力 | METAPATH/{hash}/*.lua | CREATE/UPDATE | FFIメタデータファイルを生成 |
| 設定更新 | Lua.workspace.library | UPDATE | 新規ディレクトリをライブラリパスに追加 |

## メッセージ仕様

本機能は特定のメッセージを出力しません。

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| LuaJIT以外のランタイム | 処理を中断（return） |
| cdef参照なし | 処理を中断（return） |
| コード検索失敗 | 処理を中断（return） |

## 備考

- メタデータは `METAPATH/{hash}` ディレクトリに出力されます
- ハッシュはスコープのURIから計算されます（SDBMHash）
- 新規ディレクトリの場合のみworkspace.libraryに追加されます
- ffi.meta（メタファイル）内のffi.cdefは検索対象から除外されます

---

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

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

### 推奨読解順序

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

まず、FFI関連で使用されるデータ構造を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cdefRerence.lua | `script/plugins/ffi/cdefRerence.lua` | cdef参照結果の構造を理解 |

**読解のコツ**: cdefRerence()は `{ uri: string, ... }[]` 形式の参照一覧を返します。

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

コマンドの起点となるファイルを確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | reloadFFIMeta.lua | `script/core/command/reloadFFIMeta.lua` | メイン処理（20-56行目） |

**主要処理フロー**:
1. **22-24行目**: LuaJITバージョン確認
2. **26行目**: ワークスペース準備待機
3. **28行目**: 出力ディレクトリ作成
4. **30-33行目**: cdef参照検索
5. **35-43行目**: 各参照のコード検索とビルド
6. **45-55行目**: 新規ディレクトリ時のライブラリ追加

#### Step 3: ディレクトリ作成処理を理解する

createDir()の実装を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | reloadFFIMeta.lua | `script/core/command/reloadFFIMeta.lua` | createDir関数（10-18行目） |

**主要処理フロー**:
- **11行目**: スコープのURIを取得
- **12行目**: SDBMHashでハッシュ化してディレクトリパスを生成
- **13-15行目**: 既存ディレクトリの場合はパスのみ返す
- **16行目**: 新規ディレクトリを作成

#### Step 4: cdef参照検索を理解する

cdefRerence()の実装を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | cdefRerence.lua | `script/plugins/ffi/cdefRerence.lua` | メイン処理（20-37行目） |

**主要処理フロー**:
- **21-27行目**: ffi.lua（メタファイル）を検索
- **28-35行目**: ffi.cdefの参照箇所を取得

#### Step 5: メタデータビルドを理解する

ffi.build_single()の実装を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | ffi.lua | `script/plugins/ffi/init.lua` | build_single関数の実装 |

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

```
workspace/executeCommand (lua.reloadFFIMeta)
    │
    └─ reloadFFIMeta.lua (エントリーポイント)
           │
           ├─ config.get('Lua.runtime.version')
           │
           ├─ ws.awaitReady()
           │
           ├─ createDir()
           │      ├─ scope.getScope()
           │      ├─ SDBMHash()
           │      └─ fs.create_directories()
           │
           ├─ cdefRerence()
           │      ├─ files.eachFile()
           │      └─ reference()
           │
           └─ [for each ref]
                  ├─ searchCode()
                  │
                  └─ ffi.build_single()
                         │
                         └─ (メタデータファイル出力)
```

### データフロー図

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

{ uri } ───▶ reloadFFIMeta.lua ───▶ メタデータファイル
                  │
                  ▼
            config.get('version')
                  │
                  ▼ (LuaJITの場合のみ続行)
            createDir()
                  │
                  ▼
            cdefRerence()
                  │
                  ▼
            refs[] (ffi.cdef参照一覧)
                  │
                  ▼
            [for each ref]
                  │
                  ├─ searchCode()
                  │      │
                  │      ▼
                  │  codes[] (Cコード)
                  │
                  └─ ffi.build_single()
                         │
                         ▼
                   METAPATH/{hash}/*.lua
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| reloadFFIMeta.lua | `script/core/command/reloadFFIMeta.lua` | ソース | コマンドエントリーポイント |
| cdefRerence.lua | `script/plugins/ffi/cdefRerence.lua` | ソース | cdef参照検索 |
| searchCode.lua | `script/plugins/ffi/searchCode.lua` | ソース | Cコード抽出 |
| ffi/init.lua | `script/plugins/ffi/init.lua` | ソース | FFIメタデータビルド |
| config.lua | `script/config/config.lua` | ソース | 設定取得 |
| workspace.lua | `script/workspace/workspace.lua` | ソース | ワークスペース管理 |
| scope.lua | `script/workspace/scope.lua` | ソース | スコープ管理 |
| SDBMHash.lua | `script/SDBMHash.lua` | ソース | ハッシュ計算 |
| client.lua | `script/client.lua` | ソース | 設定変更 |
