# 機能設計書 2-AST生成

## 概要

本ドキュメントは、CoffeeScriptソースコードをBabel互換のAbstract Syntax Tree (AST) に変換する機能について、その処理内容、入出力仕様、およびコードリーディングガイドを記載したものである。

### 本機能の処理概要

AST生成機能は、CoffeeScriptソースコードを解析し、Babel互換のAST（抽象構文木）形式で出力する機能である。

**業務上の目的・背景**：Babelエコシステムとの統合、ESLint等の静的解析ツールとの連携、コード変換ツールの開発において、標準化されたAST形式での出力が求められる。CoffeeScript独自のAST形式ではなく、JavaScriptエコシステムで広く採用されているBabel互換形式で出力することで、既存のツールチェーンとの互換性を確保できる。

**機能の利用シーン**：ESLintプラグインでのCoffeeScriptコード解析時、Babelプラグイン開発時のAST操作、コードフォーマッタやリファクタリングツールの開発時、IDE/エディタでのコード解析機能実装時に利用される。

**主要な処理内容**：
1. ソースコードの字句解析（トークン化）
2. 構文解析（内部AST生成）
3. 内部ASTからBabel互換ASTへの変換
4. 位置情報（loc, range）の付与
5. コメントトークンの抽出と付与
6. 最終的なAST構造の整形

**関連システム・外部連携**：Babelエコシステム（babel-eslint等）、ESLint、Prettier等の静的解析・フォーマットツール

**権限による制御**：特になし（すべてのユーザーが利用可能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLI | 主機能 | `coffee --ast`コマンドでAST出力 |

## 機能種別

計算処理 / コード変換 / データ構造変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| code | string | Yes | CoffeeScriptソースコード | 文字列であること |
| options.ast | boolean | Yes | AST生成を有効化（trueを指定） | trueであること |
| options.filename | string | No | ソースファイル名 | - |
| options.literate | boolean | No | Literate CoffeeScriptとして処理 | - |

### 入力データソース

- 直接のソースコード文字列入力
- ファイルシステムからの読み込み
- 標準入力（CLI使用時）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| type | string | "File"（ルートノードタイプ） |
| program | object | Programノード |
| program.type | string | "Program" |
| program.body | array | 文/式ノードの配列 |
| start | number | ソースコード開始位置（0） |
| end | number | ソースコード終了位置 |
| range | [number, number] | [start, end]の配列形式 |
| loc | object | 行・列の位置情報オブジェクト |
| loc.start | {line, column} | 開始位置（行は1始まり、列は0始まり） |
| loc.end | {line, column} | 終了位置 |
| tokens | array | トークン配列（オプション） |
| comments | array | コメント配列 |

### 出力先

- 戻り値として返却（API使用時）
- 標準出力（CLI使用時、JSON形式）

## 処理フロー

### 処理シーケンス

```
1. ソースコードの字句解析
   └─ Lexerでトークン列を生成

2. 構文解析
   └─ Jisonパーサーで内部AST（Nodesツリー）を生成

3. コメントトークン抽出
   └─ helpers.extractAllCommentTokensでコメント情報を収集

4. ソースコード情報取得
   └─ 行数、最終行内容を計算

5. 内部ASTからBabel互換ASTへ変換
   └─ nodes.ast(options)でAST変換を実行

6. ルートノードの位置情報調整
   └─ start, end, range, loc を正確な値に設定

7. トークン配列の付与
   └─ ast.tokens にトークン列を設定

8. AST返却
   └─ Babel互換AST構造を返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: compile関数 with ast=true] --> B[Lexerでトークン化]
    B --> C[parser.parseで構文解析]
    C --> D[内部AST Nodesツリー生成]
    D --> E[extractAllCommentTokensでコメント抽出]
    E --> F[ソースコード行数・最終行計算]
    F --> G[nodes.ast実行]
    G --> H[Babel互換AST生成]
    H --> I[ルートノード位置情報設定]
    I --> J[range配列設定]
    J --> K[loc.start/end設定]
    K --> L[tokens配列付与]
    L --> M[AST返却]
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Babel互換形式 | ASTはBabel/ESTree形式に準拠 | ast=true指定時 |
| BR-02 | 位置情報必須 | すべてのノードにloc, rangeを付与 | AST生成時 |
| BR-03 | 行番号1始まり | loc.line は1から始まる | AST生成時 |
| BR-04 | 列番号0始まり | loc.column は0から始まる | AST生成時 |

### 計算ロジック

**ソースコード行数計算**:
```coffeescript
sourceCodeNumberOfLines = (code.match(/\r?\n/g) or '').length + 1
```

**最終行取得**:
```coffeescript
sourceCodeLastLine = /.*$/.exec(code)[0]
```

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SyntaxError | 構文エラー | 不正なCoffeeScript構文 | エラー位置と詳細メッセージを表示 |

### リトライ仕様

リトライは行わない（同期処理）

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

本機能はトランザクション管理を行わない（ステートレスな変換処理）

## パフォーマンス要件

- 通常のソースファイルは数十ミリ秒以内で処理
- AST変換はJavaScript生成とほぼ同等のパフォーマンス

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

- 入力コードの検証は構文チェックのみ
- AST出力は読み取り専用のデータ構造

## 備考

- CoffeeScript 2.x以降でサポート
- ESTree形式との完全互換を目指している

---

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

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

### 推奨読解順序

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

まず、Babel互換ASTの構造とCoffeeScript内部ASTとの対応関係を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | nodes.coffee | `src/nodes.coffee` | 各ノードクラスの`ast`メソッドを確認。Babel互換形式への変換ロジックを理解 |

**読解のコツ**: CoffeeScriptの各ノードクラス（Block, Code, Call等）には`ast`メソッドがあり、これがBabel互換のプレーンオブジェクトを生成する。

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

AST生成のエントリーポイントを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | coffeescript.coffee | `src/coffeescript.coffee` | `compile`関数の94-107行目がAST生成パス。`options.ast`が真の場合の処理フローを確認 |

**主要処理フロー**:
1. **94行目**: `if options.ast` でAST生成パスに分岐
2. **95行目**: `helpers.extractAllCommentTokens(tokens)` でコメントトークン抽出
3. **96行目**: ソースコード行数計算
4. **97行目**: 最終行内容取得
5. **98行目**: `nodes.ast(options)` でAST生成
6. **99-105行目**: ルートノードの位置情報設定
7. **106行目**: トークン配列の付与
8. **107行目**: AST返却

#### Step 3: AST変換処理を理解する

各ノードのAST変換メソッドを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | nodes.coffee | `src/nodes.coffee` | Baseクラスの`ast`メソッドと各サブクラスの`astNode`/`astType`/`astProperties`を確認 |

**読解のコツ**:
- `astType`プロパティ: Babelノードタイプ名を定義
- `astProperties`メソッド: Babelノードのプロパティを返す
- `astNode`メソッド: 実際のASTノードオブジェクトを生成

#### Step 4: コメント処理を理解する

コメントトークンの抽出と付与を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | helpers.coffee | `src/helpers.coffee` | `extractAllCommentTokens`関数（112-120行目）を確認 |

**主要処理フロー**:
- **112-113行目**: コメント付きトークンを収集
- **114-117行目**: 位置でソート
- **118-120行目**: ソート済みコメント配列を返却

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

```
CoffeeScript.compile (coffeescript.coffee:62)
    │
    ├─ lexer.tokenize (lexer.coffee:37)
    │
    ├─ parser.parse (parser.coffee)
    │      └─ 内部AST (Nodesツリー) 生成
    │
    ├─ helpers.extractAllCommentTokens (helpers.coffee:112)
    │
    └─ nodes.ast (nodes.coffee)
           │
           ├─ File.ast
           │      └─ Program.ast
           │             └─ 各ノードの ast メソッド再帰呼び出し
           │
           └─ astLocationData (位置情報変換)
```

### データフロー図

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

CoffeeScript      ──▶  Lexer.tokenize          ──▶  トークン列
ソースコード             │                            [tag, value, location]
                        │
                        ▼
                  parser.parse              ──▶  内部AST
                  │                              (CoffeeScript Nodesツリー)
                  │
                  ▼
                  extractAllCommentTokens   ──▶  コメント配列
                  │
                  ▼
                  nodes.ast                 ──▶  Babel互換AST
                  │                              {
                  │                                type: "File",
                  │                                program: {...},
                  │                                loc: {...},
                  │                                range: [...]
                  │                              }
                  ▼
                  位置情報調整              ──▶  最終AST
                  + トークン付与
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| coffeescript.coffee | `src/coffeescript.coffee` | ソース | AST生成のエントリーポイント（94-107行目） |
| nodes.coffee | `src/nodes.coffee` | ソース | 各ノードクラスのastメソッド定義 |
| helpers.coffee | `src/helpers.coffee` | ソース | extractAllCommentTokens関数 |
| lexer.coffee | `src/lexer.coffee` | ソース | トークン化処理 |
| grammar.coffee | `src/grammar.coffee` | ソース | 文法定義（内部AST構造の基盤） |
