# 帳票設計書 7-HTMLReport (include-cleaner)

## 概要

本ドキュメントは、include-cleanerツールのHTMLレポート機能の設計仕様を記載する。不要・不足しているインクルードを可視化するHTML形式のデバッグレポートを生成する機能である。

### 本帳票の処理概要

HTMLReportは、include-cleanerの解析結果をインタラクティブなHTML形式で出力し、ソースコード上のシンボル参照とそれを提供するヘッダーの関係を視覚化するデバッグ用レポートを生成する。

**業務上の目的・背景**：C/C++プロジェクトでは、不要なインクルードがコンパイル時間の増加やビルド依存関係の複雑化を招く。一方、不足しているインクルードは将来のリファクタリングで問題を引き起こす可能性がある。本機能は、各シンボル参照がどのヘッダーによって提供されているかを可視化し、include-cleanerの解析ロジックをデバッグ・検証することを目的とする。

**帳票の利用シーン**：include-cleanerツールの動作検証、インクルード依存関係の調査、IWYU（Include What You Use）ポリシーの適用確認、ビルド最適化作業時に利用される。

**主要な出力内容**：
1. 注釈付きソースコード表示（行番号付き）
2. 各シンボル参照のハイライト（明示的/暗黙的/曖昧）
3. インクルード行の使用状況表示（使用済み/未使用/半使用）
4. シンボルの提供元ヘッダー情報
5. 推奨するインクルード挿入候補

**帳票の出力タイミング**：include-cleanerツールでHTML出力オプションを指定した場合、またはデバッグ目的でwriteHTMLReport()を呼び出した場合に生成される。

**帳票の利用者**：include-cleaner開発者、ツール検証担当者、ビルドシステム最適化担当者

## 帳票種別

インタラクティブHTMLレポート（デバッグ用）

## 利用画面

| 画面No | 画面名 | URL/ルーティング | 出力操作 |
|--------|--------|-----------------|---------|
| - | ブラウザ | file:///output.html | ファイル閲覧 |

## 出力形式

### 基本仕様

| 項目 | 内容 |
|-----|------|
| ファイル形式 | HTML |
| 用紙サイズ | - |
| 向き | - |
| ファイル名 | 任意（raw_ostreamに出力） |
| 出力方法 | ファイル出力 / ストリーム出力 |
| 文字コード | UTF-8 |

### HTML固有設定

| 項目 | 内容 |
|-----|------|
| スタイル | インライン CSS |
| JavaScript | インライン JS（ホバー表示） |
| 外部リソース | なし（自己完結） |

## 帳票レイアウト

### レイアウト概要

単一HTMLファイルで構成され、ソースコードとメタ情報を含む。

```
┌─────────────────────────────────────────────────────────────────┐
│ <head>                                                           │
│   <style>CSS定義</style>                                         │
│   <script>JS定義</script>                                        │
│   <template id="iXXX">インクルード情報</template>                │
│   <template id="tNNN">シンボル参照情報</template>                │
├─────────────────────────────────────────────────────────────────┤
│ <body>                                                           │
│   <pre class="code">                                             │
│     [追加推奨インクルード行（緑背景）]                           │
│     <code class="line">                                          │
│       [行番号] [シンボル参照（下線）] [インクルード（下線）]     │
│     </code>                                                      │
│   </pre>                                                         │
│                                                                  │
│   [#hover div（クリック時にポップアップ）]                       │
└─────────────────────────────────────────────────────────────────┘
```

### CSS定義内容

| クラス名 | 説明 | スタイル |
|---------|------|---------|
| .ref | シンボル参照 | 下線、青色 |
| .inc | インクルード行 | 下線、青色 |
| .ref.implicit | 暗黙参照 | 黄色背景 |
| .missing | 不足インクルード | 赤背景 |
| .unused | 未使用インクルード | 赤背景 |
| .inserted | 挿入推奨 | 緑背景 |
| .semiused | 半使用インクルード | グレー背景 |

### シンボル参照情報（template）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Symbol | シンボル種別・名前 | describeSymbol(), Sym | 文字列 |
| 2 | Details | シンボル詳細（宣言） | printDetails() | コード |
| 3 | Location | シンボル定義位置 | SymbolLocation | パス:行:列 |
| 4 | Header | 提供ヘッダー | headersForSymbol() | ファイル名 |
| 5 | Included | 既存インクルード | Includes.match() | パス、行番号リンク |
| 6 | Insert | 挿入推奨 | spellHeader() | インクルードパス |

### インクルード情報（template）

| No | 項目名 | 説明 | データ取得元 | 表示形式 |
|----|-------|------|-------------|---------|
| 1 | Resolved | 解決先ファイル | Inc.Resolved | パス |
| 2 | Provides | 提供シンボル | IncludeRefs | シンボル名、行リンク |

## 出力条件

### 抽出条件

| 条件名 | 説明 | 必須 |
|-------|------|-----|
| ソースファイル | メインファイル | Yes |
| AST | 解析済みAST | Yes |
| インクルード情報 | Includes | Yes |

### ソート順

| 優先度 | 項目 | 昇順/降順 |
|-------|------|---------|
| 1 | 参照オフセット | 昇順 |
| 2 | RefType（暗黙優先） | 暗黙→明示 |

## データベース参照仕様

### 参照データソース一覧

| データソース | 用途 | 取得方法 |
|-------------|------|---------|
| ASTContext | AST情報 | 引数 |
| Preprocessor | プリプロセッサ情報 | 引数 |
| Includes | インクルード情報 | 引数 |
| PragmaIncludes | プラグマ情報 | 引数（オプション） |

## 計算仕様

### 計算項目一覧

| 項目名 | 計算式 | 端数処理 | 備考 |
|-------|-------|---------|------|
| includeType | IncludeRefs判定 | - | unused/used/semiused |
| Satisfied | Includes.match()結果 | - | bool |

## 処理フロー

### 出力フロー

```mermaid
flowchart TD
    A[writeHTMLReport呼出] --> B[Reporter初期化]
    B --> C[Roots AST走査]
    C --> D[各参照についてaddRef]
    D --> E[MacroRefs処理]
    E --> F[R.write呼出]
    F --> G[HTMLヘッダ出力]
    G --> H[CSS/JS出力]
    H --> I[Insertionテンプレート出力]
    I --> J[Includeテンプレート出力]
    J --> K[Refテンプレート出力]
    K --> L[ソースコード出力]
    L --> M[HTMLフッタ出力]
    M --> N[終了]
```

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 表示メッセージ | 対処方法 |
|----------|---------|--------------|---------|
| 参照位置エラー | ファイル外参照 | "Ref location outside file!" | 警告出力、スキップ |

## パフォーマンス要件

| 項目 | 内容 |
|-----|------|
| 想定データ件数 | 単一ファイル |
| 目標出力時間 | 数秒 |
| 同時出力数上限 | 1 |

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

- ソースコード全文がHTMLに含まれる
- HTMLエスケープ処理あり（escapeChar/escapeString）

## 備考

- デバッグ用途のため、本番環境での使用は想定していない
- JavaScriptでクリック時にホバー情報を表示

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | HTMLReport.cpp | `clang-tools-extra/include-cleaner/lib/HTMLReport.cpp` | Ref構造体（行147-156）の定義を理解 |

**読解のコツ**: Refは参照位置(Offset)、種別(Type)、シンボル(Sym)、提供元情報(Locations, Headers, Includes)を保持する。

#### Step 2: Reporterクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | HTMLReport.cpp | 同上 | Reporterクラス（行135-495）の構造を確認 |

**主要処理フロー**:
- **行197-202**: コンストラクタでコンテキスト初期化
- **行204-222**: addRef()で参照情報を収集
- **行224-252**: write()でHTML出力

#### Step 3: CSS/JSを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | HTMLReport.cpp | 同上 | CSS定数（行33-70）とJS定数（行72-94）を確認 |

**主要処理フロー**:
- **行33-70**: CSSでスタイル定義（.ref, .inc, .missing, .unused等）
- **行72-94**: JSでselect(), fillHover()関数定義

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | HTMLReport.cpp | 同上 | writeHTMLReport()関数（行499-535） |

**主要処理フロー**:
- **行504**: Reporter初期化
- **行506-528**: Roots走査とMacroRefs処理
- **行534**: R.write()呼出

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

```
writeHTMLReport()
    │
    ├─ Reporter::Reporter()
    │
    ├─ walkAST() [Roots走査]
    │      └─ Reporter::addRef()
    │             ├─ fillTarget()
    │             │      ├─ locateSymbol()
    │             │      ├─ headersForSymbol()
    │             │      ├─ Includes.match()
    │             │      └─ spellHeader()
    │             │
    │             └─ IncludeRefs/Insertion更新
    │
    ├─ MacroRefs処理
    │      └─ Reporter::addRef()
    │
    └─ Reporter::write()
           ├─ CSS/JS出力
           ├─ writeInsertion() [template]
           ├─ writeInclude() [template]
           ├─ writeTarget() [template]
           └─ writeCode()
                  ├─ escapeChar()
                  └─ マーカー出力
```

### データフロー図

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

ASTContext ─────────┐
                    │
Preprocessor ───────┼──▶ Reporter
                    │       │
Includes ───────────┤       ├─ Refs[]
                    │       │      ├─ Offset
PragmaIncludes ─────┘       │      ├─ Type
                            │      ├─ Sym
                            │      ├─ Locations[]
                            │      ├─ Headers[]
                            │      ├─ Includes[]
                            │      └─ Insert
                            │
                            ├─ IncludeRefs{}
                            │
                            └─ Insertion{}
                                    │
                                    ▼
                              write()
                                    │
                                    ▼
                              [HTML出力]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| HTMLReport.cpp | `clang-tools-extra/include-cleaner/lib/HTMLReport.cpp` | ソース | レポート生成実装 |
| AnalysisInternal.h | `clang-tools-extra/include-cleaner/lib/AnalysisInternal.h` | ヘッダ | 内部解析関数 |
| IncludeSpeller.h | `clang-tools-extra/include-cleaner/include/clang-include-cleaner/IncludeSpeller.h` | ヘッダ | インクルードパス生成 |
| Types.h | `clang-tools-extra/include-cleaner/include/clang-include-cleaner/Types.h` | ヘッダ | 型定義 |
