# 機能設計書 19-セマンティック分類

## 概要

本ドキュメントは、F#コンパイラサービスのセマンティック分類（Semantic Classification）機能の設計を記述する。この機能は、ソースコード内の各トークンに対してセマンティック情報に基づく分類を提供し、構文ハイライトを実現する。

### 本機能の処理概要

セマンティック分類機能は、型チェック結果を利用して、各トークンの意味的な分類（型、関数、変数、プロパティなど）を判定し、IDEの構文ハイライトに必要な情報を提供する。

**業務上の目的・背景**：単純なキーワードベースの構文ハイライトでは、コンテキストに応じた正確な色分けができない。型情報に基づくセマンティック分類により、変数と型、関数とプロパティなどを正確に区別した表示が可能になる。

**機能の利用シーン**：
- Visual Studioでの構文ハイライト
- VS Codeでのセマンティックトークン
- コード分析ツールでのシンボル種別判定

**主要な処理内容**：
1. 名前解決結果の取得
2. 各名前解決に対する分類の決定
3. 範囲情報と分類のペア生成
4. フォーマット指定子の処理
5. 重複範囲の除外

**関連システム・外部連携**：
- FSharpChecker（型チェック結果の提供）
- Visual Studio Editor API
- Language Server Protocol（LSP）

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | テキストエディタ | 主機能 | セマンティックハイライト表示 |

## 機能種別

構文ハイライト / セマンティック分類 / エディタ連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| sResolutions | TcResolutions | Yes | 型チェック解決結果 | - |
| formatSpecifierLocations | (range * int)[] | Yes | フォーマット指定子の位置 | - |
| range | range option | No | 対象範囲 | - |

### 入力データソース

- 型チェック結果（CapturedNameResolutions）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SemanticClassificationItem[] | SemanticClassificationItem[] | 分類結果の配列 |
| Range | range | トークンの範囲 |
| Type | SemanticClassificationType | 分類種別 |

### 出力先

- IDE/エディタへの返却

## 処理フロー

### 処理シーケンス

```
1. 名前解決結果の取得
   └─ CapturedNameResolutionsから取得
2. 範囲フィルタリング
   └─ 指定範囲内の解決のみ抽出
3. 各解決の分類
   └─ Item種別に応じた分類を決定
4. 重複除外
   └─ HashSetで重複を管理
5. フォーマット指定子追加
   └─ Printf分類を追加
```

### フローチャート

```mermaid
flowchart TD
    A[TcResolutions] --> B[CapturedNameResolutions取得]
    B --> C{範囲指定あり?}
    C -->|Yes| D[範囲フィルタリング]
    C -->|No| E[全件処理]
    D --> F[Item分類]
    E --> F
    F --> G{Item種別?}
    G -->|Value| H[値分類]
    G -->|Type| I[型分類]
    G -->|Method| J[メソッド分類]
    G -->|Property| K[プロパティ分類]
    H --> L[重複除外]
    I --> L
    J --> L
    K --> L
    L --> M[フォーマット指定子追加]
    M --> N[SemanticClassificationItem配列]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 組み込み関数 | raise, typeof等は IntrinsicFunction | KeywordIntrinsicValue |
| BR-02 | 拡張メソッド | 拡張メソッドはExtensionMethod | IsCSharpStyleExtensionMember |
| BR-03 | Disposable | IDisposable型はDisposableType | isDisposableTy |
| BR-04 | カスタムビルダー優先 | CustomBuilderはComputationExpression | takeCustomBuilder |

### 計算ロジック

分類決定ロジック:
1. Item種別でパターンマッチ
2. 追加条件でサブ分類を決定
3. 重複は最初の分類を採用

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 解析エラー | 型チェック失敗 | 空配列を返却 |

### リトライ仕様

DiagnosticsScope.Protectで例外をキャッチし空配列返却。

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

該当なし

## パフォーマンス要件

- 分類処理: ファイルサイズに比例
- 範囲指定で処理対象を限定可能

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

特になし

## 備考

- 37種類の分類タイプを定義（SemanticClassificationType）
- PrintfのフォーマットSpecifierも分類対象

---

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SemanticClassification.fs | `src/Compiler/Service/SemanticClassification.fs` | SemanticClassificationType列挙型（22-59行目） |
| 1-2 | SemanticClassification.fs | `src/Compiler/Service/SemanticClassification.fs` | SemanticClassificationItem構造体（61-65行目） |

**主要な分類タイプ**:
- **ReferenceType (0)**: 参照型
- **ValueType (1)**: 値型
- **Function (4)**: 関数
- **Property (5)**: プロパティ
- **MutableVar (6)**: 可変変数
- **ComputationExpression (10)**: コンピュテーション式
- **ExtensionMethod (20)**: 拡張メソッド
- **DisposableType (16)**: Disposable型

#### Step 2: ヘルパー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | SemanticClassification.fs | `src/Compiler/Service/SemanticClassification.fs` | isDisposableTy（72-75行目） |
| 2-2 | SemanticClassification.fs | `src/Compiler/Service/SemanticClassification.fs` | isValRefMutable（91-95行目） |
| 2-3 | SemanticClassification.fs | `src/Compiler/Service/SemanticClassification.fs` | reprToClassificationType（101-133行目） |

**主要処理フロー**:
- **72-75行目**: IDisposable型かどうかの判定
- **91-95行目**: 可変参照かどうかの判定
- **101-133行目**: 型表現から分類タイプへの変換

#### Step 3: 分類処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | SemanticClassification.fs | `src/Compiler/Service/SemanticClassification.fs` | GetSemanticClassification（137-395行目） |

**主要処理フロー**:
- **143-151行目**: LegitTypeOccurrenceパターン
- **153-164行目**: KeywordIntrinsicValueパターン
- **176-187行目**: takeCustomBuilder - カスタムビルダー優先処理
- **207-385行目**: 各Item種別に対する分類処理

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

```
TcResolutions.GetSemanticClassification
    │
    ├─ CapturedNameResolutions取得
    │      └─ 範囲フィルタリング
    │
    ├─ takeCustomBuilder
    │      └─ CustomBuilder優先処理
    │
    ├─ 分類処理ループ
    │      ├─ Item.CustomBuilder -> ComputationExpression
    │      ├─ Item.Value
    │      │      ├─ isValRefMutable -> MutableVar
    │      │      ├─ KeywordIntrinsicValue -> IntrinsicFunction
    │      │      ├─ isForallFunctionTy -> Function/Method
    │      │      └─ isValRefDisposable -> DisposableValue
    │      ├─ Item.RecdField -> RecordField/MutableRecordField
    │      ├─ Item.Property -> Property
    │      ├─ Item.CtorGroup -> ConstructorFor*
    │      ├─ Item.MethodGroup -> Method/ExtensionMethod
    │      └─ Item.Types -> 型分類
    │
    └─ フォーマット指定子追加
           └─ Printf分類
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| SemanticClassification.fs | `src/Compiler/Service/SemanticClassification.fs` | ソース | セマンティック分類のコア実装 |
| NameResolution.fs | `src/Compiler/Checking/NameResolution.fs` | ソース | 名前解決結果の提供 |
| TypeHierarchy.fs | `src/Compiler/Checking/TypeHierarchy.fs` | ソース | 型階層判定 |
| FSharpCheckerResults.fs | `src/Compiler/Service/FSharpCheckerResults.fs` | ソース | 分類結果の取得API |
