# 機能設計書 16-InnerGraph解析

## 概要

本ドキュメントは、webpackのInnerGraph解析機能について、モジュール内の変数使用を追跡しより精密なTree Shakingを実現する設計と実装の詳細を記述する。

### 本機能の処理概要

InnerGraph解析は、モジュール内部のトップレベルシンボル（関数宣言、クラス宣言、変数宣言）の使用関係をグラフとして構築し、エクスポートされるシンボルが実際にどの内部シンボルに依存しているかを追跡する機能である。これにより、通常のTree Shakingでは除去できない間接的な未使用コードを特定できる。

**業務上の目的・背景**：通常のTree Shakingはエクスポート単位での使用/未使用を判定するが、モジュール内部の関数や変数の依存関係までは追跡しない。re-exportパターンや、エクスポートされた関数が内部的に使用する他の関数・定数がある場合、InnerGraphにより不要な内部コードも除去できる。

**機能の利用シーン**：コンポーネントライブラリのre-exportパターンでの最適化、ユーティリティライブラリの部分使用時の最適化、複雑なモジュール内部のデッドコード検出。

**主要な処理内容**：
1. パーサのprogramフックでInnerGraphを有効化
2. トップレベルのシンボル（関数/クラス/変数）にTopLevelSymbolタグを付与
3. シンボル間の使用関係をInnerGraphマップに記録
4. パーサのfinishフックでinferDependencyUsageを実行し、依存関係を推論
5. PureExpressionDependencyによる純粋式のマーキング

**関連システム・外部連携**：JavascriptParser、PureExpressionDependency、InnerGraphユーティリティモジュール、Tree Shaking（SideEffectsFlagPlugin等）と連携する。

**権限による制御**：optimization.innerGraph設定で制御。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | Login (reexport-components) | 補助機能 | re-exportパターンにおける変数使用追跡で精密なTree Shaking |
| 11 | Dashboard (reexport-components) | 補助機能 | re-exportパターンにおける変数使用追跡で精密なTree Shaking |

## 機能種別

最適化処理 / 静的解析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| optimization.innerGraph | `boolean` | No | InnerGraph解析の有効/無効 | デフォルト: productionでtrue |

### 入力データソース

- JavascriptParserによるAST解析結果
- パーサの状態（parserState）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| InnerGraph | `Map<InnerGraphKey, InnerGraphValue>` | シンボル間の使用関係グラフ |
| PureExpressionDependency | `Dependency` | 純粋式としてマークされた依存関係 |
| usedByExports | `Set<string> \| boolean` | エクスポートによる使用情報 |

### 出力先

パーサ状態のInnerGraphマップ、モジュールの依存関係リスト

## 処理フロー

### 処理シーケンス

```
1. InnerGraphの有効化（programフック）
   └─ InnerGraph.enable(parser.state)でパーサ状態にInnerGraphを初期化
2. トップレベルシンボルのタグ付け
   └─ 関数宣言、クラス宣言、変数宣言にTopLevelSymbolタグを付与
3. 使用関係の記録
   └─ シンボルの参照をInnerGraph.addUsage()で記録
4. 純粋式のマーキング
   └─ InnerGraph.onUsage()でPureExpressionDependencyを追加
5. 依存関係の推論（finishフック）
   └─ InnerGraph.inferDependencyUsage()で使用情報を確定
```

### フローチャート

```mermaid
flowchart TD
    A[parser.hooks.program] --> B[InnerGraph.enable]
    B --> C[prewalk: トップレベルシンボル収集]
    C --> D[シンボルにTopLevelSymbolタグ付与]
    D --> E[walk: シンボル使用の追跡]
    E --> F{シンボル使用<br>検出?}
    F -->|Yes| G[InnerGraph.addUsage]
    F -->|No| H[次のノードへ]
    G --> E
    H --> E
    E --> I[parser.hooks.finish]
    I --> J[InnerGraph.inferDependencyUsage]
    J --> K[PureExpressionDependency生成]
    K --> L[usedByExports設定]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | トップレベル限定 | InnerGraphはトップレベルのシンボル（関数/クラス/変数宣言）のみ追跡 | パース時 |
| BR-02 | 純粋式判定 | 副作用のない式はPureExpressionDependencyでマークされる | クラス式、関数式等 |
| BR-03 | usedByExports伝播 | usedByExportsがundefinedまたはtrueの場合は常に含まれる | コード生成時 |
| BR-04 | ESMモジュール対象 | JAVASCRIPT_MODULE_TYPE_AUTOとJAVASCRIPT_MODULE_TYPE_ESMが対象 | パーサ登録時 |

### 計算ロジック

- **InnerGraph**: `Map<TopLevelSymbol | null, Set<string | TopLevelSymbol> | true>`形式でシンボル間の使用関係を記録
- **推論アルゴリズム**: inferDependencyUsageでグラフを辿り、各依存関係のusedByExportsを確定

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

該当なし

## エラー処理

### エラーケース一覧

該当なし（解析失敗時は通常のTree Shakingにフォールバック）

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- ロガーのtimeAggregateによる推論時間の計測と集計
- WeakMapによるパーサ状態管理でメモリ効率を確保

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

該当なし

## 備考

- InnerGraph解析はTree Shaking（No.15）の補助機能として位置づけられる
- 解析精度が向上するため、re-exportを多用するコンポーネントライブラリで特に効果が大きい

---

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

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

### 推奨読解順序

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

InnerGraphのコアデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | InnerGraph.js | `lib/optimize/InnerGraph.js` | 18-31行目: 型定義（InnerGraphValueSet, InnerGraphValue, InnerGraphKey, InnerGraph, UsageCallback, StateObject） |
| 1-2 | InnerGraph.js | `lib/optimize/InnerGraph.js` | 33-41行目: TopLevelSymbolクラス |

**読解のコツ**: StateObjectが中心的なデータ構造。innerGraph（シンボル間の使用関係マップ）、currentTopLevelSymbol（現在処理中のシンボル）、usageCallbackMap（シンボルの使用コールバック）の3つのプロパティを持つ。

#### Step 2: InnerGraphの有効化と使用記録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | InnerGraph.js | `lib/optimize/InnerGraph.js` | 63-77行目: addUsage関数 |

**主要処理フロー**:
- **64行目**: getStateでパーサ状態からInnerGraph状態を取得
- **66-76行目**: innerGraphマップにシンボルの使用情報を追加。usage=trueの場合は全参照、それ以外はSetに追加

#### Step 3: プラグインの登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | InnerGraphPlugin.js | `lib/optimize/InnerGraphPlugin.js` | 39-100行目: プラグインのapply()メソッド |

**主要処理フロー**:
1. **45-48行目**: PureExpressionDependencyのテンプレートを登録
2. **59-77行目**: onUsageSuper関数でPureExpressionDependencyを生成
3. **79-81行目**: parser.hooks.programでInnerGraph.enable()を呼び出し
4. **83-89行目**: parser.hooks.finishでInnerGraph.inferDependencyUsage()を実行

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

```
JavascriptParser
    |
    +-- hooks.program
    |       +-- InnerGraphPlugin
    |               +-- InnerGraph.enable(parser.state)
    |
    +-- [prewalk/walk フェーズ]
    |       +-- InnerGraph.addUsage(state, symbol, usage)
    |       +-- InnerGraph.onUsage(state, callback)
    |       +-- parser.tagVariable(name, topLevelSymbolTag, symbol)
    |
    +-- hooks.finish
            +-- InnerGraphPlugin
                    +-- InnerGraph.inferDependencyUsage(parser.state)
                            +-- PureExpressionDependency生成
                            +-- dep.usedByExports = usedByExports
```

### データフロー図

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

ソースコードAST ----------> JavascriptParser             +--> InnerGraph Map
                               |                         |
トップレベルシンボル ----> TopLevelSymbolタグ付与       +--> TopLevelSymbol集合
                               |                         |
シンボル参照関係 --------> InnerGraph.addUsage()        +--> PureExpressionDependency
                               |                         |
                               v                         |
                        inferDependencyUsage()          +--> usedByExports情報
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| InnerGraphPlugin.js | `lib/optimize/InnerGraphPlugin.js` | ソース | InnerGraph解析プラグイン |
| InnerGraph.js | `lib/optimize/InnerGraph.js` | ソース | InnerGraphのコアロジック・データ構造 |
| PureExpressionDependency.js | `lib/dependencies/PureExpressionDependency.js` | ソース | 純粋式の依存関係 |
| JavascriptParser.js | `lib/javascript/JavascriptParser.js` | ソース | JavaScriptパーサ |
| ExportsInfo.js | `lib/ExportsInfo.js` | ソース | エクスポート使用情報 |
