# 機能設計書 61-usingディレクティブ追加

## 概要

本ドキュメントは、Roslyn IDE機能の一つである「usingディレクティブ追加（AddImport）」機能の設計を記述する。この機能は、コード内で未解決の型名に対して適切なusingディレクティブを追加するコードフィックス機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：開発者がコードを記述する際、使用したい型の完全修飾名を毎回記述するのは非効率である。本機能は、未解決の型名（コンパイラエラーCS0246等）を検出し、適切なusingディレクティブを自動的に追加することで、開発生産性を大幅に向上させる。特に.NET開発において、多数の名前空間を扱う際に不可欠な機能であり、Visual StudioのIntelliSenseと連携してスムーズな開発体験を提供する。

**機能の利用シーン**：コード編集中に未解決の型名が存在する場合、ライトバルブ（電球アイコン）またはCtrl+.キーボードショートカットで呼び出される。例えば「List」と入力したときに「using System.Collections.Generic;」を追加する候補を提示する。

**主要な処理内容**：
1. 未解決の識別子（型名、名前空間など）を持つ診断情報を受け取る
2. ソリューション内のプロジェクト、メタデータ参照、NuGetパッケージから一致するシンボルを検索
3. 見つかったシンボルに基づいてusingディレクティブ追加のコードアクションを生成
4. 必要に応じてプロジェクト参照やパッケージ参照の追加も提案

**関連システム・外部連携**：NuGetパッケージ検索サービス（ISymbolSearchService）、リモートホスト（OOP処理）、パッケージインストーラーサービス（IPackageInstallerService）と連携する。

**権限による制御**：特になし。ただし、NuGetパッケージ検索はオプションで有効/無効を切り替え可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エディタ（ライトバルブ） | 主画面 | usingディレクティブ追加の候補表示と選択 |

## 機能種別

コード修正（CodeFix）/ インポート自動追加

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象ドキュメント | null不可 |
| span | TextSpan | Yes | 診断の位置 | - |
| diagnosticId | string | Yes | 診断ID（CS0246等） | 対応する診断IDであること |
| maxResults | int | Yes | 最大結果数 | 5がデフォルト |
| symbolSearchService | ISymbolSearchService | Yes | シンボル検索サービス | - |
| options | AddImportOptions | Yes | オプション設定 | - |
| packageSources | ImmutableArray&lt;PackageSource&gt; | No | パッケージソース一覧 | - |

### 入力データソース

- コンパイラ診断情報（未解決の型名を示すエラー）
- ソリューション内のプロジェクトおよびメタデータ参照
- NuGetパッケージソース（オプション）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| AddImportFixData | ImmutableArray&lt;AddImportFixData&gt; | 修正候補のデータ |
| TextChanges | ImmutableArray&lt;TextChange&gt; | ドキュメントへのテキスト変更 |
| Title | string | ライトバルブに表示するタイトル |
| Tags | ImmutableArray&lt;string&gt; | グリフ表示用タグ |

### 出力先

エディタ上のライトバルブメニュー（コードアクションとして表示）

## 処理フロー

### 処理シーケンス

```
1. RegisterCodeFixesAsync呼び出し
   └─ 診断情報とドキュメントを受け取る
2. AddImportFeatureServiceのGetFixesAsync呼び出し
   └─ リモートホストが利用可能ならOOPで処理
3. SymbolReferenceFinderで検索
   └─ 現在プロジェクト→未参照プロジェクト→メタデータ→NuGetの順
4. AddImportFixDataの生成
   └─ 各候補についてテキスト変更と参照追加情報を生成
5. CodeAction生成と登録
   └─ ライトバルブに表示する候補を登録
```

### フローチャート

```mermaid
flowchart TD
    A[診断情報受け取り] --> B{リモートホスト利用可能?}
    B -->|Yes| C[OOPで処理]
    B -->|No| D[インプロセスで処理]
    C --> E[シンボル検索]
    D --> E
    E --> F{完全一致あり?}
    F -->|Yes| G[完全一致結果を返す]
    F -->|No| H[あいまい検索実行]
    H --> G
    G --> I[AddImportFixData生成]
    I --> J[CodeAction登録]
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-61-01 | 検索優先順位 | 現在プロジェクト→未参照プロジェクト→メタデータ→NuGetの順で検索 | 常時 |
| BR-61-02 | 最大結果数 | 1つの診断に対して最大5件の候補を返す | 常時 |
| BR-61-03 | パッケージディレクトリ除外 | NuGetパッケージディレクトリ内のDLLは直接参照として提案しない | メタデータ検索時 |
| BR-61-04 | 高優先度処理 | AddImportはCodeActionRequestPriority.Highで処理される | 常時 |

### 計算ロジック

特になし

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

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

本機能はデータベース操作を行わない。

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | キャンセル | ユーザーによる操作キャンセル | 処理を中断し空の結果を返す |
| - | リモート通信エラー | OOP通信失敗 | インプロセスにフォールバック |

### リトライ仕様

リモート通信失敗時はインプロセス処理にフォールバックする。

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

該当なし（ドキュメント編集はエディタのUndo機構で管理）

## パフォーマンス要件

- 高優先度（High Priority）で処理され、他のコードアクションより先に計算される
- 大規模ソリューションでも応答性を確保するためOOP処理を活用
- 検索結果が十分な数に達した時点で追加検索をキャンセル

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

特になし

## 備考

FixAllProviderは現時点で未サポート（GitHub Issue #34457）

---

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

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

### 推奨読解順序

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

まず、処理で使用されるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AddImportFixData.cs | `src/Features/Core/Portable/AddImport/AddImportFixData.cs` | 修正データの構造（TextChanges、Title、参照情報等） |
| 1-2 | AddImportFixKind.cs | `src/Features/Core/Portable/AddImport/AddImportFixKind.cs` | 修正の種類（ProjectSymbol、MetadataSymbol、PackageSymbol等） |
| 1-3 | AddImportOptions.cs | `src/Features/Core/Portable/AddImport/AddImportOptions.cs` | オプション設定の構造 |

**読解のコツ**: AddImportFixDataはDataContractでシリアライズ可能。OOP通信で使用されるため。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractAddImportCodeFixProvider.cs | `src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs` | CodeFixProviderとしてのエントリーポイント |

**主要処理フロー**:
1. **50-87行目**: RegisterCodeFixesAsyncメソッドで診断に対するコードフィックスを登録
2. **57行目**: IAddImportFeatureServiceを取得
3. **78-79行目**: GetFixesForDiagnosticsAsyncで修正候補を取得
4. **84行目**: GetCodeActionsForFixesでCodeActionを生成

#### Step 3: フィーチャーサービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | IAddImportFeatureService.cs | `src/Features/Core/Portable/AddImport/IAddImportFeatureService.cs` | サービスインターフェースの定義 |
| 3-2 | AbstractAddImportFeatureService.cs | `src/Features/Core/Portable/AddImport/AbstractAddImportFeatureService.cs` | 実装の中核ロジック |

**主要処理フロー**:
- **65-87行目**: GetFixesAsyncメソッドでリモート/ローカル処理を振り分け
- **89-131行目**: GetFixesInCurrentProcessAsyncで実際の検索処理
- **133-166行目**: FindResultsAsyncで完全一致→あいまい検索の流れ
- **171-206行目**: 各種検索スコープでの並列検索処理

#### Step 4: シンボル検索を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SymbolReferenceFinder.cs | `src/Features/Core/Portable/AddImport/SymbolReferenceFinder.cs` | シンボル検索のメインロジック |
| 4-2 | SearchScope.cs | `src/Features/Core/Portable/AddImport/SearchScopes/SearchScope.cs` | 検索スコープの基底クラス |

#### Step 5: コードアクション生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | AddImportCodeAction.cs | `src/Features/Core/Portable/AddImport/CodeActions/AddImportCodeAction.cs` | コードアクションの基底実装 |
| 5-2 | ProjectSymbolReferenceCodeAction.cs | `src/Features/Core/Portable/AddImport/CodeActions/ProjectSymbolReferenceCodeAction.cs` | プロジェクト参照追加アクション |

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

```
AbstractAddImportCodeFixProvider.RegisterCodeFixesAsync
    │
    ├─ IAddImportFeatureService.GetFixesForDiagnosticsAsync
    │      │
    │      ├─ GetFixesAsync
    │      │      │
    │      │      ├─ RemoteHostClient.TryInvokeAsync (OOP)
    │      │      │      └─ IRemoteMissingImportDiscoveryService
    │      │      │
    │      │      └─ GetFixesInCurrentProcessAsync (In-proc)
    │      │             │
    │      │             └─ FindResultsAsync
    │      │                    │
    │      │                    ├─ SymbolReferenceFinder
    │      │                    │      ├─ FindInAllSymbolsInStartingProjectAsync
    │      │                    │      ├─ FindInSourceSymbolsInProjectAsync
    │      │                    │      ├─ FindInMetadataSymbolsAsync
    │      │                    │      └─ FindNugetOrReferenceAssemblyReferencesAsync
    │      │                    │
    │      │                    └─ Reference.TryGetFixDataAsync
    │      │
    │      └─ GetCodeActionsForFixes
    │             └─ TryCreateCodeAction
    │
    └─ context.RegisterFixes
```

### データフロー図

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

Diagnostic          ───▶  AbstractAddImportCodeFixProvider
(CS0246等)                        │
                                  ▼
                         IAddImportFeatureService
                                  │
                                  ▼
                         SymbolReferenceFinder        ───▶  ImmutableArray<Reference>
                                  │
                                  ▼
                         AddImportFixData生成         ───▶  AddImportFixData[]
                                  │
                                  ▼
                         CodeAction生成               ───▶  ライトバルブメニュー
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractAddImportCodeFixProvider.cs | `src/Features/Core/Portable/AddImport/AbstractAddImportCodeFixProvider.cs` | ソース | CodeFixProviderエントリーポイント |
| IAddImportFeatureService.cs | `src/Features/Core/Portable/AddImport/IAddImportFeatureService.cs` | ソース | サービスインターフェース |
| AbstractAddImportFeatureService.cs | `src/Features/Core/Portable/AddImport/AbstractAddImportFeatureService.cs` | ソース | サービス実装 |
| AddImportFixData.cs | `src/Features/Core/Portable/AddImport/AddImportFixData.cs` | ソース | 修正データ構造 |
| AddImportFixKind.cs | `src/Features/Core/Portable/AddImport/AddImportFixKind.cs` | ソース | 修正種別列挙 |
| AddImportOptions.cs | `src/Features/Core/Portable/AddImport/AddImportOptions.cs` | ソース | オプション設定 |
| SymbolReferenceFinder.cs | `src/Features/Core/Portable/AddImport/SymbolReferenceFinder.cs` | ソース | シンボル検索ロジック |
| SymbolResult.cs | `src/Features/Core/Portable/AddImport/SymbolResult.cs` | ソース | 検索結果データ |
| Reference.cs | `src/Features/Core/Portable/AddImport/References/Reference.cs` | ソース | 参照の基底クラス |
| SymbolReference.cs | `src/Features/Core/Portable/AddImport/References/SymbolReference.cs` | ソース | シンボル参照 |
| ProjectSymbolReference.cs | `src/Features/Core/Portable/AddImport/References/ProjectSymbolReference.cs` | ソース | プロジェクトシンボル参照 |
| MetadataSymbolReference.cs | `src/Features/Core/Portable/AddImport/References/MetadataSymbolReference.cs` | ソース | メタデータシンボル参照 |
| PackageReference.cs | `src/Features/Core/Portable/AddImport/References/PackageReference.cs` | ソース | パッケージ参照 |
| SearchScope.cs | `src/Features/Core/Portable/AddImport/SearchScopes/SearchScope.cs` | ソース | 検索スコープ基底 |
| AddImportCodeAction.cs | `src/Features/Core/Portable/AddImport/CodeActions/AddImportCodeAction.cs` | ソース | コードアクション |
| IRemoteMissingImportDiscoveryService.cs | `src/Features/Core/Portable/AddImport/Remote/IRemoteMissingImportDiscoveryService.cs` | ソース | リモートサービスインターフェース |
