# 機能設計書 49-forをforeachに変換

## 概要

本ドキュメントは、Roslyn IDEの「forをforeachに変換（Convert For to ForEach）」機能の設計を記述したものである。この機能は、インデックスベースのfor文をforeach文に変換するコードリファクタリング機能である。

### 本機能の処理概要

**業務上の目的・背景**：for文は柔軟だが、単純なコレクション走査の場合はforeach文の方が読みやすく、意図が明確になる。この機能は、インデックス変数が単純な要素アクセスにのみ使用されている場合に、for文をforeach文に変換することで、コードの可読性を向上させる。

**機能の利用シーン**：開発者が`for (int i = 0; i < collection.Length; i++)`形式のfor文にカーソルを置き、コードアクションメニューから「Convert to foreach」を選択する場面で利用される。

**主要な処理内容**：
1. カーソル位置のfor文を取得
2. for文の構造を検証（0から開始、1ずつインクリメント、Length/Countとの比較）
3. インデックス変数の使用パターンを分析
4. foreach変数名を決定（既存の`var x = collection[i]`があれば再利用）
5. foreach文に変換
6. インデックス参照を変数名に置換

**関連システム・外部連携**：ISemanticFactsServiceを使用してユニークな変数名を生成する。ILoopOperationを使用してfor文の構造を解析する。

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象ドキュメント | null不可 |
| forStatement | TForStatementSyntax | Yes | for文ノード | 有効なfor文 |
| iterationVariable | SyntaxToken | Yes | イテレーション変数 | 有効な変数 |
| collectionExpression | TExpressionSyntax | Yes | コレクション式 | インデックス可能 |

### 入力データソース

- ソースコードのカーソル位置からfor文を取得
- セマンティックモデルとILoopOperationから詳細情報を取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| foreach文 | SyntaxNode | 変換されたforeach文 |

### 出力先

for文を置換

## 処理フロー

### 処理シーケンス

```
1. for文取得
   └─ TryGetRelevantNodeAsyncでfor文を取得
2. 構造検証
   └─ TryGetForStatementComponentsで初期化、条件、増分を取得
3. 条件検証
   └─ 0から開始、1ずつ増分、Length/Countとの比較
4. 使用パターン分析
   └─ インデックス変数が単純なアクセスのみに使用されているか
5. foreach変数決定
   └─ 既存宣言の再利用または新規生成
6. foreach文生成
   └─ ConvertForNodeでforeach文を構築
7. 参照置換
   └─ collection[i]をforeach変数に置換
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{for文あり?}
    B -->|No| C[終了:リファクタリング不可]
    B -->|Yes| D[構造解析]
    D --> E{0から開始?}
    E -->|No| C
    E -->|Yes| F{1ずつ増分?}
    F -->|No| C
    F -->|Yes| G{Length/Count比較?}
    G -->|No| C
    G -->|Yes| H[使用パターン分析]
    H --> I{単純アクセスのみ?}
    I -->|No| C
    I -->|Yes| J[foreach変数決定]
    J --> K[foreach文生成]
    K --> L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 初期値条件 | 初期値が0であること | 構造検証時 |
| BR-02 | 増分条件 | 増分が1であること（i++または i += 1） | 構造検証時 |
| BR-03 | 比較条件 | i < collection.Length または i < collection.Count | 構造検証時 |
| BR-04 | 単一変数条件 | ループ変数が1つであること | 構造検証時 |
| BR-05 | 使用制限 | インデックス変数はcollection[i]またはcollection.ElementAt(i)のみ | 使用分析時 |
| BR-06 | 既存宣言再利用 | `var x = collection[i]`が最初の文なら変数名を再利用 | 変数決定時 |
| BR-07 | 書き込み警告 | コレクションへの書き込みがある場合は警告 | 変換時 |
| BR-08 | 関数境界警告 | イテレーション変数が関数境界を越える場合は警告 | 変換時 |

### 計算ロジック

該当なし

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-01 | for文不在 | for文が見つからない | リファクタリングを提供しない |
| E-02 | 非対応パターン | 初期値が0でない、増分が1でない等 | リファクタリングを提供しない |
| E-03 | 複雑な使用 | インデックス変数が複雑に使用されている | リファクタリングを提供しない |

### リトライ仕様

なし

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

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

## パフォーマンス要件

- 使用パターン分析は構文木の走査で実行
- SemanticEquivalenceで式の等価性を判定

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

特になし

## 備考

- コレクションへの書き込みや関数境界越えがある場合は警告を付与
- 1次元配列のみ対応

---

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

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

### 推奨読解順序

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

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

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

**主要処理フロー**:
1. **53-58行目**: ComputeRefactoringsAsyncでfor文取得
2. **60-64行目**: TryGetForStatementComponentsで構造解析
3. **66-73行目**: メンバーアクセス式の検証（Length/Count）
4. **75-102行目**: 初期値0、増分1、イテレーション型の検証
5. **124-141行目**: 使用パターン分析

#### Step 2: 使用パターン分析を理解する

インデックス変数の使用パターン分析を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractConvertForToForEachCodeRefactoringProvider.cs | `src/Features/Core/Portable/ConvertForToForEach/` | IterationVariableIsUsedForMoreThanCollectionIndexメソッド |

**主要処理フロー**:
- **146-194行目**: IterationVariableIsUsedForMoreThanCollectionIndexでパターン分析
- **196-208行目**: IsGoodElementAccessExpressionで要素アクセス確認
- **210-230行目**: IsGoodInvocationExpressionでElementAt確認

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

for文からforeach文への変換ロジックを理解する。

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

**主要処理フロー**:
- **311-384行目**: ConvertForToForEachAsyncで変換処理
- **340行目**: TryDeconstructInitialDeclarationで既存宣言の検出
- **368-376行目**: RemoveNode/ReplaceNodeで変換適用

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

```
AbstractConvertForToForEachCodeRefactoringProvider.ComputeRefactoringsAsync
    │
    ├─ TryGetRelevantNodeAsync<TForStatementSyntax>
    │      └─ for文取得
    │
    ├─ TryGetForStatementComponents
    │      └─ iterationVariable, initializer, memberAccess, stepValue取得
    │
    ├─ 条件検証
    │      ├─ memberAccessName == "Length" or "Count"
    │      ├─ initializerValue == 0
    │      └─ stepValue == 1
    │
    ├─ TryGetIterationElementType
    │      └─ コレクション要素型の取得
    │
    ├─ IterationVariableIsUsedForMoreThanCollectionIndex
    │      ├─ IsGoodElementAccessExpression
    │      └─ IsGoodInvocationExpression
    │
    └─ CodeAction.Create
           │
           └─ ConvertForToForEachAsync
                  │
                  ├─ TryDeconstructInitialDeclaration
                  │      └─ 既存の var x = collection[i] を検出
                  │
                  ├─ GetIndexerType
                  │      └─ インデクサーの型を取得
                  │
                  ├─ FindAndReplaceMatches
                  │      └─ collection[i] を foreach変数に置換
                  │
                  └─ ConvertForNode
                         └─ foreach文を構築
```

### データフロー図

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

カーソル位置 ───▶ for文取得 ───▶ for文ノード
      │
      ▼
for文 ───▶ 構造解析 ───▶ 変数、初期化、条件、増分
      │
      ▼
コンポーネント ───▶ 条件検証 ───▶ 変換可否
      │
      ▼
for本体 ───▶ パターン分析 ───▶ 単純使用確認
      │
      ▼
変換可 ───▶ foreach生成 ───▶ foreach文ノード
      │
      ▼
foreach ───▶ ドキュメント更新 ───▶ 更新ドキュメント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractConvertForToForEachCodeRefactoringProvider.cs | `src/Features/Core/Portable/ConvertForToForEach/` | ソース | リファクタリングプロバイダー本体 |
| SemanticEquivalence.cs | `src/Workspaces/Core/Portable/Shared/Utilities/` | ソース | 式の意味等価性判定 |
| ISemanticFactsService.cs | `src/Workspaces/Core/Portable/LanguageService/` | ソース | ユニーク名生成サービス |
