# 帳票設計書 7-AST出力

## 概要

本ドキュメントは、パース結果のAST（抽象構文木）をJSON形式で出力する帳票「AST出力」の設計仕様を定義する。

### 本帳票の処理概要

**業務上の目的・背景**：Prettierの動作を理解したり、プラグイン開発やデバッグを行う際に、ソースコードがどのようにパースされてASTに変換されるかを確認することが重要である。本帳票は、Prettierが内部で生成するASTをJSON形式で出力し、開発者がパーサーの動作を検証したり、プリンターの入力データを理解したりすることを可能にする。

**帳票の利用シーン**：プラグイン開発時のパーサー動作確認、フォーマットの問題調査、カスタムパーサーの検証、教育目的でのPrettier内部動作理解など。

**主要な出力内容**：
1. ソースコードのAST（抽象構文木）全体
2. ノードの型、位置情報、子ノードなどの詳細

**帳票の出力タイミング**：CLIで`--debug-print-ast`オプションを指定した際に出力される。

**帳票の利用者**：Prettier開発者、プラグイン開発者、言語パーサー開発者

## 帳票種別

デバッグ出力（JSON）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| CLI-01 | コマンドライン | `prettier --debug-print-ast <file>` | コマンド実行 |
| API-01 | JavaScript API | `prettier.__debug.parse(text, options)` | 関数呼び出し |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | JSON |
| 出力先 | 標準出力 |
| 文字コード | UTF-8 |
| フォーマット | 非整形（JSON.stringify） |

### JSON構造（例：JavaScript）

```json
{
  "type": "Program",
  "body": [
    {
      "type": "VariableDeclaration",
      "declarations": [...],
      "kind": "const"
    }
  ],
  "sourceType": "module"
}
```

## 帳票レイアウト

### レイアウト概要

出力は言語パーサーが生成するAST構造をそのままJSON化したもの。

```
┌─────────────────────────────────────┐
│              JSONオブジェクト          │
├─────────────────────────────────────┤
│  {                                   │
│    "type": "Program",                │
│    "body": [                         │
│      { ノードオブジェクト },            │
│      ...                             │
│    ],                                │
│    ...                               │
│  }                                   │
└─────────────────────────────────────┘
```

### 出力項目（共通）

| No | 項目名 | 説明 | 型 | 備考 |
|----|-------|------|-----|------|
| 1 | type | ノード種別 | string | パーサー依存 |
| 2 | start / loc.start | 開始位置 | number / object | パーサー依存 |
| 3 | end / loc.end | 終了位置 | number / object | パーサー依存 |
| 4 | 子ノード | ノード固有のプロパティ | any | ノードタイプにより異なる |

### パーサー別AST構造

| パーサー | ルートノード | 主要プロパティ |
|---------|------------|---------------|
| babel | Program | body, sourceType, comments |
| typescript | SourceFile | statements |
| postcss | Root | nodes |
| markdown | root | children |
| yaml | Document | content |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| 入力ファイル | パース対象のファイル | Yes |
| --parser | 使用するパーサー | No（自動推論可） |

### 処理条件

| 条件 | 処理 |
|------|------|
| --debug-print-ast指定 | AST出力モードに切り替え |
| パース成功 | JSON.stringify(ast)を出力 |
| パースエラー | エラーメッセージ出力 |

## データフロー仕様

### 入力データ

| データ項目 | 型 | 説明 |
|-----------|-----|------|
| input | string | パース対象のソースコード |
| opt | object | パースオプション（parser等） |
| context.argv.debugPrintAst | boolean | AST出力フラグ |

### 出力データ

| データ項目 | 型 | 説明 |
|-----------|-----|------|
| ast | object | パース結果のAST |
| formatted | string | JSON.stringify(ast)の結果 |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[format関数] --> B{debugPrintAst?}
    B -->|Yes| C[prettier.__debug.parse呼び出し]
    C --> D[parseText実行]
    D --> E{パース成功?}
    E -->|Yes| F[JSON.stringify(ast)]
    E -->|No| G[エラー処理]
    F --> H[結果返却]
    G --> H
    B -->|No| I[通常フォーマット処理]
```

### パース処理フロー

```mermaid
flowchart TD
    A[prettier.__debug.parse] --> B[normalizeFormatOptions]
    B --> C[normalizeInputAndOptions]
    C --> D[parseText]
    D --> E[resolveParser]
    E --> F[parser.parse呼び出し]
    F --> G{devOptions?}
    G -->|preprocessForPrint| H[prepareToPrint]
    G -->|massage| I[massageAst]
    G -->|なし| J[結果返却]
    H --> J
    I --> J
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| SyntaxError | 構文エラー | {filename}: SyntaxError: {message} | ソースコード修正 |
| UndefinedParserError | パーサー不明 | No parser could be inferred | --parser指定 |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 処理方式 | 非同期処理（async/await） |
| 出力サイズ | ソースコードサイズの数倍程度 |

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

- ASTにはソースコードの完全な構造情報が含まれる
- デバッグ目的のため、プロダクション環境での使用は非推奨

## 備考

- 出力はJSON.stringifyで文字列化されるが、Prettierでのフォーマットは行われない
- API経由ではdevOptionsでmassageやpreprocessForPrintオプションを指定可能
- massageオプションでAST正規化（位置情報削除等）が可能

---

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

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

### 推奨読解順序

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

まず、AST出力の構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | core.js | `src/main/core.js` | parse関数の戻り値構造（369-384行目） |

**読解のコツ**: parse関数は`{ ast, text }`を返す。devOptionsでAST加工オプションを指定可能。

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

AST出力のトリガーを特定。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | format.js | `src/cli/format.js` | debugPrintAst処理（119-124行目） |

**主要処理フロー**:
1. **119行目**: debugPrintAst判定
2. **120行目**: prettier.__debug.parse呼び出し
3. **121-123行目**: JSON.stringifyで結果返却

#### Step 3: パース処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | core.js | `src/main/core.js` | parse関数（369-384行目） |
| 3-2 | parse.js | `src/main/parse.js` | parseText関数 |

**主要処理フロー**:
- **370-373行目**: オプション正規化
- **374行目**: parseText呼び出し
- **375-382行目**: devOptionsによるAST加工

#### Step 4: AST加工処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | core.js | `src/main/core.js` | devOptions処理（375-382行目） |
| 4-2 | massage-ast.js | `src/main/massage-ast.js` | massageAst関数 |

**主要処理フロー**:
- **376-378行目**: preprocessForPrint処理
- **379-381行目**: massage処理（AST正規化）

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

```
CLI: format() [src/cli/format.js:102]
    │
    └─ (--debug-print-ast時)
           │
           └─ prettier.__debug.parse() [src/index.js:119]
                  │
                  └─ core.parse() [src/main/core.js:369]
                         │
                         ├─ normalizeFormatOptions()
                         │
                         ├─ normalizeInputAndOptions()
                         │
                         ├─ parseText() [src/main/parse.js]
                         │      │
                         │      ├─ resolveParser()
                         │      │
                         │      └─ parser.parse()
                         │
                         ├─ (preprocessForPrint)
                         │      └─ prepareToPrint() [src/main/ast-to-doc.js]
                         │
                         └─ (massage)
                                └─ massageAst() [src/main/massage-ast.js]
```

### データフロー図

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

ソースコード ──────────▶ normalizeInputAndOptions()
                              │
                              ▼
                         parseText()
                              │
                              ▼
                    resolveParser() → parser特定
                              │
                              ▼
                    parser.parse() → AST生成
                              │
                              ▼
                    (devOptions: preprocessForPrint)
                              │
                              ▼
                    (devOptions: massage)
                              │
                              ▼
                    { ast, text }
                              │
                              ▼
                    JSON.stringify(ast) ──────────▶ 標準出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| format.js | `src/cli/format.js` | ソース | debugPrintAst処理 |
| index.js | `src/index.js` | ソース | __debug.parse export |
| core.js | `src/main/core.js` | ソース | parse関数実装 |
| parse.js | `src/main/parse.js` | ソース | parseText関数 |
| massage-ast.js | `src/main/massage-ast.js` | ソース | AST正規化 |
| ast-to-doc.js | `src/main/ast-to-doc.js` | ソース | prepareToPrint関数 |
| parser-and-printer.js | `src/main/parser-and-printer.js` | ソース | resolveParser関数 |
