# 機能設計書 28-シグネチャ変更

## 概要

本ドキュメントは、Roslynにおける「シグネチャ変更」機能の設計を記述するものである。シグネチャ変更機能は、メソッドやプロパティのパラメータを追加・削除・並び替え・変更し、すべての呼び出し箇所を自動的に更新するリファクタリング機能である。

### 本機能の処理概要

シグネチャ変更機能は、メソッド、プロパティ、インデクサー、デリゲート、コンストラクター等のシグネチャを変更し、すべての参照箇所(呼び出し側)も同時に更新する。パラメータの順序変更、追加、削除、型の変更などに対応する。

**業務上の目的・背景**：APIの進化やリファクタリングの過程で、メソッドのシグネチャを変更する必要が生じることは多い。手動でのシグネチャ変更は、すべての呼び出し箇所を探して更新する必要があり、見落としやミスのリスクが高い。自動化により、安全かつ効率的にシグネチャを変更できる。

**機能の利用シーン**：
1. パラメータの順序を論理的に整理する
2. 新しいパラメータを追加する(デフォルト値付き)
3. 不要になったパラメータを削除する
4. パラメータ名を変更する
5. デリゲートのシグネチャを変更する

**主要な処理内容**：
1. 対象シンボルの分析(メソッド、デリゲート等)
2. パラメータ構成の変更(UI経由)
3. すべての参照箇所の検索
4. 宣言と呼び出しの両方を更新
5. ドキュメントコメント(param要素)の更新

**関連システム・外部連携**：
- CodeRefactoringProvider/CodeAction経由でエディタに統合
- IChangeSignatureOptionsServiceでUI連携
- FindReferences機能との連携

**権限による制御**：特になし。すべてのユーザーが利用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | シグネチャ変更ダイアログ | 主画面 | パラメータの編集 |
| 20 | プレビューペイン | 補助画面 | 変更箇所のプレビュー |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象のドキュメント | 有効なドキュメントであること |
| position | int | Yes | カーソル位置 | メソッド/プロパティ宣言または呼び出し内 |
| restrictToDeclarations | bool | No | 宣言のみに制限 | - |
| updatedSignature | SignatureChange | Yes | 変更後のシグネチャ | - |

### SignatureChangeの構成

| 項目 | 型 | 説明 |
|-----|-----|------|
| OriginalConfiguration | ParameterConfiguration | 変更前のパラメータ構成 |
| UpdatedConfiguration | ParameterConfiguration | 変更後のパラメータ構成 |

### 入力データソース

- ドキュメントの構文ツリー(SyntaxTree)
- セマンティックモデル(SemanticModel)
- IChangeSignatureOptionsServiceからのユーザー入力

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ChangeSignatureResult | ChangeSignatureResult | 変更結果 |
| succeeded | bool | 成功したかどうか |
| updatedSolution | Solution | 更新後のソリューション |
| confirmationMessage | string | メタデータ参照がある場合の確認メッセージ |

### 出力先

- 更新されたソリューションとして返却

## 処理フロー

### 処理シーケンス

```
1. シンボル分析(GetInvocationSymbolAsync)
   └─ カーソル位置のメソッド/プロパティシンボルを取得
2. シンボル解決
   └─ デリゲート、イベント、レコードの場合は適切なシンボルに変換
3. 参照検索(FindChangeSignatureReferencesAsync)
   └─ すべての宣言と参照を検索
4. ノード更新の収集
   └─ 更新が必要なノードをドキュメント別に収集
5. シグネチャ変更の適用
   └─ 各ノードにChangeSignatureを適用
6. 整形(Formatter, Simplifier, ImportAdder)
   └─ 変更後のコードを整形
```

### フローチャート

```mermaid
flowchart TD
    A[開始: ChangeSignatureWithContextAsync] --> B[GetChangeSignatureContextAsync]
    B --> C{分析成功?}
    C -->|No| D[CannotChange結果返却]
    C -->|Yes| E[GetChangeSignatureOptions]
    E --> F{オプション取得成功?}
    F -->|No| G[処理中断]
    F -->|Yes| H[CreateUpdatedSolutionAsync]
    H --> I[FindChangeSignatureReferencesAsync]
    I --> J[各シンボルの処理]
    J --> K{メタデータ参照あり?}
    K -->|Yes| L[confirmationMessage設定]
    K -->|No| M[宣言と参照の更新]
    L --> M
    M --> N[Formatter.Format]
    N --> O[ImportAdder/Simplifier]
    O --> P[ChangeSignatureResult返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | シンボル制限 | IMethodSymbol, IPropertySymbolのみ対象 | 常時 |
| BR-02 | メタデータ定義 | メタデータで定義されたシンボルは変更不可 | 常時 |
| BR-03 | デリゲート変換 | デリゲート呼び出しはDelegateInvokeMethodに変換 | DelegateBeginInvoke時 |
| BR-04 | イベント変換 | イベントはその型のDelegateInvokeMethodを使用 | IEventSymbol時 |
| BR-05 | params配列 | params配列を含む場合の特別処理 | パラメータにparams |

### 計算ロジック

パラメータ順序変更ロジック:
1. 既存パラメータの新しいインデックスを計算
2. 名前付き引数が必要な場合は自動的に追加
3. 削除されたパラメータに対応する引数を除去

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

該当なし（インメモリ操作のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IncorrectKind | 不正な種類 | IMethodSymbol/IPropertySymbol以外 | エラーとして報告 |
| DefinedInMetadata | メタデータ定義 | シンボルがメタデータで定義 | エラーとして報告 |

### リトライ仕様

なし

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

該当なし

## パフォーマンス要件

- テレメトリ: 宣言・参照の更新数と処理時間を記録
- 並列処理: ProducerConsumer.RunParallelAsyncで複数ドキュメントを並列処理

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

- 特になし

## 備考

- 言語固有の実装は抽象メソッドとして定義
- ドキュメントコメントのparam要素も自動更新
- 追加パラメータにはCallSiteKind(Omitted, Todo, Inferred等)を指定可能

---

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

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

### 推奨読解順序

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

まず、シグネチャ変更で使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | SignatureChange.cs | `src/Features/Core/Portable/ChangeSignature/SignatureChange.cs` | 変更内容 |
| 1-2 | ParameterConfiguration.cs | `src/Features/Core/Portable/ChangeSignature/ParameterConfiguration.cs` | パラメータ構成 |
| 1-3 | ChangeSignatureResult.cs | `src/Features/Core/Portable/ChangeSignature/ChangeSignatureResult.cs` | 結果構造 |

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

処理の起点となるAbstractChangeSignatureService.csを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | AbstractChangeSignatureService.cs | `src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs` | メイン処理 |

**主要処理フロー**:
1. **94-101行目**: GetChangeSignatureCodeActionAsync - CodeAction取得
2. **103-188行目**: GetChangeSignatureContextAsync - シンボル分析
3. **190-209行目**: ChangeSignatureWithContextAsync - 変更実行
4. **246-441行目**: CreateUpdatedSolutionAsync - ソリューション更新

#### Step 3: 参照検索を理解する

すべての参照箇所の検索ロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractChangeSignatureService.cs | `src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs` | 225-244行目: FindChangeSignatureReferencesAsync |

#### Step 4: 引数の並び替えを理解する

呼び出し側の引数を並び替えるロジックを確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | AbstractChangeSignatureService.cs | `src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs` | 470-574行目: PermuteArguments |

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

```
AbstractChangeSignatureService.ChangeSignatureWithContextAsync
    │
    ├─ GetChangeSignatureContextAsync
    │      ├─ GetInvocationSymbolAsync
    │      ├─ SymbolFinder.FindSourceDefinitionAsync
    │      └─ ParameterConfiguration.Create
    │
    ├─ GetChangeSignatureOptions
    │      └─ IChangeSignatureOptionsService
    │
    └─ CreateUpdatedSolutionAsync
           │
           ├─ FindChangeSignatureReferencesAsync
           │      └─ FindReferencesSearchEngine
           │
           ├─ ChangeSignature (各ノードに適用)
           │      ├─ UpdateDeclarationBase
           │      └─ PermuteArguments
           │
           └─ 整形処理
                  ├─ Formatter.Format
                  ├─ ImportAdder.AddImportsFromSymbolAnnotationAsync
                  └─ Simplifier.ReduceAsync
```

### データフロー図

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

Position ───▶ GetInvocationSymbolAsync ───▶ (ISymbol, selectedIndex)
                      │
                      ▼
ISymbol ───▶ GetChangeSignatureContextAsync ───▶ ChangeSignatureAnalyzedContext
                      │
                      ▼
Context ───▶ GetChangeSignatureOptions ───▶ ChangeSignatureOptionsResult
                      │
                      ▼
Options ───▶ CreateUpdatedSolutionAsync ───▶ (Solution, confirmationMessage)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| AbstractChangeSignatureService.cs | `src/Features/Core/Portable/ChangeSignature/AbstractChangeSignatureService.cs` | ソース | メイン処理 |
| SignatureChange.cs | `src/Features/Core/Portable/ChangeSignature/SignatureChange.cs` | ソース | 変更内容 |
| ParameterConfiguration.cs | `src/Features/Core/Portable/ChangeSignature/ParameterConfiguration.cs` | ソース | パラメータ構成 |
| ChangeSignatureResult.cs | `src/Features/Core/Portable/ChangeSignature/ChangeSignatureResult.cs` | ソース | 結果構造 |
| ChangeSignatureCodeAction.cs | `src/Features/Core/Portable/ChangeSignature/ChangeSignatureCodeAction.cs` | ソース | CodeAction |
| AddedParameter.cs | `src/Features/Core/Portable/ChangeSignature/AddedParameter.cs` | ソース | 追加パラメータ |
| ExistingParameter.cs | `src/Features/Core/Portable/ChangeSignature/ExistingParameter.cs` | ソース | 既存パラメータ |
| ChangeSignatureLogger.cs | `src/Features/Core/Portable/ChangeSignature/ChangeSignatureLogger.cs` | ソース | テレメトリ |
