# 機能設計書 19-クイック情報

## 概要

本ドキュメントは、Roslynの「クイック情報」（QuickInfo / Hover）機能の設計について記述する。マウスホバー時にシンボルの詳細情報をツールチップで表示するIDE機能である。

### 本機能の処理概要

クイック情報機能は、マウスカーソルをシンボル上に移動したとき、そのシンボルの型情報、ドキュメント、プラットフォーム可用性などの詳細情報をツールチップとして表示する機能である。

**業務上の目的・背景**：コードを読む際に、シンボルの詳細情報を即座に確認できることは開発効率に直結する。この機能により、定義へ移動せずに型情報やドキュメントを確認でき、コードの理解が促進される。

**機能の利用シーン**：
- 変数の型を確認したいとき
- メソッドのドキュメントを確認したいとき
- Nullability情報を確認したいとき
- プラットフォーム可用性を確認したいとき
- awaitキーワードの戻り値の型を確認したいとき

**主要な処理内容**：
1. ホバー位置のシンボル特定
2. シンボルの型情報・ドキュメント取得
3. リンクドファイル（共有プロジェクト）対応
4. Nullability解析情報の取得
5. プラットフォーム可用性の判定
6. QuickInfoItemの生成

**関連システム・外部連携**：
- セマンティック解析エンジン
- XMLドキュメント解析システム
- LSP（Language Server Protocol）
- On-The-Fly Docs（AI生成ドキュメント）

**権限による制御**：特になし。すべての開発者が利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | ツールチップ | 主画面 | シンボル情報の表示 |
| - | エディタ | 関連画面 | マウスホバー操作 |

## 機能種別

UI情報提供 / シンボル解析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象ドキュメント | null不可 |
| position | int | Yes | ホバー位置 | 0以上 |
| options | SymbolDescriptionOptions | Yes | 表示オプション | - |
| cancellationToken | CancellationToken | Yes | キャンセルトークン | - |

### 入力データソース

- エディタからのホバー位置情報
- ドキュメントのセマンティックモデル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| quickInfo | QuickInfoItem? | クイック情報アイテム |

### QuickInfoItem

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Span | TextSpan | シンボルのテキストスパン |
| Tags | ImmutableArray\<string\> | 表示タグ |
| Sections | ImmutableArray\<QuickInfoSection\> | 情報セクション |
| RelatedSpans | ImmutableArray\<TextSpan\> | 関連スパン |
| OnTheFlyDocsInfo | OnTheFlyDocsInfo? | AI生成ドキュメント情報 |

### 出力先

- ツールチップUI

## 処理フロー

### 処理シーケンス

```
1. プロバイダ選択
   └─ 言語に応じたQuickInfoProviderを取得
2. トークン取得
   └─ ホバー位置のトークンを取得
3. シンボル解析
   └─ トークンからシンボルをバインド
4. リンクドファイル処理
   └─ 共有プロジェクトの場合、最適なバインディングを選択
5. Nullability解析
   └─ Null状態解析情報を取得
6. コンテンツ生成
   └─ QuickInfoItemを生成
7. 結果返却
   └─ 最初に見つかった非nullの結果を返却
```

### フローチャート

```mermaid
flowchart TD
    A[マウスホバー] --> B[プロバイダ取得]
    B --> C[トークン取得]
    C --> D{トークン発見?}
    D -->|No| Z[終了（null）]
    D -->|Yes| E[シンボルバインド]
    E --> F{リンクドファイル?}
    F -->|Yes| G[最適バインディング選択]
    F -->|No| H[通常バインディング]
    G --> I[Nullability解析]
    H --> I
    I --> J[QuickInfoItem生成]
    J --> K[結果返却]
    K --> Z
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | プロバイダ順序 | ExtensionOrdererで定義された順序でプロバイダを呼び出し | 常時 |
| BR-02 | 最初の結果 | 最初に非null結果を返したプロバイダの結果を使用 | 常時 |
| BR-03 | await処理 | awaitキーワードの場合はTask内部の型を表示 | IsAwaitKeyword |
| BR-04 | 属性優先 | 属性の場合はコンストラクタよりクラスを優先表示 | IsNameOfAttribute |
| BR-05 | 最良バインディング | リンクドファイルでエラーのないバインディングを優先 | 複数バインディング候補 |
| BR-06 | Suppression除去 | Null抑制演算子(!)を除去してNullability解析 | IsPostfixUnaryExpression |

### 計算ロジック

- 最良バインディング選択: エラーのないシンボルを持つドキュメントを優先

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

該当なし（メモリ内処理のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | シンボル未解決 | ホバー位置にシンボルがない | nullを返却 |
| - | エラー型 | シンボルがエラー型 | 可能な限り情報を表示 |

### リトライ仕様

特になし

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

該当なし（読み取り専用処理）

## パフォーマンス要件

- レスポンス時間: リアルタイム（マウス移動に追従）
- 非同期処理でUIスレッドをブロックしない

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

特になし（ローカルコード解析のみ）

## 備考

- C#とVBで共通の基盤を使用
- On-The-Fly Docs（AI生成ドキュメント）をサポート

---

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

### 推奨読解順序

#### Step 1: サービスとデータ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | QuickInfoService.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoService.cs` | サービスクラス。GetService、GetQuickInfoAsyncを理解する |
| 1-2 | QuickInfoItem.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoItem.cs` | 結果クラス。Span、Tags、Sections、RelatedSpans、OnTheFlyDocsInfoを理解する |

**主要処理フロー**:
- **28-29行目**: GetService - ドキュメントからサービスを取得
- **34-41行目**: GetQuickInfoAsync - 位置からクイック情報を取得

#### Step 2: プロバイダ管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | QuickInfoServiceWithProviders.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoServiceWithProviders.cs` | プロバイダ管理。GetProviders、プロバイダ順序呼び出しを理解する |

**主要処理フロー**:
- **25-41行目**: GetProviders - MEFからプロバイダを取得し順序付け
- **43-60行目**: GetQuickInfoAsync - プロバイダを順に呼び出し、最初の非null結果を返却

#### Step 3: セマンティック解析プロバイダを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CommonSemanticQuickInfoProvider.cs | `src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs` | セマンティック解析ベースのプロバイダ。シンボルバインド、リンクドファイル処理、Nullability解析を理解する |

**主要処理フロー**:
- **25-38行目**: BuildQuickInfoAsync - メイン処理（QuickInfoContext版）
- **40-50行目**: BuildQuickInfoAsync - 共通コンテキスト版
- **52-67行目**: ComputeQuickInfoDataAsync - シンボルとプラットフォーム情報の計算
- **69-134行目**: ComputeFromLinkedDocumentsAsync - リンクドファイル処理
- **156-182行目**: CreateContentAsync - QuickInfoItem生成
- **193-306行目**: GetNullabilityAnalysis - Null状態解析
- **308-339行目**: BindSymbols - シンボルバインド
- **341-368行目**: BindToken - トークンからシンボルへの変換
- **370-395行目**: GetSymbolsFromToken - トークンからシンボル取得

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

```
QuickInfoService.GetQuickInfoAsync()
    │ (QuickInfoServiceWithProviders)
    │
    ├─ GetProviders()
    │      └─ MEFからプロバイダ取得・順序付け
    │
    └─ foreach (provider in providers)
           │
           └─ QuickInfoProvider.GetQuickInfoAsync()
                  │ (CommonSemanticQuickInfoProvider)
                  │
                  ├─ ComputeQuickInfoDataAsync()
                  │      │
                  │      ├─ BindToken()
                  │      │      └─ BindSymbols()
                  │      │
                  │      └─ ComputeFromLinkedDocumentsAsync() [リンクドファイル]
                  │
                  ├─ GetNullabilityAnalysis()
                  │      └─ Null状態解析
                  │
                  └─ CreateContentAsync()
                         └─ QuickInfoUtilities.CreateQuickInfoItemAsync()
```

### データフロー図

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

Document ─────────┐
                  │
Position ─────────┼──▶ QuickInfoService ─────────────────┐
                  │         │                             │
Options ──────────┘         ▼                             │
                    プロバイダ取得                        │
                          │                               │
                          ▼                               │
                    トークン取得                          │
                          │                               │
                          ▼                               ▼
                    シンボルバインド ──────────▶ QuickInfoItem
                          │                               │
                          ▼                               │
                    リンクドファイル処理                  │
                          │                               │
                          ▼                               │
                    Nullability解析 ──────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| QuickInfoService.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoService.cs` | ソース | サービスクラス |
| QuickInfoServiceWithProviders.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoServiceWithProviders.cs` | ソース | プロバイダ管理 |
| QuickInfoItem.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoItem.cs` | ソース | 結果クラス |
| QuickInfoSection.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoSection.cs` | ソース | セクション |
| QuickInfoProvider.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoProvider.cs` | ソース | プロバイダ基底 |
| CommonSemanticQuickInfoProvider.cs | `src/Features/Core/Portable/QuickInfo/CommonSemanticQuickInfoProvider.cs` | ソース | セマンティックプロバイダ |
| QuickInfoContext.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoContext.cs` | ソース | コンテキスト |
| QuickInfoUtilities.cs | `src/Features/Core/Portable/QuickInfo/QuickInfoUtilities.cs` | ソース | ユーティリティ |
