# 画面設計書 18-セマンティックトークン（範囲）

## 概要

本ドキュメントは、Lua Language Serverの「セマンティックトークン（範囲）（textDocument/semanticTokens/range）」機能の画面設計書である。この機能は、指定範囲のセマンティックハイライト情報を提供する。

### 本画面の処理概要

この機能では、ドキュメントの指定された範囲のみを解析し、その範囲内のトークン（変数、関数、キーワード等）のセマンティック情報（種類、修飾子）を返却する。ファイル全体ではなく可視範囲のみを処理することで、パフォーマンスを向上させる。

**業務上の目的・背景**：大規模なファイルでは、ファイル全体のセマンティックトークンを計算すると時間がかかり、エディタの応答性に影響する。範囲指定のセマンティックトークン機能により、スクロール位置に応じて表示に必要な部分のみを計算でき、大規模ファイルでも快適な編集体験を提供できる。

**画面へのアクセス方法**：ファイルを開いた際、またはスクロール時にエディタが自動的にこの機能を呼び出す。クライアントがuseSemanticByRangeオプションを使用している場合に、full版の代わりにこちらが使用される。

**主要な操作・処理内容**：
1. 対象範囲を受け取る
2. ドキュメントのASTを取得する
3. 指定範囲内のソース要素のみを走査し、トークン情報を生成する
4. LSP形式のトークンデータを返却する

**画面遷移**：セマンティックトークンは表示のみの機能であり、他の機能への直接的な遷移はない。

**権限による表示制御**：特になし。LSPプロトコルレベルでの認証・権限管理は行わない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 44 | セマンティックトークン（範囲） | 主機能 | 指定範囲のセマンティックトークンを取得する主処理 |

## 画面種別

LSP機能（ハイライト情報提供）

## URL/ルーティング

LSPメソッド: `textDocument/semanticTokens/range`

## 入出力項目

### 入力項目（リクエストパラメータ）

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| textDocument | TextDocumentIdentifier | Yes | 対象ドキュメントのURI |
| range | Range | Yes | 取得対象の範囲 |

### 出力項目（レスポンス）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| data | number[] | トークンデータ（差分エンコード形式） |

### トークンデータ形式

5つの数値で1トークンを表現（LSP仕様準拠）:
1. deltaLine: 前トークンからの行差分
2. deltaStartChar: 前トークンからの文字位置差分（同一行）/ 行頭からの位置（異なる行）
3. length: トークンの長さ
4. tokenType: トークンタイプ（TokenTypes定義による）
5. tokenModifiers: 修飾子ビットフラグ（TokenModifiers定義による）

## 表示項目

| 表示項目 | 説明 |
|---------|------|
| トークンハイライト | 各トークンの種類に応じた色分け表示 |

### トークンタイプ一覧

| トークンタイプ | 説明 |
|--------------|------|
| function | 関数 |
| variable | 変数 |
| method | メソッド |
| parameter | パラメータ |
| property | プロパティ |
| class | クラス |
| type | 型 |
| keyword | キーワード |
| string | 文字列 |
| number | 数値 |
| comment | コメント |
| operator | 演算子 |
| macro | マクロ（alias/enum） |

## イベント仕様

### 1-semanticTokens/rangeリクエスト処理

1. クライアントからtextDocument/semanticTokens/rangeリクエストを受信
2. Lua.semantic.enable設定を確認
3. ドキュメントのASTを取得
4. converter.unpackRangeで範囲を内部形式に変換
5. guide.eachSourceBetweenで指定範囲内のソース要素のみを走査
6. Care関数で各ソースタイプに応じたトークン情報を生成
7. 範囲内のコメントのトークン情報を追加
8. solveMultilineAndOverlappingで重複・複数行を処理
9. buildTokensでLSP形式のデータを生成
10. トークンデータを返却

## データベース更新仕様

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

この機能はデータベース操作を行わない。ソースコードを解析するのみで、変更は行わない。

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| semanticTokens/rangeリクエスト | なし | SELECT（読み取り） | ソースコードの解析のみ |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|---------|
| WINDOW_PROCESSING_SEMANTIC_RANGE | 進捗 | 処理中表示 | トークン解析処理中 |
| - | 成功 | （トークンデータ返却） | 正常終了時 |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイルが見つからない | nullを返却 |
| ASTの取得に失敗 | nullを返却 |
| Lua.semantic.enableがfalse | 空配列を返却 |

## 備考

- full版との違いは処理対象範囲のみ。内部のトークン生成ロジックは同一
- トークンデータはLSP仕様に従い、差分エンコード形式で返却される
- 設定項目: Lua.semantic.enable（有効/無効）, Lua.semantic.variable（変数ハイライト）, Lua.semantic.annotation（アノテーションハイライト）, Lua.semantic.keyword（キーワードハイライト）
- abortByFileUpdate属性が設定されており、ファイル更新時にリクエストがキャンセルされる
- range版は常に利用可能（full版はuseSemanticByRangeオプションの設定に依存）

---

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

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

### 推奨読解順序

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

まず、トークンタイプと修飾子の定義を理解する（full版と同一）。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | define.lua | `script/proto/define.lua` | TokenTypes, TokenModifiers定義 |
| 1-2 | semantic-tokens.lua | `script/core/semantic-tokens.lua` (730-764行目) | buildTokens関数 - トークンエンコード |

**読解のコツ**: range版とfull版の主な違いは、guide.eachSourceBetweenに渡す範囲のみ。full版は0〜math.huge、range版はリクエストで指定された範囲を使用する。

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

処理の起点となるプロバイダー登録を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | provider.lua | `script/provider/provider.lua` (1111-1140行目) | textDocument/semanticTokens/rangeの登録 |

**主要処理フロー**:
1. **1111行目**: `m.register 'textDocument/semanticTokens/range'`でハンドラー登録
2. **1125行目**: `files.getRealUri`でURI正規化
3. **1129行目**: `files.getState`でAST取得
4. **1133行目**: `core/semantic-tokens`モジュールを呼び出し
5. **1134行目**: `converter.unpackRange`で範囲変換
6. **1135行目**: 指定範囲でトークン生成

#### Step 3: コア処理を理解する

セマンティックトークン生成のコアロジックを確認する（full版と共通）。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | semantic-tokens.lua | `script/core/semantic-tokens.lua` (873-951行目) | メイン関数 |
| 3-2 | semantic-tokens.lua | `script/core/semantic-tokens.lua` (894行目) | guide.eachSourceBetween呼び出し - start/finish引数が範囲を指定 |

**主要処理フロー**:
- **894行目**: `guide.eachSourceBetween(state.ast, start, finish, function ...)`で指定範囲のみを走査
- 以降の処理はfull版と同一

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

```
textDocument/semanticTokens/range (provider.lua:1111-1140)
    |
    +-- workspace.awaitReady (ワークスペース準備待機)
    |
    +-- progress.create (進捗表示)
    |
    +-- files.getState (AST取得)
    |
    +-- converter.unpackRange (範囲変換)
    |
    +-- core/semantic-tokens (semantic-tokens.lua:873-951)
           |
           +-- config.get (設定取得)
           |
           +-- guide.eachSourceBetween(start, finish) (範囲限定走査)
           |      |
           |      +-- Care (12-728行目)
           |
           +-- コメント処理 (範囲内のみ)
           |
           +-- solveMultilineAndOverlapping
           |
           +-- buildTokens
```

### データフロー図

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

SemanticTokensRangeParams      provider.lua                        SemanticTokens
+------------------+           +------------------+                 +------------------+
| textDocument.uri |  ------>  | files.getState   |                 | data: number[]   |
| range            |           | unpackRange      |                 +------------------+
|   start          |           +------------------+
|   end            |                  |
+------------------+                  v
                               semantic-tokens.lua
                               +----------------------+
                               | guide.eachSourceBetween(start, finish)
                               |   Care関数           |  -------->
                               | コメント処理(範囲内)  |
                               | solveMultiline...   |
                               | buildTokens         |
                               +----------------------+
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPメソッドハンドラー登録 |
| semantic-tokens.lua | `script/core/semantic-tokens.lua` | ソース | セマンティックトークン生成コアロジック |
| define.lua | `script/proto/define.lua` | ソース | TokenTypes, TokenModifiers定義 |
| converter.lua | `script/proto/converter.lua` | ソース | 位置・範囲変換処理 |
| linked-table.lua | `script/linked-table.lua` | ソース | 重複処理用リンクテーブル |
| files.lua | `script/files.lua` | ソース | ファイル管理・AST取得 |
| guide.lua | `script/parser/guide.lua` | ソース | AST操作ユーティリティ |
| config.lua | `script/config.lua` | ソース | 設定管理 |
