# 機能設計書 81-clang-move

## 概要

本ドキュメントは、clang-moveツールの機能設計について記述する。clang-moveは、C/C++のクラス、関数、変数などの宣言・定義を既存のソースファイルから新しいファイルに移動するリファクタリングツールである。

### 本機能の処理概要

clang-moveは、C++プロジェクトにおいてコードの再構成を自動化するツールである。指定されたシンボル（クラス、関数、変数など）を元のヘッダファイル（.h）および実装ファイル（.cc/.cpp）から新しいファイルに移動し、依存関係を自動的に解決する。

**業務上の目的・背景**：大規模なC++プロジェクトでは、コードベースの成長に伴い、ファイルの分割やコードの再配置が必要になることが多い。手動でのコード移動は時間がかかり、エラーが発生しやすい。clang-moveは、この作業を自動化し、正確かつ効率的にコードを移動させることで、開発者の生産性を向上させる。

**機能の利用シーン**：
- クラスが大きくなりすぎたため、別のファイルに分割したい場合
- モジュール構造を再編成したい場合
- 関連するクラスや関数を一つのファイルにまとめたい場合
- コードのレビューや保守性向上のためにファイル構造を改善したい場合

**主要な処理内容**：
1. 移動対象のシンボル（クラス、関数、変数）の特定とAST解析
2. 依存関係グラフの構築（ヘルパー関数、変数、クラスの参照関係）
3. 移動対象シンボルが使用するヘルパー宣言の抽出
4. 新しいファイルへの宣言・定義の挿入
5. 元ファイルからの宣言・定義の削除
6. #includeディレクティブの適切な更新
7. 名前空間の正しい管理

**関連システム・外部連携**：Clang LibTooling APIを使用してASTを解析し、コード変換を行う。clang-formatと連携して出力コードを整形できる。

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

## 関連画面

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

## 機能種別

リファクタリング / コード変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| names | string list | Yes | 移動するシンボルの完全修飾名リスト（カンマ区切り） | 空でないこと |
| old_header | string | No | 元のヘッダファイルパス | ファイルが存在すること |
| old_cc | string | No | 元の実装ファイルパス | ファイルが存在すること |
| new_header | string | No | 新しいヘッダファイルパス | パスが有効であること |
| new_cc | string | No | 新しい実装ファイルパス | パスが有効であること |
| old_depend_on_new | bool | No | 旧ファイルが新ファイルをインクルードするか | - |
| new_depend_on_old | bool | No | 新ファイルが旧ファイルをインクルードするか | - |
| style | string | No | コードフォーマットスタイル | デフォルト: llvm |
| dump_result | bool | No | 結果をJSON形式で出力するか | - |
| dump_decls | bool | No | 旧ヘッダの全宣言をJSON出力するか | - |

### 入力データソース

- ソースファイル（.h, .cc, .cpp等）
- compilation database（compile_commands.json）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 修正済み元ファイル | file | 宣言・定義が削除されたファイル |
| 新規ファイル | file | 移動された宣言・定義を含むファイル |
| JSON出力 | JSON | dump_result有効時の変換結果 |

### 出力先

- 指定されたファイルパス（new_header, new_cc）
- 標準出力（JSON形式での結果出力時）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ CommonOptionsParserでオプションとソースファイルを取得

2. MoveDefinitionSpecの構築
   └─ 移動対象シンボル名、ファイルパス、依存関係オプションを設定

3. ClangMoveContextの初期化
   └─ 作業ディレクトリ、スタイル設定を含むコンテキストを作成

4. ASTマッチャーの登録（ClangMoveTool::registerMatchers）
   └─ 旧ヘッダ・旧CCの宣言にマッチするパターンを設定

5. AST解析の実行（Tool.run）
   └─ ソースファイルを解析し、マッチした宣言を収集

6. ヘルパー宣言の参照グラフ構築
   └─ HelperDeclRefGraphで依存関係を解析

7. 宣言の移動処理（onEndOfTranslationUnit）
   └─ moveDeclsToNewFiles: 新ファイルへの挿入
   └─ removeDeclsInOldFiles: 旧ファイルからの削除

8. 新規ファイルの作成
   └─ new_header, new_ccファイルを作成

9. 変更の適用
   └─ Rewriterで置換を適用し、ファイルを上書き
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[コマンドライン解析]
    B --> C{dump_decls?}
    C -->|Yes| D[宣言一覧をJSON出力]
    D --> Z[終了]
    C -->|No| E[ClangMoveContext初期化]
    E --> F[ASTマッチャー登録]
    F --> G[AST解析実行]
    G --> H[移動対象宣言の収集]
    H --> I[ヘルパー宣言の依存関係解析]
    I --> J[新ファイルへ宣言を挿入]
    J --> K[旧ファイルから宣言を削除]
    K --> L[#include更新]
    L --> M{dump_result?}
    M -->|Yes| N[JSON形式で結果出力]
    N --> Z
    M -->|No| O[ファイルに変更を適用]
    O --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 循環依存禁止 | old_depend_on_newとnew_depend_on_oldは同時に指定不可 | 両オプション指定時 |
| BR-02 | ヘルパー宣言の自動移動 | 移動対象が使用するヘルパー宣言も一緒に移動 | 常時 |
| BR-03 | 未使用ヘルパーの削除 | 移動後に未使用となるヘルパー宣言は削除 | 常時 |
| BR-04 | 全宣言移動時の特別処理 | 全宣言が移動される場合、ファイル全体を移動 | 旧ヘッダに残る宣言がない場合 |

### 計算ロジック

ヘルパー宣言の使用判定：HelperDeclRefGraphを使用して、移動対象宣言から到達可能な全てのヘルパー宣言を抽出する。グラフ探索により、直接・間接的に参照される全ての宣言を特定する。

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| 1 | オプションエラー | old_depend_on_newとnew_depend_on_old両方指定 | どちらか一方のみ指定 |
| 1 | ビルドエラー | コンパイルエラーが発生 | ソースコードを修正 |
| EC値 | ファイルエラー | 新規ファイル作成失敗 | パスと権限を確認 |

### リトライ仕様

リトライは行わない。エラー時は即座に終了。

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

該当なし。ただし、全ての変更が成功した場合のみファイルを上書きする。

## パフォーマンス要件

特に規定なし。大規模プロジェクトでも実用的な時間内に完了すること。

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

- ファイルシステムへの書き込み権限が必要
- 信頼できないソースコードに対しては注意が必要

## 備考

- AST解析時に"-fparse-all-comments"オプションが自動追加され、コメントも適切に処理される
- テンプレートクラス・関数の移動もサポート
- forward declarationは移動対象クラスの前に自動配置

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | Move.h | `clang-tools-extra/clang-move/Move.h` | MoveDefinitionSpec, ClangMoveContext, DeclarationReporter構造体の定義を理解 |
| 1-2 | HelperDeclRefGraph.h | `clang-tools-extra/clang-move/HelperDeclRefGraph.h` | ヘルパー宣言の依存関係グラフ構造を理解 |

**読解のコツ**: MoveDefinitionSpecは移動仕様を、ClangMoveContextは実行時コンテキストを保持する。DeclarationReporterはdump_declsモード用。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ClangMove.cpp | `clang-tools-extra/clang-move/tool/ClangMove.cpp` | main関数とコマンドライン処理 |

**主要処理フロー**:
1. **97-104行目**: CommonOptionsParserでコマンドライン解析
2. **119-126行目**: MoveDefinitionSpecの構築
3. **133-137行目**: ClangMoveContext, DeclarationReporter, Factoryの初期化
4. **139-141行目**: Tool.run()でAST解析実行
5. **162-177行目**: 新規ファイルの作成
6. **187-190行目**: 変更の適用（formatAndApplyAllReplacements）

#### Step 3: ASTマッチング処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Move.cpp | `clang-tools-extra/clang-move/Move.cpp` | registerMatchers, run, onEndOfTranslationUnitメソッド |

**主要処理フロー**:
- **500-661行目**: registerMatchers - 各種宣言にマッチするパターンを登録
- **663-684行目**: run - マッチした宣言をMovedDecls, RemovedDeclsに振り分け
- **722-798行目**: removeDeclsInOldFiles - 旧ファイルから宣言を削除
- **800-842行目**: moveDeclsToNewFiles - 新ファイルへ宣言を挿入
- **879-934行目**: onEndOfTranslationUnit - 全処理の統合

#### Step 4: ヘルパー宣言グラフを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | HelperDeclRefGraph.cpp | `clang-tools-extra/clang-move/HelperDeclRefGraph.cpp` | 依存関係グラフの構築とトラバース |

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

```
main (ClangMove.cpp)
    │
    ├─ CommonOptionsParser::create
    │
    ├─ RefactoringTool::run
    │      │
    │      └─ ClangMoveActionFactory::create
    │             │
    │             └─ ClangMoveAction
    │                    │
    │                    ├─ CreateASTConsumer
    │                    │      └─ FindAllIncludes (PPCallbacks)
    │                    │
    │                    └─ MatchFinder::newASTConsumer
    │                           │
    │                           ├─ ClangMoveTool::registerMatchers
    │                           │
    │                           ├─ ClangMoveTool::run
    │                           │
    │                           └─ ClangMoveTool::onEndOfTranslationUnit
    │                                  ├─ moveDeclsToNewFiles
    │                                  └─ removeDeclsInOldFiles
    │
    ├─ CreateNewFile (new_header, new_cc)
    │
    └─ formatAndApplyAllReplacements → Rewrite.overwriteChangedFiles
```

### データフロー図

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

old_header ─────┐
                │
old_cc ─────────┼───▶ ClangMoveTool::registerMatchers ─▶ マッチャー登録
                │           │
names ──────────┘           ▼
                      AST解析 (Tool.run)
                            │
                            ▼
                      MovedDecls / RemovedDecls
                            │
                            ▼
                      HelperDeclRefGraph ─▶ 依存関係解析
                            │
                            ▼
                      ┌─────┴─────┐
                      ▼           ▼
              moveDeclsTo    removeDeclsIn
              NewFiles       OldFiles
                      │           │
                      ▼           ▼
                 new_header   old_header (修正済み)
                 new_cc       old_cc (修正済み)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ClangMove.cpp | `clang-tools-extra/clang-move/tool/ClangMove.cpp` | ソース | mainエントリーポイント、CLI処理 |
| Move.h | `clang-tools-extra/clang-move/Move.h` | ヘッダ | 主要データ構造と公開API定義 |
| Move.cpp | `clang-tools-extra/clang-move/Move.cpp` | ソース | コア移動ロジック実装 |
| HelperDeclRefGraph.h | `clang-tools-extra/clang-move/HelperDeclRefGraph.h` | ヘッダ | 依存関係グラフ定義 |
| HelperDeclRefGraph.cpp | `clang-tools-extra/clang-move/HelperDeclRefGraph.cpp` | ソース | 依存関係グラフ実装 |
| CMakeLists.txt | `clang-tools-extra/clang-move/CMakeLists.txt` | ビルド | ビルド設定 |
