# 機能設計書 5-JavaScript/TypeScript パース

## 概要

本ドキュメントは、PrettierのJavaScript/TypeScriptパース機能の設計について記述する。

### 本機能の処理概要

Babel、TypeScript、Acorn、Espree、Meriyah、Flow等の複数のパーサーを使用してJavaScript/TypeScriptをパースし、AST（抽象構文木）を生成する機能である。パーサーの選択はオプションまたはファイル拡張子から自動的に行われる。

**業務上の目的・背景**：JavaScriptとTypeScriptは最も広く使用されているプログラミング言語の一つであり、Prettierの主要なターゲット言語である。様々なパーサーをサポートすることで、異なるプロジェクト要件（例：Flow使用、ESLint連携など）に対応できる。

**機能の利用シーン**：
- JavaScript/TypeScriptファイルのフォーマット時
- JSX/TSXを含むReactコンポーネントのフォーマット
- Flowアノテーション付きコードのフォーマット
- エディタやPlaygroundでのリアルタイムパース

**主要な処理内容**：
1. パーサーの選択（babel、babel-ts、typescript、acorn等）
2. パーサーオプションの設定（プラグイン、ソースタイプ等）
3. ソースコードのパース
4. エラーリカバリーとエラーハンドリング
5. ASTの後処理（ポストプロセス）

**関連システム・外部連携**：
- @babel/parser（Babel）
- @typescript-eslint/typescript-estree（TypeScript）
- acorn、espree、meriyah（代替パーサー）
- @babel/code-frame（エラー表示）

**権限による制御**：特になし。すべてのユーザーがパーサー機能を利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | API連携 | Babel、TypeScript等のパーサーでコードをパース |
| 5 | About - Prettier概要 | 補助機能 | 対応言語としてJavaScript/TypeScriptパースを説明 |

## 機能種別

計算処理 / パース処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| text | string | Yes | パース対象のソースコード | - |
| options | object | No | パースオプション | - |
| options.parser | string | No | パーサー名（babel, babel-ts, typescript等） | 有効なパーサー名 |
| options.filepath | string | No | ファイルパス（パーサー推論用） | - |
| options.__babelSourceType | string | No | Babelのソースタイプ指定 | module/script/commonjs |

### 入力データソース

- ソースコードテキスト
- ファイルパス情報（パーサー推論用）

### サポートパーサー

| パーサー名 | 説明 | 使用ライブラリ |
|-----------|------|---------------|
| babel | 標準のJavaScriptパーサー | @babel/parser |
| babel-flow | Flowアノテーション付きJavaScript | @babel/parser + flow plugin |
| babel-ts | TypeScript（Babel経由） | @babel/parser + typescript plugin |
| typescript | TypeScript（ネイティブ） | @typescript-eslint/typescript-estree |
| acorn | 軽量JavaScriptパーサー | acorn |
| espree | ESLint標準パーサー | espree |
| meriyah | 高速JavaScriptパーサー | meriyah |

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ast | object | パースされたAST |
| text | string | 前処理後のテキスト（shebang置換等） |

### 出力先

- パース関数の戻り値として返却
- coreFormat等の上位関数で使用

## 処理フロー

### 処理シーケンス

```
1. パーサー解決
   └─ options.parserまたはfilepathからパーサーを決定

2. パーサー初期化
   └─ プラグインからパーサー定義を取得

3. プリプロセス（存在する場合）
   └─ shebang置換等の前処理

4. パースオプション設定
   ├─ ソースタイプ決定（module/script/commonjs）
   ├─ プラグイン設定（jsx、typescript、flow等）
   └─ パーサー固有オプション設定

5. パース実行
   └─ 各パーサーライブラリを呼び出し

6. エラーハンドリング
   ├─ 許容されるエラーコードの判定
   └─ エラーメッセージの整形（code-frame付き）

7. ポストプロセス
   └─ AST正規化、コメント処理等
```

### フローチャート

```mermaid
flowchart TD
    A[パース開始] --> B[パーサー解決]
    B --> C{Flowファイル?}
    C -->|Yes| D[babel-flowに切り替え]
    C -->|No| E[パースオプション設定]
    D --> E
    E --> F{パイプライン演算子あり?}
    F -->|Yes| G[pipelineOperatorプラグイン追加]
    F -->|No| H[パース実行]
    G --> H
    H --> I{パース成功?}
    I -->|No| J{許容エラー?}
    J -->|Yes| H
    J -->|No| K[エラースロー]
    I -->|Yes| L[ポストプロセス]
    L --> M[AST返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Flowファイル自動検出 | @flow/@noflowプラグマまたは.js.flow拡張子でFlowと判定 | parser=babel時 |
| BR-02 | ソースタイプ推論 | ファイル拡張子からmodule/script/commonjsを推論 | .mjs=module, .cjs=commonjs |
| BR-03 | JSX自動検出 | ファイル拡張子（.jsx, .tsx）またはコード内容からJSX有効化 | TypeScriptパーサー時 |
| BR-04 | エラーリカバリー | 特定のエラーコードは無視してパースを継続 | errorRecovery有効時 |
| BR-05 | パイプライン演算子 | `\|>`を含むコードではpipelineOperatorプラグインを試行 | Babelパーサー時 |
| BR-06 | V8 Intrinsic | `%A-Z`パターンでv8intrinsicプラグインを有効化 | Babelパーサー時 |

### 計算ロジック

**Flowファイル判定**：
```javascript
const FLOW_PRAGMA_REGEX = /@(?:no)?flow\b/;
function isFlowFile(text, filepath) {
  if (filepath?.endsWith(".js.flow")) return true;
  // コメント内の@flow/@noflowを検索
  const firstNonSpaceNonCommentCharacterIndex = ...;
  return FLOW_PRAGMA_REGEX.test(text.slice(0, firstNonSpaceNonCommentCharacterIndex));
}
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| SyntaxError | パースエラー | 構文エラー | コードを修正 |
| ConfigError | 設定エラー | パーサーが見つからない | パーサー名を確認 |

### 許容されるエラーコード（Babel）

以下のエラーコードは、パースを継続可能なエラーとして許容される：
- StrictNumericEscape
- StrictWith
- StrictOctalLiteral
- VarRedeclaration
- InvalidPrivateFieldResolution
- DuplicateExport
- その他（babel.js参照）

### リトライ仕様

複数のパーサーオプションの組み合わせを試行し、最初に成功したものを使用。

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

トランザクション管理は不要（ステートレスな処理）。

## パフォーマンス要件

- 一般的なソースファイル（1000行程度）のパースは50ms以内
- TypeScriptパーサーは型情報を扱わない軽量モードで動作

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

- 入力コードの実行は行わない（静的解析のみ）
- 外部ファイルへのアクセスは行わない

## 備考

- babelパーサーはJSONパースにも使用される
- TypeScriptパーサーは@typescript-eslint/typescript-estreeを使用
- 各パーサーはプラグインとして実装されている

---

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

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

### 推奨読解順序

#### Step 1: パーサープラグインの構成を理解する

パーサーがプラグインとしてどのように構成されているかを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | babel.js | `src/plugins/babel.js` | Babelパーサープラグインのエクスポート |
| 1-2 | typescript.js | `src/plugins/typescript.js` | TypeScriptパーサープラグインのエクスポート |

**読解のコツ**: プラグインファイルは実際のパーサー実装を再エクスポートするだけの薄いラッパー。

#### Step 2: Babelパーサーの実装を理解する

Babelパーサーの詳細な実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | babel.js | `src/language-js/parse/babel.js` | Babelパーサー本体 |

**主要処理フロー**:
- **24-57行目**: parseOptions定義（プラグイン設定）
- **80-99行目**: isFlowFile関数（Flowファイル判定）
- **115-189行目**: createParse関数（パース処理本体）
- **133-163行目**: パイプライン演算子とV8 Intrinsicの動的有効化
- **192-227行目**: 許容されるエラーコードの定義
- **229-277行目**: 各種パーサーバリエーションの作成

#### Step 3: TypeScriptパーサーの実装を理解する

TypeScriptパーサーの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | typescript.js | `src/language-js/parse/typescript.js` | TypeScriptパーサー |

**主要処理フロー**:
- **16-29行目**: baseParseOptions定義
- **54-77行目**: getParseOptionsCombinations関数
- **79-108行目**: parse関数本体

#### Step 4: パース処理の呼び出しを理解する

パース関数がどのように呼び出されるかを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | parse.js | `src/main/parse.js` | パース処理のエントリーポイント |
| 4-2 | parser-and-printer.js | `src/main/parser-and-printer.js` | パーサー解決 |

**主要処理フロー**:
- **4-25行目** (parse.js): parse関数
- **58-61行目** (parser-and-printer.js): resolveParser関数

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

```
parse (src/main/parse.js)
    │
    ├─ resolveParser (src/main/parser-and-printer.js)
    │      └─ getParserPluginByParserName
    │             └─ initParser
    │
    ├─ parser.preprocess (存在する場合)
    │
    └─ parser.parse
           │
           ├─ babel (src/language-js/parse/babel.js)
           │      ├─ isFlowFile (Flowチェック)
           │      ├─ tryCombinationsSync (複数オプション試行)
           │      ├─ babelParse / parseExpression
           │      └─ postprocess
           │
           └─ typescript (src/language-js/parse/typescript.js)
                  ├─ getParseOptionsCombinations
                  ├─ tryCombinationsSync
                  ├─ parseTypeScript
                  └─ postprocess
```

### データフロー図

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

ソースコード ───────────▶ パーサー解決 ──────────────────▶ パーサー選択
    │                         │
    │                         ▼
    │                    プリプロセス ──────────────────▶ 前処理済みテキスト
    │                         │
    │                         ▼
    │                    パースオプション設定
    │                         │
    │                         ▼
    └─────────────────▶ パース実行 ─────────────────────▶ 生AST
                              │
                              ▼
                         エラーチェック
                              │
                              ▼
                         ポストプロセス ────────────────▶ 正規化AST
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| babel.js | `src/plugins/babel.js` | ソース | Babelパーサープラグイン |
| typescript.js | `src/plugins/typescript.js` | ソース | TypeScriptパーサープラグイン |
| babel.js | `src/language-js/parse/babel.js` | ソース | Babelパーサー実装 |
| typescript.js | `src/language-js/parse/typescript.js` | ソース | TypeScriptパーサー実装 |
| acorn.js | `src/plugins/acorn.js` | ソース | Acornパーサープラグイン |
| flow.js | `src/plugins/flow.js` | ソース | Flowパーサープラグイン |
| meriyah.js | `src/plugins/meriyah.js` | ソース | Meriyahパーサープラグイン |
| parse.js | `src/main/parse.js` | ソース | パース処理エントリーポイント |
| parser-and-printer.js | `src/main/parser-and-printer.js` | ソース | パーサー解決 |
| postprocess/index.js | `src/language-js/parse/postprocess/index.js` | ソース | ASTポストプロセス |
| create-parser.js | `src/language-js/parse/utilities/create-parser.js` | ソース | パーサー作成ユーティリティ |
