# 機能設計書 125-シンボル検索

## 概要

本ドキュメントは、Roslynプロジェクトにおけるシンボル検索機能の設計仕様を記載する。NuGetパッケージや参照アセンブリからシンボル（型、名前空間）を検索し、未解決の参照に対するパッケージ追加を支援する機能を提供する。

### 本機能の処理概要

シンボル検索機能は、Elfieデータベースを使用してNuGetパッケージや参照アセンブリ内のシンボル（型、名前空間）を検索するサービスである。Add Importやパッケージ追加機能の基盤として動作する。

**業務上の目的・背景**：開発者がコード内で未解決の型や名前空間を使用した場合、それを提供するNuGetパッケージや参照アセンブリを特定する必要がある。本機能は、シンボル名から該当するパッケージを検索し、自動的なパッケージ追加提案を可能にする。これにより、開発者は手動でパッケージを探す手間を省き、生産性を向上できる。

**機能の利用シーン**：
- 未解決の型名に対するusing追加時のパッケージ検索
- NuGetパッケージ追加の候補表示
- 参照アセンブリからの型検索
- アセンブリ名からのパッケージ検索

**主要な処理内容**：
1. シンボルデータベースのダウンロードと更新
2. 型名による NuGet パッケージ検索
3. 型名による参照アセンブリ検索
4. アセンブリ名によるパッケージ検索
5. 検索結果のランキングと返却

**関連システム・外部連携**：NuGet.org、Elfieデータベース、パッチサービス（差分更新）。

**権限による制御**：インターネット接続が必要（データベース更新時）。オフラインではキャッシュされたデータベースを使用。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | バックグラウンドサービス（UI直接なし） |

## 機能種別

検索処理 / データ連携 / バックグラウンドサービス

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source | string | Yes | パッケージソース名（例: nuget.org） | 有効なソース名 |
| typeQuery | TypeQuery | Yes | 型検索クエリ（名前） | 空でない文字列 |
| namespaceQuery | NamespaceQuery | No | 名前空間検索クエリ | 名前空間の配列 |
| assemblyName | string | Yes | アセンブリ名（FindPackagesWithAssembly用） | 空でない文字列 |

### 入力データソース

- Elfieシンボルデータベース（ダウンロード/キャッシュ）
- パッチファイル（差分更新）
- ローカルキャッシュ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| PackageResult | struct | パッケージ名、ランク、型名、バージョン、名前空間 |
| ReferenceAssemblyResult | struct | アセンブリ名、型名、名前空間 |
| PackageWithAssemblyResult | struct | パッケージ名、ランク、バージョン |

### 出力先

- Add Import機能への結果返却
- パッケージ追加提案UI

## 処理フロー

### 処理シーケンス

```
1. データベース更新チェック（バックグラウンド）
   ├─ 前回更新からの経過時間確認
   ├─ パッチダウンロード
   └─ データベースマージ
2. シンボル検索リクエスト受付
   ├─ FindPackagesAsync（パッケージ検索）
   ├─ FindReferenceAssembliesAsync（参照アセンブリ検索）
   └─ FindPackagesWithAssemblyAsync（アセンブリ名検索）
3. Elfieデータベースクエリ実行
   ├─ MemberQueryによるシンボル検索
   ├─ 結果フィルタリング
   └─ ランキング適用
4. 結果返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{データベース<br/>存在?}
    B -->|No| C[データベースダウンロード]
    B -->|Yes| D{更新必要?}
    C --> E[データベースロード]
    D -->|Yes| F[パッチダウンロード]
    D -->|No| G[検索実行]
    F --> G
    E --> G
    G --> H[MemberQuery実行]
    H --> I[結果フィルタリング]
    I --> J[ランキング適用]
    J --> K[結果返却]
    K --> L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | "var"除外 | "var"という名前の検索は結果なし | 型検索時 |
| BR-002 | ネスト型除外 | ネストされた型は検索結果から除外 | 型検索時 |
| BR-003 | 参照アセンブリ分離 | MicrosoftAssemblyReferencesNameは別扱い | パッケージ検索時 |
| BR-004 | ランキング | PopularityRankに基づくソート | 結果返却時 |

### 計算ロジック

ランキング取得:
- シンボルからPackageまたはVersionまで親をたどる
- PopularityRank子ノードの値を取得
- 数値パース失敗時はランク0

```csharp
private static int GetRank(Symbol symbol)
{
    if (!TryGetRankingSymbol(symbol, out var rankingSymbol) ||
        !int.TryParse(rankingSymbol.Name.ToString(), out var rank))
    {
        return 0;
    }
    return rank;
}
```

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

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| 検索 | Elfie DB | SELECT | シンボル検索クエリ |
| 更新 | Elfie DB | MERGE | パッチ適用 |

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

#### Elfie AddReferenceDatabase

| 操作 | 項目 | 説明 | 備考 |
|-----|------|------|------|
| SELECT | Symbol | シンボル情報 | MemberQueryによる検索 |
| SELECT | PackageVersion | パッケージバージョン | GetPackageVersionで取得 |
| SELECT | PopularityRank | 人気ランク | ランキング用 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | データベース未初期化 | 初回起動でダウンロード未完了 | 空結果を返却 |
| - | ネットワークエラー | データベースダウンロード失敗 | キャッシュ使用またはリトライ |
| - | パースエラー | ランキング値パース失敗 | ランク0として処理 |

### リトライ仕様

データベース更新は定期的にバックグラウンドで実行されるため、一時的な失敗は次回更新で回復。

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

ファイルベースのデータベースのため、明示的なトランザクション管理なし。データベース更新時は一時ファイルを使用して原子的に置換。

## パフォーマンス要件

- Elfieデータベースによる高速インメモリ検索
- 結果は100件を上限（PartialArray）
- パッチベース更新による帯域節約

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

- データベースはHTTPSでダウンロード
- ローカルキャッシュはユーザーディレクトリに保存
- 外部パッケージ情報のみ、コード内容は送信しない

## 備考

- Windows環境専用の最適化実装あり（SymbolSearchUpdateEngine）
- SourceBuild環境向けのNoOp実装あり

---

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

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

### 推奨読解順序

#### Step 1: メインエンジンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SymbolSearchUpdateEngine.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngine.cs` | シンボル検索エンジンの本体 |

**主要処理フロー**:
- **33-68行目**: クラス定義とコンストラクタ
- **35行目**: `_sourceToDatabase`でソース別データベースを管理
- **75-95行目**: `FindPackagesAsync`でパッケージ検索
- **97-112行目**: `FindReferenceAssembliesAsync`で参照アセンブリ検索
- **114-175行目**: `FindPackageOrReferenceAssembliesAsync`で共通検索ロジック
- **176-215行目**: `FindPackagesWithAssemblyAsync`でアセンブリ名検索
- **217-268行目**: ランキングとヘルパーメソッド

**読解のコツ**:
- `MemberQuery`でElfieデータベースにクエリを実行
- `FilterToViableSymbols`で結果をフィルタリング
- `packageNameMatches`デリゲートでパッケージ/参照アセンブリを区別

#### Step 2: データベース更新を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SymbolSearchUpdateEngine.Update.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngine.Update.cs` | データベース更新処理 |

#### Step 3: サービスインターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SymbolSearchOptions.cs | `src/Features/Core/Portable/SymbolSearch/SymbolSearchOptions.cs` | オプション設定 |
| 3-2 | SymbolSearchUpdateNoOpEngine.cs | `src/Features/Core/Portable/SymbolSearch/SymbolSearchUpdateNoOpEngine.cs` | NoOp実装 |

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

```
ISymbolSearchUpdateEngine
    │
    ├─ FindPackagesAsync
    │      └─ FindPackageOrReferenceAssembliesAsync
    │             ├─ MemberQuery.TryFindMembers
    │             ├─ FilterToViableSymbols
    │             └─ GetRank
    │
    ├─ FindReferenceAssembliesAsync
    │      └─ FindPackageOrReferenceAssembliesAsync
    │             └─ (同上)
    │
    └─ FindPackagesWithAssemblyAsync
           ├─ StringStore.TryFindString
           ├─ Index.TryGetMatchesInRange
           └─ GetRank

SymbolSearchUpdateEngine.Update
    │
    ├─ UpdateDatabaseAsync
    │      ├─ DownloadDatabase
    │      └─ MergePatches
    │
    └─ DownloadPatchAsync
           ├─ IFileDownloaderFactory
           └─ IPatchService
```

### データフロー図

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

TypeQuery ──────────────▶ MemberQuery ─────────────▶ Symbol[]
    │                          │
    │                          ▼
    │                    FilterToViableSymbols
    │                          │
NamespaceQuery ────────────────┘
    │                          │
    │                          ▼
    │                    GetRank
    │                          │
    │                          ▼
    └────────────────▶ PackageResult[]
                       ReferenceAssemblyResult[]

[バックグラウンド]

NuGet.org ──────▶ DownloadDatabase ──────▶ Elfie DB
    │                   │
    ▼                   ▼
PatchService ────▶ MergePatches ──────────▶ Updated DB
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SymbolSearchUpdateEngine.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngine.cs` | ソース | メイン検索エンジン |
| SymbolSearchUpdateEngine.Update.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngine.Update.cs` | ソース | データベース更新 |
| SymbolSearchUpdateEngine.DatabaseFactoryService.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngine.DatabaseFactoryService.cs` | ソース | DB作成サービス |
| SymbolSearchUpdateEngine.IOService.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngine.IOService.cs` | ソース | IOサービス |
| SymbolSearchUpdateEngine.DelayService.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngine.DelayService.cs` | ソース | 遅延サービス |
| SymbolSearchUpdateEngine.PatchService.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngine.PatchService.cs` | ソース | パッチサービス |
| SymbolSearchUpdateNoOpEngine.cs | `src/Features/Core/Portable/SymbolSearch/SymbolSearchUpdateNoOpEngine.cs` | ソース | NoOp実装 |
| SymbolSearchOptions.cs | `src/Features/Core/Portable/SymbolSearch/SymbolSearchOptions.cs` | ソース | オプション |
| SymbolSearchUpdateEngineFactory.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngineFactory.cs` | ソース | ファクトリ |
| SymbolSearchUpdateEngineProxy.cs | `src/Features/Core/Portable/SymbolSearch/Windows/SymbolSearchUpdateEngineProxy.cs` | ソース | プロキシ |
