# 機能設計書 50-ifをswitchに変換

## 概要

本ドキュメントは、Roslyn IDEの「ifをswitchに変換（Convert If to Switch）」機能の設計を記述したものである。この機能は、if-else連鎖をswitch文またはswitch式に変換するコードリファクタリング機能である。

### 本機能の処理概要

**業務上の目的・背景**：複数の条件分岐を持つif-else連鎖は、条件が増えると可読性が低下する。switch文やswitch式に変換することで、分岐条件が一目で分かりやすくなり、コードの保守性が向上する。また、C# 8.0以降のパターンマッチング機能を活用した簡潔なswitch式への変換もサポートする。

**機能の利用シーン**：開発者が複数の条件分岐を持つif文にカーソルを置き、コードアクションメニューから「Convert to switch statement」または「Convert to switch expression」を選択する場面で利用される。

**主要な処理内容**：
1. カーソル位置のif文を取得
2. if-else連鎖を解析し、switchセクションを抽出
3. 変換可能性を検証（共通のターゲット式、2つ以上のラベル）
4. switch文またはswitch式への変換
5. パターンマッチングの活用（orパターン等）

**関連システム・外部連携**：SyntaxEditorBasedCodeRefactoringProviderを継承し、一括修正（Fix All）もサポートする。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能には専用の関連画面はない |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象ドキュメント | null不可 |
| ifStatement | TIfStatementSyntax | Yes | if文ノード | 有効なif文 |
| sections | ImmutableArray<AnalyzedSwitchSection> | Yes | 解析されたswitchセクション | 2つ以上のラベル |
| target | TExpressionSyntax | Yes | switchのターゲット式 | 共通の式 |

### 入力データソース

- ソースコードのカーソル位置からif文を取得
- IConditionalOperationを使用してif文の構造を解析

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| switch文 | SyntaxNode | 変換されたswitch文 |
| switch式 | SyntaxNode | 変換されたswitch式（選択時） |

### 出力先

if文を置換

## 処理フロー

### 処理シーケンス

```
1. if文取得
   └─ TryGetRelevantNodeAsyncでif文を取得
2. 構造解析
   └─ AnalyzeIfStatementSequenceでセクションとターゲットを抽出
3. 変換可否検証
   └─ ラベル数が2以上であることを確認
4. switch式変換可否判定
   └─ 全セクションがreturn/throwで、default存在
5. アクション登録
   └─ switch文とswitch式（可能な場合）のアクションを登録
6. 変換実行
   └─ UpdateDocumentAsyncでドキュメントを更新
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{if文あり?}
    B -->|No| C[終了:リファクタリング不可]
    B -->|Yes| D[構造解析]
    D --> E{IBlockOperation内?}
    E -->|No| C
    E -->|Yes| F[セクション抽出]
    F --> G{ラベル2つ以上?}
    G -->|No| C
    G -->|Yes| H[switch文アクション登録]
    H --> I{switch式可能?}
    I -->|Yes| J[switch式アクション登録]
    I -->|No| K[終了]
    J --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | ラベル数条件 | switchラベルが2つ以上必要 | 変換可否判定時 |
| BR-02 | ブロック内条件 | if文がIBlockOperation内にあること | 構造検証時 |
| BR-03 | エラーなし条件 | if文に構文エラーがないこと | 構造検証時 |
| BR-04 | switch式条件 | 全セクションがreturn/throw、default存在 | switch式判定時 |
| BR-05 | orパターン条件 | orパターン使用時はガードなし | switch式判定時 |

### 計算ロジック

該当なし

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

該当なし（ソースコード操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-01 | if文不在 | if文が見つからない | リファクタリングを提供しない |
| E-02 | 構文エラー | if文にエラーがある | リファクタリングを提供しない |
| E-03 | ラベル不足 | ラベルが2つ未満 | リファクタリングを提供しない |
| E-04 | MiscellaneousFiles | 臨時ファイル | リファクタリングを提供しない |

### リトライ仕様

なし

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

ドキュメント変更は単一のCodeActionでアトミックに適用される

## パフォーマンス要件

- 一括修正（Fix All）は外側のifから処理
- TrackNodesで変更追跡を最適化

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

特になし

## 備考

- SyntaxEditorBasedCodeRefactoringProviderを継承
- C# 8.0以降のswitch式とorパターンをサポート
- 一括修正でネストしたif文も正しく処理

---

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

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

### 推奨読解順序

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

AnalyzedSwitchSectionとFeature列挙型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AnalyzedNodes.cs | `src/Features/Core/Portable/ConvertIfToSwitch/` | AnalyzedSwitchSection構造 |

**読解のコツ**: AnalyzedSwitchSectionはLabels（パターン一覧）とBody（処理）を持つ。

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

リファクタリングプロバイダーが処理の起点となる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractConvertIfToSwitchCodeRefactoringProvider.cs | `src/Features/Core/Portable/ConvertIfToSwitch/` | ComputeRefactoringsAsyncが開始点 |

**主要処理フロー**:
1. **34-69行目**: ComputeRefactoringsAsyncでif文取得とアクション登録
2. **37-39行目**: MiscellaneousFilesワークスペースでは無効
3. **45-48行目**: ShouldOfferRefactoringで変換可否判定
4. **52-57行目**: switch文アクション登録
5. **59-68行目**: switch式アクション登録（条件付き）

#### Step 3: 解析ロジックを理解する

if-else連鎖の解析ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Analyzer.cs | `src/Features/Core/Portable/ConvertIfToSwitch/` | AnalyzeIfStatementSequenceメソッド |

**主要処理フロー**:
- if-else連鎖を解析してセクションとターゲット式を抽出
- パターンマッチングの解析

#### Step 4: 変換ロジックを理解する

switch文/式への変換ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Rewriting.cs | `src/Features/Core/Portable/ConvertIfToSwitch/` | UpdateDocumentAsyncメソッド |

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

```
AbstractConvertIfToSwitchCodeRefactoringProvider.ComputeRefactoringsAsync
    │
    ├─ TryGetRelevantNodeAsync<TIfStatementSyntax>
    │      └─ if文取得
    │
    ├─ ShouldOfferRefactoring
    │      │
    │      ├─ GetDiagnostics().Any(Error)
    │      │      └─ 構文エラーチェック
    │      │
    │      ├─ SemanticModel.GetOperation
    │      │      └─ IConditionalOperation取得
    │      │
    │      ├─ CreateAnalyzer
    │      │      └─ 言語固有Analyzerを作成
    │      │
    │      └─ AnalyzeIfStatementSequence
    │             └─ セクションとターゲットを抽出
    │
    ├─ CanConvertToSwitchExpression
    │      └─ switch式変換可否判定
    │
    └─ CodeAction.Create
           │
           └─ UpdateDocumentAsync
                  │
                  ├─ switch文への変換
                  │
                  └─ switch式への変換
```

### データフロー図

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

カーソル位置 ───▶ if文取得 ───▶ if文ノード
      │
      ▼
if文 ───▶ Operation取得 ───▶ IConditionalOperation
      │
      ▼
Operation ───▶ 解析 ───▶ セクション一覧、ターゲット式
      │
      ▼
セクション ───▶ 変換可否判定 ───▶ switch文/式可否
      │
      ▼
変換結果 ───▶ ドキュメント更新 ───▶ 更新ドキュメント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractConvertIfToSwitchCodeRefactoringProvider.cs | `src/Features/Core/Portable/ConvertIfToSwitch/` | ソース | リファクタリングプロバイダー本体 |
| AbstractConvertIfToSwitchCodeRefactoringProvider.Analyzer.cs | `src/Features/Core/Portable/ConvertIfToSwitch/` | ソース | if文解析ロジック |
| AbstractConvertIfToSwitchCodeRefactoringProvider.AnalyzedNodes.cs | `src/Features/Core/Portable/ConvertIfToSwitch/` | ソース | 解析結果のデータ構造 |
| AbstractConvertIfToSwitchCodeRefactoringProvider.Rewriting.cs | `src/Features/Core/Portable/ConvertIfToSwitch/` | ソース | switch文/式への変換ロジック |
| SyntaxEditorBasedCodeRefactoringProvider.cs | `src/Features/Core/Portable/CodeRefactorings/` | ソース | 基底クラス（Fix Allサポート） |
