# 機能設計書 25-言語機能ハンドラ

## 概要

本ドキュメントは、F# Language Serverにおける言語機能ハンドラの設計を記述する。この機能は、LSPの言語機能リクエスト（補完、定義ジャンプ、診断等）を処理し、F#固有の言語機能を提供する。

### 本機能の処理概要

LSPプロトコルのtextDocument/diagnostic、textDocument/semanticTokens/fullなどの言語機能リクエストを処理し、F#コンパイラサービスの解析結果をLSP形式に変換して返却する。

**業務上の目的・背景**：エディタ上でのF#開発支援機能（エラー表示、構文ハイライト、コード補完等）を提供する。これらの機能により、開発者はリアルタイムでコードの問題を検出し、効率的にコードを記述できる。

**機能の利用シーン**：コード編集中の構文エラー・型エラーの表示、セマンティックハイライトによるコードの視覚的理解支援、コード補完によるコーディング支援で利用される。

**主要な処理内容**：
1. textDocument/diagnosticリクエストの処理（診断情報の取得と変換）
2. textDocument/semanticTokens/fullリクエストの処理（セマンティックトークンの取得）
3. FSharpWorkspace.Queryを通じたコンパイラサービスへの問い合わせ
4. 結果のLSP形式への変換

**関連システム・外部連携**：FSharpWorkspace、FSharpChecker、LSPクライアント。

**権限による制御**：特になし。すべての言語機能が利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エディタの問題パネル | 結果表示画面 | 診断結果の表示 |
| - | エディタのテキスト領域 | 主画面 | セマンティックハイライト、エラー下線表示 |

## 機能種別

解析結果提供 / データ変換

## 入力仕様

### 入力パラメータ

#### textDocument/diagnostic

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| TextDocument.Uri | DocumentUri | Yes | 診断対象ドキュメントのURI | 有効なURI形式 |

#### textDocument/semanticTokens/full

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| TextDocument.Uri | DocumentUri | Yes | トークン取得対象ドキュメントのURI | 有効なURI形式 |

### 入力データソース

LSPクライアントからのJSON-RPCリクエストメッセージ。

## 出力仕様

### 出力データ

#### textDocument/diagnostic

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Items | Diagnostic[] | 診断項目の配列 |
| ResultId | string | 結果の識別子（差分計算用） |
| RelatedDocuments | Dictionary | 関連ドキュメントの診断情報 |

#### textDocument/semanticTokens/full

| 項目名 | 型 | 説明 |
|--------|-----|------|
| Data | int[] | エンコードされたセマンティックトークン配列 |

### 出力先

LSPクライアントへのJSON-RPCレスポンス。

## 処理フロー

### 処理シーケンス

```
1. LSPクライアントからリクエストを受信
   └─ Methods.TextDocumentDiagnosticName等
2. CancellableTaskでキャンセル可能な非同期処理を開始
3. FSharpRequestContextからワークスペースにアクセス
4. Queryメソッドで解析結果を取得
   └─ GetDiagnosticsForFile / GetSemanticTokensForFile
5. 結果をLSP形式に変換
   └─ ToLspDiagnostic等
6. レスポンスを構築して返却
```

### フローチャート

```mermaid
flowchart TD
    A[開始: LSPリクエスト受信] --> B{リクエストの種類}
    B -->|diagnostic| C[HandleRequestAsync - diagnostic]
    B -->|semanticTokens| D[HandleRequestAsync - semanticTokens]
    C --> E[cancellableTask開始]
    D --> E
    E --> F[Workspace.Queryでデータ取得]
    F --> G{データ種別}
    G -->|diagnostic| H[GetDiagnosticsForFile]
    G -->|semanticTokens| I[GetSemanticTokensForFile]
    H --> J[ToLspDiagnostic変換]
    I --> K[SemanticTokens構築]
    J --> L[RelatedFullDocumentDiagnosticReport構築]
    K --> M[SemanticTokensレスポンス]
    L --> N[レスポンス返却]
    M --> N
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | MutatesSolutionState | 言語機能ハンドラはソリューション状態を変更しない（読み取り専用） | 常時 |
| BR-02 | キャンセル対応 | 長時間の解析処理はCancellationTokenでキャンセル可能 | 非同期処理時 |
| BR-03 | 結果ID管理 | 診断結果にはResultIdを付与し差分計算に使用 | diagnostic時 |
| BR-04 | RelatedDocuments | 対象ドキュメントの診断情報をRelatedDocumentsに含める | diagnostic時 |

### 計算ロジック

セマンティックトークンのエンコーディング（LSP仕様）:
- 各トークンは5つの整数で表現: deltaLine, deltaStartChar, length, tokenType, tokenModifiers
- 前のトークンからの相対位置で表現

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | OperationCanceledException | リクエストがキャンセルされた場合 | キャンセルレスポンスを返却 |
| - | FileNotFoundException | 対象ファイルが存在しない場合 | 空の結果を返却 |

### リトライ仕様

クライアント側で必要に応じてリトライ。サーバー側でのリトライは不要。

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

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

## パフォーマンス要件

- 診断リクエストは数秒以内に応答（ファイルサイズに依存）
- セマンティックトークンは1秒以内に応答
- キャンセル処理は即座に応答

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

- 解析結果はメモリ上で処理
- 外部への通信は発生しない
- 機密情報は診断メッセージに含まれる可能性あり（ローカル環境のため問題なし）

## 備考

- CancellableTasksを使用した非同期処理
- Microsoft.VisualStudio.FSharp.Editorとの統合
- 将来的にはより多くのLSP言語機能（補完、定義ジャンプ等）を実装予定

---

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

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

### 推奨読解順序

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

まず、LanguageFeaturesHandlerが実装するインターフェースを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | LanguageFeaturesHandler.fs | `src/FSharp.Compiler.LanguageServer/Handlers/LanguageFeaturesHandler.fs` | IMethodHandler実装（15-17行目） |
| 1-2 | LanguageFeaturesHandler.fs | `src/FSharp.Compiler.LanguageServer/Handlers/LanguageFeaturesHandler.fs` | IRequestHandler実装（19-59行目） |

**読解のコツ**: MutatesSolutionState = falseに注目。このハンドラは読み取り専用であることを宣言している。

#### Step 2: 診断処理を理解する

診断リクエストの処理フローを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | LanguageFeaturesHandler.fs | `src/FSharp.Compiler.LanguageServer/Handlers/LanguageFeaturesHandler.fs` | diagnostic処理（19-50行目） |
| 2-2 | LanguageFeaturesHandler.fs | `src/FSharp.Compiler.LanguageServer/Handlers/LanguageFeaturesHandler.fs` | cancellableTaskの使用（28-49行目） |

**主要処理フロー**:
1. **24行目**: LanguageServerEndpoint属性でLSPメソッド名を指定
2. **28行目**: cancellableTask計算式で非同期処理を開始
3. **30行目**: GetDiagnosticsForFileで診断情報を取得
4. **32-36行目**: FullDocumentDiagnosticReportを構築
5. **38-47行目**: RelatedFullDocumentDiagnosticReportを構築

#### Step 3: セマンティックトークン処理を理解する

セマンティックトークンリクエストの処理フローを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | LanguageFeaturesHandler.fs | `src/FSharp.Compiler.LanguageServer/Handlers/LanguageFeaturesHandler.fs` | semanticTokens処理（52-59行目） |

**主要処理フロー**:
1. **53行目**: LanguageServerEndpoint属性でLSPメソッド名を指定
2. **55-58行目**: cancellableTaskでGetSemanticTokensForFileを呼び出し
3. **57行目**: SemanticTokensオブジェクトを構築

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

```
LanguageFeaturesHandler
    │
    ├─ HandleRequestAsync (DocumentDiagnosticParams)
    │      └─ cancellableTask
    │             ├─ context.Workspace.Query.GetDiagnosticsForFile
    │             ├─ fsharpDiagnosticReport.Diagnostics.map(_.ToLspDiagnostic())
    │             ├─ FullDocumentDiagnosticReport構築
    │             └─ RelatedFullDocumentDiagnosticReport構築
    │
    └─ HandleRequestAsync (SemanticTokensParams)
           └─ cancellableTask
                  ├─ context.GetSemanticTokensForFile
                  └─ SemanticTokens構築
```

### データフロー図

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

DocumentDiagnosticParams ───▶ LanguageFeaturesHandler ───▶ RelatedFullDocumentDiagnosticReport
    │                              │                              │
    └─ Uri                         ├─ GetDiagnosticsForFile       ├─ Items (Diagnostic[])
                                   ├─ ToLspDiagnostic変換          ├─ ResultId
                                   └─ RelatedDocuments構築         └─ RelatedDocuments

SemanticTokensParams ───▶ LanguageFeaturesHandler ───▶ SemanticTokens
    │                              │                        │
    └─ Uri                         └─ GetSemanticTokensForFile  └─ Data (int[])
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| LanguageFeaturesHandler.fs | `src/FSharp.Compiler.LanguageServer/Handlers/LanguageFeaturesHandler.fs` | ソース | 言語機能ハンドラのメイン実装 |
| FSharpRequestContext.fs | `src/FSharp.Compiler.LanguageServer/Common/FSharpRequestContext.fs` | ソース | リクエストコンテキストとワークスペースアクセス |
| FSharpLanguageServer.fs | `src/FSharp.Compiler.LanguageServer/FSharpLanguageServer.fs` | ソース | ハンドラの登録 |
| Utils.fs | `src/FSharp.Compiler.LanguageServer/Utils.fs` | ソース | 変換ユーティリティ |
