# 通知設計書 7-スコープダンプ出力

## 概要

本ドキュメントは、Babelのトラバース処理中にスコープの情報をデバッグ用にダンプ出力する機能について設計内容を記載する。

### 本通知の処理概要

この通知は、@babel/traverseパッケージのScopeクラスが提供する`dump()`メソッドを呼び出した際に、現在のスコープおよび親スコープのバインディング情報をコンソールに出力する機能である。

**業務上の目的・背景**：Babelプラグインの開発やデバッグ時に、スコープ内のバインディング（変数宣言）の状態を確認したい場合がある。スコープはJavaScriptの変数スコープを追跡し、各変数の定数性（constant）、参照回数（references）、再代入回数（constantViolations）などの情報を保持している。この情報は、変数のリネームや未使用変数の検出、最適化などのプラグイン開発において重要である。

**通知の送信タイミング**：開発者がプラグイン内で明示的に`scope.dump()`を呼び出した時点で送信される。

**通知の受信者**：プラグイン開発者（標準出力を監視しているユーザー）

**通知内容の概要**：スコープの種類（ブロックタイプ）と、そのスコープ内のバインディング情報（変数名、定数フラグ、参照回数、再代入回数、種別）が出力される。親スコープの情報も再帰的に出力される。

**期待されるアクション**：プラグイン開発者は、この情報を参考にして、スコープの状態を確認し、プラグインのロジックをデバッグまたは最適化することができる。

## 通知種別

コンソール出力（標準出力：stdout）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（console.log） |
| 優先度 | 低（デバッグ用） |
| リトライ | なし |

### 送信先決定ロジック

標準出力（stdout）に固定。

## 通知テンプレート

### コンソール通知の場合

| 項目 | 内容 |
|-----|------|
| 出力先 | 標準出力（stdout） |
| フォーマット | プレーンテキスト |

### 本文テンプレート

```
------------------------------------------------------------
# {blockType}
 - {bindingName1} { constant: {bool}, references: {num}, violations: {num}, kind: {kind} }
 - {bindingName2} { constant: {bool}, references: {num}, violations: {num}, kind: {kind} }
# {parentBlockType}
 - {parentBindingName} { constant: {bool}, references: {num}, violations: {num}, kind: {kind} }
------------------------------------------------------------
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| blockType | スコープのブロック種別 | scope.block.type | Yes |
| bindingName | バインディング（変数）名 | Object.keys(scope.bindings) | Yes |
| constant | 定数フラグ | binding.constant | Yes |
| references | 参照回数 | binding.references | Yes |
| violations | 再代入回数 | binding.constantViolations.length | Yes |
| kind | バインディング種別 | binding.kind | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| API呼び出し | scope.dump()メソッド呼び出し | なし（常に出力） | 開発者が明示的に呼び出す |

### 送信抑止条件

特になし（dump()メソッドは常に出力を行う）

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[scope.dump呼び出し] --> B[セパレータ出力]
    B --> C[現在スコープのblockType出力]
    C --> D[現在スコープのbindings走査]
    D --> E[各バインディング情報出力]
    E --> F{親スコープあり?}
    F -->|Yes| G[親スコープに移動]
    G --> C
    F -->|No| H[セパレータ出力]
    H --> I[終了]
```

## データベース参照・更新仕様

該当なし（データベースを使用しない）

## エラー処理

### エラーケース一覧

特にエラー処理は行われない。スコープ情報の出力は単純なログ処理である。

### リトライ仕様

リトライなし

## 配信設定

### レート制限

該当なし

### 配信時間帯

制限なし

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

変数名が出力されるため、コード内の命名規則やビジネスロジックのヒントが漏洩する可能性がある。プロダクション環境では使用しないこと。

## 備考

- このメソッドは開発・デバッグ専用であり、通常のプラグイン動作には使用しない
- 親スコープが存在する限り再帰的に出力が続く
- バインディングのkindには以下の種類がある：var、let、const、param、hoisted、module、local、unknown

---

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

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

### 推奨読解順序

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

この通知に関わるデータ構造は、ScopeクラスとBindingクラスである。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | index.ts | `packages/babel-traverse/src/scope/index.ts` | Scopeクラスのプロパティ定義（415-431行目）を確認 |
| 1-2 | binding.ts | `packages/babel-traverse/src/scope/binding.ts` | Bindingクラスの定義を確認 |

**読解のコツ**: Scopeクラスには`bindings: Record<string, Binding>`プロパティがあり、スコープ内の各変数を追跡している。

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

dump()メソッドの実装を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | index.ts | `packages/babel-traverse/src/scope/index.ts` | dump()メソッド（657-674行目） |

**主要処理フロー**:
1. **658行目**: セパレータ文字列を生成（"-"を60個）
2. **659行目**: `console.log(sep)` でセパレータ出力
3. **660-661行目**: `let scope = this` でスコープを初期化し、do-whileループ開始
4. **662行目**: `console.log("#", scope.block.type)` でブロックタイプ出力
5. **663-670行目**: バインディングを走査して各情報を出力
6. **672行目**: ループ終了後にセパレータ出力

#### Step 3: バインディング情報の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | index.ts | `packages/babel-traverse/src/scope/index.ts` | バインディング出力部分（663-670行目） |

**主要処理フロー**:
- **663行目**: `Object.keys(scope.bindings)` でバインディング名を取得
- **664行目**: `scope.bindings[name]` でBindingオブジェクトを取得
- **665-669行目**: `console.log(" -", name, {...})` で各バインディング情報を出力

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

```
Babelプラグイン
    │
    └─ path.scope.dump()
           │
           └─ Scope.dump()
                  │
                  ├─ console.log(sep) [セパレータ]
                  │
                  └─ do-while (scope = scope.parent)
                         │
                         ├─ console.log("#", scope.block.type)
                         │
                         └─ for (name in scope.bindings)
                                │
                                └─ console.log(" -", name, {
                                       constant: binding.constant,
                                       references: binding.references,
                                       violations: binding.constantViolations.length,
                                       kind: binding.kind
                                   })
```

### データフロー図

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

scope.dump()呼び出し ─────▶ Scope.dump()
                                   │
                                   ▼
                           セパレータ出力 ───────▶ stdout: "----..."
                                   │
                                   ▼
                           スコープ走査ループ
                                   │
                                   ├─▶ stdout: "# {blockType}"
                                   │
                                   └─▶ stdout: " - {name} {...}"
                                   │
                                   ▼
                           親スコープに移動
                           (存在する限りループ継続)
                                   │
                                   ▼
                           セパレータ出力 ───────▶ stdout: "----..."
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| index.ts | `packages/babel-traverse/src/scope/index.ts` | ソース | Scopeクラスとdump()メソッドの実装 |
| binding.ts | `packages/babel-traverse/src/scope/binding.ts` | ソース | Bindingクラスの定義 |
