# 機能設計書 22-コードリファクタリング

## 概要

本ドキュメントは、Roslynにおける「コードリファクタリング」機能の設計を記述するものである。CodeRefactoring機能は、コード品質向上のための変換操作を提供し、開発者がより良いコードを書くことを支援する。

### 本機能の処理概要

コードリファクタリング機能は、コードの動作を変えずに構造や可読性を改善するための変換操作を提供する機能である。エラーや警告がなくても、コードを改善するためのアクションを提案する。ライトバルブメニューに表示され、開発者は必要に応じてリファクタリングを適用できる。

**業務上の目的・背景**：ソフトウェア開発において、機能を追加するだけでなく、既存コードの品質を継続的に改善することが重要である。リファクタリングは、技術的負債を減らし、コードの保守性・可読性を向上させるための重要な実践である。手動でのリファクタリングは時間がかかり、ミスも発生しやすいため、自動化されたリファクタリング機能が必要とされる。

**機能の利用シーン**：
1. メソッドの抽出や名前の変更など、一般的なリファクタリング操作
2. 変数のインライン化やメソッドのインライン化
3. パラメータの追加・削除・並び替え
4. 型の移動や名前空間の変更
5. コードのモダン化（新しい言語機能の活用）

**主要な処理内容**：
1. カーソル位置・選択範囲に応じたリファクタリング候補の検出
2. 複数のCodeRefactoringProviderからの候補収集
3. 並列実行による効率的な候補取得
4. リファクタリング適用とコードの整形

**関連システム・外部連携**：
- エディタ(Visual Studio, VS Code)のLightBulb機能との統合
- FixAllProvider連携による一括適用
- Workspace変更の通知機能

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | ライトバルブメニュー | 主画面 | リファクタリング候補の一覧表示と選択 |
| 20 | プレビューペイン | 補助画面 | コード変更のプレビュー表示 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | TextDocument | Yes | 対象のドキュメント | 有効なドキュメントであること |
| state | TextSpan | Yes | カーソル位置または選択範囲 | 有効なテキスト範囲であること |
| priority | CodeActionRequestPriority | No | 優先度 | 列挙値であること |
| cancellationToken | CancellationToken | Yes | キャンセルトークン | - |

### 入力データソース

- ドキュメントの構文ツリー(SyntaxTree)
- セマンティックモデル(SemanticModel)
- MEFで登録されたCodeRefactoringProvider

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| CodeRefactoring | CodeRefactoring | リファクタリング候補 |
| actions | ImmutableArray<(CodeAction, TextSpan?)> | アクションとその適用範囲 |
| fixAllProviderInfo | FixAllProviderInfo | 一括適用情報 |

### 出力先

- エディタのライトバルブメニューに表示
- 適用された変更はドキュメントに反映

## 処理フロー

### 処理シーケンス

```
1. Providerの取得
   └─ 言語・ドキュメント種別・拡張子に対応するProviderを取得
2. 優先度フィルタリング
   └─ 指定された優先度に一致するProviderをフィルタリング
3. 並列実行
   └─ ProducerConsumer.RunParallelAsyncで並列にProvider実行
4. 候補収集
   └─ 各ProviderのComputeRefactoringsAsyncを呼び出し
5. ソート
   └─ Providerの順序に従ってソート
6. 結果返却
   └─ CodeRefactoring配列として返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: GetRefactoringsAsync] --> B[GetProviders呼び出し]
    B --> C[優先度でフィルタリング]
    C --> D[ProducerConsumer.RunParallelAsync]
    D --> E[各ProviderでComputeRefactoringsAsync]
    E --> F{アクションあり?}
    F -->|No| G[次のProviderへ]
    F -->|Yes| H[FixAllProviderInfo取得]
    H --> I[CodeRefactoring生成]
    I --> J[コールバックで結果通知]
    J --> G
    G --> K{全Provider完了?}
    K -->|No| E
    K -->|Yes| L[結果をソート]
    L --> M[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Interactive制限 | Interactive Workspaceではプロジェクトレベルのリファクタリング不可 | WorkspaceKind.Interactive時 |
| BR-02 | 優先度マッチング | Providerの優先度と要求優先度が一致する必要あり | priorityが指定された場合 |
| BR-03 | ドキュメント種別対応 | ProviderはTextDocumentKindを指定可能 | 常時 |
| BR-04 | ファイル拡張子対応 | Providerは対象ファイル拡張子を指定可能 | 常時 |

### 計算ロジック

Provider選択ロジック:
1. 言語でフィルタリング
2. ドキュメント種別(SourceDocument/AdditionalDocument等)でフィルタリング
3. ファイル拡張子でフィルタリング(空の場合は全拡張子対応)

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Provider例外 | Providerの実行時に例外発生 | ExtensionManagerでキャッチ、nullを返却 |
| - | キャンセル | OperationCancelledException | 処理を中断 |

### リトライ仕様

なし（ユーザーが再度操作することで再実行）

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

該当なし（ドキュメント変更はCodeActionの適用時に行われる）

## パフォーマンス要件

- テレメトリ: 500ms以上かかる処理は個別にログ記録
- 並列実行によるレスポンス時間の最適化
- HasRefactoringsAsyncでは最初の候補発見時に早期終了

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

- 信頼できないCodeRefactoringProviderからの例外は適切にキャッチ

## 備考

- CodeRefactoringServiceはMEFでエクスポートされ、シングルトンとして動作
- ワークスペースレベルとプロジェクトレベル(NuGet)のProviderをサポート
- ProviderはLanguage、DocumentKind、DocumentExtensionで登録可能

---

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

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

### 推奨読解順序

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

まず、リファクタリング機能で使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | CodeRefactoring.cs | `src/Features/Core/Portable/CodeRefactorings/CodeRefactoring.cs` | リファクタリング候補のデータ構造 |
| 1-2 | ICodeRefactoringService.cs | `src/Features/Core/Portable/CodeRefactorings/ICodeRefactoringService.cs` | サービスインターフェース |

**読解のコツ**: CodeRefactoringは、Provider、Actions(CodeActionとapplicableToSpan)、FixAllProviderInfoを保持する。

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

処理の起点となるCodeRefactoringServiceを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | CodeRefactoringService.cs | `src/Features/Core/Portable/CodeRefactorings/CodeRefactoringService.cs` | メインのサービス実装 |

**主要処理フロー**:
1. **33-39行目**: Lazy初期化でProviderマップを構築
2. **80-119行目**: GetProviders - 言語・ドキュメント種別・拡張子に応じたProvider取得
3. **121-178行目**: HasRefactoringsAsync - 高速な存在確認
4. **180-235行目**: GetRefactoringsAsync - 並列でProvider実行

#### Step 3: Provider管理を理解する

Providerの登録・取得ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CodeRefactoringService.cs | `src/Features/Core/Portable/CodeRefactorings/CodeRefactoringService.cs` | 45-72行目: DistributeLanguagesAndDocuments |

**主要処理フロー**:
- **45-72行目**: MEFからのProviderを言語・ドキュメント種別・拡張子で分類
- **285-303行目**: ProjectCodeRefactoringProvider - プロジェクトレベルのProvider管理

#### Step 4: 個別Provider実行を理解する

各Providerの呼び出しロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CodeRefactoringService.cs | `src/Features/Core/Portable/CodeRefactorings/CodeRefactoringService.cs` | 237-283行目: GetRefactoringFromProviderAsync |

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

```
CodeRefactoringService.GetRefactoringsAsync
    │
    ├─ GetProviders
    │      ├─ LanguageDocumentToProvidersMap検索
    │      └─ ProjectCodeRefactoringProvider.GetExtensions
    │
    └─ ProducerConsumer.RunParallelAsync
           │
           └─ GetRefactoringFromProviderAsync
                  │
                  ├─ ExtensionManager.PerformFunctionAsync
                  │      └─ CodeRefactoringProvider.ComputeRefactoringsAsync
                  │
                  └─ FixAllProviderInfo.Create
```

### データフロー図

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

Document + TextSpan ───▶ GetProviders ───▶ ConcatImmutableArray<CodeRefactoringProvider>
                              │
                              ▼
Providers ───▶ ProducerConsumer.RunParallelAsync ───▶ (provider, CodeRefactoring)[]
                              │
                              ▼
Results ───▶ OrderBy(providerToIndex) ───▶ ImmutableArray<CodeRefactoring>
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CodeRefactoringService.cs | `src/Features/Core/Portable/CodeRefactorings/CodeRefactoringService.cs` | ソース | メインサービス実装 |
| ICodeRefactoringService.cs | `src/Features/Core/Portable/CodeRefactorings/ICodeRefactoringService.cs` | ソース | サービスインターフェース |
| CodeRefactoring.cs | `src/Features/Core/Portable/CodeRefactorings/CodeRefactoring.cs` | ソース | データ構造 |
| PredefinedCodeRefactoringProviderNames.cs | `src/Features/Core/Portable/CodeRefactorings/PredefinedCodeRefactoringProviderNames.cs` | ソース | 組み込みProvider名定義 |
| AbstractExtractMethodCodeRefactoringProvider.cs | `src/Features/Core/Portable/CodeRefactorings/ExtractMethod/AbstractExtractMethodCodeRefactoringProvider.cs` | ソース | メソッド抽出リファクタリング |
| MoveTypeCodeRefactoringProvider.cs | `src/Features/Core/Portable/CodeRefactorings/MoveType/MoveTypeCodeRefactoringProvider.cs` | ソース | 型移動リファクタリング |
| AbstractSyncNamespaceCodeRefactoringProvider.cs | `src/Features/Core/Portable/CodeRefactorings/SyncNamespace/AbstractSyncNamespaceCodeRefactoringProvider.cs` | ソース | 名前空間同期リファクタリング |
