# 機能設計書 39-型生成

## 概要

本ドキュメントは、Roslynの「型生成（Generate Type）」機能の設計仕様を記述する。この機能は、存在しない型への参照に対して新しい型（クラス、構造体、インターフェース、列挙型、デリゲート）を自動生成するコード生成機能である。

### 本機能の処理概要

**業務上の目的・背景**：開発中にまだ定義されていない型を使用したい場合、その都度型定義を手動で作成する必要がある。この機能は、使用箇所から型の骨格を自動生成することで、テスト駆動開発（TDD）やトップダウン設計を支援する。

**機能の利用シーン**：
1. `new MyClass()`と書いたが`MyClass`がまだ定義されていない場合
2. `catch (MyException ex)`と書いたが`MyException`がまだ定義されていない場合
3. 変数宣言で未定義の型を使用した場合

**主要な処理内容**：
1. 存在しない型参照の検出と解析
2. 使用コンテキストに基づく型種別（class/struct/interface/enum/delegate）の推論
3. 新規ファイルまたは既存ファイル内への型生成
4. コンストラクタ引数からのフィールド/プロパティ生成

**関連システム・外部連携**：型生成オプションダイアログサービス（IGenerateTypeOptionsService）を使用してユーザー入力を取得する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | 型生成オプションダイアログ | 主機能 | 型種別、名前空間、ファイル設定 |

## 機能種別

コード生成 / クイック修正

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 操作対象のドキュメント | null不可 |
| node | SyntaxNode | Yes | 型参照ノード | 有効な型参照 |
| typeKind | TypeKind | No | 生成する型の種類 | Class/Struct/Interface/Enum/Delegate |
| accessibility | Accessibility | No | アクセス修飾子 | Public/Internal/Private |
| inNewFile | bool | No | 新規ファイルに生成するか | デフォルトfalse |

### 入力データソース

- エディタ上の存在しない型参照
- IGenerateTypeOptionsServiceによるダイアログ入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| modifiedSolution | Solution | 変更が適用されたソリューション |

### 出力先

- 新規ファイル（inNewFile=trueの場合）
- 既存ファイル（既存の名前空間または型の中）

## 処理フロー

### 処理シーケンス

```
1. 型参照の解析
   └─ TryInitializeState()でコンテキスト情報を収集
   └─ 型名、名前空間、コンストラクタ引数等を解析

2. 型種別の推論
   └─ 使用コンテキストに基づく推論
   └─ catch句内 → Exception派生クラス
   └─ インターフェースリスト → インターフェース
   └─ 配列要素型 → 値型の可能性
   └─ 型引数制約 → 制約に応じた型種別

3. アクセシビリティの決定
   └─ 使用箇所のアクセシビリティを考慮
   └─ IsPublicOnlyAccessibilityでpublic限定かチェック

4. 生成オプションの決定
   a. 既存名前空間への生成
   b. 既存型への入れ子型として生成
   c. 新規ファイルへの生成
   d. ダイアログによる詳細設定

5. 型の生成
   └─ TypeKindに応じた型宣言の生成
   └─ コンストラクタ引数からメンバー生成
   └─ 型パラメータの継承

6. ソリューションの更新
   └─ AddDocumentまたは既存ドキュメントの更新
   └─ using/importディレクティブの追加
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[型参照解析]
    B --> C{型名有効?}
    C -->|No| Z[終了]
    C -->|Yes| D[型種別推論]
    D --> E[アクセシビリティ決定]
    E --> F{生成先の選択}
    F -->|新規ファイル| G[新規ファイル生成]
    F -->|既存名前空間| H[既存ファイルに追加]
    F -->|既存型| I[入れ子型として追加]
    F -->|ダイアログ| J[オプションダイアログ]
    G --> K[型宣言生成]
    H --> K
    I --> K
    J --> K
    K --> L{コンストラクタ引数?}
    L -->|Yes| M[メンバー生成]
    L -->|No| N[型のみ生成]
    M --> O[ソリューション更新]
    N --> O
    O --> Z[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-39-01 | catch句推論 | catch句内の型はException派生クラスとして推論 | catch句コンテキスト |
| BR-39-02 | インターフェースリスト推論 | 型のインターフェースリスト内はインターフェースとして推論 | base listコンテキスト |
| BR-39-03 | 配列要素型推論 | 配列要素型は値型（struct）の可能性を考慮 | 配列コンテキスト |
| BR-39-04 | 型引数制約推論 | class/struct制約に応じた型種別を推論 | ジェネリック制約コンテキスト |
| BR-39-05 | Attribute接尾辞 | Attribute属性使用時は名前に"Attribute"接尾辞を追加 | 属性コンテキスト |
| BR-39-06 | 新規ファイル名 | 型名に対応したファイル名（TypeName.cs）を生成 | 新規ファイル生成時 |

### 計算ロジック

型種別決定ロジック：
```
if (InCatchDeclaration) {
    baseType = typeof(Exception)
    typeKind = TypeKindOptions.Class
} else if (InInterfaceList) {
    typeKind = TypeKindOptions.Interface
} else if (IsInValueTypeConstraintContext) {
    typeKind = TypeKindOptions.Struct
} else if (IsArrayElementType) {
    typeKind = TypeKindOptions.MustBeValueType
} else {
    typeKind = TypeKindOptions.AllOptions // ユーザー選択
}
```

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

該当なし（メモリ上のシンボルとソースコードの操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | 検証エラー | 無効な型名 | コード生成を提供しない |
| N/A | 検証エラー | 予約語を型名として使用 | コード生成を提供しない |
| N/A | 検証エラー | 既存の型と名前衝突 | コード生成を提供しない |

### リトライ仕様

該当なし（インタラクティブな操作のため）

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

ソリューション全体の変更を適用。すべての変更が成功するか、すべて適用されないかのいずれかとなる。

## パフォーマンス要件

- UIのレスポンシブ性を維持するため、キャンセル可能な操作として実装

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

- ソースコードへの書き込み権限が必要
- 新規ファイル作成にはプロジェクトへの書き込み権限が必要

## 備考

- ジェネリック型も生成可能（型パラメータを維持）
- 部分クラス（partial）の生成はサポートされる
- 名前空間がネストしている場合も適切に処理

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AbstractGenerateTypeService.cs | `src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs` | IGenerateTypeServiceの実装。GenerateTypeAsyncがエントリーポイント |

**主要処理フロー**:
1. **66-96行目**: GenerateTypeAsync - メイン処理
2. **73-75行目**: State.GenerateAsync - 状態生成
3. **78-91行目**: GetActions - CodeAction生成

#### Step 2: 状態解析を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractGenerateTypeService.cs | `src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs` | TryInitializeState（抽象メソッド）、各種コンテキスト判定メソッド |

**主要処理フロー**:
- **35行目**: TryInitializeState - 状態初期化（抽象メソッド）
- **47-50行目**: IsInCatchDeclaration、IsArrayElementType、IsInVariableTypeContext等のコンテキスト判定
- **52-53行目**: TryGetBaseList、IsPublicOnlyAccessibility

#### Step 3: アクション生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractGenerateTypeService.cs | `src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs` | GetActions |

**主要処理フロー**:
- **98-136行目**: GetActions - CodeAction生成ロジック
- **107-112行目**: 新規ファイルへの生成
- **119-125行目**: 既存名前空間への生成
- **129-130行目**: 既存型への入れ子型生成
- **132-133行目**: ダイアログ付きCodeAction

#### Step 4: 型パラメータ処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AbstractGenerateTypeService.cs | `src/Features/Core/Portable/GenerateType/AbstractGenerateTypeService.cs` | GetTypeParameters |

**主要処理フロー**:
- **180-230行目**: GetTypeParameters - 型パラメータの生成
- **193-214行目**: 型引数からの型パラメータ名の生成
- **222-227行目**: 型パラメータの一意性確保

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

```
AbstractGenerateTypeService.GenerateTypeAsync
    │
    ├─ SemanticDocument.CreateAsync
    │
    ├─ State.GenerateAsync
    │      └─ TryInitializeState (abstract)
    │             ├─ GetLeftSideOfDot
    │             ├─ TryGetArgumentList
    │             └─ IsGenericName
    │
    └─ GetActions
           │
           ├─ [新規ファイル] GenerateTypeCodeAction(inNewFile: true)
           │
           ├─ [既存名前空間] GenerateTypeCodeAction(inNamespace: true, inNewFile: false)
           │
           ├─ [既存型] GenerateTypeCodeAction(inNamespace: false, inNewFile: false)
           │
           └─ [ダイアログ] GenerateTypeCodeActionWithOption
                  │
                  └─ IGenerateTypeOptionsService
                         │
                         └─ 型の生成
                                ├─ GetTypeName
                                ├─ GetTypeParameters
                                ├─ DetermineDefaultAccessibility
                                └─ GetOrGenerateEnclosingNamespaceSymbol
```

### データフロー図

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

存在しない型参照 ─────────▶ AbstractGenerateTypeService.GenerateTypeAsync
                                 │
                                 ▼
                        State.GenerateAsync ───▶ State (型情報)
                                 │
                                 ▼
                        コンテキスト判定
                        (catch/interface/array/constraint)
                                 │
                                 ▼
                        GetActions ───▶ CodeActionリスト
                                 │
                        ┌────────┼────────┐
                        ▼        ▼        ▼
                    新規ファイル 既存名前空間 既存型
                        │        │        │
                        └────────┼────────┘
                                 ▼
                        型宣言生成
                                 │
                                 ▼
                        ソリューション更新
                                 │
                                 ▼
                        更新されたソリューション
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractGenerateTypeService.cs | `src/Features/Core/Portable/GenerateType/` | ソース | サービスの基底クラス |
| AbstractGenerateTypeService.State.cs | `src/Features/Core/Portable/GenerateType/` | ソース | 状態管理 |
| AbstractGenerateTypeService.GenerateNamespaceOrType.cs | `src/Features/Core/Portable/GenerateType/` | ソース | 名前空間/型の生成 |
| GenerateTypeCodeAction.cs | `src/Features/Core/Portable/GenerateType/` | ソース | 基本CodeAction |
| GenerateTypeCodeActionWithOption.cs | `src/Features/Core/Portable/GenerateType/` | ソース | ダイアログ付きCodeAction |
| IGenerateTypeService.cs | `src/Features/Core/Portable/GenerateType/` | ソース | サービスインターフェース |
| CSharpGenerateTypeService.cs | `src/Features/CSharp/Portable/GenerateType/` | ソース | C#固有の実装 |
