# 機能設計書 11-@babel/code-frame

## 概要

本ドキュメントは、Babelの@babel/code-frameパッケージの機能設計を記述する。@babel/code-frameは、ソースコードの特定位置を視覚的にハイライトして表示するためのユーティリティパッケージである。

### 本機能の処理概要

@babel/code-frameは、JavaScriptソースコードのエラーや警告メッセージにおいて、問題のある箇所を視覚的に分かりやすく表示するためのコードフレーム生成機能を提供する。

**業務上の目的・背景**：コンパイラやリンターがエラーメッセージを出力する際、単に行番号と列番号を表示するだけでは問題箇所の特定が困難である。@babel/code-frameは、対象行の前後のコンテキストを含めた視覚的なコードフレームを生成することで、開発者がエラー箇所を素早く特定できるようにする。この機能は、Babel本体のエラー出力だけでなく、ESLint、Webpack、その他多くのJavaScriptツールで広く利用されている。

**機能の利用シーン**：構文エラーや型エラーの発生時にエラーメッセージとともに問題箇所を表示する場合、コードレビューツールで特定行をハイライト表示する場合、IDEやエディタでエラー箇所を視覚的に示す場合などに利用される。

**主要な処理内容**：
1. ソースコード文字列と位置情報（開始行/列、終了行/列）を受け取る
2. 指定位置の前後の行を抽出する（デフォルト：前2行、後3行）
3. 行番号ガターを付与して整形する
4. エラー箇所を`>`マーカーと`^`で示す
5. ターミナル環境ではシンタックスハイライトを適用する
6. オプションでエラーメッセージをインラインまたは上部に表示する

**関連システム・外部連携**：@babel/coreのエラー出力、@babel/parserのパースエラー表示、ESLintのエラーフォーマッタ、Webpackのビルドエラー表示などと連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | なし | - | CLIツールおよびAPIとして利用 |

## 機能種別

ユーティリティ / 文字列整形処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| rawLines | string | Yes | ソースコード全体の文字列 | 空文字列も許容 |
| loc | NodeLocation | Yes | ハイライトする位置情報 | startプロパティ必須 |
| loc.start | Location | Yes | 開始位置（line, column） | line >= 1, column >= 0 |
| loc.end | Location | No | 終了位置（line, column） | 省略時はstart位置のみ |
| opts.highlightCode | boolean | No | シンタックスハイライトの有効化 | デフォルト: false |
| opts.linesAbove | number | No | エラー行より上に表示する行数 | デフォルト: 2 |
| opts.linesBelow | number | No | エラー行より下に表示する行数 | デフォルト: 3 |
| opts.forceColor | boolean | No | 非ターミナルでも色付けを強制 | デフォルト: false |
| opts.message | string | No | エラーメッセージ | 指定時はマーカー付近に表示 |

### 入力データソース

API呼び出しによる直接入力（ソースコード文字列と位置情報）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| codeFrame | string | 整形されたコードフレーム文字列 |

### 出力先

関数の戻り値として文字列を返す。呼び出し元でconsole.errorやログファイルに出力される。

## 処理フロー

### 処理シーケンス

```
1. オプションの正規化
   └─ デフォルト値の設定（linesAbove=2, linesBelow=3）

2. カラーサポートの判定
   └─ 環境変数とターミナル能力を確認し、色付けの可否を決定

3. ソースコードの行分割
   └─ 改行コード（\r\n, \n, \r, U+2028, U+2029）で分割

4. マーカー行の計算
   └─ 開始位置と終了位置から、マーキングが必要な行と列範囲を算出

5. 表示範囲の決定
   └─ start行 - linesAbove から end行 + linesBelow の範囲を抽出

6. シンタックスハイライトの適用（有効時）
   └─ js-tokensでトークン化し、各トークンにANSIカラーコードを適用

7. 行ごとの整形
   └─ 各行に対して行番号ガター、マーカー（>）、インデントを付与

8. マーカー行の生成
   └─ エラー位置に^マーカーを配置、メッセージがあれば追加

9. フレーム文字列の結合
   └─ 全行を改行で結合して返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: codeFrameColumns呼び出し] --> B{カラーサポート?}
    B -->|Yes| C[highlight関数を設定]
    B -->|No| D[無変換関数を設定]
    C --> E[_codeFrameColumns呼び出し]
    D --> E
    E --> F[ソースコードを行分割]
    F --> G[getMarkerLines: マーカー位置計算]
    G --> H[表示範囲の抽出]
    H --> I{highlightCode有効?}
    I -->|Yes| J[highlight: トークン化とカラー適用]
    I -->|No| K[そのまま使用]
    J --> L[行ごとの整形ループ]
    K --> L
    L --> M{マーカー行?}
    M -->|Yes| N[> マーカーとガターを追加]
    M -->|No| O[ガターのみ追加]
    N --> P[^ マーカー行を追加]
    O --> Q{最終行?}
    P --> Q
    Q -->|No| L
    Q -->|Yes| R[フレーム文字列を結合]
    R --> S[終了: コードフレーム文字列を返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 行番号の1始まり | 行番号は1から始まる | 常時 |
| BR-02 | 列番号の0始まり | 列番号は0から始まる | 常時 |
| BR-03 | 複数行マーキング | 開始行と終了行が異なる場合、範囲内全行をマーク | loc.end指定時 |
| BR-04 | カラーサポート判定 | TTY接続時かつNO_COLOR未設定時に色付け | highlightCode=true |
| BR-05 | ブラウザ環境 | ブラウザではシンタックスハイライト無効 | browser.tsエントリポイント使用時 |

### 計算ロジック

マーカー位置の計算:
- startLine = loc.start.line - startLineBase (通常0ベースに変換)
- 表示開始行 = max(startLine - linesAbove - 1, 0)
- 表示終了行 = min(source.length, endLine + linesBelow)
- マーカースペーシング = 対象行のstartColumn-1までの文字をスペースに置換（タブは保持）

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 範囲外参照 | 指定行が存在しない | 空文字列または部分的なフレームを返却 |

### リトライ仕様

本機能にリトライ処理は存在しない。

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

本機能はトランザクション処理を行わない。

## パフォーマンス要件

- シンタックスハイライト処理は大きなファイルでも数ミリ秒以内に完了すること
- js-tokensによるトークン化は正規表現ベースで高速

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

- 入力ソースコードの検証は行わない（信頼されたソースからの入力を前提）
- ANSIエスケープシーケンスを出力するため、ログファイルへの出力時は注意が必要

## 備考

- Node.js v20.19.0以上またはv22.12.0以上が必要
- ブラウザ環境用のエントリポイント（browser.ts）ではシンタックスハイライト機能が無効化される

---

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

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

### 推奨読解順序

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

まず、入出力の型定義を理解することが重要である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | common.ts | `packages/babel-code-frame/src/common.ts` | NodeLocation型、Options型の定義を確認 |
| 1-2 | defs.ts | `packages/babel-code-frame/src/defs.ts` | InternalTokenType型とDefs型の定義を確認 |

**読解のコツ**:
- **3-11行目**: Location型とNodeLocation型の定義。行は1始まり、列は0始まりであることを理解する
- **13-35行目**: Optionsインターフェースの定義。各オプションの用途とデフォルト値を把握する

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

処理の起点となるファイルを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-code-frame/src/index.ts` | メインのcodeFrameColumns関数の実装 |
| 2-2 | browser.ts | `packages/babel-code-frame/src/browser.ts` | ブラウザ環境用の簡易実装 |

**主要処理フロー**:
1. **13-32行目**: codeFrameColumns関数の定義。カラーサポート判定と_codeFrameColumns呼び出し
2. **18-19行目**: forceColorオプションまたはターミナルのカラーサポートに基づく判定
3. **21-31行目**: _codeFrameColumnsへのデリゲート。ハイライト関数の有無を渡す

#### Step 3: コアロジックを理解する

マーカー計算とフレーム生成のコアロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | common.ts | `packages/babel-code-frame/src/common.ts` | getMarkerLines関数と_codeFrameColumns関数 |

**主要処理フロー**:
- **49-121行目**: getMarkerLines関数。開始/終了位置からマーキング対象行と列範囲を計算
- **123-205行目**: _codeFrameColumns関数。フレーム文字列の実際の組み立て処理
- **160-198行目**: 行ごとのマップ処理。ガター、マーカー、ハイライトの適用

#### Step 4: シンタックスハイライト処理を理解する

トークン化とカラー適用のロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | highlight.ts | `packages/babel-code-frame/src/highlight.ts` | highlight関数とトークナイザーの実装 |
| 4-2 | defs.ts | `packages/babel-code-frame/src/defs.ts` | トークンタイプごとの色定義 |

**主要処理フロー**:
- **43-111行目**: getTokenType関数。js-tokensのトークンをInternalTokenTypeに変換
- **116-142行目**: tokenize関数。テンプレートリテラルの特別処理を含むジェネレータ
- **144-161行目**: highlight関数。トークン化して各トークンに色を適用
- **31-47行目** (defs.ts): 各トークンタイプの色定義（keyword=cyan, string=greenなど）

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

```
codeFrameColumns (index.ts)
    │
    ├─ isColorSupported (defs.ts)
    │      └─ Node.js styleText API を使用
    │
    ├─ highlight (highlight.ts)
    │      ├─ tokenize (highlight.ts)
    │      │      ├─ jsTokens (外部ライブラリ)
    │      │      └─ getTokenType (highlight.ts)
    │      │             ├─ isKeyword (@babel/helper-validator-identifier)
    │      │             └─ isStrictReservedWord (@babel/helper-validator-identifier)
    │      │
    │      └─ defs (defs.ts)
    │
    └─ _codeFrameColumns (common.ts)
           ├─ getMarkerLines (common.ts)
           └─ defs.gutter/marker/message/reset (defs.ts)
```

### データフロー図

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

rawLines (string)  ─────┬─────> split(NEWLINE)  ───────────────────> lines[]
                        │
loc (NodeLocation) ─────┼─────> getMarkerLines ───────────────────> markerLines{}
                        │                                                │
opts (Options)     ─────┴─────> _codeFrameColumns ────────────────────────┤
                                      │                                   │
                                      ├── highlight (色付け) ──────────────┤
                                      │                                   │
                                      └── 行ごとの整形 ────────────────────┴──> frame (string)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-code-frame/src/index.ts` | ソース | Node.js環境用エントリーポイント、codeFrameColumns関数のエクスポート |
| browser.ts | `packages/babel-code-frame/src/browser.ts` | ソース | ブラウザ環境用エントリーポイント、シンタックスハイライトなし版 |
| common.ts | `packages/babel-code-frame/src/common.ts` | ソース | コアロジック、getMarkerLinesと_codeFrameColumns関数 |
| highlight.ts | `packages/babel-code-frame/src/highlight.ts` | ソース | シンタックスハイライト処理、トークン化とカラー適用 |
| defs.ts | `packages/babel-code-frame/src/defs.ts` | ソース | 色定義、トークンタイプ定義、isColorSupported関数 |
| package.json | `packages/babel-code-frame/package.json` | 設定 | パッケージ設定、依存関係定義 |
| test/index.js | `packages/babel-code-frame/test/index.js` | テスト | 機能テスト |
