# 機能設計書 93-CodeLens

## 概要

本ドキュメントは、Roslyn の CodeLens 機能の設計を定義する。CodeLens は、コードエディタ上でメソッドやクラスの上に参照数やテスト状況などのインライン情報を表示する機能である。

### 本機能の処理概要

CodeLens は、シンボル（メソッド、クラス、プロパティなど）の宣言箇所に、そのシンボルがプロジェクト内で何回参照されているかを表示する。開発者はこの情報を見ることで、コードの依存関係や影響範囲を素早く把握できる。

**業務上の目的・背景**：大規模なコードベースでは、あるメソッドがどこから呼び出されているかを把握することが困難になる。CodeLens によって、コードを読みながらリアルタイムで参照情報を確認でき、リファクタリングや変更の影響範囲分析が容易になる。

**機能の利用シーン**：開発者がメソッドを編集しようとする際、そのメソッドが何箇所から呼び出されているかを確認する。参照数が多い場合は慎重に変更を行い、参照がない場合は削除候補として検討する。

**主要な処理内容**：
1. ドキュメント内のシンボル宣言を検出
2. シンボルごとに参照を非同期で検索
3. 参照数と参照元情報をキャッシュ
4. エディタ上にインライン表示

**関連システム・外部連携**：Visual Studio CodeLens インフラストラクチャ、Find References 機能との連携。

**権限による制御**：特になし。プロジェクト内のすべてのシンボルが対象。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コードエディタ | 主画面 | シンボル上に参照数を表示 |
| - | 参照リスト | 結果表示画面 | CodeLens クリック時の参照一覧 |

## 機能種別

参照検索 / 情報表示 / コード分析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| solution | Solution | Yes | 対象ソリューション | null チェック |
| documentId | DocumentId | Yes | 対象ドキュメント ID | null チェック |
| syntaxNode | SyntaxNode | Yes | シンボル宣言ノード | 宣言ノードであること |
| maxSearchResults | int | No | 検索結果の上限 | 正の整数 |

### 入力データソース

- ワークスペースのソリューション構造
- ソースコードのセマンティックモデル

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ReferenceCount | int | 参照数 |
| IsCapped | bool | 検索上限に達したかどうか |
| VersionStamp | string | プロジェクトバージョン（キャッシュ用） |
| ReferenceLocations | ReferenceLocationDescriptor[] | 参照位置の詳細情報 |
| ReferenceMethods | ReferenceMethodDescriptor[] | 参照元メソッドの情報 |

### 出力先

- エディタ上のインライン表示
- 参照リストビュー

## 処理フロー

### 処理シーケンス

```
1. シンボル検出
   └─ ドキュメント内の宣言シンボルを特定
2. 参照検索開始
   └─ CodeLensFindReferencesProgress で非同期検索
3. 結果収集
   └─ SymbolFinder.FindReferencesAsync で参照を収集
4. 結果加工
   └─ 参照位置情報を ReferenceLocationDescriptor に変換
5. 表示更新
   └─ 参照数をエディタに表示
```

### フローチャート

```mermaid
flowchart TD
    A[ドキュメントオープン] --> B[シンボル宣言検出]
    B --> C[各シンボルに対して参照検索]
    C --> D{検索上限設定あり?}
    D -->|Yes| E[上限付き検索]
    D -->|No| F[全件検索]
    E --> G[CodeLensFindReferencesProgress]
    F --> G
    G --> H[参照位置収集]
    H --> I{上限到達?}
    I -->|Yes| J[IsCapped = true で返却]
    I -->|No| K[全結果を返却]
    J --> L[エディタに表示]
    K --> L
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-93-01 | 非並列検索 | パフォーマンス影響を避けるため参照検索は直列実行 | Explicit = false |
| BR-93-02 | 単方向継承カスケード | 呼び出し可能な参照のみを検索 | UnidirectionalHierarchyCascade = true |
| BR-93-03 | 検索上限 | 指定された上限に達したら検索を中断 | searchCap > 0 の場合 |
| BR-93-04 | バージョン管理 | プロジェクトバージョンでキャッシュ有効性を判断 | GetDependentVersionAsync |

### 計算ロジック

参照数の計算:
- 宣言自身は参照数にカウントしない
- 継承階層での参照は設定に応じてカウント

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

本機能はデータベースを直接操作しない。

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

| 操作 | 対象テーブル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| - | - | - | データベース操作なし |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | OperationCanceledException | 検索がキャンセルされた | 正常なキャンセル |
| - | ドキュメント未検出 | DocumentId に対応するドキュメントがない | null を返却 |
| - | シンボル未検出 | SyntaxNode に対応するシンボルがない | null を返却 |

### リトライ仕様

エラー時のリトライは行わない。次回の CodeLens 更新時に再計算される。

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

トランザクション不要（読み取り専用操作）。

## パフォーマンス要件

- 参照数取得: 100ms 以内（キャッシュヒット時）
- 参照一覧取得: 500ms 以内
- バックグラウンド実行によりエディタ操作をブロックしない

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

- プロジェクト内のコードのみ検索対象
- 外部システムへのアクセスなし

## 備考

CodeLens は Visual Studio の機能であり、VS Code では別途実装が必要。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ReferenceCount.cs | `src/Features/Core/Portable/CodeLens/ReferenceCount.cs` | 参照数の結果構造 |
| 1-2 | ReferenceLocationDescriptor.cs | `src/Features/Core/Portable/CodeLens/ReferenceLocationDescriptor.cs` | 参照位置の詳細情報 |
| 1-3 | ReferenceMethodDescriptor.cs | `src/Features/Core/Portable/CodeLens/ReferenceMethodDescriptor.cs` | 参照元メソッドの情報 |

**読解のコツ**: これらは record/readonly struct として定義されており、不変データ構造として設計されている。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ICodeLensReferencesService.cs | `src/Features/Core/Portable/CodeLens/ICodeLensReferencesService.cs` | CodeLens サービスインターフェース |
| 2-2 | ICodeLensDisplayInfoService.cs | `src/Features/Core/Portable/CodeLens/ICodeLensDisplayInfoService.cs` | 表示情報サービスインターフェース |

#### Step 3: コア実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | CodeLensReferencesService.cs | `src/Features/Core/Portable/CodeLens/CodeLensReferencesService.cs` | 参照検索のメイン実装 |

**主要処理フロー**:
- **25-28行目**: MethodDisplayFormat の定義
- **36-41行目**: FindReferencesSearchOptions の設定（非並列、単方向）
- **43-83行目**: FindAsync メソッド - 検索の共通ロジック
- **90-100行目**: GetReferenceCountAsync - 参照数取得
- **198-211行目**: FindReferenceLocationsAsync - 参照位置取得
- **370-384行目**: FindReferenceMethodsAsync - 参照メソッド取得

#### Step 4: 進捗管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CodeLensFindReferenceProgress.cs | `src/Features/Core/Portable/CodeLens/CodeLensFindReferenceProgress.cs` | 検索進捗と上限管理 |

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

```
ICodeLensReferencesService
    │
    └─ CodeLensReferencesService
           │
           ├─ GetReferenceCountAsync()
           │      └─ FindAsync<ReferenceCount>()
           │             └─ SymbolFinder.FindReferencesAsync()
           │                    └─ CodeLensFindReferencesProgress
           │
           ├─ FindReferenceLocationsAsync()
           │      └─ FindAsync<ImmutableArray<ReferenceLocationDescriptor>>()
           │             └─ GetDescriptorOfEnclosingSymbolAsync()
           │
           └─ FindReferenceMethodsAsync()
                  └─ FindAsync<ImmutableArray<ReferenceMethodDescriptor>>()
                         └─ TryGetMethodDescriptorAsync()
```

### データフロー図

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

SyntaxNode ─────────────▶ SemanticModel.GetDeclaredSymbol() ───▶ ISymbol
(宣言ノード)                      │
                                  ▼
Solution ───────────────▶ SymbolFinder.FindReferencesAsync() ──▶ Locations
                                  │
                                  ▼
                    CodeLensFindReferencesProgress ──────────▶ ReferenceCount
                                  │                                   │
                                  ▼                                   ▼
                    GetDescriptorOfEnclosingSymbolAsync() ────▶ ReferenceLocationDescriptor[]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| CodeLensReferencesService.cs | `src/Features/Core/Portable/CodeLens/` | ソース | 参照検索サービス実装 |
| ICodeLensReferencesService.cs | `src/Features/Core/Portable/CodeLens/` | ソース | サービスインターフェース |
| CodeLensFindReferenceProgress.cs | `src/Features/Core/Portable/CodeLens/` | ソース | 検索進捗管理 |
| ReferenceCount.cs | `src/Features/Core/Portable/CodeLens/` | ソース | 参照数データ構造 |
| ReferenceLocationDescriptor.cs | `src/Features/Core/Portable/CodeLens/` | ソース | 参照位置データ構造 |
| ReferenceMethodDescriptor.cs | `src/Features/Core/Portable/CodeLens/` | ソース | 参照メソッドデータ構造 |
| ICodeLensDisplayInfoService.cs | `src/Features/Core/Portable/CodeLens/` | ソース | 表示情報サービス |
| CodeLensReferencesServiceFactory.cs | `src/Features/Core/Portable/CodeLens/` | ソース | サービスファクトリ |
| IRemoteCodeLensReferencesService.cs | `src/Features/Core/Portable/CodeLens/` | ソース | リモートサービスインターフェース |
| CodeLensHelpers.cs | `src/Features/Core/Portable/CodeLens/` | ソース | ヘルパーメソッド |
| LocationComparer.cs | `src/Features/Core/Portable/CodeLens/` | ソース | 位置比較 |
| ICodeLensMemberFinder.cs | `src/Features/Core/Portable/CodeLens/` | ソース | メンバー検索インターフェース |
