# 機能設計書 65-@async

## 概要

本ドキュメントは、Lua Language Serverにおける`@async`アノテーション機能の設計を記述する。`@async`は非同期関数を示すためのLuaDocアノテーションであり、コルーチンベースの非同期処理を行う関数であることをマーキングする機能を提供する。

### 本機能の処理概要

`@async`アノテーションは、関数が非同期処理を行うことを示すマーカーである。Luaのコルーチンを使用した非同期パターンにおいて、関数が`coroutine.yield`や`coroutine.resume`を使用することを明示し、型システムと診断機能で適切な警告を提供する。

**業務上の目的・背景**：Luaでの非同期処理は主にコルーチンを使用して実装される。しかし、どの関数が非同期かを型情報だけで判断することは困難である。`@async`アノテーションにより、非同期関数の明示的なマーキングが可能となり、呼び出し側で適切な`await`処理が必要かどうかを判断できる。

**機能の利用シーン**：
- コルーチンを使用した非同期I/O処理
- ゲームループでのコルーチンベースの処理
- Luaサーバーフレームワークでの非同期リクエスト処理
- 長時間実行される計算の非同期化

**主要な処理内容**：
1. `---@async`で始まるコメント行を検出
2. `doc.async`ノードを生成
3. 直後の関数定義にバインド
4. 型推論で関数に`async`フラグを設定
5. 非同期関数を同期的に呼び出した場合の警告を提供（オプション）

**関連システム・外部連携**：
- パーサー（`script/parser/luadoc.lua`）：アノテーション構文の解析
- 型推論エンジン（`script/vm/infer.lua`）：非同期フラグの伝播
- ホバー情報：非同期関数の表示
- バインディング処理：関数定義との関連付け

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

## 関連画面

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

## 機能種別

コード解析 / メタデータ付与

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| コメントテキスト | string | Yes | `---@async`で始まるコメント行 | `@async`キーワードの存在確認 |

### 入力データソース

Luaソースファイル内の`---@async`形式のコメント行

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| doc.async | table | 非同期マーカーのASTノード |
| start | integer | 開始位置 |
| finish | integer | 終了位置 |
| bindSource | table | バインドされた関数への参照 |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. コメント解析開始
   └─ `---@async`形式のコメントを検出
2. トークン解析
   └─ コメントテキストをトークンに分割
3. `async`キーワード認識
   └─ docSwitch関数でasyncケースにディスパッチ
4. ASTノード構築
   └─ `doc.async`ノードを生成（シンプルなノード）
5. 関数バインディング
   └─ 直後の関数定義にバインド
6. ドキュメントリストに追加
   └─ `state.ast.docs`にノードを追加
7. 型システム連携
   └─ 関数のasyncフラグを設定
```

### フローチャート

```mermaid
flowchart TD
    A[コメント検出] --> B{@asyncキーワード?}
    B -->|No| Z[終了]
    B -->|Yes| C[doc.asyncノード生成]
    C --> D[位置情報設定]
    D --> E[ASTに追加]
    E --> F[bindDoc処理]
    F --> G{関数定義あり?}
    G -->|Yes| H[関数にバインド]
    G -->|No| I[バインドなし]
    H --> J[asyncフラグ設定]
    I --> Z
    J --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | シンプルマーカー | @asyncは追加パラメータなしで機能 | @asyncアノテーション使用時 |
| BR-02 | 関数バインド | 関数定義に対してのみバインド可能 | @asyncの後に関数定義がある場合 |
| BR-03 | asyncフラグ | 関数の型情報にasyncフラグを付与 | バインド成功時 |
| BR-04 | ホバー表示 | ホバー情報にasyncであることを表示 | async関数にホバー時 |

### 計算ロジック

特になし

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | @asyncの解析自体でエラーは発生しない | - |

### リトライ仕様

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

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

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

## パフォーマンス要件

- @asyncの解析は0.1ms以内に完了すること

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

特になし

## 備考

- `@async`は単独で使用可能（追加パラメータ不要）
- `@param`、`@return`などと組み合わせて使用可能
- `async fun(...)`形式の関数型定義でもasyncを指定可能
- `fun`関数型の直前に`async`キーワードを付けることも可能

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | luadoc.lua | `script/parser/luadoc.lua` | `doc.async`ノードの構造（非常にシンプル） |
| 1-2 | luadoc.lua | `script/parser/luadoc.lua` | `parser.object`の`async`フィールド（150行目） |

**読解のコツ**: `doc.async`ノードは以下のフィールドを持つ：
- `type`: `'doc.async'`
- `start`: 開始位置
- `finish`: 終了位置

また、関数型（`doc.type.function`）には`async`フラグと`asyncPos`位置情報が付与される。

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

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

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

**主要処理フロー**:
1. **1517-1521行目**: シンプルなテーブルを返却
   - `type = 'doc.async'`
   - `start = getFinish()`
   - `finish = getFinish()`

このケースは非常にシンプルで、追加の解析処理は行わない。

#### Step 3: async関数型の解析を理解する

`async fun(...)`形式の関数型解析を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | luadoc.lua | `script/parser/luadoc.lua` | `parseFunction`関数（670-690行目） |

**主要処理フロー**:
- **672行目**: `content == 'async'`をチェック
- **673-674行目**: `nextToken()`で次に進み、位置を記録
- **678行目**: `func`が取得できれば`async = true`を設定
- **681行目**: `asyncPos`に位置を記録

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

非同期マーカーが関数にバインドされる仕組みを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | luadoc.lua | `script/parser/luadoc.lua` | `bindDoc`関数内のasync処理（2016-2023行目） |

**主要処理フロー**:
- **2017行目**: `doc.type == 'doc.async'`の条件分岐
- **2018行目**: `doc.type == 'doc.nodiscard'`も同様の処理
- **2019-2023行目**: `source.type == 'function'`の場合にバインド

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

```
luadoc (メイン関数)
    │
    ├─ buildLuaDoc
    │      └─ convertTokens
    │             └─ docSwitch('async')
    │                    └─ シンプルなノード返却
    │
    ├─ parseFunction (async fun型の解析)
    │      └─ 'async'キーワードの検出
    │             └─ func.async = true 設定
    │
    └─ bindDocs
           └─ bindDocsBetween
                  └─ bindDoc
                         └─ doc.async処理
                                └─ 関数へのバインド
```

### データフロー図

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

---@async
function fetch() end
        │
        ▼
  parseTokens              ───▶  トークン配列
        │
        ▼
  docSwitch('async')       ───▶  asyncケース処理
        │
        ▼
  シンプルノード生成       ───▶  {type: 'doc.async', ...}
        │
        ▼
  bindDoc                  ───▶  関数定義にバインド
        │
        ▼
  state.ast.docs に追加    ───▶  完成したASTノード
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| luadoc.lua | `script/parser/luadoc.lua` | ソース | LuaDocアノテーションの解析メイン処理 |
| await.lua | `script/await.lua` | ソース | 非同期処理のユーティリティ（実行時） |
| infer.lua | `script/vm/infer.lua` | ソース | 型推論エンジン |
| hover/init.lua | `script/core/hover/init.lua` | ソース | ホバー情報にasyncフラグを表示 |
| compile.lua | `script/parser/compile.lua` | ソース | Luaソースコードのコンパイル |
