# 機能設計書 60-@field アノテーション

## 概要

本ドキュメントは、Lua Language Serverにおける`@field`アノテーション機能の設計を記載する。この機能は、クラスやテーブルのフィールド（メンバ変数）に対して型情報と説明を付与するためのアノテーションを提供する。

### 本機能の処理概要

`@field`アノテーションは、`@class`アノテーションの直後に配置し、クラスのフィールドを定義する機能である。フィールドの可視性（public/protected/private/package）も指定できる。

**業務上の目的・背景**：クラスのフィールド型を明示することで、フィールドアクセス時の型推論と補完機能が向上し、開発者が正しいフィールドを使用できるようになる。

**機能の利用シーン**：
- クラス定義時のフィールド型指定
- テーブルのフィールド構造定義
- APIドキュメントの生成
- フィールドアクセスの型チェック

**主要な処理内容**：
1. `---@field`コメントの解析
2. 可視性修飾子の解析（オプション）
3. フィールド名の解析
4. 型式の解析
5. クラスへのバインド

**関連システム・外部連携**：LuaDoc解析、@classアノテーション、型推論と連携。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | ホバー情報表示 | 主機能 | フィールド型を表示 |
| 2 | 自動補完 | 主機能 | フィールド候補を表示 |
| 3 | 定義へ移動 | 補助機能 | フィールド定義への移動 |

## 機能種別

データ定義 / フィールド型指定

## 入力仕様

### 入力パラメータ

アノテーション構文：
```lua
---@field [visible] fieldName[?] Type [description]
---@field [visible] [key] Type [description]
```

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| visible | string | No | 可視性（public/protected/private/package） | 指定値のみ |
| fieldName | string | Yes | フィールド名（名前または`[index]`形式） | 有効な識別子 |
| ? | symbol | No | 省略可能フラグ | - |
| Type | string | Yes | 型名 | 有効な型式 |
| description | string | No | 説明文 | - |

### 入力データソース

- Luaソースコード内の`---@field`コメント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| doc.field | parser.object | フィールド定義ASTノード |
| doc.field.field | parser.object | フィールド名ノード |
| doc.field.extends | parser.object | 型ノード |
| visible | string | 可視性修飾子 |
| optional | boolean | 省略可能フラグ |
| class | parser.object | 所属するクラス参照 |

### 出力先

- ast.docs（ドキュメント配列）
- 対応するクラスへのバインド（class.fields配列）

## 処理フロー

### 処理シーケンス

```
1. トークン解析
   └─ `field`キーワードを検出

2. 可視性チェック
   └─ public/protected/private/packageを確認

3. フィールド名解析
   ├─ parseName（通常の名前）
   └─ parseIndexField（`[type]`形式のインデックス）

4. Optionalチェック
   └─ `?`の有無を確認

5. 型解析
   └─ parseType()で型式を解析

6. クラスへのバインド
   └─ class.fields配列に追加
```

### フローチャート

```mermaid
flowchart TD
    A[---@field検出] --> B{可視性修飾子?}
    B -->|Yes| C[visible設定]
    B -->|No| D[フィールド名解析]
    C --> D
    D --> E{名前解析成功?}
    E -->|No| F[LUADOC_MISS_FIELD_NAME警告]
    E -->|Yes| G{?存在?}
    G -->|Yes| H[optional=true]
    G -->|No| I[型解析]
    H --> I
    I --> J{型解析成功?}
    J -->|No| K[LUADOC_MISS_FIELD_EXTENDS警告]
    J -->|Yes| L[doc.fieldノード返却]
    F --> M[nil返却]
    K --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-60-01 | 名前必須 | フィールド名は必須 | 常時 |
| BR-60-02 | 型必須 | 型は必須 | 常時 |
| BR-60-03 | Optional | `?`で省略可能なフィールドを表現 | nilを許容 |
| BR-60-04 | 可視性 | public/protected/private/packageで可視性を指定 | アクセス制御 |
| BR-60-05 | インデックス | `[type]`でインデックスキーの型を指定 | 辞書型フィールド |
| BR-60-06 | クラス所属 | @classの後に配置して関連付け | クラス定義時 |

### 計算ロジック

**フィールド定義例**：
```lua
---@class User
---@field name string ユーザー名
---@field age? number 年齢（省略可能）
---@field private password string パスワード（プライベート）
---@field [string] any 動的なプロパティ

---@class Config
---@field public debug boolean デバッグモード
---@field protected internal table 内部設定
---@field package shared table パッケージ内共有
```

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

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| LUADOC_MISS_FIELD_NAME | フィールド名不足 | フィールド名が指定されていない | 警告を出力、nil返却 |
| LUADOC_MISS_FIELD_EXTENDS | 型不足 | 型が指定されていない | 警告を出力、nil返却 |

### リトライ仕様

リトライは行わない。

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

トランザクションは使用しない。

## パフォーマンス要件

特になし。

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

特になし。

## 備考

- `@field`は`@class`の直後に続けて記述する
- 可視性はコード補完時のフィルタリングに使用される
- インデックス形式`[type]`は辞書型テーブルのキー型定義に使用

---

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

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

### 推奨読解順序

#### Step 1: 解析処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | luadoc.lua | `script/parser/luadoc.lua` | docSwitch 'field'（1216-1268行目） |
| 1-2 | luadoc.lua | `script/parser/luadoc.lua` | parseIndexField（292-300行目） |

**主要処理フロー**:
1. **1218-1220行目**: doc.fieldノードの初期化
2. **1222-1239行目**: 可視性修飾子（public/protected/private/package）のチェック
3. **1240-1241行目**: parseNameまたはparseIndexFieldでフィールド名を解析
4. **1253-1256行目**: `?`でoptionalをチェック
5. **1257行目**: parseTypeで型を解析

#### Step 2: クラスへのバインド処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | luadoc.lua | `script/parser/luadoc.lua` | bindDocs内のdoc.field処理（2135-2145行目） |

**バインド処理**:
1. **2136-2138行目**: classが存在する場合、class.fieldsに追加
2. **2140-2142行目**: sourceが存在する場合、doc.sourceにバインド
3. **2144行目**: コメントをドキュメントにバインド

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

```
docSwitch 'field'
    │
    ├─ try() [可視性チェック]
    │      └─ public/protected/private/package
    │
    ├─ parseName('doc.field.name', result)
    │  └─ parseIndexField(result) [代替]
    │         └─ parseType(parent) [キー型]
    │
    ├─ checkToken('symbol', '?') [optional]
    │
    └─ parseType(result) [値型]

bindDocs (doc.field)
    │
    ├─ class.fields に追加
    │
    ├─ doc.class = class
    │
    └─ bindCommentsToDoc(doc, comments)
```

### データフロー図

```
入力: ---@field protected name string ユーザー名
                   │
                   ▼
           ┌──────────────┐
           │ docSwitch    │
           │  'field'     │
           └──────────────┘
                   │
    ┌──────────────┼──────────────┐
    ▼              ▼              ▼
┌────────┐   ┌──────────┐   ┌──────────┐
│visible │   │ field    │   │ extends  │
│ 解析   │   │ 名解析   │   │ 型解析   │
└────────┘   └──────────┘   └──────────┘
    │              │              │
    ▼              ▼              ▼
"protected"   doc.field.name   doc.type
                   │
                   ▼
           ┌──────────────┐
           │ doc.field    │
           │   ノード     │
           └──────────────┘
                   │
                   ▼
           ┌──────────────┐
           │ class.fields │
           │   に追加     │
           └──────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| luadoc.lua | `script/parser/luadoc.lua` | ソース | @field解析とバインド |
| compiler.lua | `script/vm/compiler.lua` | ソース | フィールド型の推論 |
| completion.lua | `script/core/completion/completion.lua` | ソース | フィールド補完候補の提供 |
| hover/field.lua | `script/core/hover/field.lua` | ソース | ホバーでのフィールド表示 |
