# 機能設計書 35-パラメータの導入

## 概要

本ドキュメントは、Roslynの「パラメータの導入（Introduce Parameter）」機能の設計仕様を記述する。この機能は、メソッド内の式を新しいパラメータとして抽出し、呼び出し元でその値を渡すようにするリファクタリング機能である。

### 本機能の処理概要

**業務上の目的・背景**：メソッド内にハードコードされた値や計算式がある場合、それをパラメータ化することで柔軟性と再利用性が向上する。この機能は、そのような場面で式を安全にパラメータとして抽出し、すべての呼び出し元を自動的に更新する。

**機能の利用シーン**：開発者がメソッド内の特定の値を外部から指定可能にしたい場合に使用する。例えば、`void Process() { DoWork(10); }`を`void Process(int value) { DoWork(value); }`に変換し、すべての呼び出し元に`10`を引数として追加する場面で活用される。

**主要な処理内容**：
1. 選択された式の検証（パラメータ化可能かどうかの判定）
2. 新しいパラメータ名の生成
3. メソッドシグネチャへのパラメータ追加
4. すべての呼び出し元への引数追加
5. 式をパラメータ参照で置換

**関連システム・外部連携**：シンボル検索サービス（SymbolFinder）を使用して呼び出し元を検索する。

**権限による制御**：コンストラクタの場合はトランポリン/オーバーロード方式が利用不可。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| N/A | N/A | N/A | コードエディタ上のコンテキストメニューから直接実行 |

## 機能種別

コードリファクタリング / コード変換

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 操作対象のドキュメント | null不可 |
| expression | TExpressionSyntax | Yes | パラメータ化する式 | 有効な式 |
| allOccurrences | bool | No | 同一式のすべての出現を置換するか | デフォルトfalse |
| codeActionKind | IntroduceParameterCodeActionKind | Yes | 実行方式（Refactor/Trampoline/Overload） | 有効な値 |

### 入力データソース

- エディタで選択された式

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| modifiedSolution | Solution | 変更が適用されたソリューション |

### 出力先

- メソッド定義ドキュメント（パラメータ追加、式置換）
- 呼び出し元ドキュメント（引数追加）

## 処理フロー

### 処理シーケンス

```
1. 選択された式の取得
   └─ TryGetRelevantNodeAsync<TExpressionSyntax>で取得

2. 式の検証
   └─ IsValidExpression()
   └─ 名前空間/型コンテキスト内でないこと
   └─ メンバーアクセス式の名前部分でないこと
   └─ 初期化子の名前部分でないこと
   └─ 属性引数やパラメータ内でないこと

3. 含まれるメソッドの特定
   └─ パラメータリストを持つ先祖ノードを検索
   └─ Ordinary/LocalFunction/Constructor のみ対象
   └─ デストラクタは除外

4. 式の内容分析
   └─ ローカル変数やレンジ変数を含む場合は除外
   └─ paramsパラメータを含む場合は除外
   └─ this/base参照を含む場合の検出

5. 呼び出し元の検索
   └─ FindCallSitesAsync()
   └─ SymbolFinder.FindReferencesAsyncで参照検索

6. CodeActionの種類決定
   a. Refactor: 呼び出し元を直接更新
   b. Trampoline: 新メソッドを作成し呼び出しを委譲
   c. Overload: オーバーロードを作成

7. パラメータ導入の実行
   └─ IntroduceParameterAsync()
   └─ IntroduceParameterDocumentRewriter.RewriteDocumentAsync()

8. ソリューションの更新
   └─ 変更されたドキュメントをすべて適用
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[式の取得]
    B --> C{有効な式?}
    C -->|No| Z[終了]
    C -->|Yes| D{メソッド内?}
    D -->|No| Z
    D -->|Yes| E{対象メソッド種別?}
    E -->|無効| Z
    E -->|有効| F[式の内容分析]
    F --> G{ローカル/レンジ変数?}
    G -->|Yes| Z
    G -->|No| H[呼び出し元検索]
    H --> I{this/base参照?}
    I -->|Yes| J[Refactorのみ提供]
    I -->|No| K[全方式提供]
    J --> L[CodeAction登録]
    K --> L
    L --> M{ユーザー選択}
    M --> N[IntroduceParameterAsync]
    N --> O[ソリューション更新]
    O --> Z[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-35-01 | 式コンテキスト制限 | 名前空間/型コンテキスト内の式は対象外 | 常に適用 |
| BR-35-02 | メンバーアクセス名除外 | メンバーアクセス式の名前部分は対象外 | 常に適用 |
| BR-35-03 | ローカル変数除外 | ローカル変数やレンジ変数を含む式は対象外 | 常に適用 |
| BR-35-04 | params除外 | paramsパラメータを含む式は対象外 | 常に適用 |
| BR-35-05 | コンストラクタ制限 | コンストラクタではTrampoline/Overload不可 | コンストラクタの場合 |
| BR-35-06 | ローカル関数制限 | ローカル関数ではOverload不可 | ローカル関数の場合 |
| BR-35-07 | this/base制限 | this/baseを含む場合はRefactorのみ | インスタンス参照を含む場合 |

### 計算ロジック

CodeAction種類の決定ロジック：
```
if (式がthis/base参照を含む) {
    提供アクション = [Refactor]
} else if (メソッドがコンストラクタ) {
    提供アクション = [Refactor]
} else {
    提供アクション = [Refactor]
    if (!呼び出し元がオブジェクト生成を含む) {
        提供アクション += [Trampoline]
    }
    if (メソッドがローカル関数でない) {
        提供アクション += [Overload]
    }
}
```

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

該当なし（メモリ上のシンボルとソースコードの操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| N/A | 検証エラー | 名前空間/型コンテキスト内の式 | リファクタリングを提供しない |
| N/A | 検証エラー | ローカル変数を含む式 | リファクタリングを提供しない |
| N/A | 検証エラー | paramsパラメータを含む式 | リファクタリングを提供しない |
| N/A | 検証エラー | メソッド外の式 | リファクタリングを提供しない |

### リトライ仕様

該当なし（インタラクティブな操作のため）

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

ソリューション全体の変更を適用。すべての変更が成功するか、すべて適用されないかのいずれかとなる。

## パフォーマンス要件

- 呼び出し元の検索は並列実行
- ProducerConsumerを使用した効率的な処理

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

- ソースコードへの書き込み権限が必要

## 備考

- Refactor方式: 既存メソッドにパラメータを追加し、呼び出し元を更新
- Trampoline方式: 既存メソッドを新パラメータ付きに変更し、旧シグネチャの新メソッドを作成
- Overload方式: オーバーロードを作成し、既存メソッドから新オーバーロードを呼び出す

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | AbstractIntroduceParameterCodeRefactoringProvider.cs | `src/Features/Core/Portable/IntroduceParameter/AbstractIntroduceParameterCodeRefactoringProvider.cs` | CodeRefactoringProviderの実装。ComputeRefactoringsAsyncがエントリーポイント |

**主要処理フロー**:
1. **36-42行目**: IntroduceParameterCodeActionKind列挙型 - Refactor/Trampoline/Overload
2. **48-118行目**: ComputeRefactoringsAsyncメソッド - 式の取得と検証
3. **60-61行目**: IsValidExpression呼び出し
4. **63-65行目**: パラメータリストを持つ先祖ノード検索
5. **88-93行目**: メソッド種別の検証（Ordinary/LocalFunction/Constructor）
6. **95-96行目**: FindCallSitesAsyncで呼び出し元検索
7. **101-117行目**: CodeAction登録（allOccurrences: true/false）

#### Step 2: 式の検証ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractIntroduceParameterCodeRefactoringProvider.cs | `src/Features/Core/Portable/IntroduceParameter/AbstractIntroduceParameterCodeRefactoringProvider.cs` | IsValidExpression、ShouldExpressionDisplayCodeActionAsync |

**主要処理フロー**:
- **120-147行目**: IsValidExpression - コンテキスト検証
- **211-246行目**: ShouldExpressionDisplayCodeActionAsync - 式内容の分析（ローカル/レンジ変数、params、this/base）

#### Step 3: アクション生成ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractIntroduceParameterCodeRefactoringProvider.cs | `src/Features/Core/Portable/IntroduceParameter/AbstractIntroduceParameterCodeRefactoringProvider.cs` | GetActionsAsync |

**主要処理フロー**:
- **154-204行目**: GetActionsAsync - CodeAction種類の決定と生成
- **168-172行目**: Refactorアクション（常に提供）
- **174-183行目**: Trampolineアクション（条件付き）
- **185-191行目**: Overloadアクション（条件付き）

#### Step 4: パラメータ導入処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AbstractIntroduceParameterCodeRefactoringProvider.cs | `src/Features/Core/Portable/IntroduceParameter/AbstractIntroduceParameterCodeRefactoringProvider.cs` | IntroduceParameterAsync |

**主要処理フロー**:
- **251-279行目**: IntroduceParameterAsync - メイン処理
- **259-276行目**: ProducerConsumer.RunParallelAsyncによる並列処理

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

```
AbstractIntroduceParameterCodeRefactoringProvider.ComputeRefactoringsAsync
    │
    ├─ TryGetRelevantNodeAsync<TExpressionSyntax>
    │
    ├─ IsValidExpression
    │      └─ ISyntaxFactsService (コンテキスト判定)
    │
    ├─ SemanticModel.GetDeclaredSymbol (メソッドシンボル取得)
    │
    ├─ ShouldExpressionDisplayCodeActionAsync
    │      └─ SemanticModel.GetOperation (ローカル変数/this/base検出)
    │
    ├─ FindCallSitesAsync
    │      └─ SymbolFinder.FindReferencesAsync
    │
    └─ GetActionsAsync
           │
           ├─ CreateNewCodeAction (Refactor)
           ├─ CreateNewCodeAction (Trampoline)
           └─ CreateNewCodeAction (Overload)
                  │
                  └─ IntroduceParameterAsync
                         │
                         ├─ ProducerConsumer.RunParallelAsync
                         │      └─ IntroduceParameterDocumentRewriter.RewriteDocumentAsync
                         │
                         └─ Solution.WithDocumentSyntaxRoots
```

### データフロー図

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

式選択 ─────────────────▶ AbstractIntroduceParameterCodeRefactoringProvider
                                 │
                                 ▼
                        IsValidExpression + ShouldExpressionDisplayCodeAction
                                 │
                                 ▼
                        FindCallSitesAsync ───▶ 呼び出し元リスト
                                 │
                                 ▼
                        GetActionsAsync ───▶ CodeActionリスト
                                 │
                                 ▼
                        IntroduceParameterAsync
                                 │
                        ┌────────┴────────┐
                        ▼                 ▼
              並列ドキュメント処理    IntroduceParameterDocumentRewriter
                        │                 │
                        └────────┬────────┘
                                 ▼
                        Solution.WithDocumentSyntaxRoots
                                 │
                                 ▼
                        更新されたソリューション
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractIntroduceParameterCodeRefactoringProvider.cs | `src/Features/Core/Portable/IntroduceParameter/` | ソース | リファクタリングプロバイダーの基底クラス |
| AbstractIntroduceParameterCodeRefactoringProvider.IntroduceParameterDocumentRewriter.cs | `src/Features/Core/Portable/IntroduceParameter/` | ソース | ドキュメント書き換え処理 |
| CSharpIntroduceParameterCodeRefactoringProvider.cs | `src/Features/CSharp/Portable/IntroduceParameter/` | ソース | C#固有の実装 |
