# 機能設計書 29-ASTパース（__debug.parse）

## 概要

本ドキュメントは、Prettier デバッグAPIにおける`__debug.parse`関数の機能設計を記述する。この関数は、ソースコードを抽象構文木（AST）にパースするデバッグ用APIである。

### 本機能の処理概要

**業務上の目的・背景**：Prettierの動作を理解・デバッグするために、ソースコードがどのようなASTに変換されるかを確認する必要がある。本機能は、パーサーが生成するASTを直接取得し、開発者がPrettierの内部動作を調査できるようにする。

**機能の利用シーン**：
- プラグイン開発時のパーサー動作確認
- フォーマット結果の問題調査
- Playgroundでのデバッグパネル
- 単体テストでのAST検証

**主要な処理内容**：
1. 入力テキストとオプションの正規化
2. 適切なパーサーの解決
3. ソースコードのパース
4. オプションに応じたAST後処理（プリプロセス、マッサージ）
5. ASTとテキストの返却

**関連システム・外部連携**：
- パーサープラグイン（Babel、TypeScript、PostCSS等）
- オプション正規化システム

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | 補助機能 | デバッグパネルでASTを表示する際に使用 |
| 16 | Usage - API | 補助機能 | APIでのデバッグパース関数の使い方を説明 |

## 機能種別

パース処理 / デバッグ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| text | string | Yes | パースするソースコード | - |
| options | object | No | Prettierオプション | - |
| options.parser | string | Yes（推論不可の場合） | 使用するパーサー | 有効なパーサー名 |
| options.plugins | array | No | 使用するプラグイン | - |
| devOptions | object | No | 開発用オプション | - |
| devOptions.preprocessForPrint | boolean | No | 印刷用プリプロセスを実行するか | デフォルト: false |
| devOptions.massage | boolean | No | ASTマッサージを実行するか | デフォルト: false |

### 入力データソース

- 関数引数

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| text | string | パース前のテキスト（正規化後） |
| ast | object | パースされた抽象構文木 |

### 出力先

- 戻り値（Promise<{ text, ast }>）

**使用例**：
```javascript
import { __debug } from "prettier";

const result = await __debug.parse("const x = 1;", { parser: "babel" });
console.log(JSON.stringify(result.ast, null, 2));
```

## 処理フロー

### 処理シーケンス

```
1. オプションの正規化
   └─ normalizeFormatOptionsで正規化

2. 入力テキストの正規化
   └─ BOMの除去
   └─ 改行コードの正規化（CRLF→LF）
   └─ カーソルオフセットの調整

3. テキストのパース
   └─ parseText関数でパース
   └─ パーサーのプリプロセス実行（存在する場合）
   └─ パーサーのparse関数実行

4. devOptionsに基づく後処理
   └─ preprocessForPrint: prepareToPrint実行
   └─ massage: massageAst実行

5. 結果構築
   └─ { text, ast }オブジェクトを返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[オプション正規化]
    B --> C[テキスト正規化]
    C --> D[パーサー解決]
    D --> E{プリプロセスあり?}
    E -->|Yes| F[プリプロセス実行]
    E -->|No| G[パース実行]
    F --> G
    G --> H{devOptions.preprocessForPrint?}
    H -->|Yes| I[prepareToPrint実行]
    H -->|No| J{devOptions.massage?}
    I --> J
    J -->|Yes| K[massageAst実行]
    J -->|No| L[結果構築]
    K --> L
    L --> M[Promise<{ text, ast }>]
    M --> N[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-29-1 | BOM除去 | 入力テキストのBOM（U+FEFF）を除去 | 常時 |
| BR-29-2 | 改行正規化 | CRLF/CRをLFに統一 | 常時 |
| BR-29-3 | パーサー必須 | パーサーが推論できない場合はエラー | パーサー未指定時 |
| BR-29-4 | プリプロセス優先 | パーサーにpreprocess関数があれば先に実行 | 常時 |
| BR-29-5 | デバッグ専用 | `__debug`プレフィックスはデバッグ専用であることを示す | 常時 |

### 計算ロジック

**改行正規化**：
```javascript
text = text.replace(/\r\n?/g, '\n');
```

**BOM除去**：
```javascript
if (text.charAt(0) === '\uFEFF') {
  text = text.slice(1);
}
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | UndefinedParserError | パーサーが指定されておらず推論もできない | 適切なパーサーを指定 |
| - | SyntaxError | 入力テキストが不正な構文 | ソースコードを修正 |

### リトライ仕様

リトライは行わない。

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

トランザクション管理は不要。

## パフォーマンス要件

- パース処理は入力サイズに応じて時間がかかる
- 大規模ファイルではメモリ使用量に注意

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

- 任意のコードをパースするが、実行はしない
- ASTデータのみを返す

## 備考

- `__debug`プレフィックスはAPIが不安定であることを示す
- CLIの`--debug-print-ast`オプションはこの関数を内部で使用

---

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

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

### 推奨読解順序

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

パース結果の構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | parse.js | `src/main/parse.js` | パース結果の型（{ text, ast }） |

**読解のコツ**: ASTの構造はパーサーによって異なる。各言語のASTノードタイプを理解する必要がある。

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

API公開の流れを把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.js | `src/index.js` | debugApis.parseの定義とエクスポート |

**主要処理フロー**:
- **118-126行目**: debugApisオブジェクト定義
- **119行目**: withPlugins(core.parse)でラップ
- **128-129行目**: __debugとしてエクスポート

#### Step 3: 本体実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | core.js | `src/main/core.js` | parse関数の実装 |

**主要処理フロー**:
- **369-384行目**: parse関数
- **370-372行目**: normalizeFormatOptionsで正規化
- **374行目**: parseTextでパース
- **375-381行目**: devOptionsに基づく後処理

#### Step 4: パース処理の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | parse.js | `src/main/parse.js` | parseText関数（ファイル内ではparseとして定義） |

**主要処理フロー**:
- **4-25行目**: parse関数
- **5行目**: resolveParserでパーサー解決
- **6-8行目**: preprocessの実行（存在する場合）
- **12-19行目**: パーサーのparse関数実行
- **20-22行目**: パースエラーのハンドリング

#### Step 5: 入力正規化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | core.js | `src/main/core.js` | normalizeInputAndOptions関数 |

**主要処理フロー**:
- **270-312行目**: normalizeInputAndOptions関数
- **276-283行目**: BOM処理
- **285-299行目**: 改行コード正規化

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

```
src/index.js::__debug.parse()
    │
    └─ withPlugins()
           │
           ├─ loadBuiltinPlugins()
           │
           ├─ loadPlugins()
           │
           └─ src/main/core.js::parse()
                  │
                  ├─ normalizeFormatOptions()
                  │
                  ├─ normalizeInputAndOptions()
                  │      ├─ BOM除去
                  │      └─ 改行正規化
                  │
                  ├─ src/main/parse.js::parseText()
                  │      ├─ resolveParser()
                  │      ├─ parser.preprocess() [オプション]
                  │      └─ parser.parse()
                  │
                  ├─ prepareToPrint() [devOptions.preprocessForPrint時]
                  │
                  └─ massageAst() [devOptions.massage時]
```

### データフロー図

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

text (ソースコード) ────▶ オプション正規化 ───────────────▶ 正規化オプション
options ─────────────────▶│
                               ▼
                         テキスト正規化 ───────────────────▶ 正規化テキスト
                         (BOM除去、改行統一)
                               │
                               ▼
                         パーサー解決 ─────────────────────▶ パーサー関数
                               │
                               ▼
正規化テキスト ──────────▶ preprocess [オプション] ────────▶ 前処理済みテキスト
                               │
                               ▼
                         parser.parse() ───────────────────▶ AST
                               │
                               ▼
devOptions ──────────────▶ 後処理 [オプション] ────────────▶ 処理済みAST
                               │
                               ▼
                         結果構築 ─────────────────────────▶ { text, ast }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| core.js | `src/main/core.js` | ソース | parse関数実装 |
| parse.js | `src/main/parse.js` | ソース | parseText関数実装 |
| index.js | `src/index.js` | ソース | API公開エントリーポイント |
| parser-and-printer.js | `src/main/parser-and-printer.js` | ソース | パーサー解決 |
| normalize-format-options.js | `src/main/normalize-format-options.js` | ソース | オプション正規化 |
| massage-ast.js | `src/main/massage-ast.js` | ソース | ASTマッサージ |
| ast-to-doc.js | `src/main/ast-to-doc.js` | ソース | prepareToPrint関数 |
