# 機能設計書 62-@enum

## 概要

本ドキュメントは、Lua Language Serverにおける`@enum`アノテーション機能の設計を記述する。`@enum`は列挙型を定義するためのLuaDocアノテーションであり、テーブル内の定数値に名前を付けて型として扱えるようにする機能を提供する。

### 本機能の処理概要

`@enum`アノテーションは、Luaのテーブルを列挙型として定義する機能である。これにより、テーブル内の各フィールドを列挙値として扱い、型チェックや補完候補の提供に活用できる。

**業務上の目的・背景**：Lua言語にはネイティブの列挙型が存在しないため、定数値をテーブルで管理することが一般的である。しかし、単なるテーブルでは型安全性が確保できず、誤った値の使用を検出できない。`@enum`アノテーションを使用することで、列挙型のセマンティクスを追加し、静的解析による型チェックが可能となる。

**機能の利用シーン**：
- 状態管理（STATE_IDLE, STATE_RUNNING等）のような定数集合を定義する場合
- エラーコードの集合を定義する場合
- 設定オプションの有効値を制限する場合
- 関数パラメータとして特定の値のみを許可する場合

**主要な処理内容**：
1. `---@enum`で始まるコメント行を検出
2. ドキュメント属性（オプション）を解析
3. 列挙型名を解析し、`doc.enum.name`ノードを生成
4. 直後のテーブル定義にバインド
5. テーブルのフィールドを列挙値として登録
6. 型システムに列挙型を追加し、補完・型チェックで利用可能に

**関連システム・外部連携**：
- パーサー（`script/parser/luadoc.lua`）：アノテーション構文の解析
- バインディング処理（`script/parser/luadoc.lua` `bindDoc`）：テーブルとの関連付け
- 型推論エンジン（`script/vm/infer.lua`）：列挙型の解決
- 補完システム：列挙値の補完候補提供

**権限による制御**：本機能に権限制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はエディタのコメント入力時に動作し、専用の画面は存在しない |

## 機能種別

コード解析 / 型定義

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| コメントテキスト | string | Yes | `---@enum`で始まるコメント行 | `@enum`キーワードの存在確認 |
| 列挙型名 | string | Yes | 定義する列挙型の名前 | 有効な識別子であること |
| バインド対象テーブル | table | Yes | 列挙値を含むテーブル定義 | 直後のテーブル定義であること |

### 入力データソース

Luaソースファイル内の`---@enum`形式のコメント行と、直後のテーブル定義

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| doc.enum | table | 列挙型定義のASTノード |
| doc.enum.name | table | 列挙型名を表すノード |
| doc.enum.docAttr | table | ドキュメント属性（存在する場合） |
| bindSource | table | バインドされたテーブルへの参照 |

### 出力先

パーサーの状態オブジェクト（`state.ast.docs`）に追加される

## 処理フロー

### 処理シーケンス

```
1. コメント解析開始
   └─ `---@enum`形式のコメントを検出
2. トークン解析
   └─ コメントテキストをトークンに分割
3. `enum`キーワード認識
   └─ docSwitch関数でenumケースにディスパッチ
4. ドキュメント属性解析（オプション）
   └─ `(key)`などの属性があれば解析
5. 列挙型名解析
   └─ `doc.enum.name`ノードを生成
6. ASTノード構築
   └─ `doc.enum`ノードを生成
7. テーブルバインディング
   └─ 直後のテーブル定義を検索しバインド
8. ドキュメントリストに追加
   └─ `state.ast.docs`にノードを追加
```

### フローチャート

```mermaid
flowchart TD
    A[コメント検出] --> B{@enumキーワード?}
    B -->|No| Z[終了]
    B -->|Yes| C[docAttr解析]
    C --> D{列挙型名あり?}
    D -->|No| E[nil返却]
    E --> Z
    D -->|Yes| F[列挙型名ノード生成]
    F --> G[doc.enumノード構築]
    G --> H[bindDoc処理]
    H --> I{テーブル定義あり?}
    I -->|Yes| J[テーブルにバインド]
    I -->|No| K[バインドなし]
    J --> L[ASTに追加]
    K --> L
    L --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 列挙型名必須 | 列挙型定義には必ず名前が必要 | @enumアノテーション使用時 |
| BR-02 | テーブルバインド | 直後のテーブル定義または代入文のテーブルにバインド | @enumアノテーション使用時 |
| BR-03 | フィールド値の型 | テーブルのフィールド値が列挙値となる | バインド時 |
| BR-04 | キー属性 | `(key)`属性でキーを列挙値として扱うことが可能 | docAttrに`key`指定時 |

### 計算ロジック

特になし

## データベース操作仕様

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

本機能はデータベースを使用しない（メモリ上でAST操作を行う）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | 列挙型名が指定されていない場合はnilを返却し警告なし | 正しい列挙型名を指定する |

### リトライ仕様

リトライは不要（構文解析時のエラーは即座に報告される）

## トランザクション仕様

トランザクション管理は不要（メモリ上の解析処理）

## パフォーマンス要件

- 単一の列挙型解析は1ms以内に完了すること
- テーブルバインディング処理は追加で1ms以内

## セキュリティ考慮事項

- 入力文字列の検証（不正な識別子の排除）
- 極端に大きなテーブル定義の処理制限

## 備考

- `@enum`は主にテーブル定義の直前に記述される
- VSCodeなどのエディタでは、列挙型名にホバーすると定義内容が表示される
- 列挙値は補完候補として自動的に提示される

---

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

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

### 推奨読解順序

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

まず、`@enum`アノテーションがどのようなASTノードとして表現されるかを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | luadoc.lua | `script/parser/luadoc.lua` | `doc.enum`ノードの構造、`doc.enum.name`、`docAttr`フィールドの役割 |

**読解のコツ**: `doc.enum`ノードは以下のフィールドを持つ：
- `type`: `'doc.enum'`
- `enum`: 列挙型名（`doc.enum.name`型）
- `docAttr`: ドキュメント属性（オプション）
- `start`, `finish`: 位置情報

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

`@enum`アノテーションの解析処理の起点を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | luadoc.lua | `script/parser/luadoc.lua` | `docSwitch`の`'enum'`ケース（1677-1696行目） |

**主要処理フロー**:
1. **1679行目**: `parseDocAttr`でドキュメント属性を解析
2. **1680行目**: `parseName`で列挙型名を解析
3. **1681-1683行目**: 名前がない場合はnilを返却
4. **1684-1690行目**: `doc.enum`ノードを構築
5. **1691-1694行目**: 親子関係を設定

#### Step 3: バインディング処理を理解する

列挙型定義がテーブルにバインドされる処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | luadoc.lua | `script/parser/luadoc.lua` | `bindDoc`関数内のenum処理（2024-2032行目） |
| 3-2 | luadoc.lua | `script/parser/luadoc.lua` | `bindCommentsAndFields`関数内のalias/enum処理（2158-2161行目） |

**主要処理フロー**:
- **2024-2032行目**: `doc.enum`がテーブルまたは代入文にバインドされる
- **2025-2028行目**: `source.type == 'table'`の場合に直接バインド
- **2029-2031行目**: 代入文（`source.value`）がテーブルの場合にバインド

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

```
luadoc (メイン関数)
    │
    ├─ buildLuaDoc
    │      └─ convertTokens
    │             └─ docSwitch('enum')
    │                    ├─ parseDocAttr
    │                    └─ parseName
    │
    └─ bindDocs
           └─ bindDocsBetween
                  └─ bindDoc
                         └─ doc.enum処理
                                └─ テーブルへのバインド
```

### データフロー図

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

---@enum Status
local Status = {
    IDLE = 1,
    RUNNING = 2,
}
        │
        ▼
  parseTokens              ───▶  トークン配列
        │
        ▼
  docSwitch('enum')        ───▶  enumケース処理
        │
        ▼
  parseName                ───▶  doc.enum.name = "Status"
        │
        ▼
  doc.enumノード構築       ───▶  {type: 'doc.enum', ...}
        │
        ▼
  bindDoc                  ───▶  テーブルにバインド
        │
        ▼
  state.ast.docs に追加    ───▶  完成したASTノード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| luadoc.lua | `script/parser/luadoc.lua` | ソース | LuaDocアノテーションの解析メイン処理 |
| compile.lua | `script/parser/compile.lua` | ソース | Luaソースコードのコンパイル |
| guide.lua | `script/parser/guide.lua` | ソース | AST操作のユーティリティ関数 |
| infer.lua | `script/vm/infer.lua` | ソース | 型推論エンジン（列挙型の解決） |
| completion.lua | `script/core/completion/completion.lua` | ソース | 補完候補の提供（列挙値の補完） |
