# 機能設計書 69-未使用変数削除

## 概要

本ドキュメントは、Roslyn IDE機能の一つである「未使用変数削除（RemoveUnusedVariable）」機能の設計を記述する。この機能は、宣言されているが使用されていないローカル変数を検出し、削除するコードフィックス機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：コードリファクタリングの過程で、変数の使用箇所が削除されても変数宣言が残ってしまうことがある。未使用の変数はコードの可読性を低下させ、開発者に混乱を招く。本機能は、コンパイラ警告（IDE0059等）と連動して未使用変数を自動的に削除し、コードをクリーンに保つ。

**機能の利用シーン**：コード編集中に未使用変数の警告が表示された際に、ライトバルブで「未使用変数を削除」オプションが表示される。FixAllでプロジェクト全体の未使用変数を一括削除することも可能。

**主要な処理内容**：
1. 未使用変数の診断情報を受け取る
2. 変数の参照箇所を検索し、使用状況を確認
3. 変数宣言と関連する参照を削除
4. 複数の変数宣言がある場合は適切にマージ

**関連システム・外部連携**：SymbolFinder（シンボル参照検索）と連携。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | エディタ（ライトバルブ） | 主画面 | 未使用変数削除の実行 |

## 機能種別

コード修正（CodeFix）/ 変数管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| context | CodeFixContext | Yes | コードフィックスコンテキスト | - |

### 入力データソース

- コンパイラ診断情報（IDE0059等）
- 変数のシンボル情報
- 変数の参照情報

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 変更されたドキュメント | Document | 変数削除後のドキュメント |

### 出力先

エディタ上のドキュメント

## 処理フロー

### 処理シーケンス

```
1. RegisterCodeFixesAsync呼び出し
   └─ 診断位置のノードを取得
2. ShouldOfferFixForLocalDeclarationチェック
   └─ 修正を提供すべきかどうか判定
3. FixAllAsync（SyntaxEditorベース）
   └─ 複数の診断に対して変更を適用
4. SymbolFinder.FindReferencesAsync
   └─ 変数の参照箇所を検索
5. RemoveOrReplaceNode
   └─ 変数宣言と参照を削除/置換
6. MergeNodesToRemove
   └─ 複数宣言の場合はマージ
```

### フローチャート

```mermaid
flowchart TD
    A[診断位置取得] --> B[ノード検索]
    B --> C{修正提供可能?}
    C -->|No| D[終了]
    C -->|Yes| E[CodeFix登録]
    E --> F[FixAllAsync実行]
    F --> G[変数参照検索]
    G --> H{catch宣言識別子?}
    H -->|Yes| I[トークンを空に置換]
    H -->|No| J[ノードを削除対象に追加]
    I --> K[参照箇所を検索]
    J --> K
    K --> L[GetNodeToRemoveOrReplace]
    L --> M[削除ノードをマージ]
    M --> N[逆順で削除実行]
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-69-01 | catch識別子の特別処理 | catch文の変数識別子は空トークンに置換 | IsCatchDeclarationIdentifier時 |
| BR-69-02 | 宣言マージ | 同一文内の複数変数がすべて未使用なら文全体を削除 | 複数変数宣言時 |
| BR-69-03 | 逆順処理 | SpanStartの逆順で削除を実行して競合を回避 | 常時 |
| BR-69-04 | トリビア保持 | ディレクティブを含むトリビアは保持 | 先頭にディレクティブがある場合 |
| BR-69-05 | エラスティックマーカー | 先頭文でない場合はエラスティックマーカーを除去 | ブロック内の2番目以降の文 |

### 計算ロジック

特になし

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

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

本機能はデータベース操作を行わない。

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 修正不可 | ShouldOfferFixForLocalDeclarationがfalse | 修正を提供しない |

### リトライ仕様

特になし

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

該当なし（ドキュメント編集はエディタのUndo機構で管理）

## パフォーマンス要件

- FixAllでは逆順処理により効率的に変更を適用

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

特になし

## 備考

SyntaxEditorBasedCodeFixProviderを継承してFixAllをサポート

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AbstractRemoveUnusedVariableCodeFixProvider.cs | `src/Features/Core/Portable/RemoveUnusedVariable/AbstractRemoveUnusedVariableCodeFixProvider.cs` | CodeFixProvider実装 |

**主要処理フロー**:
1. **24-28行目**: ジェネリック型パラメータ（TLocalDeclarationStatement, TVariableDeclarator, TVariableDeclaration）
2. **29-37行目**: 抽象メソッド定義
3. **39-53行目**: RegisterCodeFixesAsyncで修正登録

#### Step 2: FixAllロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | FixAllAsync | AbstractRemoveUnusedVariableCodeFixProvider.cs内 | FixAll処理 |

**主要処理フロー**:
- **55-115行目**: FixAllAsyncでSyntaxEditorを使用
- **70-77行目**: catch識別子の特別処理
- **78-103行目**: 変数参照の検索と削除対象追加
- **109-114行目**: 逆順で削除実行

#### Step 3: 削除ノードマージを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | MergeNodesToRemove | AbstractRemoveUnusedVariableCodeFixProvider.cs内 | 削除ノードのマージ |

**主要処理フロー**:
- **163-198行目**: MergeNodesToRemoveで同一文内の変数をマージ
- **166-175行目**: 削除候補のLocalDeclarationStatementを収集
- **177-196行目**: すべての変数が削除対象なら文全体を削除

#### Step 4: 削除オプションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CreateSyntaxRemoveOptions | AbstractRemoveUnusedVariableCodeFixProvider.cs内 | 削除オプション設定 |

**主要処理フロー**:
- **124-158行目**: CreateSyntaxRemoveOptionsで削除オプション決定
- **132-135行目**: ディレクティブがある場合はトリビア保持
- **143-152行目**: ブロック内の位置に応じてエラスティックマーカー制御

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

```
AbstractRemoveUnusedVariableCodeFixProvider.RegisterCodeFixesAsync
    │
    ├─ ShouldOfferFixForLocalDeclaration（抽象）
    │
    └─ RegisterCodeFix → FixAllAsync
           │
           ├─ DocumentEditor.CreateAsync
           │
           ├─ foreach diagnostic
           │      │
           │      ├─ IsCatchDeclarationIdentifier（抽象）
           │      │      └─ syntaxEditor.ReplaceNode
           │      │
           │      ├─ nodesToRemove.Add
           │      │
           │      └─ SymbolFinder.FindReferencesAsync
           │             │
           │             └─ GetNodeToRemoveOrReplace（抽象）
           │                    └─ nodesToRemove.Add
           │
           ├─ MergeNodesToRemove
           │      │
           │      └─ GetVariables（抽象）
           │
           └─ foreach (逆順)
                  │
                  └─ RemoveOrReplaceNode（抽象）
                         │
                         └─ RemoveNode (static)
                                │
                                └─ CreateSyntaxRemoveOptions
```

### データフロー図

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

Diagnostic          ───▶  AbstractRemoveUnusedVariableCodeFixProvider
(IDE0059等)                       │
                                  ▼
                         ShouldOfferFixForLocalDeclaration
                                  │
                                  ▼
                         FixAllAsync (SyntaxEditor)
                                  │
                                  ▼
                         SymbolFinder.FindReferencesAsync
                                  │
                                  ▼
nodesToRemove       ◀───  GetNodeToRemoveOrReplace
                                  │
                                  ▼
                         MergeNodesToRemove
                                  │
                                  ▼
                         RemoveOrReplaceNode (逆順)
                                  │
                                  ▼
                         変更されたDocument         ───▶  エディタに適用
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractRemoveUnusedVariableCodeFixProvider.cs | `src/Features/Core/Portable/RemoveUnusedVariable/AbstractRemoveUnusedVariableCodeFixProvider.cs` | ソース | 抽象基底CodeFixProvider |
| CSharpRemoveUnusedVariableCodeFixProvider.cs | `src/Features/CSharp/Portable/RemoveUnusedVariable/CSharpRemoveUnusedVariableCodeFixProvider.cs` | ソース | C#固有実装 |
| VisualBasicRemoveUnusedVariableCodeFixProvider.cs | `src/Features/VisualBasic/Portable/RemoveUnusedVariable/VisualBasicRemoveUnusedVariableCodeFixProvider.cs` | ソース | VB固有実装 |
