# 機能設計書 134-宣言の移動

## 概要

本ドキュメントは、Roslynの「宣言の移動（MoveDeclarationNearReference）」機能の設計を記述する。この機能は、変数宣言を最初の使用箇所の近くに移動するリファクタリング機能である。

### 本機能の処理概要

この機能は、ローカル変数の宣言文を、その変数が最初に使用される箇所の直前に移動する。これにより、変数のスコープを最小化し、コードの可読性と保守性を向上させる。

**業務上の目的・背景**：
変数宣言がその使用箇所から離れた場所にあると、コードの理解が困難になる。特に長いメソッドでは、変数が宣言された場所と使用される場所の間に多くのコードが存在する場合がある。本機能により、変数のスコープを局所化し、コードの意図を明確にできる。

**機能の利用シーン**：
- メソッドのリファクタリング時
- コードレビューでの指摘対応時
- レガシーコードの改善時
- 変数の初期化を使用箇所近くで行いたい場合

**主要な処理内容**：
1. ローカル変数宣言文の検出
2. 変数の最初の使用箇所の特定
3. 移動可能性の判定（スコープ変更による意味変更のチェック）
4. 宣言文の移動（削除と挿入）
5. 必要に応じて宣言と代入のマージ

**関連システム・外部連携**：
- Simplifier API：移動後の宣言を明示的にする
- Formatter：移動後のコード整形

**権限による制御**：
特に権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エディタウィンドウ | 主画面 | Quick Actionsメニューからの実行 |

## 機能種別

コードリファクタリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象ドキュメント | null不可 |
| localDeclarationStatement | SyntaxNode | Yes | ローカル変数宣言文 | TLocalDeclarationStatementSyntax型 |

### 入力データソース

- ソースコードドキュメント
- セマンティックモデル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| canMove | bool | 移動可能かどうか |
| mayChangeSemantics | bool | 意味が変わる可能性があるか |
| updatedDocument | Document | 変更適用後のドキュメント |

### 出力先

- 編集後のドキュメント

## 処理フロー

### 処理シーケンス

```
1. ComputeRefactoringsAsync呼び出し
   └─ TryGetRelevantNodeでローカル宣言を取得
2. 変数数チェック
   └─ GetVariablesOfLocalDeclarationStatementで変数数確認（1つのみ許可）
3. CanMoveDeclarationNearReferenceAsync判定
   └─ State.GenerateAsyncで状態解析
4. CodeAction登録
   └─ 移動可能な場合はアクションを登録
5. MoveDeclarationNearReferenceAsync実行（ユーザー選択時）
   └─ SyntaxEditorで宣言を移動
```

### フローチャート

```mermaid
flowchart TD
    A[ローカル宣言取得] --> B{変数は1つ?}
    B -->|No| Z[リファクタリング不可]
    B -->|Yes| C[State.GenerateAsync]
    C --> D{移動可能?}
    D -->|No| Z
    D -->|Yes| E{意味が変わる?}
    E -->|No| F[Move declaration near reference]
    E -->|Yes| G[Move declaration near reference - may change semantics]
    F --> H[CodeAction登録]
    G --> H
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-134-01 | 単一変数制限 | 複数変数の宣言は対象外 | 宣言文の変数数が1より大きい場合 |
| BR-134-02 | スコープ変更警告 | 意味が変わる可能性がある場合は警告 | CrossesMeaningfulBlock == true |
| BR-134-03 | 宣言と代入のマージ | 初期値なし宣言は最初の代入とマージ可能 | CanMergeDeclarationAndAssignment判定 |
| BR-134-04 | 既に最適位置 | 宣言が最初の使用箇所の直前にある場合はスキップ | IndexOfDeclarationStatement == IndexOfFirstStatement - 1 |

### 計算ロジック

移動可能性判定:
- State.GenerateAsyncで内部状態を構築
- InnermostBlockとOutermostBlockを特定
- CanMoveToBlockで移動先ブロックへの移動可否を判定

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

### 操作別データベース影響一覧

データベース操作なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 状態生成失敗 | State.GenerateAsyncがnull | リファクタリング不可として処理 |
| - | シンボル解決失敗 | ローカル変数のシンボルが取得できない | 処理をスキップ |

### リトライ仕様

リトライは行わない。

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

SyntaxEditorによる原子的な変更適用。Undoで元に戻せる。

## パフォーマンス要件

- CodeRefactoringProviderとして実装
- 低優先度（CodeActionPriority.Low）で登録

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

特になし。

## 備考

- 意味が変わる可能性がある場合は異なるタイトルで表示
- WarningAnnotationによる視覚的警告対応

---

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

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

### 推奨読解順序

#### Step 1: サービスインターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IMoveDeclarationNearReferenceService.cs | `src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/MoveDeclarationNearReference/` | サービスインターフェース定義 |

**読解のコツ**: `CanMoveDeclarationNearReferenceAsync`と`MoveDeclarationNearReferenceAsync`の2つのメソッドが主要API。

#### Step 2: リファクタリングプロバイダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractMoveDeclarationNearReferenceCodeRefactoringProvider.cs | `src/Features/Core/Portable/MoveDeclarationNearReference/` | リファクタリングプロバイダー基底クラス |

**主要処理フロー**:
1. **16-44行目**: ComputeRefactoringsAsyncでリファクタリング可否判定
2. **24-26行目**: 変数数チェック（1つのみ許可）
3. **29行目**: CanMoveDeclarationNearReferenceAsyncで移動可否判定
4. **33-35行目**: 意味変更の可能性に応じたタイトル設定
5. **46-51行目**: 実際の移動処理

#### Step 3: サービス実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractMoveDeclarationNearReferenceService.cs | `src/Workspaces/SharedUtilitiesAndExtensions/Workspace/Core/LanguageServices/MoveDeclarationNearReference/` | サービス実装 |

**主要処理フロー**:
- **38-45行目**: CanMoveDeclarationNearReferenceAsync - 移動可否と意味変更の判定
- **77-116行目**: MoveDeclarationNearReferenceAsync - 実際の移動処理
- **118-157行目**: MoveDeclarationToFirstReferenceAsync - 宣言の移動
- **159-175行目**: MergeDeclarationAndAssignment - 宣言と代入のマージ

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

```
AbstractMoveDeclarationNearReferenceCodeRefactoringProvider
    │
    ├─ ComputeRefactoringsAsync
    │      ├─ TryGetRelevantNodeAsync
    │      ├─ GetVariablesOfLocalDeclarationStatement
    │      └─ IMoveDeclarationNearReferenceService.CanMoveDeclarationNearReferenceAsync
    │
    └─ MoveDeclarationNearReferenceAsync
           └─ IMoveDeclarationNearReferenceService.MoveDeclarationNearReferenceAsync

AbstractMoveDeclarationNearReferenceService
    │
    ├─ CanMoveDeclarationNearReferenceAsync
    │      └─ ComputeStateAsync
    │             └─ State.GenerateAsync
    │
    └─ MoveDeclarationNearReferenceAsync
           ├─ CanMergeDeclarationAndAssignmentAsync
           ├─ MergeDeclarationAndAssignment
           └─ MoveDeclarationToFirstReferenceAsync
```

### データフロー図

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

LocalDeclaration ───▶ State.GenerateAsync ───▶ canMove, mayChangeSemantics
        │                    │
        │                    ├─ IndexOfDeclaration計算
SemanticModel              ├─ IndexOfFirstStatement計算
        │                    └─ CrossesMeaningfulBlock判定
        │
        ▼
SyntaxEditor ───▶ RemoveNode + InsertBefore ───▶ 更新済みDocument
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IMoveDeclarationNearReferenceService.cs | `src/Workspaces/.../MoveDeclarationNearReference/` | ソース | サービスインターフェース |
| AbstractMoveDeclarationNearReferenceService.cs | `src/Workspaces/.../MoveDeclarationNearReference/` | ソース | サービス実装基底クラス |
| AbstractMoveDeclarationNearReferenceService.State.cs | `src/Workspaces/.../MoveDeclarationNearReference/` | ソース | 状態管理クラス |
| AbstractMoveDeclarationNearReferenceCodeRefactoringProvider.cs | `src/Features/Core/Portable/MoveDeclarationNearReference/` | ソース | リファクタリングプロバイダー基底クラス |
| CSharpMoveDeclarationNearReferenceCodeRefactoringProvider.cs | `src/Features/CSharp/Portable/MoveDeclarationNearReference/` | ソース | C#用プロバイダー |
