# 機能設計書 30-名前空間の移動

## 概要

本ドキュメントは、Roslynにおける「名前空間の移動」機能の設計を記述するものである。名前空間の移動機能は、型またはネームスペース宣言を新しい名前空間に移動し、すべての参照を自動的に更新するリファクタリング機能である。

### 本機能の処理概要

名前空間の移動機能は、選択された型または名前空間宣言を別の名前空間に移動する。フォルダ構造と名前空間を同期させる場合や、より適切な名前空間に型を再配置する場合に使用される。すべてのusing文と完全修飾名の参照が自動的に更新される。

**業務上の目的・背景**：プロジェクトが成長するにつれて、初期の名前空間設計が適切でなくなることがある。また、フォルダ構造と名前空間を一致させるというベストプラクティスに従うためにも、名前空間の変更が必要になることがある。手動での変更は、すべてのusing文と参照の更新が必要で、エラーが発生しやすい。

**機能の利用シーン**：
1. フォルダ構造と名前空間を同期させる
2. 型を別の名前空間に移動する
3. プロジェクト構造のリファクタリング
4. ソリューション全体の名前空間戦略の見直し

**主要な処理内容**：
1. 型/名前空間宣言の分析
2. ターゲット名前空間の指定(UI経由)
3. IChangeNamespaceServiceによる名前空間変更
4. using文の追加・削除
5. 参照の更新

**関連システム・外部連携**：
- CodeRefactoringProvider経由でエディタに統合
- IMoveToNamespaceOptionsServiceでUI連携
- IChangeNamespaceServiceとの連携
- IMoveTypeServiceとの連携(型移動時)

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | 名前空間の移動ダイアログ | 主画面 | ターゲット名前空間の指定 |
| 20 | プレビューペイン | 補助画面 | 変更箇所のプレビュー |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象のドキュメント | 有効なドキュメントであること |
| position | int | Yes | カーソル位置 | 名前空間宣言または型宣言内 |
| targetNamespace | string | Yes | 移動先の名前空間 | 有効な名前空間であること |

### 入力データソース

- ドキュメントの構文ツリー(SyntaxTree)
- セマンティックモデル(SemanticModel)
- IMoveToNamespaceOptionsServiceからのユーザー入力
- プロジェクト内の既存名前空間一覧

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| MoveToNamespaceResult | MoveToNamespaceResult | 移動結果 |
| originalSolution | Solution | 元のソリューション |
| changedSolution | Solution | 更新後のソリューション |
| originalDocumentId | DocumentId | 変更されたドキュメントID |
| newNameOriginalSymbolMapping | ImmutableDictionary | 新しい名前と元のシンボルのマッピング |

### 出力先

- 更新されたソリューションとして返却

## 処理フロー

### 処理シーケンス

```
1. 型分析(AnalyzeTypeAtPositionAsync)
   └─ カーソル位置の名前空間または型宣言を取得
2. 移動可能性判定
   └─ IChangeNamespaceService.CanChangeNamespaceAsyncで判定
3. オプション取得
   └─ IMoveToNamespaceOptionsServiceからターゲット名前空間を取得
4. コンテナ種別判定
   └─ Namespace(名前空間)またはNamedType(型)
5. 移動実行
   └─ MoveItemsInNamespaceAsync または MoveTypeToNamespaceAsync
6. 名前空間変更
   └─ IChangeNamespaceService.ChangeNamespaceAsync
7. 整形
   └─ Formatterで整形、リンクドキュメントへの伝播
```

### フローチャート

```mermaid
flowchart TD
    A[開始: MoveToNamespaceAsync] --> B[AnalyzeTypeAtPositionAsync]
    B --> C{CanPerform?}
    C -->|No| D[Failed結果返却]
    C -->|Yes| E{Container種別?}
    E -->|Namespace| F[MoveItemsInNamespaceAsync]
    E -->|NamedType| G[MoveTypeToNamespaceAsync]
    F --> H[IChangeNamespaceService.ChangeNamespaceAsync]
    G --> I[IMoveTypeService.GetModifiedSolutionAsync]
    I --> J[PropagateChangeToLinkedDocumentsAsync]
    J --> K[MoveItemsInNamespaceAsync]
    H --> L[MoveToNamespaceResult返却]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ネストされた名前空間 | ネストされた名前空間宣言はサポート外 | GetNamespaceInSpineCount > 1 |
| BR-02 | グローバル名前空間の型 | グローバル名前空間内の単一型のみ移動可能 | namespaceInSpineCount == 0 |
| BR-03 | ネストされた型 | 複数の型がネストされている場合はサポート外 | ContainsMultipleTypesInSpine |
| BR-04 | OptionsService必須 | IMoveToNamespaceOptionsServiceがない場合は機能不可 | 常時 |
| BR-05 | 名前空間位置制限 | 名前空間キーワード上にカーソルがある場合のみ | IsContainedInNamespaceDeclaration |

### 計算ロジック

新しいシンボル名の計算:
```
offset = symbol.ContainingNamespace.IsGlobalNamespace ? 0
       : symbol.ContainingNamespace.ToDisplayString().Length + 1;
newName = $"{targetNamespace}.{symbol.ToDisplayString()[offset..]}";
```

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

該当なし（インメモリ操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | CanPerform=false | ネストされた名前空間、複数型など | リファクタリング不可として表示しない |
| - | MoveToNamespaceResult.Failed | 移動処理の失敗 | エラーメッセージ表示 |

### リトライ仕様

なし

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

該当なし

## パフォーマンス要件

- 非同期処理でUIスレッドをブロックしない
- PropagateChangeToLinkedDocumentsAsyncでリンクドキュメントを一括更新

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

- 特になし

## 備考

- IMoveTypeServiceを使用して型のスコープ移動を実現
- IChangeNamespaceServiceで実際の名前空間変更を実行
- GlobalNamespaceからの移動もサポート(単一型のみ)

---

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

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

### 推奨読解順序

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

まず、名前空間の移動で使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MoveToNamespaceResult.cs | `src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceResult.cs` | 結果構造 |
| 1-2 | MoveToNamespaceAnalysisResult.cs | `src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceAnalysisResult.cs` | 分析結果 |
| 1-3 | MoveToNamespaceOptionsResult.cs | `src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceOptionsResult.cs` | オプション |

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

処理の起点となるAbstractMoveToNamespaceService.csを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractMoveToNamespaceService.cs | `src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs` | メイン処理 |

**主要処理フロー**:
1. **45-61行目**: GetCodeActionsAsync - CodeAction取得
2. **63-86行目**: AnalyzeTypeAtPositionAsync - 型/名前空間分析
3. **87-110行目**: TryAnalyzeNamespaceAsync - 名前空間分析
4. **112-159行目**: TryAnalyzeNamedTypeAsync - 型分析
5. **170-184行目**: MoveToNamespaceAsync - 移動処理ディスパッチ

#### Step 3: 名前空間変更を理解する

IChangeNamespaceServiceを使用した名前空間変更を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractMoveToNamespaceService.cs | `src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs` | 214-235行目: MoveItemsInNamespaceAsync |

#### Step 4: 型移動を理解する

IMoveTypeServiceを使用した型移動を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AbstractMoveToNamespaceService.cs | `src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs` | 237-273行目: MoveTypeToNamespaceAsync |

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

```
AbstractMoveToNamespaceService.MoveToNamespaceAsync
    │
    ├─ AnalyzeTypeAtPositionAsync
    │      ├─ TryAnalyzeNamespaceAsync
    │      │      └─ IChangeNamespaceService.CanChangeNamespaceAsync
    │      │
    │      └─ TryAnalyzeNamedTypeAsync
    │             └─ IChangeNamespaceService.CanChangeNamespaceAsync
    │
    └─ (Container種別による分岐)
           │
           ├─ MoveItemsInNamespaceAsync (Namespace)
           │      ├─ GetMemberSymbolsAsync
           │      └─ IChangeNamespaceService.ChangeNamespaceAsync
           │
           └─ MoveTypeToNamespaceAsync (NamedType)
                  ├─ IMoveTypeService.GetModifiedSolutionAsync
                  ├─ PropagateChangeToLinkedDocumentsAsync
                  └─ MoveItemsInNamespaceAsync
```

### データフロー図

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

Position ───▶ AnalyzeTypeAtPositionAsync ───▶ MoveToNamespaceAnalysisResult
                      │
                      ▼
AnalysisResult ───▶ GetChangeNamespaceOptions ───▶ MoveToNamespaceOptionsResult
                      │
                      ▼
Container ───▶ MoveItemsInNamespaceAsync/MoveTypeToNamespaceAsync
                      │
                      ▼
Solution ───▶ IChangeNamespaceService.ChangeNamespaceAsync ───▶ Solution
                      │
                      ▼
Solution ───▶ PropagateChangeToLinkedDocumentsAsync ───▶ MoveToNamespaceResult
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractMoveToNamespaceService.cs | `src/Features/Core/Portable/MoveToNamespace/AbstractMoveToNamespaceService.cs` | ソース | メイン処理 |
| IMoveToNamespaceService.cs | `src/Features/Core/Portable/MoveToNamespace/IMoveToNamespaceService.cs` | ソース | サービスインターフェース |
| MoveToNamespaceResult.cs | `src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceResult.cs` | ソース | 結果構造 |
| MoveToNamespaceAnalysisResult.cs | `src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceAnalysisResult.cs` | ソース | 分析結果 |
| MoveToNamespaceOptionsResult.cs | `src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceOptionsResult.cs` | ソース | オプション |
| MoveToNamespaceCodeAction.cs | `src/Features/Core/Portable/MoveToNamespace/MoveToNamespaceCodeAction.cs` | ソース | CodeAction |
| IMoveToNamespaceOptionsService.cs | `src/Features/Core/Portable/MoveToNamespace/IMoveToNamespaceOptionsService.cs` | ソース | オプションサービス |
| IChangeNamespaceService.cs | `src/Features/Core/Portable/ChangeNamespace/IChangeNamespaceService.cs` | ソース | 名前空間変更サービス |
