# 機能設計書 69-ナビゲーションバー

## 概要

本ドキュメントは、Visual Studio統合におけるF#のナビゲーションバー（ドロップダウンナビゲーション）機能の設計について記述する。この機能は、エディタ上部にドロップダウンリストを表示し、現在のファイル内のモジュール、型、メンバーへの素早いナビゲーションを提供する。

### 本機能の処理概要

**業務上の目的・背景**：
大規模なF#ファイルにおいて、特定の型や関数に素早く移動できることは、開発効率の向上に直結する。本機能により、開発者はスクロールやテキスト検索を行わずに、ファイル内の任意の宣言に即座にジャンプできる。

**機能の利用シーン**：
- ファイル内の特定の関数を探したい場合
- モジュール構造を把握したい場合
- 型定義に素早く移動したい場合
- 現在のカーソル位置がどの宣言内にあるかを確認したい場合

**主要な処理内容**：
1. F#パーサーの構文木から宣言情報を抽出
2. トップレベル宣言（モジュール、型）のリスト生成
3. ネストされた宣言（メンバー、関数）のリスト生成
4. 各宣言のテキストスパンを計算
5. グリフ（アイコン）情報を設定
6. ナビゲーションバーアイテムとして返却

**関連システム・外部連携**：
- Microsoft.CodeAnalysis.ExternalAccess.FSharp.Editor: Roslynナビゲーションバーインターフェース
- FSharp.Compiler.EditorServices.Navigation: F#コンパイラのナビゲーション情報API

**権限による制御**：
特になし。すべてのユーザーがこの機能を利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 専用の設定画面なし |

## 機能種別

コードナビゲーション機能

## 入力仕様

### 入力パラメータ

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

### 入力データソース

- F#パーサーの解析結果（ParseTree）
- ドキュメントのソーステキスト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Items | IList<FSharpNavigationBarItem> | ナビゲーションバー項目のリスト |
| Text | string | 宣言の論理名 |
| Glyph | Glyph | アイコン種別 |
| Spans | TextSpan[] | 宣言のテキストスパン |
| ChildItems | FSharpNavigationBarItem[] | ネストされた宣言 |

### 出力先

Visual Studio エディタ上部のナビゲーションバードロップダウン

## 処理フロー

### 処理シーケンス

```
1. パース結果取得
   └─ GetFSharpParseResultsAsyncでパース結果取得

2. ナビゲーション情報抽出
   └─ Navigation.getNavigationでParseTreeからナビゲーション情報を抽出

3. ソーステキスト取得
   └─ document.GetTextAsync

4. トップレベル宣言処理
   └─ 各宣言についてTextSpan計算とアイテム生成

5. ネスト宣言処理
   └─ 各トップレベル宣言のネストされた宣言を処理

6. 結果返却
   └─ IList<FSharpNavigationBarItem>として返却
```

### フローチャート

```mermaid
flowchart TD
    A[ナビゲーションバー更新リクエスト] --> B[GetFSharpParseResultsAsync]
    B --> C[Navigation.getNavigation]
    C --> D{Declarationsあり?}
    D -->|No| Z[空リスト返却]
    D -->|Yes| E[GetTextAsync]
    E --> F[各トップレベル宣言を処理]
    F --> G[TryFSharpRangeToTextSpan]
    G --> H{変換成功?}
    H -->|No| I[次の宣言]
    I --> F
    H -->|Yes| J[ネスト宣言処理]
    J --> K[NavigationBarSymbolItem生成]
    K --> L[次の宣言]
    L --> F
    F --> M[IList生成]
    M --> N[返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-69-01 | 論理名表示 | 宣言のLogicalNameを表示テキストとして使用 | アイテム生成時 |
| BR-69-02 | Roslynグリフ | RoslynGlyphプロパティでアイコン種別を取得 | アイテム生成時 |
| BR-69-03 | 階層構造 | トップレベル宣言は子項目を持ち、2レベルの階層を表現 | 構造生成時 |
| BR-69-04 | スパン変換失敗スキップ | rangeからTextSpanへの変換に失敗した宣言はスキップ | 変換時 |

### 計算ロジック

該当なし（F#コンパイラのNavigation APIが情報を提供）

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

該当なし（メモリ内解析のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 宣言なし | ファイルに宣言がない | 空リストを返却 |
| - | スパン変換失敗 | rangeをTextSpanに変換できない | 該当宣言をスキップ |

### リトライ仕様

リトライなし。

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

該当なし（読み取り専用操作）

## パフォーマンス要件

- ファイル変更時に迅速に更新
- 大規模ファイルでもUIをブロックしない

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

該当なし

## 備考

- FSharpNavigationBarItemServiceがIFSharpNavigationBarItemServiceを実装
- NavigationBarSymbolItemがFSharpNavigationBarItemを継承
- 2レベルの階層（トップレベル→ネスト）のみサポート

---

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

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

### 推奨読解順序

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

ナビゲーションバーで使用される主要なデータ型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | NavigationBarItemService.fs | `vsintegration/src/FSharp.Editor/Navigation/NavigationBarItemService.fs` | NavigationBarSymbolItem、FSharpNavigationBarItem |

**読解のコツ**:
- NavigationBarSymbolItem（14-15行目）: FSharpNavigationBarItemを継承したカスタム型
- Navigation.getNavigation: F#コンパイラのナビゲーション情報取得API

#### Step 2: エントリーポイントを理解する

IFSharpNavigationBarItemServiceの実装から読み始める。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | NavigationBarItemService.fs | `vsintegration/src/FSharp.Editor/Navigation/NavigationBarItemService.fs` | FSharpNavigationBarItemServiceクラス |

**主要処理フロー**:
1. **17-18行目**: クラス定義とExportアトリビュート
2. **20行目**: 空結果用の定数
3. **22-62行目**: GetItemsAsync実装

#### Step 3: アイテム生成ロジックを理解する

GetItemsAsyncがナビゲーションバーアイテムを生成。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | NavigationBarItemService.fs | `vsintegration/src/FSharp.Editor/Navigation/NavigationBarItemService.fs` | GetItemsAsync実装 |

**主要処理フロー**:
- **23-62行目**: GetItemsAsyncメソッド本体
- **28行目**: GetFSharpParseResultsAsyncでパース結果取得
- **30行目**: Navigation.getNavigationでナビゲーション情報抽出
- **31行目**: GetTextAsyncでソーステキスト取得
- **33-34行目**: rangeToTextSpanヘルパー関数
- **36-37行目**: 宣言がない場合の早期リターン
- **40-59行目**: 宣言のマッピング処理
- **42-50行目**: ネスト宣言の処理
- **52-58行目**: トップレベル宣言の処理

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

```
IFSharpNavigationBarItemService.GetItemsAsync
    │
    ├─ document.GetFSharpParseResultsAsync
    │      └─ ParseResults取得
    │
    ├─ Navigation.getNavigation
    │      └─ parseResults.ParseTree
    │             │
    │             └─ NavigationItems (Declarations[])
    │
    ├─ document.GetTextAsync
    │      └─ SourceText取得
    │
    └─ Declarations処理
           │
           ├─ rangeToTextSpan (ヘルパー)
           │      └─ RoslynHelpers.TryFSharpRangeToTextSpan
           │
           ├─ Array.chooseV (トップレベル)
           │      │
           │      └─ NavigationBarSymbolItem生成
           │             │
           │             ├─ LogicalName
           │             ├─ RoslynGlyph
           │             ├─ TextSpan[]
           │             └─ ChildItems
           │
           └─ Array.chooseV (ネスト)
                  │
                  └─ NavigationBarSymbolItem生成
```

### データフロー図

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

Document ─────────────▶ GetFSharpParseResultsAsync ────┐
                              │                        │
                              ▼                        │
                        ParseResults                   │
                              │                        │
                              ▼                        │
                        Navigation.getNavigation ──────┤
                              │                        │
                              ▼                        │
                        NavigationItems                │
                              │                        │
                              ├─ Declarations          │
                              │      │                 │
                              │      ├─ Declaration    │
                              │      │      └─ Range, LogicalName, RoslynGlyph
                              │      │                 │
                              │      └─ Nested[]       │
                              │             └─ Range, LogicalName, RoslynGlyph
                              │                        │
                              ▼                        ▼
                        IList<FSharpNavigationBarItem> ──▶ ナビゲーションバーUI
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| NavigationBarItemService.fs | `vsintegration/src/FSharp.Editor/Navigation/NavigationBarItemService.fs` | ソース | ナビゲーションバーサービス実装 |
| Navigation.fs | `src/Compiler/Service/ServiceNavigation.fs` | ソース | F#コンパイラのナビゲーションAPI |
| RoslynHelpers.fs | `vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs` | ソース | range→TextSpan変換 |
