# 機能設計書 78-コード構造

## 概要

本ドキュメントは、Roslynのコード構造（Structure）機能の設計を記載する。この機能は、コードのアウトライン表示と折りたたみ機能を提供し、開発者がコードの全体構造を把握しながら必要な部分に集中できるようにする。

### 本機能の処理概要

**業務上の目的・背景**：大規模なソースファイルでは、数百行から数千行のコードが含まれることがある。全てのコードを常に表示していると、全体像を把握することが困難になる。コード構造機能は、名前空間、クラス、メソッド、コメント、リージョンなどのコードブロックを折りたたみ可能な領域として識別し、開発者が必要に応じて展開/折りたたみを行えるようにする。これにより、コードのナビゲーションと理解が大幅に向上する。

**機能の利用シーン**：
1. エディタでコードファイルを開いたときの自動アウトライン生成
2. 「定義に折りたたむ」コマンドの実行
3. 個別のコードブロックの展開/折りたたみ
4. ドキュメントアウトラインビューでの構造表示

**主要な処理内容**：
1. ドキュメント内の折りたたみ可能領域（BlockSpan）の検出
2. 各ブロックの種類（Type, Member, Statement等）の分類
3. ヒントテキスト（ホバー時のプレビュー）の生成
4. バナーテキスト（折りたたみ時の表示テキスト）の設定
5. 自動折りたたみ設定の適用

**関連システム・外部連携**：Visual Studioエディタ、Language Server Protocol (LSP)、エディタの折りたたみマージン、ドキュメントアウトラインビューと連携する。

**権限による制御**：特になし。全ユーザーが利用可能な標準機能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | ドキュメントアウトラインビュー | 主機能 | ドキュメント内のシンボル構造のツリー表示・検索・ソート |

## 機能種別

エディタ支援機能（構造可視化・ナビゲーション）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象ドキュメント | null不可 |
| options | BlockStructureOptions | Yes | 構造オプション | - |
| cancellationToken | CancellationToken | No | キャンセルトークン | - |

### 入力データソース

- ドキュメントの構文木
- BlockStructureOptions設定

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Spans | ImmutableArray<BlockSpan> | 折りたたみ可能領域のコレクション |

### 出力先

- BlockStructure構造体として返却
- エディタの折りたたみマージン

## 処理フロー

### 処理シーケンス

```
1. サービスの取得
   └─ BlockStructureServiceを言語に応じて取得
2. プロバイダーによる構造取得
   └─ 各BlockStructureProviderでブロックを収集
3. BlockSpanの生成
   ├─ TextSpan: 折りたたみ対象のテキスト範囲
   ├─ HintSpan: ホバープレビューのテキスト範囲
   ├─ Type: ブロック種別（Type, Member等）
   ├─ BannerText: 折りたたみ時の表示テキスト（"..."等）
   ├─ IsCollapsible: 折りたたみ可能か
   ├─ AutoCollapse: 「定義に折りたたむ」対象か
   └─ IsDefaultCollapsed: デフォルトで折りたたむか
4. 結果返却
   └─ BlockStructureとして返却
```

### フローチャート

```mermaid
flowchart TD
    A[GetBlockStructureAsync開始] --> B[構文木取得]
    B --> C[プロバイダー呼び出し]
    C --> D{次のプロバイダーあり?}
    D -->|No| E[BlockStructure生成]
    D -->|Yes| F[CollectBlockSpans実行]
    F --> G[BlockSpanをコレクションに追加]
    G --> D
    E --> H[結果返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-78-1 | ブロック種別分類 | 各ブロックはType, Member, Statement, Expression等に分類 | 常時 |
| BR-78-2 | コメント/リージョン特別扱い | コメントとリージョンは個別の折りたたみ設定を持つ | コメント/リージョン |
| BR-78-3 | 重複ブロック除外 | 同一行範囲の重複ブロックは内側のみ保持 | 重複検出時 |
| BR-78-4 | 自動折りたたみ | AutoCollapseがtrueのブロックは「定義に折りたたむ」対象 | コマンド実行時 |
| BR-78-5 | デフォルト折りたたみ | IsDefaultCollapsedがtrueのブロックは初期表示で折りたたみ | ファイルオープン時 |

### 計算ロジック

ブロック種別判定:
- BlockTypes.Type: クラス、構造体、インターフェース等
- BlockTypes.Member: メソッド、プロパティ、フィールド等
- BlockTypes.Statement: if文、for文、switch文等
- BlockTypes.Expression: ラムダ式、オブジェクト初期化子等
- BlockTypes.Comment: コメントブロック
- BlockTypes.PreprocessorRegion: #region/#endregion

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

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

データベース操作なし。メモリ上のドキュメントモデルに対する読み取り操作のみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | CancellationException | ユーザーがキャンセル | 処理中断 |

### リトライ仕様

リトライなし。失敗時は空のBlockStructureを返却。

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

トランザクションなし。読み取り専用操作。

## パフォーマンス要件

- ファイルオープン時に素早く構造を計算
- 増分更新により変更箇所のみ再計算
- 大規模ファイルでもスムーズに動作

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

特になし。ローカルの読み取り専用操作のみ。

## 備考

- C#とVisual Basicの両言語で利用可能
- 言語固有のプロバイダーが構文ノードの種類に応じたブロックを生成
- LSPのFoldingRangeリクエストで使用される

---

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

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

### 推奨読解順序

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

まず、コード構造機能で使用されるデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | BlockSpan.cs | `src/Features/Core/Portable/Structure/BlockSpan.cs` | 折りたたみ領域を表す構造体 |
| 1-2 | BlockStructure.cs | `src/Features/Core/Portable/Structure/BlockStructure.cs` | BlockSpanのコレクションを保持するクラス |
| 1-3 | BlockTypes.cs | `src/Features/Core/Portable/Structure/BlockTypes.cs` | ブロック種別の定義 |

**読解のコツ**:
- **BlockSpan.cs 10-18行目**: プライマリコンストラクタで主要プロパティを定義
- **BlockSpan.cs 25-74行目**: 各プロパティの説明（IsCollapsible, TextSpan, HintSpan等）
- **BlockTypes.cs 9-27行目**: ブロック種別の定数定義

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BlockStructureService.cs | `src/Features/Core/Portable/Structure/BlockStructureService.cs` | サービス抽象クラス |
| 2-2 | BlockStructureServiceWithProviders.cs | `src/Features/Core/Portable/Structure/BlockStructureServiceWithProviders.cs` | プロバイダーベースの実装 |

**主要処理フロー**:
- **BlockStructureService.cs 19-20行目**: GetServiceでドキュメントからサービスを取得
- **BlockStructureService.cs 27行目**: GetBlockStructureAsyncで構造を非同期取得

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | BlockStructureProvider.cs | `src/Features/Core/Portable/Structure/BlockStructureProvider.cs` | プロバイダー基底クラス |
| 3-2 | BlockStructureContext.cs | `src/Features/Core/Portable/Structure/BlockStructureContext.cs` | プロバイダーコンテキスト |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AbstractBlockStructureProvider.cs | `src/Features/Core/Portable/Structure/Syntax/AbstractBlockStructureProvider.cs` | 構文ベースのプロバイダー |
| 4-2 | AbstractSyntaxNodeStructureProvider.cs | `src/Features/Core/Portable/Structure/Syntax/AbstractSyntaxNodeStructureProvider.cs` | ノードベースのプロバイダー |
| 4-3 | BlockSpanCollector.cs | `src/Features/Core/Portable/Structure/Syntax/BlockSpanCollector.cs` | ブロック収集ロジック |

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

```
エディタ（ファイルオープン/スクロール）
    │
    └─ BlockStructureService.GetBlockStructureAsync
           │
           ├─ Document.GetSyntaxRootAsync
           │
           └─ BlockStructureProvider.ProvideBlockStructureAsync
                  │
                  ├─ BlockSpanCollector.CollectBlockSpans
                  │      │
                  │      ├─ AbstractSyntaxNodeStructureProvider
                  │      │      └─ 構文ノードからBlockSpan生成
                  │      │
                  │      └─ AbstractSyntaxTriviaStructureProvider
                  │             └─ コメント/リージョンからBlockSpan生成
                  │
                  └─ BlockStructure生成
```

### データフロー図

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

Document        ───▶ GetBlockStructureAsync      ───▶ BlockStructure
Options         ───▶                                   └─ ImmutableArray<BlockSpan>
                      │                                       ├─ TextSpan
                      ├─ 構文木解析                            ├─ HintSpan
                      │                                       ├─ Type
                      ├─ プロバイダー呼び出し                   ├─ BannerText
                      │                                       ├─ IsCollapsible
                      └─ BlockSpan収集                         ├─ AutoCollapse
                                                              └─ IsDefaultCollapsed
                                                         │
                                                         ▼
                                                  エディタ折りたたみマージン
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BlockStructureService.cs | `src/Features/Core/Portable/Structure/` | サービス | サービス抽象クラス |
| BlockStructureServiceWithProviders.cs | `src/Features/Core/Portable/Structure/` | 実装 | プロバイダーベース実装 |
| BlockStructure.cs | `src/Features/Core/Portable/Structure/` | データ型 | BlockSpanコレクション |
| BlockSpan.cs | `src/Features/Core/Portable/Structure/` | データ型 | 折りたたみ領域情報 |
| BlockTypes.cs | `src/Features/Core/Portable/Structure/` | 定数 | ブロック種別定義 |
| BlockStructureOptions.cs | `src/Features/Core/Portable/Structure/` | オプション | 構造オプション設定 |
| BlockStructureProvider.cs | `src/Features/Core/Portable/Structure/` | プロバイダー | プロバイダー基底クラス |
| BlockStructureContext.cs | `src/Features/Core/Portable/Structure/` | コンテキスト | プロバイダーコンテキスト |
| AbstractBlockStructureProvider.cs | `src/Features/Core/Portable/Structure/Syntax/` | 抽象クラス | 構文ベースプロバイダー |
| AbstractSyntaxNodeStructureProvider.cs | `src/Features/Core/Portable/Structure/Syntax/` | 抽象クラス | ノードベースプロバイダー |
| AbstractSyntaxTriviaStructureProvider.cs | `src/Features/Core/Portable/Structure/Syntax/` | 抽象クラス | トリビアベースプロバイダー |
| AbstractSyntaxStructureProvider.cs | `src/Features/Core/Portable/Structure/Syntax/` | 抽象クラス | 構文プロバイダー基底 |
| BlockSpanCollector.cs | `src/Features/Core/Portable/Structure/Syntax/` | ユーティリティ | ブロック収集ロジック |
| BlockStructureExtensions.cs | `src/Features/Core/Portable/Structure/Syntax/` | 拡張 | 拡張メソッド |
