# 機能設計書 67-構文木(AST)生成

## 概要

本ドキュメントは、Lua Language Serverにおける「構文木(AST)生成」機能の設計を記述する。本機能は、Luaソースコードの構文解析結果として抽象構文木（Abstract Syntax Tree）を生成し、後続の全ての言語機能の基盤となるデータ構造を提供する。

### 本機能の処理概要

構文木(AST)生成機能は、パーサー（compile.lua）によって生成される抽象構文木の構造と、その生成プロセスを定義する。ASTは各構文要素（変数、関数、式、文など）をノードとして表現し、親子関係により階層構造を形成する。

**業務上の目的・背景**：プログラムの構造をデータとして表現することで、型推論、補完、リファクタリングなどの高度な機能を実現できる。ASTはソースコードの意味的な構造を保持し、コード変換や解析の基盤となる。

**機能の利用シーン**：
- 変数の定義・参照関係の解析
- 関数のシグネチャ抽出
- スコープの階層構造の把握
- コード補完候補の計算
- 診断（エラー・警告）の生成

**主要な処理内容**：
1. 各種ASTノードタイプの定義と生成
2. 親子関係（parent/children）の設定
3. 位置情報（start/finish）の記録
4. スコープ情報の付与
5. 特殊ノード（getlocal/setlocal等）の生成
6. メタデータ（型情報等）の付与

**関連システム・外部連携**：
- compile.lua：ASTの生成元
- guide.lua：AST操作のユーティリティ
- vm/各モジュール：ASTを入力として処理
- core/各機能：ASTを利用した機能提供

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 41 | AST可視化 | 主機能 | 抽象構文木をGraphviz形式で可視化するCLI処理 |
| 42 | PSIビュー | 補助機能 | 構文木の生成処理 |
| 43 | PSI選択 | 補助機能 | 構文木の生成処理 |

## 機能種別

コード解析 / データ構造生成

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| ソースコード | string | Yes | 解析対象のLuaコード | - |

### 入力データソース

パーサー（compile.lua）の解析処理

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ast | table | ASTのルートノード |
| ast.type | string | ノードタイプ（'main'等） |
| ast.start | integer | 開始位置 |
| ast.finish | integer | 終了位置 |
| ast.uri | string | ファイルURI |
| ast[n] | table | 子ノード（配列部分） |

### 出力先

state.astとして返却される

## 処理フロー

### 処理シーケンス

```
1. ルートノード生成
   └─ type='main'のノードを作成
2. 文の解析と追加
   └─ 各文をルートノードの子として追加
3. 各ノードの構築
   ├─ ノードタイプの設定
   ├─ 位置情報の設定
   ├─ 親子関係の設定
   └─ スコープ情報の付与
4. 変数参照の解決
   └─ getlocal/getglobal等のノード生成
5. 関数定義の処理
   └─ 引数、本体、戻り値のノード構築
6. 表構造の処理
   └─ tablefield、tableindex等のノード構築
7. 最終化
   └─ state.astに設定
```

### フローチャート

```mermaid
flowchart TD
    A[パーサー開始] --> B[ルートノード生成]
    B --> C[文の解析ループ]
    C --> D{文の種類}
    D -->|変数宣言| E[local/globalノード生成]
    D -->|関数定義| F[functionノード生成]
    D -->|制御構文| G[if/for/whileノード生成]
    D -->|式| H[expノード生成]
    E --> I[親子関係設定]
    F --> I
    G --> I
    H --> I
    I --> J[位置情報設定]
    J --> K{次の文あり?}
    K -->|Yes| C
    K -->|No| L[state.astに設定]
    L --> M[AST完成]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ノードタイプ必須 | 全てのノードにはtypeフィールドが必須 | 常時 |
| BR-02 | 位置情報必須 | 全てのノードにstart/finishが設定される | 常時 |
| BR-03 | 親参照 | 子ノードは親への参照（parent）を持つ | 常時 |
| BR-04 | スコープ管理 | ローカル変数はスコープ（chunk）に登録 | 変数宣言時 |
| BR-05 | 参照解決 | 変数参照はgetlocal/getglobalに変換 | 変数参照時 |

### 計算ロジック

位置情報の計算：
- `position = LineMulti * Line + offset - LineOffset`
- LineMulti = 10000（行番号の重み）

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | AST生成自体ではエラーは発生しない | - |

### リトライ仕様

リトライは不要

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

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

## パフォーマンス要件

- AST生成はパーサー処理の一部として100ms以内
- メモリ使用量はソースコードサイズの10倍以内

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

特になし

## 備考

- ASTノードは多くのフィールドを持ち、guide.luaでアクセスすることが推奨される
- ノードタイプは60種類以上存在する

---

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

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

### 推奨読解順序

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

まず、ASTノードの基本構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | guide.lua | `script/parser/guide.lua` | ASTノードの共通フィールド、操作関数 |
| 1-2 | compile.lua | `script/parser/compile.lua` | ノード生成のパターン |

**読解のコツ**: ASTノードの共通フィールド：
- `type`: ノードの種類（'local', 'function', 'call'等）
- `start`: 開始位置（行と列をエンコード）
- `finish`: 終了位置
- `parent`: 親ノードへの参照
- `[1]`: 名前などの主要な値（ノードタイプにより異なる）

#### Step 2: 主要なノードタイプを理解する

頻出するノードタイプの構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | compile.lua | `script/parser/compile.lua` | 変数関連ノード（local, getlocal, setlocal等） |
| 2-2 | compile.lua | `script/parser/compile.lua` | 関数関連ノード（function, call, return等） |
| 2-3 | compile.lua | `script/parser/compile.lua` | テーブル関連ノード（table, tablefield, tableindex等） |

**主要ノードタイプ**:
- `local`: ローカル変数宣言
- `getlocal`: ローカル変数参照
- `setlocal`: ローカル変数への代入
- `getglobal`: グローバル変数参照
- `setglobal`: グローバル変数への代入
- `function`: 関数定義
- `call`: 関数呼び出し
- `table`: テーブルコンストラクタ
- `tablefield`: テーブルの名前付きフィールド
- `tableindex`: テーブルのインデックスアクセス

#### Step 3: ノード生成の流れを理解する

ASTノードが生成される流れを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | compile.lua | `script/parser/compile.lua` | `createLocal`関数（729-757行目） |
| 3-2 | compile.lua | `script/parser/compile.lua` | `parseSimple`関数 |
| 3-3 | compile.lua | `script/parser/compile.lua` | `parseTable`関数 |

**主要処理フロー**:
- ノードタイプをテーブルの`type`フィールドに設定
- `getPosition`関数で位置情報を計算
- 子ノードの`parent`フィールドに親ノードを設定
- チャンク（スコープ）の`locals`配列に変数を登録

#### Step 4: guide.luaのユーティリティを理解する

AST操作のためのユーティリティ関数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | guide.lua | `script/parser/guide.lua` | `eachSourceType`関数 |
| 4-2 | guide.lua | `script/parser/guide.lua` | `getParentBlock`関数 |
| 4-3 | guide.lua | `script/parser/guide.lua` | `positionOf`, `rowColOf`関数 |

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

```
compile (エントリーポイント)
    │
    ├─ parseActions
    │      │
    │      ├─ parseLocal
    │      │      └─ createLocal
    │      │             └─ {type='local', ...}
    │      │
    │      ├─ parseFunction
    │      │      └─ {type='function', args=..., ...}
    │      │
    │      ├─ parseExp
    │      │      ├─ parseName → {type='getlocal'/'getglobal'}
    │      │      └─ parseTable → {type='table', ...}
    │      │
    │      └─ 各文の解析関数
    │
    └─ state.ast = {type='main', ...}

guide (ユーティリティ)
    │
    ├─ eachSourceType (ノード検索)
    ├─ getParentBlock (スコープ取得)
    └─ positionOf (位置変換)
```

### データフロー図

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

local x = 1
        │
        ▼
  parseLocal           ───▶  ノード生成
        │
        ▼
  createLocal          ───▶  {
        │                      type = 'local',
        │                      start = 10001,
        │                      finish = 10007,
        │                      [1] = 'x',
        │                      value = {
        │                        type = 'integer',
        │                        [1] = 1
        │                      }
        │                    }
        ▼
  Chunk.locals追加     ───▶  スコープに登録
        │
        ▼
  state.ast            ───▶  {
                              type = 'main',
                              [1] = {type='local', ...}
                            }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| compile.lua | `script/parser/compile.lua` | ソース | AST生成のメイン処理 |
| guide.lua | `script/parser/guide.lua` | ソース | AST操作ユーティリティ |
| tokens.lua | `script/parser/tokens.lua` | ソース | 字句解析（AST生成前処理） |
| luadoc.lua | `script/parser/luadoc.lua` | ソース | アノテーションのAST拡張 |
| files.lua | `script/files.lua` | ソース | ASTキャッシュ管理 |
| infer.lua | `script/vm/infer.lua` | ソース | ASTを使用した型推論 |
