# 機能設計書 85-modularize

## 概要

本ドキュメントは、modularizeツールの機能設計について記述する。modularizeは、C/C++ヘッダファイル群がモジュール化に適しているかどうかをチェックし、モジュールマップの生成を支援するツールである。

### 本機能の処理概要

modularizeは、ヘッダファイルを個別にコンパイルし、同じエンティティ（マクロ、型、変数）が複数の場所で異なる定義を持っていないか、ヘッダの内容がインクルード順序によって変化しないかを検証する。また、既存のモジュールマップがディレクトリ内の全ヘッダをカバーしているかのカバレッジチェックも行う。

**業務上の目的・背景**：C++20モジュールやClangモジュールへの移行において、既存のヘッダファイルがモジュール化に適しているかを事前に検証する必要がある。手動での検証は非常に困難であるため、自動化ツールが必要とされる。

**機能の利用シーン**：
- 大規模プロジェクトのモジュール化準備
- ヘッダ依存関係の問題検出
- module.modulemapの自動生成
- マクロや型の重複定義の検出

**主要な処理内容**：
1. ヘッダファイルリストまたはモジュールマップの読み込み
2. 各ヘッダの個別コンパイルと定義の収集
3. 同一エンティティの複数定義チェック
4. マクロ/条件分岐の一貫性チェック
5. extern/namespace内#includeの検出
6. オプションでmodule.modulemapを生成

**関連システム・外部連携**：Clang LibTooling API、Clang ModuleMap API。

**権限による制御**：特になし。ファイルシステムへの読み書き権限が必要。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | CLIツール | 主画面 | コマンドライン経由での実行 |

## 機能種別

静的解析 / モジュール化支援

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| header-list | string list | Yes | ヘッダファイルリストまたはモジュールマップ | 1つ以上 |
| -prefix | string | No | ヘッダパスに付加するプレフィックス | - |
| -module-map-path | string | No | 生成するモジュールマップのパス | - |
| -root-module | string | No | ルートモジュール名 | - |
| -problem-files-list | string | No | 問題ファイルリスト（除外用） | - |
| -no-coverage-check | bool | No | カバレッジチェックを無効化 | - |
| -coverage-check-only | bool | No | カバレッジチェックのみ実行 | - |
| -display-file-lists | bool | No | ファイルリストを表示 | - |
| -block-check-header-list-only | bool | No | ブロック内#includeをリストのヘッダのみ警告 | - |

### 入力データソース

- ヘッダファイルリスト（テキストファイル）
- モジュールマップファイル（module.modulemap）
- ソースファイル（.h, .c, .cpp等）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| エラーメッセージ | stderr | 重複定義、不整合の報告 |
| 警告メッセージ | stderr | カバレッジ不足等の警告 |
| モジュールマップ | file | -module-map-path指定時 |
| ファイルリスト | stdout | -display-file-lists指定時 |

### 出力先

- 標準エラー出力（診断メッセージ）
- 指定されたモジュールマップファイル

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ cl::ParseCommandLineOptionsでオプションを取得

2. ヘッダリスト/モジュールマップの読み込み
   └─ ModularizeUtilitiesで依存関係含めて解析

3. アシスタントモードの判定
   └─ -module-map-path指定時はモジュールマップ生成のみ

4. カバレッジチェック（モジュールマップ入力時）
   └─ ディレクトリ内ヘッダとマップ内ヘッダを比較

5. 表示モードの場合
   └─ 各ヘッダを個別コンパイルしてエラーチェック
   └─ 良好/問題ファイルリストを作成

6. エンティティ収集パス
   └─ CollectEntitiesActionで各ヘッダを解析
   └─ EntityMapにエンティティ（tag/value/macro）を記録

7. 重複定義チェック
   └─ 同じ名前のエンティティが複数箇所で定義されていないか

8. マクロ/条件分岐の一貫性チェック
   └─ PreprocessorTrackerで不整合を検出

9. ヘッダ内容の一貫性チェック
   └─ インクルード順序による内容変化を検出

10. 結果の出力
    └─ エラー/警告メッセージを表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コマンドライン解析]
    B --> C{ヘッダリスト指定?}
    C -->|No| D[ヘルプ表示]
    D --> Z[終了]
    C -->|Yes| E[ModularizeUtilities初期化]
    E --> F[ヘッダリスト/依存関係読み込み]
    F --> G{-module-map-path?}
    G -->|Yes| H[createModuleMap]
    H --> Z
    G -->|No| I{カバレッジチェック必要?}
    I -->|Yes| J[doCoverageCheck]
    J --> K{-coverage-check-only?}
    K -->|Yes| Z
    K -->|No| L[CompilationDatabase作成]
    I -->|No| L
    L --> M{-display-file-lists?}
    M -->|Yes| N[個別コンパイルチェック]
    N --> O[良好/問題リスト作成]
    O --> P[EntityMap収集]
    M -->|No| P
    P --> Q[重複定義チェック]
    Q --> R[マクロ一貫性チェック]
    R --> S[条件分岐一貫性チェック]
    S --> T[ヘッダ内容一貫性チェック]
    T --> U{-display-file-lists?}
    U -->|Yes| V[ファイルリスト表示]
    U -->|No| Z
    V --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 重複定義禁止 | 同一エンティティは複数箇所で定義不可 | 常時 |
| BR-02 | 一貫した展開 | マクロは全インクルードパスで同じ値に展開 | 常時 |
| BR-03 | ブロック内#include警告 | extern/namespace内での#includeを警告 | 常時 |
| BR-04 | カバレッジ必須 | モジュールマップは全ヘッダをカバーすべき | モジュールマップ入力時 |

### チェック対象エンティティ

- **EK_Tag**: 構造体、クラス、列挙型の定義
- **EK_Value**: 変数、関数の定義
- **EK_Macro**: マクロ定義

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

該当なし（ファイルベースの操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | 読み込みエラー | ヘッダリストファイルが開けない | パスを確認 |
| 1 | コンパイルエラー | ヘッダのコンパイルに失敗 | ヘッダを修正 |
| 1 | 重複定義 | 同一エンティティが複数定義 | 定義を統一 |
| 2 | その他エラー | 内部エラー | ログを確認 |

### リトライ仕様

リトライは行わない。問題があっても可能な限り処理を継続。

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

該当なし。

## パフォーマンス要件

特に規定なし。ヘッダファイル数とサイズに比例。

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

- ソースファイルへの読み取りアクセスが必要
- モジュールマップ生成時は書き込みアクセスが必要

## 備考

- ヘッダファイルはデフォルトでC++としてコンパイル
- 他言語の場合は-xオプションで指定（例: -x c）
- private/textual/excludeマークのヘッダはチェック対象外

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Modularize.h | `clang-tools-extra/modularize/Modularize.h` | DependencyMapとグローバル定義 |
| 1-2 | Modularize.cpp | `clang-tools-extra/modularize/Modularize.cpp` | Location, Entry, EntityMap構造体 |

**読解のコツ**: EntryはEK_Tag/EK_Value/EK_Macroの3種類。EntityMapはエンティティ名から定義位置のマップ。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Modularize.cpp | `clang-tools-extra/modularize/Modularize.cpp` | main関数と処理フロー |

**主要処理フロー**:
1. **789-802行目**: コマンドライン解析
2. **810-819行目**: ModularizeUtilities初期化
3. **822-828行目**: アシスタントモード判定
4. **830-835行目**: カバレッジチェック
5. **860-887行目**: 表示モードでの個別コンパイル
6. **882-887行目**: EntityMap収集パス
7. **900-934行目**: 重複定義チェック
8. **938-944行目**: マクロ/条件分岐チェック

#### Step 3: エンティティ収集を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Modularize.cpp | `clang-tools-extra/modularize/Modularize.cpp` | CollectEntitiesVisitor, CollectEntitiesAction |

**主要処理フロー**:
- **528-634行目**: CollectEntitiesVisitor - AST走査
- **636-675行目**: CollectEntitiesConsumer - エンティティ収集
- **677-715行目**: CollectEntitiesAction/Factory

#### Step 4: プリプロセッサトラッキングを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | PreprocessorTracker.h | `clang-tools-extra/modularize/PreprocessorTracker.h` | トラッカーインターフェース |
| 4-2 | PreprocessorTracker.cpp | `clang-tools-extra/modularize/PreprocessorTracker.cpp` | マクロ/条件分岐追跡実装 |

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

```
main (Modularize.cpp)
    │
    ├─ cl::ParseCommandLineOptions
    │
    ├─ ModularizeUtilities::createModularizeUtilities
    │      └─ loadAllHeaderListsAndDependencies
    │
    ├─ createModuleMap (アシスタントモード時)
    │
    ├─ ModularizeUtilities::doCoverageCheck (カバレッジチェック時)
    │
    ├─ PreprocessorTracker::create
    │
    └─ ClangTool::run
           │
           ├─ CompileCheckFrontendActionFactory (表示モード時)
           │
           └─ ModularizeFrontendActionFactory
                  │
                  └─ CollectEntitiesAction
                         │
                         ├─ CreateASTConsumer
                         │      └─ CollectEntitiesConsumer
                         │             │
                         │             ├─ HandleTranslationUnit
                         │             │      ├─ CollectEntitiesVisitor
                         │             │      │      ├─ VisitNamedDecl
                         │             │      │      ├─ VisitLinkageSpecDecl
                         │             │      │      └─ VisitNamespaceDecl
                         │             │      │
                         │             │      └─ macro_iterator (マクロ収集)
                         │             │
                         │             └─ EntityMap.mergeCurHeaderContents
                         │
                         └─ PreprocessorTracker
                                ├─ handlePreprocessorEntry
                                └─ handlePreprocessorExit
```

### データフロー図

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

header-list.txt ────┐
                    │
module.modulemap ───┼─▶ ModularizeUtilities ─▶ HeaderFileNames[]
                    │
                    │
-prefix ────────────┘         │
                              ▼
                        ClangTool::run
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
    CollectEntities   PreprocessorTracker  CoverageCheck
              │               │               │
              ▼               ▼               │
        EntityMap    Macro/Conditional    カバレッジ
              │          一貫性             警告
              │               │               │
              └───────────────┼───────────────┘
                              │
                              ▼
                    重複定義/不整合チェック
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
         エラー出力      警告出力       ファイルリスト
           (stderr)      (stderr)        (stdout)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Modularize.cpp | `clang-tools-extra/modularize/Modularize.cpp` | ソース | mainエントリーポイント、エンティティ収集 |
| Modularize.h | `clang-tools-extra/modularize/Modularize.h` | ヘッダ | グローバル定義、依存関係マップ |
| ModularizeUtilities.h | `clang-tools-extra/modularize/ModularizeUtilities.h` | ヘッダ | ユーティリティクラス |
| ModularizeUtilities.cpp | `clang-tools-extra/modularize/ModularizeUtilities.cpp` | ソース | ヘッダリスト/モジュールマップ読み込み |
| PreprocessorTracker.h | `clang-tools-extra/modularize/PreprocessorTracker.h` | ヘッダ | プリプロセッサトラッカーインターフェース |
| PreprocessorTracker.cpp | `clang-tools-extra/modularize/PreprocessorTracker.cpp` | ソース | マクロ/条件分岐追跡 |
| ModuleAssistant.cpp | `clang-tools-extra/modularize/ModuleAssistant.cpp` | ソース | モジュールマップ生成 |
| CoverageChecker.cpp | `clang-tools-extra/modularize/CoverageChecker.cpp` | ソース | カバレッジチェック |
