# 機能設計書 22-パラメータ情報

## 概要

本ドキュメントは、F#コンパイラサービスが提供するパラメータ情報機能の設計を記述する。この機能は、関数呼び出し時にパラメータのヒント情報を提供し、IDEのシグネチャヘルプ機能を支援する。

### 本機能の処理概要

この機能は、F#ソースコード内のカーソル位置に基づいて、関数呼び出しのパラメータ情報（引数の位置、名前付き引数、タプル引数等）を解析・提供する。

**業務上の目的・背景**：関数やメソッドの呼び出し時に、開発者が正しい引数を入力できるようガイドする。特にF#では、カリー化された関数、タプル引数、名前付き引数、型パラメータなど多様な引数形式があるため、適切なパラメータヒントが生産性向上に重要である。

**機能の利用シーン**：関数名を入力して開き括弧を入力した際のシグネチャヘルプ表示、引数入力中のカンマ区切りでの次パラメータへの移動、名前付き引数入力時のパラメータ名補完、型パラメータ（ジェネリック）入力時のヒント表示で利用される。

**主要な処理内容**：
1. カーソル位置から関数呼び出し式を特定
2. 関数の識別子（長いID）と呼び出し範囲を抽出
3. 引数リストの構造を解析（タプル、単一引数、ユニット等）
4. 各引数の範囲情報と名前付き引数の有無を判定
5. 開き括弧位置、閉じ括弧の有無、カンマ位置を記録
6. ParameterLocationsオブジェクトとして結果を返却

**関連システム・外部連携**：FSharpCheckerを通じてVisual StudioのシグネチャヘルプやLSPのtextDocument/signatureHelpリクエストから呼び出される。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | Visual Studio シグネチャヘルプ | 主画面 | 関数のパラメータ情報をツールチップで表示 |
| - | VS Code パラメータヒント | 主画面 | 関数呼び出し時のパラメータ情報表示 |

## 機能種別

位置解析 / 構造解析

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pos | pos | Yes | カーソル位置（行、列） | 有効な位置情報 |
| parseTree | ParsedInput | Yes | パース済みのF#ソースコード | null不可 |

### 入力データソース

FSharpCheckerによる構文解析結果（ParsedInput）とエディタから取得したカーソル位置情報。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| LongId | string list | 関数の長いID（名前空間を含む） |
| LongIdStartLocation | pos | 関数IDの開始位置 |
| LongIdEndLocation | pos | 関数IDの終了位置 |
| OpenParenLocation | pos | 開き括弧の位置 |
| TupleEndLocations | pos array | 各引数の終了位置（カンマまたは閉じ括弧） |
| IsThereACloseParen | bool | 閉じ括弧が存在するか |
| NamedParamNames | string option array | 名前付き引数の名前（非名前付きはNone） |
| ArgumentLocations | TupledArgumentLocation array | 各引数の詳細位置情報 |

### 出力先

呼び出し元のIDEサービスに返却。シグネチャヘルプ機能で使用される。

## 処理フロー

### 処理シーケンス

```
1. ParameterLocations.Find呼び出し
   └─ traverseInput関数でASTを走査
2. SyntaxTraversal.Traverseで構文木を訪問
   └─ SyntaxVisitorBaseの各メソッドで式を処理
3. 関数呼び出し式（SynExpr.App）を検出
   └─ digOutIdentFromFuncExprで関数識別子を抽出
4. 引数式を解析（searchSynArgExpr）
   └─ タプル、単一引数、ユニット等の形式を判別
5. 名前付き引数の検出（getNamedParamName）
   └─ "arg=value"形式のパターンマッチ
6. ParameterLocationsオブジェクトを構築して返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: ParameterLocations.Find] --> B[traverseInput]
    B --> C[SyntaxTraversal.Traverse]
    C --> D{式の種類を判別}
    D -->|SynExpr.App| E[関数呼び出しを処理]
    D -->|SynExpr.New| F[コンストラクタ呼び出しを処理]
    D -->|SynExpr.TypeApp| G[型アプリケーションを処理]
    D -->|その他| H[defaultTraverse]
    E --> I[digOutIdentFromFuncExpr]
    F --> I
    G --> I
    I --> J[searchSynArgExpr]
    J --> K{引数形式?}
    K -->|タプル| L[各引数の位置を記録]
    K -->|単一引数| M[単一引数として記録]
    K -->|ユニット| N[空の引数として記録]
    L --> O[ParameterLocations生成]
    M --> O
    N --> O
    O --> P[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 位置範囲判定 | カーソル位置が括弧内にある場合のみ結果を返す | 常時 |
| BR-02 | 名前付き引数検出 | "x=value"または"?x=value"形式を名前付き引数として認識 | 引数式がApp形式の場合 |
| BR-03 | インフィックス演算子除外 | 中置演算子は引数情報を返さない | 演算子が中置形式の場合 |
| BR-04 | 静的パラメータ対応 | 型プロバイダの静的パラメータも解析対象 | TypeApp式の場合 |

### 計算ロジック

名前付き引数の検出パターン:
```fsharp
// f(x=4) 形式
SynExpr.App(_, _, SynExpr.App(_, true, SynExpr.LongIdent("op_Equality"), SynExpr.Ident n, _), _, _)

// f(?x=4) 形式（オプション引数）
SynExpr.App(_, _, SynExpr.App(_, true, SynExpr.LongIdent("op_Equality"), SynExpr.LongIdent(true, [n], _, _), _), _, _)
```

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

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

該当なし。本機能はインメモリでの構文木解析のみを行い、データベース操作は発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | None返却 | カーソル位置が関数呼び出しの引数部分にない場合 | 正常動作としてNoneを返す |
| - | None返却 | 構文エラーにより解析不能な場合 | 正常動作としてNoneを返す |

### リトライ仕様

リトライは不要。同期処理で即座に結果を返す。

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

該当なし。読み取り専用の解析処理。

## パフォーマンス要件

- 解析処理はカーソル位置までの構文木走査で完了
- 通常のコード編集では即座に応答（数ミリ秒以内）
- メモリ使用量は最小限（結果オブジェクトのみ）

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

- 信頼されていないコードの構文解析は可能だが、実行は行わない
- ファイルシステムへのアクセスは発生しない
- ネットワーク通信は発生しない

## 備考

- TupledArgumentLocationはIsNamedArgumentフラグとArgumentRangeを持つ
- 静的パラメータ（型プロバイダ）もサポートしており、`TP<42, Arg3=6>`のような形式を解析可能
- 不完全なコード（閉じ括弧がない場合など）でも可能な限り情報を提供する

---

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

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

### 推奨読解順序

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

まず、パラメータ情報機能で使用される主要なデータ型を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | TupledArgumentLocation型（11-15行目）の定義 |
| 1-2 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | ParameterLocations型（17-57行目）の定義とメンバー |

**読解のコツ**: ParameterLocationsクラスが保持する情報（LongId、OpenParenLocation、TupleEndLocations等）を理解することで、IDEがどのような情報を必要としているかがわかる。

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

処理の起点となる関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | ParameterLocations.Find拡張メソッド（419-439行目）がエントリーポイント |
| 2-2 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | traverseInput関数（247-417行目）がメインの解析ロジック |

**主要処理フロー**:
1. **421行目**: traverseInputを呼び出して解析を実行
2. **423-438行目**: デバッグビルド時の範囲検証

#### Step 3: 式の解析処理を理解する

関数呼び出し式の解析方法を追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | VisitExprメソッド（252-379行目）で各種式を処理 |
| 3-2 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | SynExpr.Appの処理（305-341行目）で関数呼び出しを解析 |
| 3-3 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | digOutIdentFromFuncExpr（72-81行目）で関数識別子を抽出 |

**主要処理フロー**:
- **306-308行目**: まず関数式を再帰的に走査
- **314行目**: searchSynArgExprで引数部分を解析
- **319-338行目**: 結果が見つかればParameterLocationsを構築

#### Step 4: 引数解析を理解する

引数リストの解析方法を詳しく追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | searchSynArgExpr関数（150-212行目）の処理フロー |
| 4-2 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | タプル引数の処理（152-175行目） |
| 4-3 | ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | getNamedParamName関数（97-119行目）で名前付き引数を検出 |

**主要処理フロー**:
- **152-175行目**: タプル引数の場合、各要素の範囲と名前付き引数情報を収集
- **185-186行目**: 単一引数の場合、handleSingleArgで処理
- **188-193行目**: ArbitraryAfterError（不完全なコード）の処理
- **195-200行目**: Unit引数の処理

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

```
ParameterLocations.Find(pos, parseTree)
    │
    └─ traverseInput(pos, parseTree)
           │
           └─ SyntaxTraversal.Traverse
                  │
                  ├─ VisitExpr (SynExpr.New)
                  │      └─ searchSynArgExpr
                  │             └─ handleSingleArg
                  │
                  ├─ VisitExpr (SynExpr.App)
                  │      ├─ digOutIdentFromFuncExpr
                  │      └─ searchSynArgExpr
                  │             ├─ タプル引数処理
                  │             ├─ 単一引数処理
                  │             └─ getNamedParamName
                  │
                  ├─ VisitExpr (SynExpr.TypeApp)
                  │      └─ 静的パラメータ処理
                  │
                  ├─ VisitTypeAbbrev
                  │      └─ StaticParametersパターン
                  │
                  └─ VisitImplicitInherit
                         └─ searchSynArgExpr
```

### データフロー図

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

(pos, ParsedInput) ───▶ ParameterLocations.Find ───▶ ParameterLocations option
                              │                              │
                              ├─ AST走査                     ├─ LongId (関数名)
                              ├─ 関数呼び出し検出            ├─ OpenParenLocation
                              ├─ 引数リスト解析              ├─ TupleEndLocations[]
                              └─ 名前付き引数検出            └─ NamedParamNames[]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ServiceParamInfoLocations.fs | `src/Compiler/Service/ServiceParamInfoLocations.fs` | ソース | パラメータ情報機能のメイン実装 |
| SyntaxTree.fs | `src/Compiler/SyntaxTree/SyntaxTree.fs` | ソース | SynExpr等の構文木定義 |
| SyntaxTreeOps.fs | `src/Compiler/SyntaxTree/SyntaxTreeOps.fs` | ソース | 構文木操作ユーティリティ |
| SyntaxTraversal.fs | `src/Compiler/Service/SyntaxTraversal.fs` | ソース | 構文木走査のビジターパターン実装 |
| service.fs | `src/Compiler/Service/service.fs` | ソース | FSharpChecker経由でのパラメータ情報呼び出し |
