# 画面設計書 29-問題解決

## 概要

本ドキュメントは、Lua Language Serverにおける「問題解決」機能の画面設計書です。LSPコマンド `lua.solve` に対応し、診断で検出された問題の自動修正を実行します。

### 本画面の処理概要

問題解決機能は、診断で検出された特定の問題パターンに対して、自動修正を適用するコマンドです。特に演算子の優先順位に関する問題（`or` 演算子と算術演算子の組み合わせ）を括弧で明確化する修正を行います。

**業務上の目的・背景**：Luaの演算子優先順位は直感的でない場合があり、特に `or` 演算子と算術演算子の組み合わせは、意図しない評価順序となる可能性があります。例えば `a + b or 0` は `(a + b) or 0` ではなく `a + (b or 0)` として評価される場合があります。この機能により、曖昧な式に括弧を追加して意図を明確化し、バグを防止できます。

**画面へのアクセス方法**：この機能は、以下の方法で呼び出されます：
- コードアクション（クイックフィックス）メニューから選択
- 診断結果からのクイックフィックスとして実行
- コマンドパレットから `lua.solve` を実行

**主要な操作・処理内容**：
1. コマンド `lua.solve` がトリガーされる（問題の範囲情報を含む）
2. 対象範囲のソースコードを解析
3. `or` 演算子と算術演算子の組み合わせパターンを検出
4. 適切な括弧を追加するTextEditを構築
5. `workspace/applyEdit` リクエストでエディタに適用

**画面遷移**：独立したコマンドとして動作し、特定の画面遷移はありません。処理結果は現在のエディタに直接反映されます。

**権限による表示制御**：特別な権限制御はありません。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 26 | 問題解決 (lua.solve) | 主機能 | 診断の自動修正を実行するコマンド処理 |

## 画面種別

LSPコマンド

## URL/ルーティング

LSPコマンド: `lua.solve`
LSPメソッド: `workspace/executeCommand`

## 入出力項目

### 入力パラメータ

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| uri | uri | はい | 対象ドキュメントのURI |
| range | Range | はい | 問題の範囲 |

### 出力パラメータ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| - | - | 戻り値なし（workspace/applyEditで変更を適用） |

## 表示項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| - | - | エディタ上で修正結果が表示される |

## イベント仕様

### 1-問題解決コマンド実行

1. ユーザーが `lua.solve` コマンドを実行
2. `workspace/executeCommand` ハンドラが呼び出される
3. `core/command/solve.lua` が実行される
4. 対象範囲のソースを解析（`guide.eachSourceContain`）
5. `or` 演算子と算術演算子のパターンを検出
6. 括弧を追加するTextEditを構築
7. `workspace/applyEdit` リクエストでエディタに適用

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 問題解決コマンド実行 | - | - | データベース操作なし（ファイル編集のみ） |

## メッセージ仕様

| メッセージID | 種別 | 表示内容 | 発生条件 |
|-------------|------|----------|----------|
| COMMAND_REMOVE_SPACE | ラベル | 編集ラベル | 編集適用時のラベル（注：実装上のラベル再利用） |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| ファイル状態が取得できない | 処理を終了（何もしない） |
| ファイルテキストが取得できない | 処理を終了（何もしない） |
| 対象パターンが見つからない | 処理を終了（何もしない） |

## 備考

- 対象となる算術演算子：`+`, `-`, `*`, `/`, `//`, `^`, `<<`, `>>`, `&`, `|`, `~`, `..`
- 対象となるリテラル型：number, integer, boolean, string, table
- パターン1：`a + b or 0` → `a + (b or 0)` への変換
- パターン2：`a or b + c` → `(a or b) + c` への変換
- 括弧の追加により演算子の優先順位を明確化

---

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

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

### 推奨読解順序

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

演算子の種類とリテラルの種類を定義するマップを理解することが重要です。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | solve.lua | `script/core/command/solve.lua` | opMap（7-20行目）とliteralMap（22-28行目）を確認 |

**読解のコツ**: opMapは括弧を追加すべき演算子を、literalMapは比較対象となるリテラル型を定義しています。

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

コマンドハンドラがどのように呼び出されるかを理解します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | provider.lua | `script/provider/provider.lua` | `workspace/executeCommand` ハンドラ（977-1021行目）を確認 |

**主要処理フロー**:
1. **977行目**: `m.register 'workspace/executeCommand'` でハンドラを登録
2. **996-998行目**: `lua.solve` の場合、solve.luaを実行

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

実際の問題解決処理を確認します。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | solve.lua | `script/core/command/solve.lua` | 問題解決処理（31-99行目）を確認 |

**主要処理フロー**:
- **31-37行目**: ファイル状態とテキストの取得
- **39行目**: 範囲を変換
- **41-77行目**: パターンマッチング処理
  - **42-45行目**: 範囲一致と`or`演算子の確認
  - **52-63行目**: パターン1（`a + b or 0`）の検出
  - **65-76行目**: パターン2（`a or b + c`）の検出
- **83-98行目**: `workspace/applyEdit` で変更を適用

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

```
workspace/executeCommand (provider.lua:977-1021)
    │
    └─ 'lua.solve' (996-998行目)
           │
           └─ core/command/solve.lua (31-99行目)
                  │
                  ├─ files.getText(uri) - テキスト取得
                  │
                  ├─ files.getState(uri) - ファイル状態取得
                  │
                  ├─ converter.unpackRange() - 範囲変換
                  │
                  ├─ guide.eachSourceContain() - パターン検出
                  │      │
                  │      ├─ source.op.type == 'or' チェック
                  │      │
                  │      ├─ パターン1: a + b or 0
                  │      │
                  │      └─ パターン2: a or b + c
                  │
                  └─ proto.awaitRequest('workspace/applyEdit', ...)
```

### データフロー図

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

{                              1. ファイル取得                  workspace/applyEdit {
  uri: 'file:///path/to/file', 2. 範囲変換                        label: '...',
  range: {                     3. パターン検出                    edit: {
    start: {...},                 ├─ or演算子を含む式を検索         changes: {
    end: {...}                    ├─ 算術演算子との組み合わせ確認      [uri]: [
  }                               └─ リテラルとの組み合わせ確認         {
}                              4. 括弧追加位置を決定                  range: ...,
                               5. TextEdit構築                       newText: '(...)'
                               6. applyEdit送信                     }
                                                                   ]
                                                                 }
                                                               }
                                                              }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| provider.lua | `script/provider/provider.lua` | ソース | LSPコマンドハンドラの登録・処理 |
| solve.lua | `script/core/command/solve.lua` | ソース | 問題解決処理のコアロジック |
| files.lua | `script/files.lua` | ソース | ファイル状態・テキストの管理 |
| guide.lua | `script/parser/guide.lua` | ソース | AST操作ユーティリティ（eachSourceContain） |
| proto.lua | `script/proto/proto.lua` | ソース | LSPプロトコル通信 |
| converter.lua | `script/proto/converter.lua` | ソース | LSPプロトコル型変換 |
