# 機能設計書 63-シグネチャヘルプ

## 概要

本ドキュメントは、Visual Studio統合におけるF#のシグネチャヘルプ（関数シグネチャ表示）機能の設計について記述する。この機能は、関数呼び出しやメソッド呼び出し時に、引数の型情報やパラメータ名をインラインで表示し、現在入力中の引数をハイライトする。

### 本機能の処理概要

**業務上の目的・背景**：
F#では関数のカリー化やオーバーロード、オプション引数など複雑な引数パターンが存在する。本機能により、開発者は関数呼び出し時に正しい引数の型と順序を即座に確認でき、型エラーを未然に防ぐことができる。

**機能の利用シーン**：
- 関数呼び出し時に括弧を入力した直後
- メソッド呼び出しでカンマを入力して次の引数に移った場合
- スペースキーを押してF#関数適用を開始した場合
- 型プロバイダの静的パラメータを入力する場合

**主要な処理内容**：
1. トリガー文字（`(`、`<`、`,`、` `）の検出
2. カーソル位置のコンテキスト分析（メソッド呼び出し vs 関数適用）
3. パラメータ位置情報の解析
4. 該当メソッド/関数のシグネチャ情報取得
5. 現在の引数インデックスの計算
6. シグネチャヘルプアイテムの生成と表示

**関連システム・外部連携**：
- Microsoft.CodeAnalysis.ExternalAccess.FSharp.SignatureHelp: Roslynシグネチャヘルプインターフェース
- FSharp.Compiler.EditorServices: F#コンパイラのパラメータ位置API
- XMLドキュメントサービス: パラメータドキュメント取得

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

## 関連画面

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

## 機能種別

入力支援・情報表示機能

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象のドキュメント | null不可 |
| position | int | Yes | カーソル位置（文字オフセット） | 0以上、ドキュメント長未満 |
| triggerInfo | FSharpSignatureHelpTriggerInfo | Yes | トリガー情報（文字、理由） | null不可 |

### 入力データソース

- Visual Studioエディタのカーソル位置
- トリガー文字（`(`、`<`、`,`、` `）
- F#コンパイラサービスの解析結果

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SignatureHelpItems | FSharpSignatureHelpItems | シグネチャヘルプ項目のコレクション |
| ApplicableSpan | TextSpan | 適用範囲のテキストスパン |
| ArgumentIndex | int | 現在の引数インデックス |
| ArgumentCount | int | 総引数数 |
| ArgumentName | string | 名前付き引数の名前（該当する場合） |

### 出力先

Visual Studio エディタ上のシグネチャヘルプUI

## 処理フロー

### 処理シーケンス

```
1. トリガー検出
   └─ IsTriggerCharacter / IsRetriggerCharacterで判定

2. 解析結果の取得
   └─ GetFSharpParseAndCheckResultsAsyncで解析結果取得

3. コンテキスト判定
   └─ トリガー文字とカーソル位置からメソッド呼び出しか関数適用かを判定

4. パラメータ情報取得
   └─ メソッド: FindParameterLocations + GetMethods
   └─ 関数: GetAllArgumentsForFunctionApplicationAtPosition

5. 引数インデックス計算
   └─ カーソル位置から現在の引数位置を特定

6. シグネチャヘルプアイテム構築
   └─ パラメータ情報からFSharpSignatureHelpItemを生成

7. 結果返却
   └─ FSharpSignatureHelpItemsとして返却
```

### フローチャート

```mermaid
flowchart TD
    A[トリガー検出] --> B{トリガー文字?}
    B -->|No| Z[null返却]
    B -->|Yes| C[解析結果取得]
    C --> D{スペース + 関数適用?}
    D -->|Yes| E[ProvideParametersAsyncAux]
    D -->|No| F[FindParameterLocations]
    F --> G{パラメータ位置あり?}
    G -->|No| Z
    G -->|Yes| H[ProvideMethodsAsyncAux]
    E --> I{シグネチャあり?}
    H --> I
    I -->|No| Z
    I -->|Yes| J[FSharpSignatureHelpItems生成]
    J --> K[返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-63-01 | メソッド呼び出し vs 関数適用 | スペースキーかつ調整位置がカンマ/括弧でない場合は関数適用として処理 | トリガー判定時 |
| BR-63-02 | 静的パラメータ検出 | 開き括弧が`<`の場合は型プロバイダの静的パラメータとして処理 | パラメータ解析時 |
| BR-63-03 | パイプライン考慮 | パイプライン演算子経由の引数は引数インデックスからオフセット | 関数適用時 |
| BR-63-04 | 不正位置除外 | カンマや括弧が実際の検出位置と異なる場合はヘルプ非表示 | トリガー検証時 |

### 計算ロジック

引数インデックスの計算（169-185行目）：
- tupleEndsからカーソル位置を含むTextSpanを探索
- 最後のTextSpan終端にカーソルがある場合は末尾インデックス

引数カウントの計算（187-190行目）：
- TupleEndLocationsの長さを基本に、開き括弧直後の場合は0

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | メソッド不在 | GetMethodsが空を返す | nullを返却 |
| - | パラメータなし | HasParameters=falseのメソッドのみ | nullを返却 |
| - | 位置不正 | トリガー位置が実際の引数位置と不一致 | nullを返却 |

### リトライ仕様

リトライなし。エラー発生時はシグネチャヘルプを表示しない。

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

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

## パフォーマンス要件

- トリガー文字入力から即座に表示
- 非同期処理によりUIスレッドをブロックしない

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

該当なし

## 備考

- CurrentSignatureHelpSessionKind（FunctionApplication/MethodCall）で現在のセッション種別を追跡
- 同一セッション内での再トリガー時は前回の種別を考慮して処理を分岐

---

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

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

### 推奨読解順序

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

シグネチャヘルプで使用される主要なデータ型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SignatureHelp.fs | `vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs` | SignatureHelpParameterInfo、SignatureHelpItem、SignatureHelpData型 |

**読解のコツ**:
- SignatureHelpParameterInfo（25-32行目）: 各パラメータの情報
- SignatureHelpItem（34-43行目）: 1つのオーバーロードの情報
- SignatureHelpData（49-57行目）: 全体のシグネチャヘルプ情報
- CurrentSignatureHelpSessionKind（45-47行目）: セッション種別

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

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

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

**主要処理フロー**:
1. **59-64行目**: FSharpSignatureHelpProviderクラスの定義
2. **708-712行目**: IsTriggerCharacter / IsRetriggerCharacterの実装
3. **714-788行目**: GetItemsAsyncメソッドの実装

#### Step 3: メソッド呼び出し用ロジックを理解する

ProvideMethodsAsyncAuxがメソッド呼び出しのシグネチャヘルプを提供。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SignatureHelp.fs | `vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs` | ProvideMethodsAsyncAux関数 |

**主要処理フロー**:
- **73-284行目**: ProvideMethodsAsyncAux静的メソッド
- **90-91行目**: GetMethodsでメソッドグループ取得
- **97-101行目**: 静的パラメータ（型プロバイダ）の検出
- **103-113行目**: フィルタリング処理
- **169-185行目**: argumentIndex計算
- **199-271行目**: SignatureHelpItem構築

#### Step 4: 関数適用用ロジックを理解する

ProvideParametersAsyncAuxがF#関数適用のシグネチャヘルプを提供。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | SignatureHelp.fs | `vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs` | ProvideParametersAsyncAux関数 |

**主要処理フロー**:
- **286-603行目**: ProvideParametersAsyncAux静的メソッド
- **321-334行目**: レキサーシンボル取得
- **336-342行目**: GetSymbolUseAtLocationでシンボル使用取得
- **350行目**: FSharpMemberOrFunctionOrValueへのパターンマッチ
- **364-370行目**: パイプライン経由の引数数計算
- **404-425行目**: 引数インデックス計算（複雑なロジック）
- **450-556行目**: パラメータ表示部品の構築

#### Step 5: 統合ロジックを理解する

ProvideSignatureHelpが両方のパターンを統合。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | SignatureHelp.fs | `vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs` | ProvideSignatureHelp関数 |

**主要処理フロー**:
- **605-706行目**: ProvideSignatureHelp静的メソッド
- **631-643行目**: adjustedColumnInSource計算
- **647-690行目**: コンテキストに応じた分岐
- **651-670行目**: スペーストリガーかつ関数適用パターン
- **691-705行目**: メソッド呼び出しパターン

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

```
FSharpSignatureHelpProvider.GetItemsAsync
    │
    └─ ProvideSignatureHelp
           │
           ├─ document.GetFSharpParseAndCheckResultsAsync
           │
           ├─ [スペース + 関数適用の場合]
           │      └─ ProvideParametersAsyncAux
           │             ├─ parseResults.IsPosContainedInApplication
           │             ├─ Tokenizer.getSymbolAtPosition
           │             ├─ checkFileResults.GetSymbolUseAtLocation
           │             ├─ checkFileResults.GetToolTip
           │             └─ XmlDocumentation.BuildDataTipText
           │
           └─ [メソッド呼び出しの場合]
                  └─ ProvideMethodsAsyncAux
                         ├─ parseResults.FindParameterLocations
                         ├─ checkFileResults.GetMethods
                         └─ XmlDocumentation.BuildMethodOverloadTipText
```

### データフロー図

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

TriggerCharacter ───────▶ IsTriggerCharacter ────┐
                                                 │
Document + Position ────▶ ProvideSignatureHelp ──┤
                              │                  │
                              ├─ [Function]      │
                              │   ProvideParams  │
                              │                  │
                              └─ [Method]        │
                                  ProvideMethods │
                                                 ▼
                                         SignatureHelpData
                                                 │
                                                 ▼
                                    FSharpSignatureHelpItems
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SignatureHelp.fs | `vsintegration/src/FSharp.Editor/Completion/SignatureHelp.fs` | ソース | シグネチャヘルプサービスの実装 |
| XmlDocumentation.fs | `vsintegration/src/FSharp.Editor/Common/XmlDocumentation.fs` | ソース | XMLドキュメント処理 |
| Tokenizer.fs | `vsintegration/src/FSharp.Editor/Common/Tokenizer.fs` | ソース | トークン化・シンボル取得 |
| RoslynHelpers.fs | `vsintegration/src/FSharp.Editor/Common/RoslynHelpers.fs` | ソース | Roslyn型変換・TaggedText処理 |
