# 機能設計書 66-コードフィックス

## 概要

本ドキュメントは、Visual Studio統合におけるF#のコードフィックス（クイック修正）機能の設計について記述する。この機能は、診断で検出されたコード品質問題に対して、自動修正の提案を行い、ユーザーの選択により修正を適用する。

### 本機能の処理概要

**業務上の目的・背景**：
コードの問題を検出するだけでなく、その修正方法を提案し自動適用できることで、開発者の生産性が大幅に向上する。本機能により、定型的な修正作業を自動化し、コーディング規約への準拠を効率的に行える。

**機能の利用シーン**：
- 未使用のopen文を削除したい場合
- 型注釈を追加してコンパイルエラーを解決したい場合
- 変数名の提案を受け入れてタイプミスを修正したい場合
- 不要な括弧を削除してコードを簡潔にしたい場合
- インターフェース実装のスタブを自動生成したい場合

**主要な処理内容**：
1. 診断情報に基づいてコードフィックスを特定
2. 該当する診断IDに対応するフィックスプロバイダを呼び出し
3. 修正案（TextChange）を生成
4. ユーザーに修正提案を表示
5. 選択された修正をドキュメントに適用

**関連システム・外部連携**：
- Microsoft.CodeAnalysis.CodeFixes: Roslynコードフィックスフレームワーク
- 診断アナライザ（No.65）: 修正対象の診断を提供

**権限による制御**：
特になし。すべてのユーザーがこの機能を利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 3 | Code Fixes オプション設定画面 | 設定画面 | 名前の簡略化、未使用open、未使用宣言、名前サジェスト、括弧削除の有効/無効設定 |

## 機能種別

リファクタリング・自動修正機能

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context | CodeFixContext | Yes | コードフィックスのコンテキスト | null不可 |
| diagnostic | Diagnostic | Yes | 修正対象の診断情報 | null不可 |

### 入力データソース

- 診断アナライザからの診断情報
- プロジェクト設定（コードフィックスの有効/無効）
- ドキュメントのソーステキスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| FSharpCodeFix | FSharpCodeFix | 修正提案（名前、メッセージ、変更リスト） |
| CodeAction | CodeAction | Roslynコードアクション |

### 出力先

- Visual Studio ライトバルブUI
- クイックアクションメニュー

## 処理フロー

### 処理シーケンス

```
1. 診断IDの照合
   └─ FixableDiagnosticIdsで対応可能か確認

2. コードフィックスコンテキスト取得
   └─ ドキュメント、スパン、診断情報を取得

3. フィックス生成
   └─ GetCodeFixIfAppliesAsync / GetCodeFixesAsyncでTextChange生成

4. コードアクション作成
   └─ FSharpCodeFixからCodeActionに変換

5. 登録
   └─ context.RegisterCodeFixでRoslynに登録

6. ユーザー選択
   └─ ライトバルブから修正を選択

7. 適用
   └─ TextChangeをドキュメントに適用
```

### フローチャート

```mermaid
flowchart TD
    A[診断検出] --> B{対応フィックスあり?}
    B -->|No| Z[なにもしない]
    B -->|Yes| C[RegisterCodeFixesAsync]
    C --> D{単一/複数フィックス?}
    D -->|単一| E[IFSharpCodeFixProvider.GetCodeFixIfAppliesAsync]
    D -->|複数| F[IFSharpMultiCodeFixProvider.GetCodeFixesAsync]
    E --> G[FSharpCodeFix生成]
    F --> G
    G --> H[CodeAction作成]
    H --> I[context.RegisterCodeFix]
    I --> J[ライトバルブ表示]
    J --> K{ユーザー選択?}
    K -->|No| L[キャンセル]
    K -->|Yes| M[TextChange適用]
    M --> N[完了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-66-01 | 診断ID対応 | 各フィックスプロバイダはFixableDiagnosticIdsで対応する診断IDを宣言 | フィックス登録時 |
| BR-66-02 | Fix All対応 | RegisterFsharpFixAllでドキュメント/プロジェクト全体への一括適用を提供 | Fix All操作時 |
| BR-66-03 | 設定による制御 | プロジェクト設定で個別のフィックスを有効/無効化可能 | フィックス実行前 |

### 計算ロジック

該当なし（修正内容は各フィックスプロバイダで個別に定義）

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | フィックス不可 | 対応するフィックスが見つからない | 空のリストを返却 |
| - | 適用失敗 | TextChange適用に失敗 | エラーを無視（ドキュメント変更なし） |

### リトライ仕様

リトライなし。

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

- 各TextChangeは原子的に適用
- 複数のTextChangeは一括でドキュメントに反映

## パフォーマンス要件

- ライトバルブ表示は診断検出後に即座に表示
- Fix All操作はバックグラウンドで実行

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

該当なし

## 備考

- IFSharpCodeFixProvider: 単一の修正提案を生成
- IFSharpMultiCodeFixProvider: 複数の修正提案を生成
- 約40種類のコードフィックスプロバイダが実装されている

---

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

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

### 推奨読解順序

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

コードフィックスで使用される主要なデータ型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IFSharpCodeFix.fs | `vsintegration/src/FSharp.Editor/CodeFixes/IFSharpCodeFix.fs` | FSharpCodeFix、IFSharpCodeFixProvider、IFSharpMultiCodeFixProvider |

**読解のコツ**:
- FSharpCodeFix（10-15行目）: 修正提案を表すレコード型
- IFSharpCodeFixProvider（17-19行目）: 単一フィックス用インターフェース
- IFSharpMultiCodeFixProvider（21-23行目）: 複数フィックス用インターフェース

#### Step 2: 具体的なフィックスプロバイダを理解する

RemoveUnusedOpensCodeFixProviderを例に構造を理解。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | RemoveUnusedOpens.fs | `vsintegration/src/FSharp.Editor/CodeFixes/RemoveUnusedOpens.fs` | RemoveUnusedOpensCodeFixProviderクラス |

**主要処理フロー**:
1. **16-17行目**: ExportCodeFixProviderアトリビュートとクラス定義
2. **22-23行目**: FixableDiagnosticIdsプロパティ
3. **25行目**: RegisterCodeFixesAsyncの実装
4. **27行目**: GetFixAllProviderの実装
5. **29-49行目**: IFSharpCodeFixProvider.GetCodeFixIfAppliesAsync実装

#### Step 3: ヘルパー関数を理解する

CodeFixHelpersモジュールがフィックス登録をサポート。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CodeFixHelpers.fs | `vsintegration/src/FSharp.Editor/CodeFixes/CodeFixHelpers.fs` | RegisterFsharpFix、RegisterFsharpFixAll拡張メソッド |

**主要処理フロー**:
- RegisterFsharpFix: 単一フィックスをRoslynに登録
- RegisterFsharpFixAll: Fix All機能を登録
- GetSourceTextAsync: ソーステキスト取得のヘルパー

#### Step 4: 代表的なフィックスパターンを理解する

様々な種類のフィックスパターンを確認。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ReplaceWithSuggestion.fs | `vsintegration/src/FSharp.Editor/CodeFixes/ReplaceWithSuggestion.fs` | 名前サジェスト（複数フィックス） |
| 4-2 | AddTypeAnnotationToObjectOfIndeterminateType.fs | `vsintegration/src/FSharp.Editor/CodeFixes/AddTypeAnnotationToObjectOfIndeterminateType.fs` | 型注釈追加 |
| 4-3 | ImplementInterface.fs | `vsintegration/src/FSharp.Editor/CodeFixes/ImplementInterface.fs` | インターフェース実装 |

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

```
CodeFixProvider (Roslyn)
    │
    ├─ FixableDiagnosticIds (プロパティ)
    │      └─ 対応する診断IDを返却
    │
    ├─ RegisterCodeFixesAsync
    │      │
    │      └─ context.RegisterFsharpFix(this)
    │             │
    │             └─ IFSharpCodeFixProvider.GetCodeFixIfAppliesAsync
    │                    │
    │                    ├─ context.GetSourceTextAsync
    │                    │
    │                    └─ FSharpCodeFix生成
    │                           │
    │                           └─ CodeAction.Create
    │
    └─ GetFixAllProvider
           │
           └─ RegisterFsharpFixAll
                  │
                  └─ Fix All Scope選択
                         │
                         ├─ Document
                         ├─ Project
                         └─ Solution
```

### データフロー図

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

Diagnostic ────────────▶ CodeFixProvider選択 ────────────────┐
                              │                              │
                              ▼                              │
CodeFixContext ────────▶ GetCodeFixIfAppliesAsync ───────────┤
                              │                              │
                              ▼                              │
                        FSharpCodeFix                        │
                              │                              │
                              ├─ Name                        │
                              ├─ Message                     │
                              └─ Changes: TextChange list    │
                                      │                      │
                                      ▼                      │
                              CodeAction.Create ─────────────┤
                                      │                      │
                                      ▼                      ▼
                              context.RegisterCodeFix ──▶ ライトバルブUI
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IFSharpCodeFix.fs | `vsintegration/src/FSharp.Editor/CodeFixes/IFSharpCodeFix.fs` | ソース | インターフェース定義 |
| CodeFixHelpers.fs | `vsintegration/src/FSharp.Editor/CodeFixes/CodeFixHelpers.fs` | ソース | ヘルパー関数 |
| RemoveUnusedOpens.fs | `vsintegration/src/FSharp.Editor/CodeFixes/RemoveUnusedOpens.fs` | ソース | 未使用open削除 |
| RemoveUnusedBinding.fs | `vsintegration/src/FSharp.Editor/CodeFixes/RemoveUnusedBinding.fs` | ソース | 未使用バインディング削除 |
| ReplaceWithSuggestion.fs | `vsintegration/src/FSharp.Editor/CodeFixes/ReplaceWithSuggestion.fs` | ソース | 名前サジェスト |
| SimplifyName.fs | `vsintegration/src/FSharp.Editor/CodeFixes/SimplifyName.fs` | ソース | 名前簡略化 |
| RemoveUnnecessaryParentheses.fs | `vsintegration/src/FSharp.Editor/CodeFixes/RemoveUnnecessaryParentheses.fs` | ソース | 不要括弧削除 |
| AddOpenCodeFixProvider.fs | `vsintegration/src/FSharp.Editor/CodeFixes/AddOpenCodeFixProvider.fs` | ソース | open文追加 |
| ImplementInterface.fs | `vsintegration/src/FSharp.Editor/CodeFixes/ImplementInterface.fs` | ソース | インターフェース実装 |
