# 画面設計書 35-ウォッチ式ビュー

## 概要

本ドキュメントは、VS Codeのウォッチ式ビュー（Watch Expressions View）画面の設計仕様を定義する。デバッグセッション中に任意の式を登録し、その評価結果を継続的に監視するためのビューである。

### 本画面の処理概要

ウォッチ式ビューは、ユーザーが指定した式をデバッグセッション中に継続的に評価し、スタックフレームが変わるたびに最新の値を表示する。

**業務上の目的・背景**：変数ビューでは現在のスコープ内の変数しか確認できないが、特定の式や計算結果、グローバル変数などを常に監視したい場合がある。ウォッチ式により、開発者は任意の式を登録しておき、デバッグ進行中もその値の変化を追跡できる。

**画面へのアクセス方法**：
- デバッグビューのサイドバー内「ウォッチ」セクション
- デバッグセッション開始時に表示
- コマンドパレット「Debug: Add to Watch」

**主要な操作・処理内容**：
1. 式の追加：新しいウォッチ式を登録
2. 式の編集：既存のウォッチ式の名前を変更
3. 式の削除：ウォッチ式を削除
4. 全式削除：すべてのウォッチ式を一括削除
5. 式のコピー：ウォッチ式をクリップボードにコピー
6. 値の編集：式の評価結果を直接編集
7. 順序変更：ドラッグ&ドロップで式の順序を変更
8. 子要素の展開：オブジェクトや配列の子要素を展開表示

**画面遷移**：
- 遷移元：デバッグセッション開始、変数ビューからのウォッチ追加
- 遷移先：なし（同一ビュー内で完結）

**権限による表示制御**：デバッガの能力（supportsSetExpression等）に応じて値編集の可否が変化。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 24 | デバッグ | 主機能 | デバッグ時のウォッチ式監視 |
| 65 | デバッグ拡張API | API連携 | Debug Adapter経由の式評価 |

## 画面種別

ツリービュー

## URL/ルーティング

- ビューID: `workbench.debug.watchExpressionsView`（WATCH_VIEW_ID）
- コンテキストキー: `CONTEXT_WATCH_EXPRESSIONS_FOCUSED`, `CONTEXT_WATCH_EXPRESSIONS_EXIST`

## 入出力項目

| 項目名 | 入力/出力 | データ型 | 必須 | 説明 |
|--------|----------|----------|------|------|
| 式入力 | 入力 | string | 必須 | ウォッチする式のテキスト |
| 値入力 | 入力 | string | - | 式の値を編集する場合の新しい値 |
| 式一覧 | 出力 | Expression[] | - | 登録されたウォッチ式と評価結果 |

## 表示項目

| 項目名 | データ型 | 説明 |
|--------|----------|------|
| 式 | Expression | ウォッチ式（名前と評価結果） |
| 変数 | Variable | 式の子要素（オブジェクトプロパティ等） |
| ビジュアライズ式 | VisualizedExpression | ビジュアライザで表示される式 |
| 型表示 | string | 変数の型（設定で表示切替） |
| アクションバー | ActionBar | 追加、全削除、折りたたみボタン |

## イベント仕様

### 1-ウォッチ式追加

1. 追加ボタンクリックまたはダブルクリック
2. debugService.addWatchExpression()呼び出し
3. 空の式が追加され入力モードに
4. 式入力後、式が評価される
5. ツリーに結果を表示

### 2-ウォッチ式編集（式名変更）

1. 式をダブルクリック
2. setSelectedExpression呼び出し
3. 入力ボックス表示
4. 入力確定後、renameWatchExpression呼び出し
5. 式を再評価して表示更新

### 3-値の直接編集

1. 変数値をダブルクリック
2. settingValue=trueでgetInputBoxOptions
3. 入力確定後、expression.setExpression呼び出し
4. updateViews()で画面更新

### 4-ドラッグ&ドロップ

1. 式をドラッグ開始
2. onDragStartでdataTransferに式名を設定
3. onDragOverで挿入位置を計算
4. dropでmoveWatchExpression呼び出し
5. 式の順序が更新される

### 5-スタックフレーム変更時の更新

1. onDidFocusStackFrameイベント発火
2. watchExpressionsUpdatedScheduler.schedule()
3. 50ms遅延後にtree.updateChildren()
4. 全式がfocusedStackFrameで再評価
5. 表示更新

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

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

ウォッチ式はデバッグモデル内で管理され、セッション間で永続化される。

| 操作（イベント） | 対象 | 操作種別 | 概要 |
|----------------|------|---------|------|
| 式追加 | DebugModel | INSERT | 新しいウォッチ式を追加 |
| 式削除 | DebugModel | DELETE | ウォッチ式を削除 |
| 式変更 | DebugModel | UPDATE | ウォッチ式の名前を変更 |
| 順序変更 | DebugModel | UPDATE | ウォッチ式の表示順序を変更 |

## メッセージ仕様

| メッセージID | 種別 | 表示条件 | メッセージ内容 |
|-------------|------|---------|---------------|
| watchAriaTreeLabel | アクセシビリティ | 常時 | Debug Watch Expressions |
| watchExpressionAriaLabel | アクセシビリティ | 式要素 | {0}, value {1} |
| watchVariableAriaLabel | アクセシビリティ | 変数要素 | {0}, value {1} |
| typeNewValue | アクセシビリティ | 値編集時 | Type new value |
| watchExpressionInputAriaLabel | アクセシビリティ | 式入力時 | Type watch expression |
| watchExpressionPlaceholder | プレースホルダ | 式入力時 | Expression to watch |
| addWatchExpression | ツールチップ | 追加ボタン | Add Expression |
| removeAllWatchExpressions | ツールチップ | 全削除ボタン | Remove All Expressions |
| copyWatchExpression | メニュー | 式選択時 | Copy Expression |

## 例外処理

| 例外条件 | 処理内容 |
|---------|---------|
| 式評価エラー | エラーメッセージを値として表示 |
| 式名が空 | 式を削除 |
| ドラッグ対象が式でない | ドラッグ操作を拒否 |

## 備考

- ウォッチ式は1024文字まで表示（MAX_VALUE_RENDER_LENGTH_IN_VIEWLET）
- useCachedEvaluationフラグで不要な再評価を防止
- ignoreViewUpdatesフラグでリネーム時のちらつきを防止
- debug.showVariableTypes設定で型表示を切替

---

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

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

### 推奨読解順序

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

Expressionクラスとウォッチ式の管理を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | debug.ts | `src/vs/workbench/contrib/debug/common/debug.ts` | IExpression, IDebugModel.getWatchExpressions() |
| 1-2 | debugModel.ts | `src/vs/workbench/contrib/debug/common/debugModel.ts` | Expressionクラス、evaluate()メソッド |

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

WatchExpressionsViewクラスの構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | watchExpressionsView.ts | `src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts` | WatchExpressionsViewクラス（ViewPaneを継承） |

**主要処理フロー**:
1. **48行目**: `class WatchExpressionsView extends ViewPane` - ViewPaneを継承
2. **77-84行目**: コンストラクタでのスケジューラ、コンテキストキー設定
3. **86-185行目**: `renderBody` - UI構築、イベント登録
4. **201-216行目**: onMouseDblClick - ダブルクリック処理

#### Step 3: レンダラーとデータソースを理解する

ウォッチ式のレンダリングとデータ取得を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | watchExpressionsView.ts | `src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts` | WatchExpressionsRenderer, WatchExpressionsDataSource |

**主要処理フロー**:
- **238-256行目**: WatchExpressionsDelegate - テンプレートID決定
- **262-280行目**: WatchExpressionsDataSource - 子要素取得、式評価
- **283-392行目**: WatchExpressionsRenderer - 式表示と入力処理

#### Step 4: ドラッグ&ドロップを理解する

式の順序変更機能を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | watchExpressionsView.ts | `src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts` | WatchExpressionsDragAndDrop |

**主要処理フロー**:
- **497-586行目**: WatchExpressionsDragAndDropクラス
- **500-504行目**: onDragStart
- **506-534行目**: onDragOver
- **552-583行目**: drop

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

```
WatchExpressionsView (ViewPane)
    │
    ├─ renderBody()
    │      ├─ renderViewTree() → treeContainer
    │      └─ WorkbenchAsyncDataTree 作成
    │             ├─ WatchExpressionsDelegate
    │             ├─ WatchExpressionsDataSource
    │             ├─ WatchExpressionsDragAndDrop
    │             └─ Renderers
    │                    ├─ WatchExpressionsRenderer
    │                    ├─ VariablesRenderer
    │                    └─ VisualizedVariableRenderer
    │
    ├─ watchExpressionsUpdatedScheduler
    │      └─ tree.updateChildren()
    │             └─ WatchExpressionsDataSource.doGetChildren()
    │                    └─ expression.evaluate()
    │
    ├─ onMouseDblClick()
    │      ├─ (式の場合) setSelectedExpression()
    │      └─ (空の場合) addWatchExpression()
    │
    └─ onContextMenu()
           └─ getContextForWatchExpressionMenuWithDataAccess()
                  └─ contextMenuService.showContextMenu()
```

### データフロー図

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

式追加 ────────────▶ addWatchExpression() ────▶ ツリーに空の式追加
                                                    │
                                                    ▼
式入力確定 ─────────▶ renameWatchExpression() ──▶ 式評価開始
                                                    │
                                                    ▼
スタックフレーム変更 ▶ watchExpressionsUpdated  ──▶ 全式再評価
                          Scheduler                 │
                                                    ▼
                    expression.evaluate()           │
                          │                         ▼
                          ▼               WatchExpressionsRenderer
                    Debug Adapter                   │
                    (evaluate request)             ▼
                                              式と値を表示

ドラッグ&ドロップ ──▶ moveWatchExpression() ────▶ 順序更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| watchExpressionsView.ts | `src/vs/workbench/contrib/debug/browser/watchExpressionsView.ts` | ソース | メインのWatchExpressionsViewクラス |
| debugModel.ts | `src/vs/workbench/contrib/debug/common/debugModel.ts` | ソース | Expressionクラス |
| debug.ts | `src/vs/workbench/contrib/debug/common/debug.ts` | ソース | インターフェース定義 |
| variablesView.ts | `src/vs/workbench/contrib/debug/browser/variablesView.ts` | ソース | VariablesRenderer（共有） |
| baseDebugView.ts | `src/vs/workbench/contrib/debug/browser/baseDebugView.ts` | ソース | AbstractExpressionsRenderer |
| debugExpressionRenderer.ts | `src/vs/workbench/contrib/debug/browser/debugExpressionRenderer.ts` | ソース | 式値レンダリング |
| debugIcons.ts | `src/vs/workbench/contrib/debug/browser/debugIcons.ts` | ソース | watchExpressionsAdd, watchExpressionsRemoveAll |
| viewPane.ts | `src/vs/workbench/browser/parts/views/viewPane.ts` | ソース | ViewPaneベースクラス |
