# 機能設計書 51-LINQクエリ変換

## 概要

本ドキュメントは、Roslyn機能「LINQクエリ変換」の機能設計書である。LINQメソッド構文とクエリ構文の相互変換、およびforeachループとLINQの相互変換を提供するコードリファクタリング機能について記述する。

### 本機能の処理概要

**業務上の目的・背景**：LINQ（Language Integrated Query）は、C#およびVisual Basicにおいてデータのクエリを宣言的に記述できる強力な機能である。LINQにはクエリ構文（from ... select形式）とメソッド構文（.Where().Select()形式）の2種類があり、開発者の好みやコードの可読性によって使い分けられる。本機能は、これらの構文を相互変換することで、チームのコーディング規約への準拠や可読性の向上を支援する。

**機能の利用シーン**：
- コードレビュー時にチームのコーディング規約に合わせて構文を統一したい場合
- 複雑なクエリ構文をメソッドチェーンに変換してステップバイステップでデバッグしたい場合
- foreachループをLINQに変換してコードを簡潔化したい場合
- LINQクエリをforeachに変換してパフォーマンスを向上させたい場合

**主要な処理内容**：
1. LINQクエリ構文（from...select）をforeachループに変換
2. foreachループをLINQクエリ構文に変換
3. foreachループをLINQメソッド構文に変換
4. 変換時のローカル変数宣言の適切な処理
5. yield returnを使用したイテレータメソッドへの変換

**関連システム・外部連携**：該当なし（IDE内機能）

**権限による制御**：該当なし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エディタ | 主画面 | リファクタリング候補の表示とクイックアクション実行 |

## 機能種別

コードリファクタリング

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| QueryExpression | SyntaxNode | Yes | LINQクエリ式のAST | 有効なクエリ構文であること |
| ForEachStatement | SyntaxNode | Yes | foreachステートメントのAST | 有効なforeachであること |
| Document | Document | Yes | 対象ドキュメント | null不可 |
| SemanticModel | SemanticModel | Yes | セマンティック情報 | null不可 |

### 入力データソース

エディタ内の選択位置またはカーソル位置にあるLINQクエリ式またはforeachステートメント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ConvertedCode | SyntaxNode | 変換後のコード（foreachまたはLINQ式） |
| DocumentUpdateInfo | DocumentUpdateInfo | ドキュメント更新情報 |

### 出力先

エディタ（ソースコードの置換）

## 処理フロー

### 処理シーケンス

```
1. リファクタリングコンテキストの取得
   └─ カーソル位置のノードを特定

2. 変換対象の検証
   └─ クエリ構文またはforeachであるかを判定
   └─ 診断エラーがないことを確認
   └─ ディレクティブが含まれていないことを確認

3. 変換の実行
   └─ クエリ構文 → foreach: TryConvertメソッドで変換
   └─ foreach → LINQ: CreateForEachInfoでforeachを解析

4. 結果のドキュメントへの適用
   └─ SyntaxEditorでノードを置換
   └─ System.Linqのusingを追加（必要な場合）
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{対象ノードの種類}
    B -->|QueryExpression| C[クエリ構文を解析]
    B -->|ForEachStatement| D[foreach構文を解析]
    C --> E{変換可能?}
    D --> E
    E -->|Yes| F[コード変換を実行]
    E -->|No| G[リファクタリング提示なし]
    F --> H[ドキュメント更新]
    H --> I[終了]
    G --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-51-01 | コメント除外 | コメントを含むクエリは変換対象外 | クエリ内にコメントが存在する場合 |
| BR-51-02 | ディレクティブ除外 | プリプロセッサディレクティブを含むクエリは変換対象外 | 条件付きコンパイルが存在する場合 |
| BR-51-03 | GroupBy未対応 | GroupByを含むクエリはforeachへの変換対象外 | GroupByクエリの場合 |
| BR-51-04 | OrderBy未対応 | OrderByを含むクエリはforeachへの変換対象外 | OrderByクエリの場合 |

### 計算ロジック

特になし

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 変換不可 | サポート外の構文 | リファクタリングを提示しない |
| - | 診断エラー | 構文エラーがある場合 | リファクタリングを提示しない |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- リファクタリング候補の計算は非同期で実行
- 大規模なクエリでも数百ミリ秒以内に応答

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

該当なし（コード変換のみでセキュリティ上のリスクなし）

## 備考

本機能はC#およびVisual Basicの両方で利用可能。ただし、言語固有の実装は別クラスで提供される。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ForEachInfo.cs | `src/Features/Core/Portable/ConvertLinq/ConvertForEachToLinqQuery/ForEachInfo.cs` | foreachループの解析情報を保持する構造体 |
| 1-2 | ExtendedSyntaxNode.cs | `src/Features/Core/Portable/ConvertLinq/ConvertForEachToLinqQuery/ExtendedSyntaxNode.cs` | 拡張構文ノード（追加トリビア付き） |
| 1-3 | IConverter.cs | `src/Features/Core/Portable/ConvertLinq/ConvertForEachToLinqQuery/IConverter.cs` | 変換インターフェースの定義 |

**読解のコツ**: ForEachInfo構造体のプロパティを確認し、foreachループから抽出される情報を把握する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractConvertLinqQueryToForEachProvider.cs | `src/Features/Core/Portable/ConvertLinq/AbstractConvertLinqQueryToForEachProvider.cs` | LINQクエリ→foreach変換の抽象クラス |
| 2-2 | AbstractConvertForEachToLinqQueryProvider.cs | `src/Features/Core/Portable/ConvertLinq/ConvertForEachToLinqQuery/AbstractConvertForEachToLinqQueryProvider.cs` | foreach→LINQ変換の抽象クラス |

**主要処理フロー**:
1. **31-53行目**: ComputeRefactoringsAsyncでリファクタリング候補を計算
2. **44-52行目**: TryConvertで変換可能性を検証しCodeActionを登録
3. **65-143行目**: foreach→LINQ変換のComputeRefactoringsAsync

#### Step 3: C#言語固有実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CSharpConvertLinqQueryToForEachProvider.cs | `src/Features/CSharp/Portable/ConvertLinq/CSharpConvertLinqQueryToForEachProvider.cs` | C#固有のLINQ→foreach変換実装 |
| 3-2 | CSharpConvertForEachToLinqQueryProvider.cs | `src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/CSharpConvertForEachToLinqQueryProvider.cs` | C#固有のforeach→LINQ変換実装 |

**主要処理フロー**:
- **65-106行目**: TryConvertメソッドで変換ロジックを実行
- **108-218行目**: ProcessClauseで各クエリ句をforeachのネスト構造に変換

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

```
ComputeRefactoringsAsync
    │
    ├─ TryGetRelevantNodeAsync<QueryExpression/ForEachStatement>
    │      └─ 対象ノードの取得
    │
    ├─ TryConvert / TryBuildConverter
    │      ├─ CreateForEachInfo
    │      │      └─ foreachの解析情報を構築
    │      ├─ TryBuildSpecificConverter
    │      │      └─ Count/ToList等の特殊ケース処理
    │      └─ CreateDefaultConverter
    │             └─ 汎用変換処理
    │
    └─ ApplyConversionAsync
           ├─ SyntaxEditor.Convert
           └─ AddLinqUsing
```

### データフロー図

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

QueryExpression ───▶ TryConvert ───▶ ForEachStatements
                     Converter.Convert
ForEachStatement ───▶ CreateForEachInfo ───▶ LinqExpression
                     BuildConverter
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractConvertLinqQueryToForEachProvider.cs | `src/Features/Core/Portable/ConvertLinq/` | ソース | クエリ→foreach抽象プロバイダ |
| AbstractConvertForEachToLinqQueryProvider.cs | `src/Features/Core/Portable/ConvertLinq/ConvertForEachToLinqQuery/` | ソース | foreach→クエリ抽象プロバイダ |
| ForEachInfo.cs | `src/Features/Core/Portable/ConvertLinq/ConvertForEachToLinqQuery/` | ソース | foreach情報構造体 |
| IConverter.cs | `src/Features/Core/Portable/ConvertLinq/ConvertForEachToLinqQuery/` | ソース | 変換インターフェース |
| ExtendedSyntaxNode.cs | `src/Features/Core/Portable/ConvertLinq/ConvertForEachToLinqQuery/` | ソース | 拡張構文ノード |
| CSharpConvertLinqQueryToForEachProvider.cs | `src/Features/CSharp/Portable/ConvertLinq/` | ソース | C#固有のLINQ→foreach変換 |
| CSharpConvertForEachToLinqQueryProvider.cs | `src/Features/CSharp/Portable/ConvertLinq/ConvertForEachToLinqQuery/` | ソース | C#固有のforeach→LINQ変換 |
