# 機能設計書 71-ブレークポイント解決

## 概要

本ドキュメントは、Visual Studio統合におけるF#エディタ用ブレークポイント位置解決機能の設計を記述する。デバッグ時にユーザーが設定したブレークポイントの位置を、F#コードの実行可能な位置に正確にマッピングする機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：デバッグはソフトウェア開発において不可欠な作業であり、開発者がコードの動作を理解し問題を特定するために使用される。F#は関数型プログラミング言語であり、式ベースの構文を持つため、従来の命令型言語とは異なるブレークポイントの設定箇所が存在する。本機能は、ユーザーがVisual Studioでブレークポイントを設定した際に、その位置がF#コードの有効な実行位置であるかを検証し、必要に応じて適切な位置に調整する役割を担う。

**機能の利用シーン**：開発者がVisual StudioでF#コードをデバッグする際、コード上の任意の行にブレークポイントを設定する場面で利用される。設定されたブレークポイントがコメント行や空白行など実行不可能な位置にある場合、本機能が自動的に最も近い有効な位置を特定する。

**主要な処理内容**：
1. ユーザーが指定したテキスト位置からドキュメントとテキストスパンを取得
2. F#パーサーを呼び出して構文解析結果を取得
3. `ValidateBreakpointLocation`メソッドで指定位置が有効なブレークポイント位置かを検証
4. 有効な場合は正確な範囲を返却、無効な場合は`ValueNone`を返却
5. Roslyn座標系とF#コンパイラサービス座標系の変換を行う

**関連システム・外部連携**：Visual StudioのRoslynインフラストラクチャ、F#コンパイラサービス（FSharp.Compiler.Service）、Microsoft.CodeAnalysis.ExternalAccess.FSharpと連携する。

**権限による制御**：本機能に特別な権限制御は存在しない。Visual Studioエディタ内でF#ファイルを開いているすべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 10 | デバッグプロパティページ | 主画面 | デバッグ時の起動アクション、コマンドライン引数、作業ディレクトリ等の設定 |

## 機能種別

デバッグ支援 / コード解析 / 座標変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象となるRoslynドキュメント | null不可 |
| textSpan | TextSpan | Yes | ユーザーが指定したテキスト範囲 | 有効なテキストスパンであること |
| cancellationToken | CancellationToken | Yes | キャンセルトークン | - |

### 入力データソース

- Visual Studioエディタからのドキュメント参照
- ユーザーがクリックした行位置情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| FSharpBreakpointResolutionResult | FSharpBreakpointResolutionResult | 解決されたブレークポイント位置情報を含む結果オブジェクト |

### 出力先

- Visual Studioデバッガーインフラストラクチャへ返却

## 処理フロー

### 処理シーケンス

```
1. ドキュメントからソーステキストを取得
   └─ document.GetTextAsync(ct)を呼び出し
2. テキストスパン開始位置の行位置を算出
   └─ sourceText.Lines.GetLinePosition(textSpan.Start)
3. 行の内容を取得し、空白のみかチェック
   └─ 空白のみの場合はValueNoneを返却
4. Roslyn行番号をFCS行番号に変換
   └─ Line.fromZで0ベースから1ベースへ変換
5. F#パース結果を取得
   └─ document.GetFSharpParseResultsAsync呼び出し
6. ブレークポイント位置の検証
   └─ parseResults.ValidateBreakpointLocationを呼び出し
7. 検証結果をRoslyn座標系に変換
   └─ RoslynHelpers.TryFSharpRangeToTextSpanで変換
8. FSharpBreakpointResolutionResultを生成して返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: ResolveBreakpointAsync] --> B[ソーステキスト取得]
    B --> C[行位置算出]
    C --> D{行が空白のみ?}
    D -->|Yes| E[ValueNone返却]
    D -->|No| F[FCS行番号に変換]
    F --> G[F#パース結果取得]
    G --> H[ValidateBreakpointLocation呼び出し]
    H --> I{有効な位置?}
    I -->|No| E
    I -->|Yes| J[Roslyn座標に変換]
    J --> K{変換成功?}
    K -->|No| E
    K -->|Yes| L[FSharpBreakpointResolutionResult生成]
    L --> M[終了]
    E --> M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-71-01 | 空白行スキップ | 空白のみの行はブレークポイント設定不可 | 対象行が空白文字のみで構成される場合 |
| BR-71-02 | 構文解析依存 | ブレークポイント位置はF#パーサーの解析結果に基づく | 常時 |
| BR-71-03 | 座標系変換 | Roslynの0ベース行番号をFCSの1ベースに変換 | 位置検証前 |

### 計算ロジック

- 行番号変換: `fcsLineNumber = roslynLineNumber + 1`（Line.fromZ関数による）

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効位置 | ブレークポイントを設定できない位置 | ValueNoneを返却し、デフォルト値を使用 |
| - | キャンセル | ユーザーまたはシステムによるキャンセル | CancellationTokenによる処理中断 |

### リトライ仕様

リトライは行わない。キャンセル時は即座に処理を中断する。

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

本機能はトランザクション管理を必要としない読み取り専用処理である。

## パフォーマンス要件

- ユーザーがブレークポイントを設定する際のインタラクティブな応答を妨げないこと
- 非同期処理（CancellableTask）により、UIスレッドをブロックしないこと

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

- 本機能は読み取り専用の解析処理であり、特別なセキュリティ考慮は不要
- ドキュメントアクセスはVisual Studioのアクセス制御に従う

## 備考

- `ResolveBreakpointsAsync`メソッドは完全修飾関数名によるブレークポイント設定機能として将来実装予定（FSROSLYNTODO）
- 現在は空の結果を返却するスタブ実装

---

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

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

### 推奨読解順序

#### Step 1: インターフェース定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IFSharpBreakpointResolutionService | Microsoft.CodeAnalysis.ExternalAccess.FSharp | F#ブレークポイント解決サービスのインターフェース定義 |

**読解のコツ**: このインターフェースはRoslynの外部アクセスAPIの一部であり、Visual StudioがF#固有のブレークポイント解決ロジックを呼び出すための契約を定義している。

#### Step 2: メイン実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | BreakpointResolutionService.fs | `vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs` | ブレークポイント解決の主要ロジック |

**主要処理フロー**:
1. **24-47行目**: `GetBreakpointLocation`静的メソッド - ブレークポイント位置検証の中核ロジック
2. **28-33行目**: ソーステキスト取得と行テキスト抽出
3. **35-36行目**: 空白行チェック
4. **38-39行目**: Roslyn座標系からFCS座標系への変換
5. **41行目**: F#パース結果の非同期取得
6. **43-44行目**: `ValidateBreakpointLocation`による位置検証
7. **49-66行目**: `IFSharpBreakpointResolutionService`インターフェース実装

#### Step 3: 座標変換ヘルパーを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | RoslynHelpers.fs | `vsintegration/src/FSharp.Editor/` | Roslyn/FCS座標変換ユーティリティ |

**主要処理フロー**:
- `TryFSharpRangeToTextSpan`: FCSのRange型をRoslynのTextSpanに変換

#### Step 4: F#コンパイラサービスとの連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ParsedInput.fs | `src/Compiler/Service/` | `ValidateBreakpointLocation`の実装 |

**読解のコツ**: F#コンパイラサービスは、構文木を走査して指定位置が有効なブレークポイント位置かを判定する。式の開始位置、パターンマッチのケース、関数本体など、実行可能なコード位置を識別する。

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

```
Visual Studio Debugger Infrastructure
    │
    └─ IFSharpBreakpointResolutionService.ResolveBreakpointAsync
           │
           ├─ Document.GetTextAsync
           │      └─ SourceText（Roslyn）
           │
           ├─ Document.GetFSharpParseResultsAsync
           │      └─ FSharpParseFileResults（FCS）
           │
           ├─ FSharpParseFileResults.ValidateBreakpointLocation
           │      └─ Range option（FCS）
           │
           └─ RoslynHelpers.TryFSharpRangeToTextSpan
                  └─ TextSpan（Roslyn）
```

### データフロー図

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

Document ──────────────▶ GetTextAsync ─────────────────────▶ SourceText
    │                                                           │
    │                                                           ▼
TextSpan ─────────────▶ GetLinePosition ──────────────────▶ LinePosition
    │                                                           │
    │                                                           ▼
    │                   CheckWhitespace ─────────────────▶ bool (isEmpty)
    │                                                           │
    │                                                           ▼
    └──────────────────▶ GetFSharpParseResultsAsync ──────▶ ParseResults
                               │
                               ▼
                        ValidateBreakpointLocation
                               │
                               ▼
                        TryFSharpRangeToTextSpan
                               │
                               ▼
                        FSharpBreakpointResolutionResult
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| BreakpointResolutionService.fs | `vsintegration/src/FSharp.Editor/Debugging/BreakpointResolutionService.fs` | ソース | ブレークポイント解決サービスの主実装 |
| RoslynHelpers.fs | `vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs` | ソース | Roslyn/FCS座標変換ユーティリティ |
| DocumentExtensions.fs | `vsintegration/src/FSharp.Editor/Common/DocumentExtensions.fs` | ソース | ドキュメント拡張メソッド（GetFSharpParseResultsAsync等） |
| Position.fs | `src/Compiler/Text/Position.fs` | ソース | FCS座標系のPosition型定義 |
| Range.fs | `src/Compiler/Text/Range.fs` | ソース | FCS座標系のRange型定義 |
