# 機能設計書 45-匿名型を構造体に変換

## 概要

本ドキュメントは、Roslyn IDEの「匿名型を構造体に変換（Convert Anonymous Type）」機能の設計を記述したものである。この機能は、匿名型（anonymous type）をタプルまたは名前付き構造体/クラスに変換するコードリファクタリング機能である。

### 本機能の処理概要

**業務上の目的・背景**：匿名型はLINQクエリや一時的なデータ構造として便利だが、メソッドの戻り値として使用できない、再利用性が低いなどの制限がある。この機能は、匿名型を明示的な型（タプルまたはクラス/構造体）に変換することで、コードの再利用性と型安全性を向上させる。

**機能の利用シーン**：開発者がLINQクエリ内の匿名型や`new { ... }`形式の式にカーソルを置き、コードアクションメニューから変換オプションを選択する場面で利用される。

**主要な処理内容**：
1. カーソル位置の匿名型式を取得
2. セマンティックモデルから匿名型の型情報を取得
3. 変換先（タプルまたはクラス）を選択
4. 新しい型定義を生成
5. 匿名型の使用箇所を新しい型に置換

**関連システム・外部連携**：AbstractConvertAnonymousTypeToTupleCodeRefactoringProviderとAbstractConvertAnonymousTypeToClassCodeRefactoringProviderの2つの派生プロバイダーがそれぞれタプル変換とクラス変換を担当する。

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

## 関連画面

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

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象ドキュメント | null不可 |
| span | TextSpan | Yes | カーソル位置または選択範囲 | 有効な範囲内 |
| anonymousObject | TAnonymousObjectCreationExpressionSyntax | Yes | 匿名型式ノード | null不可 |
| anonymousType | INamedTypeSymbol | Yes | 匿名型のシンボル | 匿名型であること |

### 入力データソース

- ソースコードのカーソル位置から匿名型式を取得
- セマンティックモデルから型情報を取得

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 新しい型定義 | SyntaxNode | 生成されたタプル型またはクラス定義 |
| 更新された式 | SyntaxNode | 匿名型から新しい型への置換 |

### 出力先

ソースコード内の匿名型式を置換、必要に応じて型定義を追加

## 処理フロー

### 処理シーケンス

```
1. 匿名型式の取得
   └─ TryGetRelevantNodeAsyncで匿名型式を取得
2. 型情報の取得
   └─ SemanticModel.GetTypeInfoで型シンボルを取得
3. 変換先選択
   └─ タプルまたはクラス/構造体
4. 型生成（クラスの場合）
   └─ プロパティとコンストラクタを含む型を生成
5. 式の置換
   └─ 匿名型式を新しい型のインスタンス生成に置換
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{匿名型式あり?}
    B -->|No| C[終了:リファクタリング不可]
    B -->|Yes| D[型情報取得]
    D --> E{有効な匿名型?}
    E -->|No| C
    E -->|Yes| F[変換オプション登録]
    F --> G{タプル変換選択?}
    G -->|Yes| H[タプルに変換]
    G -->|No| I[クラス/構造体に変換]
    H --> J[終了]
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 匿名型判定 | INamedTypeSymbol.IsAnonymousTypeで判定 | 型検証時 |
| BR-02 | タプル変換 | プロパティをタプル要素に変換 | タプル選択時 |
| BR-03 | クラス変換 | プロパティとコンストラクタを持つクラスを生成 | クラス選択時 |

### 計算ロジック

該当なし

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-01 | 式不在 | 匿名型式が見つからない | リファクタリングを提供しない |
| E-02 | 型エラー | 匿名型でない | リファクタリングを提供しない |

### リトライ仕様

なし

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

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

## パフォーマンス要件

- 型情報取得は非同期で実行

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

特になし

## 備考

- 言語固有の実装は各言語のプロバイダーで行う

---

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

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

### 推奨読解順序

#### Step 1: 基底クラスを理解する

匿名型取得の共通ロジックを理解する。

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

**主要処理フロー**:
- **17-33行目**: TryGetAnonymousObjectAsyncで匿名型式と型情報を取得

#### Step 2: タプル変換を理解する

タプルへの変換ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractConvertAnonymousTypeToTupleCodeRefactoringProvider.cs | `src/Features/Core/Portable/ConvertAnonymousType/` | タプル変換の実装 |

#### Step 3: クラス変換を理解する

クラスへの変換ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs | `src/Features/Core/Portable/ConvertAnonymousType/` | クラス変換の実装 |

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

```
AbstractConvertAnonymousTypeCodeRefactoringProvider
    │
    ├─ TryGetAnonymousObjectAsync
    │      ├─ TryGetRelevantNodeAsync
    │      └─ SemanticModel.GetTypeInfo
    │
    ├─ AbstractConvertAnonymousTypeToTupleCodeRefactoringProvider
    │      └─ タプル変換処理
    │
    └─ AbstractConvertAnonymousTypeToClassCodeRefactoringProvider
           └─ クラス/構造体変換処理
```

### データフロー図

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

カーソル位置 ───▶ 匿名型式取得 ───▶ 匿名型ノード
      │
      ▼
匿名型ノード ───▶ 型情報取得 ───▶ 匿名型シンボル
      │
      ▼
匿名型シンボル ───▶ 変換処理 ───▶ タプル/クラス
      │
      ▼
新しい型 ───▶ 式置換 ───▶ 更新ドキュメント
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractConvertAnonymousTypeCodeRefactoringProvider.cs | `src/Features/Core/Portable/ConvertAnonymousType/` | ソース | 基底プロバイダー |
| AbstractConvertAnonymousTypeToTupleCodeRefactoringProvider.cs | `src/Features/Core/Portable/ConvertAnonymousType/` | ソース | タプル変換 |
| AbstractConvertAnonymousTypeToClassCodeRefactoringProvider.cs | `src/Features/Core/Portable/ConvertAnonymousType/` | ソース | クラス変換 |
