# 機能設計書 87-メタデータソース表示

## 概要

本ドキュメントは、Roslyn IDEにおけるメタデータソース表示（Metadata As Source）機能の設計を記載する。この機能は、ソースコードがないアセンブリからシンボルのシグネチャを抽出し、読み取り可能なソースコード形式で表示する。

### 本機能の処理概要

メタデータソース表示機能は、外部アセンブリ（NuGetパッケージ、フレームワークライブラリ等）のシンボルにナビゲーションした際に、そのシンボルのシグネチャやドキュメントコメントをソースコード形式で表示する。逆コンパイルが無効な場合やソースが利用できない場合のフォールバックとして機能する。

**業務上の目的・背景**：開発者は外部ライブラリのAPIを理解するために、シンボルの定義を確認する必要がある。ソースコードがない場合でも、メタデータからシグネチャを抽出してソースコード形式で表示することで、APIの構造を理解しやすくなる。

**機能の利用シーン**：
- 外部ライブラリのクラスやメソッドに「定義へ移動」した場合
- NuGetパッケージのAPIを調査したい場合
- フレームワーククラスのメンバー構成を確認したい場合
- ソースLinkやPDBソースが利用できない場合

**主要な処理内容**：
1. シンボルからメタデータ情報を抽出
2. コード生成APIを使用してシグネチャを構築
3. ドキュメントコメントの変換（XMLからコメント形式）
4. 一時ファイルへの出力とエディタでの表示

**関連システム・外部連携**：
- IDecompiledSourceService（逆コンパイル連携）
- IPdbSourceDocumentLoaderService（PDBソース連携）
- Symbol Server / Source Link

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コードエディタ | 主画面 | 定義へ移動の実行 |
| - | メタデータソースビュー | 結果表示画面 | 生成されたソースの表示 |

## 機能種別

コードナビゲーション / ソース表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| symbol | ISymbol | Yes | 対象シンボル | null不可、Namespace以外 |
| sourceProject | Project | Yes | 元のプロジェクト | null不可 |
| signaturesOnly | bool | No | シグネチャのみモード | - |
| options | MetadataAsSourceOptions | Yes | 表示オプション | - |

### 入力データソース

- アセンブリのメタデータ
- XMLドキュメントコメント
- オプション設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| MetadataAsSourceFile | MetadataAsSourceFile | 生成されたファイル情報 |

### 出力先

一時フォルダ内のソースファイル

## 処理フロー

### 処理シーケンス

```
1. シンボル検証
   └─ Namespace以外、メタデータ位置あり
2. プロバイダー順次処理
   └─ PdbSourceDocument → Decompiled → MetadataAsSource
3. ワークスペース初期化
   └─ MetadataAsSourceWorkspaceを作成/取得
4. ソース生成
   └─ AddSourceToAsyncでドキュメント生成
5. ファイル出力
   └─ 一時フォルダにファイル作成
```

### フローチャート

```mermaid
flowchart TD
    A[定義へ移動実行] --> B[GetGeneratedFileAsync]
    B --> C[シンボル検証]
    C --> D{Namespace?}
    D -->|Yes| E[エラー]
    D -->|No| F[ワークスペース初期化]
    F --> G[古いファイルのクリーンアップ]
    G --> H{各プロバイダー順次処理}
    H --> I[PdbSourceDocumentProvider]
    I --> J{成功?}
    J -->|Yes| K[結果返却]
    J -->|No| L[DecompiledSourceProvider]
    L --> M{成功?}
    M -->|Yes| K
    M -->|No| N[MetadataAsSourceProvider]
    N --> O[AddSourceToAsync]
    O --> P[ドキュメント生成]
    P --> Q[フォーマット]
    Q --> R[Simplify]
    R --> S[ファイル書き込み]
    S --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | シンボル制限 | Namespace以外のシンボルが対象 | ナビゲーション対象 |
| BR-02 | プロバイダー優先順位 | ExtensionOrderer順でプロバイダー実行 | 最初に成功したものを使用 |
| BR-03 | ファイルキャッシュ | 同一シンボルは再生成しない | 既存ファイルを再利用 |
| BR-04 | クリーンアップ | 他VSインスタンスの古いファイルを削除 | Mutexで判定 |

### 計算ロジック

ファイルパスは`[TEMP]/MetadataAsSource/[GUID]/[プロバイダー名]/[シンボル名].cs`形式

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ArgumentException | Namespaceシンボル指定 | 例外をスロー |
| - | ファイル書き込み失敗 | ディスク容量不足等 | 次のプロバイダーを試行 |

### リトライ仕様

プロバイダー失敗時は次のプロバイダーを試行

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

なし

## パフォーマンス要件

- ソース生成は2秒以内
- キャッシュ利用時は即座に表示

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

- 一時ファイルは読み取り専用に設定
- テレメトリ送信（匿名化）

## 備考

- 折りたたみ設定はBlockStructureOptionsで制御
- SymbolMappingで元プロジェクトとの対応を維持

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | MetadataAsSourceFile.cs | `src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFile.cs` | 生成ファイル情報の構造 |
| 1-2 | MetadataAsSourceOptions.cs | `src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceOptions.cs` | オプション設定 |

**読解のコツ**: MetadataAsSourceFileはファイルパスとナビゲーション位置を保持する。

#### Step 2: サービスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | IMetadataAsSourceFileService.cs | `src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceFileService.cs` | サービスインターフェース |
| 2-2 | MetadataAsSourceFileService.cs | `src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFileService.cs` | サービス実装 |

**主要処理フロー**:
- **71-117行目**: GetGeneratedFileAsyncで生成処理
- **88行目**: GetOriginalUnreducedDefinitionでシンボル正規化
- **90-114行目**: プロバイダーを順次処理
- **119-159行目**: CleanupGeneratedFilesで古いファイル削除

#### Step 3: ソース生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractMetadataAsSourceService.cs | `src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs` | ソース生成の中核 |

**主要処理フロー**:
- **21-65行目**: AddSourceToAsyncでソース追加
- **32-39行目**: CodeGenerationContextの構築
- **42-46行目**: CodeGenerator.AddNamespaceOrTypeDeclarationAsync
- **48行目**: AddNullableRegionsAsync
- **51行目**: ConvertDocCommentsToRegularCommentsAsync
- **56-61行目**: Formatter.FormatAsync
- **64行目**: Simplifier.ReduceAsync

#### Step 4: プロバイダーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | IMetadataAsSourceFileProvider.cs | `src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceFileProvider.cs` | プロバイダーインターフェース |

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

```
MetadataAsSourceFileService.GetGeneratedFileAsync
    │
    ├─ ワークスペース初期化
    │      └─ MetadataAsSourceWorkspace (new)
    │
    ├─ CleanupGeneratedFiles
    │      └─ Mutex判定で古いフォルダ削除
    │
    └─ foreach (IMetadataAsSourceFileProvider)
           │
           ├─ PdbSourceDocumentProvider
           │      └─ IPdbSourceDocumentLoaderService
           │
           ├─ DecompiledSourceProvider
           │      └─ IDecompiledSourceService
           │
           └─ MetadataAsSourceProvider (フォールバック)
                  └─ AbstractMetadataAsSourceService.AddSourceToAsync
                         ├─ CodeGenerator.AddNamespaceOrTypeDeclarationAsync
                         ├─ AddNullableRegionsAsync
                         ├─ ConvertDocCommentsToRegularCommentsAsync
                         ├─ Formatter.FormatAsync
                         └─ Simplifier.ReduceAsync
```

### データフロー図

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

ISymbol ─────────▶ GetGeneratedFileAsync
                        │
                        ▼
MetadataAsSourceOptions ──▶ プロバイダー選択
                        │
                        ├─ PdbSourceDocumentProvider ──▶ (PDBソース)
                        │
                        ├─ DecompiledSourceProvider ──▶ (逆コンパイル)
                        │
                        └─ AbstractMetadataAsSourceService
                               │
                               ▼
Compilation ────────▶ CodeGenerator ──▶ Document
                               │
                               ▼
                        Formatter/Simplifier
                               │
                               ▼
                        ファイル書き込み ──▶ MetadataAsSourceFile
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IMetadataAsSourceFileService.cs | `src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceFileService.cs` | ソース | サービスインターフェース |
| MetadataAsSourceFileService.cs | `src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFileService.cs` | ソース | サービス実装 |
| IMetadataAsSourceService.cs | `src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceService.cs` | ソース | ソース生成インターフェース |
| AbstractMetadataAsSourceService.cs | `src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs` | ソース | ソース生成基底クラス |
| IMetadataAsSourceFileProvider.cs | `src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceFileProvider.cs` | ソース | プロバイダーインターフェース |
| MetadataAsSourceFile.cs | `src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceFile.cs` | ソース | 生成ファイル情報 |
| MetadataAsSourceOptions.cs | `src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceOptions.cs` | ソース | オプション設定 |
| MetadataAsSourceWorkspace.cs | `src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceWorkspace.cs` | ソース | 専用ワークスペース |
| MetadataAsSourceHelpers.cs | `src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceHelpers.cs` | ソース | ヘルパー関数 |
| WrappedNamedTypeSymbol.cs | `src/Features/Core/Portable/MetadataAsSource/WrappedNamedTypeSymbol.cs` | ソース | シンボルラッパー |
| WrappedMethodSymbol.cs | `src/Features/Core/Portable/MetadataAsSource/WrappedMethodSymbol.cs` | ソース | メソッドラッパー |
