# 機能設計書 80-clang-change-namespace

## 概要

本ドキュメントは、LLVM/Clangプロジェクトにおける名前空間変更ツール「clang-change-namespace」の機能設計書である。クラス・関数定義の囲む名前空間を変更するリファクタリングを行う。

### 本機能の処理概要

clang-change-namespaceは、C++ソースコードを解析し、指定された名前空間内の定義を別の名前空間に移動するリファクタリングツールである。名前空間の変更に伴い、必要な参照の修正も自動的に行う。

**業務上の目的・背景**：大規模なC++プロジェクトにおいて、コードの再編成や命名規則の変更により名前空間を変更する必要が生じることがある。手動での変更は労力がかかり、参照の修正漏れによるコンパイルエラーを招きやすい。clang-change-namespaceは、この作業を自動化し安全に実行する。

**機能の利用シーン**：
- プロジェクト構造の再編成
- 命名規則の変更対応
- ライブラリのモジュール分割
- レガシーコードの名前空間整理

**主要な処理内容**：
1. ソースファイルの解析とAST構築
2. 対象名前空間内の定義の特定
3. ASTマッチャーによる参照箇所の検出
4. 名前空間の変更と参照の修正
5. コードスタイルに合わせたフォーマット

**関連システム・外部連携**：compile_commands.json、clang-format

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 端末出力 | 結果表示画面 | 変更後のソースコード表示 |
| - | YAML出力 | 結果表示画面 | 変更内容のYAML形式出力 |

## 機能種別

リファクタリング / 名前空間操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --old_namespace | string | Yes | 変更前の名前空間 | 有効な名前空間形式 |
| --new_namespace | string | Yes | 変更後の名前空間 | 有効な名前空間形式 |
| --file_pattern | string | Yes | 対象ファイルのパターン | 正規表現 |
| -i | flag | No | ファイルを直接編集 | - |
| --dump_result | flag | No | 結果をYAML形式で出力 | - |
| --style | string | No | フォーマットスタイル | 有効なスタイル名 |
| --allowed_file | string | No | 更新除外シンボルのパターンファイル | 有効なファイルパス |
| source_files | string[] | Yes | 対象ファイル | 有効なC++ファイル |

### 入力データソース

- C++ソースファイル
- コンパイルデータベース（compile_commands.json）
- 許可パターンファイル（オプション）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 変更後ソース | text/file | 名前空間変更後のソースコード |
| YAML出力 | YAML | 変更ファイルとその内容のリスト |
| 変更サマリー | text | 変更されたファイルの一覧と内容 |

### 出力先

- 標準出力（デフォルト、--dump_result時）
- ファイル（-i指定時）

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数の解析
   └─ 名前空間、ファイルパターン、オプションの取得

2. 許可パターンファイルの読み込み
   └─ 更新対象外シンボルのパターン取得

3. RefactoringToolとChangeNamespaceToolの初期化
   └─ マッチャーの登録

4. ASTマッチャーによる解析
   └─ 対象名前空間内の定義と参照を検出

5. Replacementsの収集
   └─ 名前空間変更と参照修正のリプレースメント生成

6. フォーマットと適用
   └─ formatAndApplyAllReplacementsで整形・適用

7. 結果出力
   └─ 標準出力、YAML、またはファイル書き込み
```

### フローチャート

```mermaid
flowchart TD
    A[開始: clang-change-namespace] --> B[コマンドライン解析]
    B --> C[GetAllowedSymbolPatterns]
    C --> D[RefactoringTool作成]
    D --> E[ChangeNamespaceTool作成]
    E --> F[MatchFinder::registerMatchers]
    F --> G[Tool::run]
    G --> H[AST解析・マッチング]
    H --> I[Replacements収集]
    I --> J[formatAndApplyAllReplacements]
    J --> K{-i 指定?}
    K -->|Yes| L[overwriteChangedFiles]
    K -->|No| M{--dump_result?}
    M -->|Yes| N[YAML出力]
    M -->|No| O[標準出力に表示]
    L --> P[終了]
    N --> P
    O --> P
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-80-01 | 必須パラメータ | old_namespace, new_namespace, file_patternは必須 | 常時 |
| BR-80-02 | デフォルトスタイル | フォーマットスタイルのデフォルトはLLVM | --style未指定時 |
| BR-80-03 | 参照自動修正 | 名前空間変更に伴い参照も自動修正 | 常時 |
| BR-80-04 | パターンマッチ | file_patternにマッチするファイルのみ処理 | 常時 |

### 計算ロジック

ChangeNamespaceToolはASTマッチャーを使用して、old_namespaceに属する定義を検出し、new_namespaceに移動する。参照箇所は元の名前空間での完全修飾名に変換される（例：na::nb::Y の X への参照は na::X となる）。

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 許可ファイルエラー | --allowed_fileのファイルが開けない | エラーを報告して終了 |
| - | 解析エラー | ソースファイルがコンパイル不可 | エラーを報告して終了 |
| - | 適用エラー | Replacementsの適用に失敗 | エラーを報告して終了 |

### リトライ仕様

リトライなし。エラー発生時は即座に終了。

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

該当なし。

## パフォーマンス要件

特になし。

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

- -i オプション使用時はソースファイルを直接変更する

## 備考

- ネストした名前空間もサポート（"na::nb"形式で指定）
- 移動先の名前空間が存在しない場合は自動的に作成される

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ChangeNamespace.h | `clang-tools-extra/clang-change-namespace/ChangeNamespace.h` | ChangeNamespaceToolクラス定義 |

#### Step 2: メイン処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ClangChangeNamespace.cpp | `clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp` | 全体の処理フロー |

**主要処理フロー**:
1. **8-29行目**: ツールの使用例（コメント）
2. **46-79行目**: コマンドラインオプションの定義
3. **81-96行目**: GetAllowedSymbolPatterns関数
4. **100-181行目**: main関数

**main関数の詳細**:
- **102-107行目**: CommonOptionsParser作成
- **110行目**: RefactoringTool作成
- **111-117行目**: 許可パターン取得
- **118-124行目**: ChangeNamespaceTool作成とマッチャー登録
- **126-140行目**: ツール実行と結果適用
- **141-142行目**: -i オプション時のファイル書き込み
- **148-168行目**: --dump_result時のYAML出力
- **171-178行目**: デフォルトの標準出力

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

```
main
    │
    ├─ CommonOptionsParser::create()
    │
    ├─ GetAllowedSymbolPatterns()
    │      └─ MemoryBuffer::getFile()
    │
    ├─ RefactoringTool()
    │
    ├─ ChangeNamespaceTool()
    │      └─ registerMatchers()
    │
    ├─ newFrontendActionFactory()
    │
    ├─ Tool::run()
    │      └─ ChangeNamespaceTool (ASTマッチング)
    │             └─ Replacements収集
    │
    ├─ formatAndApplyAllReplacements()
    │
    └─ [出力]
           ├─ overwriteChangedFiles() (-i)
           ├─ WriteToYAML() (--dump_result)
           └─ outs() (デフォルト)
```

### データフロー図

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

ソースファイル群 ─────▶ Tool::run() ─────▶ ASTマッチング
                                               │
old_namespace ──────────▶ ChangeNamespaceTool   │
new_namespace ──────────▶                       │
file_pattern ───────────▶                       │
                                               ▼
                                        Replacements
                                               │
                                               ▼
                              formatAndApplyAllReplacements()
                                               │
                                               ▼
                                        Rewriter
                                               │
                        ┌──────────────────────┼──────────────────────┐
                        │                      │                      │
                        ▼                      ▼                      ▼
                  ファイル更新            YAML出力               標準出力
                     (-i)            (--dump_result)          (デフォルト)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ClangChangeNamespace.cpp | `clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp` | ソース | メイン実装 |
| ChangeNamespace.h | `clang-tools-extra/clang-change-namespace/ChangeNamespace.h` | ヘッダ | ChangeNamespaceToolクラス定義 |
| ChangeNamespace.cpp | `clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp` | ソース | ChangeNamespaceTool実装 |
