# 画面設計書 45-APIレポート

## 概要

本ドキュメントは、Lua Language Serverの内部LSP機能「APIレポート」の画面設計書です。外部アプリケーション（ゲームエンジン、フレームワーク等）のAPIメタデータを受け取り、Lua Language Serverが利用可能なLuaDocアノテーション形式のメタファイルに変換・生成する機能です。

### 本画面の処理概要

**業務上の目的・背景**：ゲームエンジン（Unity、Unreal Engine等）やLuaフレームワークは独自のAPIを提供しますが、これらのAPIはLua Language Serverのデフォルト設定では認識されません。本機能は、外部ツールやエディタ拡張機能からAPIメタデータ（クラス、メソッド、フィールドの定義）を受け取り、LuaDoc形式のメタファイルを自動生成します。生成されたメタファイルはワークスペースライブラリに追加され、コード補完やホバー情報などのLSP機能で外部APIを認識できるようになります。

**画面へのアクセス方法**：外部ツールまたはエディタ拡張機能から内部LSPリクエスト `$/api/report` を送信することでアクセスします。通常のユーザー操作ではなく、プログラマティックに呼び出される機能です。

**主要な操作・処理内容**：
1. クライアントからLSPリクエスト `$/api/report` を受信する
2. リクエストパラメータからAPIメタデータ（クラス、メソッド、フィールド定義）を取得する
3. メタファイルの保存先ディレクトリを決定する（名前、ハッシュ、エンコーディングを考慮）
4. APIメタデータをLuaDoc形式のLuaファイルに変換する
5. 生成されたファイルをディスクに保存する
6. 生成されたディレクトリをワークスペースライブラリに追加する設定変更を行う

**画面遷移**：LSPリクエスト/レスポンス形式のため、画面遷移はありません。処理完了後、ワークスペース設定が更新され、新しいAPIメタデータが利用可能になります。

**権限による表示制御**：特別な権限制御はありません。ファイルシステムへの書き込み権限が必要です。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 90 | メタデータ構築 | 主機能 | APIメタデータをレポート・生成する内部処理 |
| 72 | 設定管理 | 補助機能 | 設定情報の取得・更新 |

## 画面種別

LSP内部リクエスト

## URL/ルーティング

LSPメソッド: `$/api/report`

## 入出力項目

### 入力パラメータ（meta 構造）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| name | string | No | メタデータセットの名前（デフォルト: "default"） |
| root | string | Yes | ルートネームスペース名 |
| classes | meta.class[] | Yes | クラス定義の配列 |

### meta.class 構造

| フィールド | 型 | 説明 |
|-----------|-----|------|
| name | string | クラス名 |
| comment | string | クラスのコメント/説明 |
| location | string | 定義位置（ソースファイル参照用） |
| namespace | string | 名前空間 |
| baseClass | string | 基底クラス名 |
| attribute | string | 属性情報 |
| interface | string[] | 実装インターフェース |
| fields | meta.field[] | フィールド定義配列 |
| methods | meta.method[] | メソッド定義配列 |

### meta.field 構造

| フィールド | 型 | 説明 |
|-----------|-----|------|
| name | string | フィールド名 |
| typeName | string | 型名 |
| comment | string | コメント/説明 |
| location | string | 定義位置 |

### meta.method 構造

| フィールド | 型 | 説明 |
|-----------|-----|------|
| name | string | メソッド名 |
| comment | string | コメント/説明 |
| location | string | 定義位置 |
| isStatic | boolean | 静的メソッドか |
| returnTypeName | string | 戻り値の型名 |
| params | {name: string, typeName: string}[] | パラメータ配列 |

### 出力

本機能は明示的なレスポンスを返しません。副作用として以下が発生します：

- メタファイルがファイルシステムに生成される
- ワークスペースライブラリ設定が更新される

## 表示項目

| 項目名 | 説明 | 形式 |
|--------|------|------|
| 進捗表示 | メタファイル構築の進捗状況 | プログレスバー |
| 進捗メッセージ | 現在処理中の名前空間 | テキスト |

## イベント仕様

### 1-APIレポートリクエスト

LSPリクエスト `$/api/report` を受信すると、以下の処理が行われます：

1. `script/provider/provider.lua` の `$/api/report` ハンドラが呼び出される（1556-1583行目）
2. 既存の `api/report` 非同期タスクを終了する
3. 新しい非同期タスクIDを設定する
4. メタデータセットの名前を決定する（デフォルト: "default"）
5. ワークスペースURIのハッシュを計算する
6. ファイルエンコーディング設定を取得する
7. 保存先ディレクトリパスを構築する
8. ディレクトリを作成する
9. `build-meta.build()` を呼び出してメタファイルを生成する
10. `client.setConfig()` でワークスペースライブラリに追加する

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

本機能はデータベースを使用しません。

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | データベース操作なし |

### ファイルシステム更新

| 操作 | 対象パス | 操作種別 | 概要 |
|-----|---------|---------|------|
| APIレポート | `{METAPATH}/{name} {hash} {encoding}/` | CREATE | メタファイルディレクトリ作成 |
| APIレポート | `{METAPATH}/{name} {hash} {encoding}/*.lua` | CREATE/UPDATE | メタファイル生成 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|-------------|------|---------------|---------|
| WINDOW_PROCESSING_BUILD_META | 進捗 | メタファイル構築中の進捗表示 | 処理中 |

## 例外処理

| 例外条件 | 処理内容 | レスポンス |
|---------|---------|-----------|
| ディレクトリ作成失敗 | ファイルシステムエラー | エラー |
| ファイル書き込み失敗 | ファイルシステムエラー | エラー |
| メソッド名が不正 | スキップして続行 | なし |

## 備考

- 本機能は `$/` プレフィックスで始まるLSP仕様外の拡張リクエストです
- 生成されるメタファイルは `---@meta` ディレクティブで始まるLuaDoc形式です
- 同じ名前・ハッシュ・エンコーディングの組み合わせで既存ファイルは上書きされます
- ワークスペースライブラリへの追加は `client.setConfig()` を通じて行われます
- メソッド名が識別子として不正な場合（`[^%a_][^%w_]*`）はスキップされます
- ソース位置情報は `#` を `:` に置換して `---@source` ディレクティブに出力されます

---

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

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

### 推奨読解順序

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

まず、APIメタデータのデータ構造を理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | build-meta.lua | `script/provider/build-meta.lua` | `meta`, `meta.class`, `meta.field`, `meta.method` クラス定義（8-36行目）でメタデータ構造を理解 |

**読解のコツ**: `meta` はルートネームスペースと`classes`配列を持ち、各クラスは名前空間、フィールド、メソッドを含む階層構造です。

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

処理の起点となるLSPハンドラを特定します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | provider.lua | `script/provider/provider.lua` | `$/api/report` ハンドラの登録（1556-1583行目）がエントリーポイント |

**主要処理フロー**:
1. **1558行目**: 非同期関数の定義開始
2. **1559行目**: `build-meta` モジュールをrequire
3. **1560行目**: `SDBMHash` モジュールをrequire
4. **1561-1562行目**: 既存タスクを終了し、新しいタスクIDを設定
5. **1563行目**: メタデータ名を取得（デフォルト: "default"）
6. **1564-1565行目**: ワークスペースURIのハッシュを計算
7. **1566行目**: ファイルエンコーディング設定を取得
8. **1567-1571行目**: ディレクトリパスを構築
9. **1572行目**: ディレクトリを作成
10. **1573行目**: `buildMeta.build()` を呼び出し
11. **1574-1581行目**: ワークスペースライブラリに追加

#### Step 3: メタファイル生成処理を理解する

メタファイル生成の詳細ロジックを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | build-meta.lua | `script/provider/build-meta.lua` | `build()` 関数（130-151行目）で全体フローを理解 |
| 3-2 | build-meta.lua | `script/provider/build-meta.lua` | `buildText()` 関数（89-116行目）でクラス定義のテキスト生成を理解 |
| 3-3 | build-meta.lua | `script/provider/build-meta.lua` | `addMethod()` 関数（62-84行目）でメソッド定義のテキスト生成を理解 |
| 3-4 | build-meta.lua | `script/provider/build-meta.lua` | `addComments()` 関数（50-57行目）でコメント出力を理解 |

**主要処理フロー**:
- **130-134行目**: `build()` 関数でファイルコンテンツを初期化（`---@meta`ヘッダー）
- **136行目**: ルートネームスペースのテキストを追加
- **138-146行目**: 全クラスをループし、名前空間ごとにテキストを生成
- **148-150行目**: ファイルを名前空間ごとに保存

#### Step 4: 出力フォーマットを理解する

生成されるLuaDocアノテーションの形式を理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | build-meta.lua | `script/provider/build-meta.lua` | `buildText()` 関数で `---@class`, `---@field`, `---@source` の出力形式を確認 |
| 4-2 | build-meta.lua | `script/provider/build-meta.lua` | `addMethod()` 関数で `---@param`, `---@return`, `function` の出力形式を確認 |

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

```
$/api/report handler [provider.lua:1556]
    │
    ├─ require 'provider.build-meta' [1559行目]
    │
    ├─ require 'SDBMHash' [1560行目]
    │
    ├─ await.close 'api/report' [1561行目]
    │
    ├─ await.setID 'api/report' [1562行目]
    │
    ├─ workspace.getFirstScope().uri [1564行目]
    │
    ├─ SDBMHash():hash(uri) [1565行目]
    │
    ├─ config.get(nil, 'Lua.runtime.fileEncoding') [1566行目]
    │
    ├─ fs.create_directories(fs.path(fileDir)) [1572行目]
    │
    ├─ buildMeta.build(fileDir, params) [1573行目]
    │      │
    │      ├─ buildRootText(api) [136行目]
    │      │
    │      ├─ [ループ] buildText(api.root, class) [143行目]
    │      │      │
    │      │      ├─ addComments(lines, class.comment) [92行目]
    │      │      │
    │      │      ├─ [ループ] addComments + フィールド出力 [100-104行目]
    │      │      │
    │      │      └─ [ループ] addMethod(lines, name, method) [111行目]
    │      │             │
    │      │             ├─ addComments(lines, method.comment) [66行目]
    │      │             │
    │      │             ├─ ---@source 出力 [67行目]
    │      │             │
    │      │             ├─ ---@param 出力 [69-71行目]
    │      │             │
    │      │             ├─ ---@return 出力 [73-76行目]
    │      │             │
    │      │             └─ function 定義出力 [77-82行目]
    │      │
    │      └─ util.saveFile(...) [149行目]
    │
    └─ client.setConfig() [1574行目]
           │
           └─ Lua.workspace.library に追加
```

### データフロー図

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

LSPリクエスト
{name: "unity",
 root: "CS",
 classes: [...]} ───▶ $/api/report handler
                              │
                              ▼
                     SDBMHash(uri) ───▶ ハッシュ値
                              │
                              ▼
                     fileDir構築 ───▶ "{METAPATH}/{name} {hash} {encoding}"
                              │
                              ▼
                     fs.create_directories()
                              │
                              ▼
                     buildMeta.build()
                              │
    ┌─────────────────────────┼─────────────────────────┐
    ▼                         ▼                         ▼
buildRootText()        buildText(class1)        buildText(classN)
    │                         │                         │
    ▼                         ▼                         ▼
"---@class CS\n        "---@class CS.GameObject\n ...
 CS = {}"               ---@field name string\n
                        function CS.GameObject.new() end"
    │                         │                         │
    └─────────────────────────┼─────────────────────────┘
                              ▼
                     util.saveFile()
                              │
                              ▼
                     ファイル出力: {fileDir}/*.lua
                              │
                              ▼
                     client.setConfig()
                              │
                              ▼
                     Lua.workspace.library 更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPリクエストハンドラ（1556-1583行目） |
| build-meta.lua | `script/provider/build-meta.lua` | ソース | メタファイル生成のコア実装 |
| SDBMHash.lua | `script/SDBMHash.lua` | ソース | ハッシュ計算ユーティリティ |
| utility.lua | `script/utility.lua` | ソース | ファイル保存等のユーティリティ（saveFile, multiTable） |
| client.lua | `script/client.lua` | ソース | クライアント通信（setConfig） |
| config.lua | `script/config.lua` | ソース | 設定管理（Lua.runtime.fileEncoding） |
| workspace.lua | `script/workspace/init.lua` | ソース | ワークスペース管理（getFirstScope） |
| await.lua | `script/await.lua` | ソース | 非同期処理管理（close, setID, delay） |
| progress.lua | `script/progress.lua` | ソース | 進捗表示管理 |
| language.lua | `script/language.lua` | ソース | 多言語対応（WINDOW_PROCESSING_BUILD_META） |
