# 機能設計書 71-括弧補完

## 概要

本ドキュメントは、Roslynの括弧補完（BraceCompletion）機能の設計を記載する。この機能は、開発者がコードを入力する際に、開き括弧を入力すると対応する閉じ括弧を自動的に挿入し、コーディング効率を向上させる。

### 本機能の処理概要

**業務上の目的・背景**：プログラミングにおいて、括弧（丸括弧、波括弧、角括弧、引用符など）は常にペアで使用される。開発者が手動で閉じ括弧を入力する必要があると、入力ミスや括弧の不一致が発生しやすくなる。括弧補完機能は、これらの問題を解決し、開発者の生産性を向上させるために設計されている。また、コード構造の整合性を維持し、コンパイルエラーを事前に防ぐ役割も果たす。

**機能の利用シーン**：コードエディタでの入力時に自動的に発動する。開発者が`{`、`(`、`[`、`<`、`"`、`'`などの開き括弧を入力した瞬間に、対応する閉じ括弧が自動挿入される。また、Enterキー押下時のブロック展開やオーバータイプ（既存の閉じ括弧を上書きせずにスキップする）機能も提供する。

**主要な処理内容**：
1. 開き括弧入力時の閉じ括弧自動挿入
2. 入力位置がユーザーコード（文字列リテラルやコメント外）かの判定
3. 補完後のキャレット位置の調整
4. Enterキー押下時のフォーマットとインデント調整
5. 閉じ括弧のオーバータイプ許可判定
6. 補間文字列内のエスケープ処理（`{{`の検出）

**関連システム・外部連携**：Visual Studioエディタ、Language Server Protocol (LSP)、エディタのテキスト変更通知システムと連携する。

**権限による制御**：特になし。全ユーザーが利用可能な標準機能である。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コードエディタ | 主画面 | 括弧入力時の自動補完処理 |

## 機能種別

エディタ支援機能（テキスト自動補完）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| brace | char | Yes | 入力された開き括弧文字 | `{`, `(`, `[`, `<`, `"`, `'`のいずれか |
| openingPosition | int | Yes | 括弧が挿入される位置 | 0以上、ドキュメント長以下 |
| document | ParsedDocument | Yes | 解析済みドキュメント | null不可 |
| cancellationToken | CancellationToken | No | キャンセルトークン | - |

### 入力データソース

- ユーザーのキーボード入力
- エディタからのテキスト変更イベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| TextChanges | ImmutableArray<TextChange> | 適用すべきテキスト変更の配列 |
| CaretLocation | LinePosition | 補完後のキャレット位置 |

### 出力先

- エディタのテキストバッファ
- キャレット位置の更新

## 処理フロー

### 処理シーケンス

```
1. 括弧入力の検出
   └─ ユーザーが開き括弧を入力
2. 補完可否の判定（CanProvideBraceCompletion）
   └─ 入力位置がユーザーコード内かチェック
   └─ 文字列リテラル・コメント内の場合は補完しない
3. 括弧補完の実行（GetBraceCompletion）
   └─ 閉じ括弧のTextChangeを生成
   └─ キャレット位置を括弧間に設定
4. 後続フォーマット（GetTextChangesAfterCompletion）
   └─ 必要に応じてインデント調整
5. Enterキー対応（GetTextChangeAfterReturn）
   └─ ブロック内でのEnterキーによる展開処理
```

### フローチャート

```mermaid
flowchart TD
    A[開き括弧入力] --> B{ユーザーコード内?}
    B -->|No| C[補完なし]
    B -->|Yes| D{適切なトークン?}
    D -->|No| C
    D -->|Yes| E[閉じ括弧を挿入]
    E --> F[キャレットを括弧間に配置]
    F --> G{フォーマット必要?}
    G -->|Yes| H[インデント調整]
    G -->|No| I[完了]
    H --> I
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-71-1 | 非ユーザーコード除外 | 文字列リテラル・コメント内では補完しない | 常時 |
| BR-71-2 | エスケープシーケンス検出 | `{{`のような連続括弧はエスケープと判断 | 補間文字列内 |
| BR-71-3 | スキップトークン除外 | SkippedTokensTrivia内のトークンは除外 | 常時 |
| BR-71-4 | セマンティクス必要時の遅延読み込み | 一部の補完にはセマンティックモデルが必要 | 型パラメータの`<>`など |

### 計算ロジック

エスケープ検出ロジック（CouldEscapePreviousOpenBrace）:
- 現在位置から前方に同じ開き括弧が連続しているかカウント
- 奇数個の場合はエスケープの可能性ありと判定

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

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

データベース操作なし。メモリ上のドキュメントモデルに対する操作のみ。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | CancellationException | ユーザーがキャンセル | 処理中断 |
| - | InvalidOperationException | 無効な位置指定 | 補完スキップ |

### リトライ仕様

リトライなし。失敗時は補完をスキップし、通常の文字入力として処理される。

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

トランザクションなし。単一のテキスト変更操作として実行される。

## パフォーマンス要件

- 括弧入力からの応答時間: 50ms以内
- FrozenPartialSemanticsを使用し、ソースジェネレータの完了を待たない

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

特になし。ローカルのコード編集操作のみ。

## 備考

- C#とVisual Basicの両言語で利用可能
- 各括弧タイプ（波括弧、丸括弧、角括弧、山括弧、引用符）に対して個別の実装クラスが存在

---

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

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

### 推奨読解順序

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

まず、括弧補完で使用されるデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IBraceCompletionService.cs | `src/Features/Core/Portable/BraceCompletion/IBraceCompletionService.cs` | BraceCompletionResult、BraceCompletionContext構造体の定義を確認 |

**読解のコツ**:
- **73-90行目**: `BraceCompletionResult`はテキスト変更とキャレット位置を保持
- **92-109行目**: `BraceCompletionContext`は補完コンテキスト（開始位置、終了位置、ドキュメント）を保持

#### Step 2: インターフェースを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | IBraceCompletionService.cs | `src/Features/Core/Portable/BraceCompletion/IBraceCompletionService.cs` | サービスインターフェースの各メソッドの役割を把握 |

**主要処理フロー**:
- **31行目**: `CanProvideBraceCompletion` - 補完可否を判定
- **37行目**: `HasBraceCompletionAsync` - 補完結果が利用可能かを非同期判定
- **42行目**: `GetBraceCompletion` - 閉じ括弧の挿入テキスト変更を取得
- **53行目**: `GetTextChangesAfterCompletion` - 補完後のフォーマット処理
- **58行目**: `GetTextChangeAfterReturn` - Enterキー押下後の処理

#### Step 3: 抽象基底クラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | AbstractBraceCompletionService.cs | `src/Features/Core/Portable/BraceCompletion/AbstractBraceCompletionService.cs` | 共通ロジックの実装を確認 |

**主要処理フロー**:
- **19-22行目**: 抽象プロパティ定義（SyntaxFacts, OpeningBrace, ClosingBrace）
- **56-67行目**: `GetBraceCompletion` - テキスト変更とキャレット位置を計算
- **75-86行目**: `CanProvideBraceCompletion` - 非ユーザーコード内チェック
- **153-187行目**: 各種括弧の文字定義（CurlyBrace, Parenthesis, Bracketなど）
- **194-218行目**: `CouldEscapePreviousOpenBrace` - エスケープシーケンス検出

#### Step 4: 言語固有実装を理解する（C#の例）

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | CurlyBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/CurlyBraceCompletionService.cs` | C#の波括弧補完実装 |
| 4-2 | ParenthesisBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/ParenthesisBraceCompletionService.cs` | C#の丸括弧補完実装 |

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

```
エディタ（文字入力イベント）
    │
    ├─ IBraceCompletionService.CanProvideBraceCompletion
    │      └─ ISyntaxFactsService.IsInNonUserCode
    │
    ├─ IBraceCompletionService.HasBraceCompletionAsync
    │      └─ IsValidOpenBraceTokenAtPosition
    │             └─ IsValidOpeningBraceToken（言語固有）
    │
    ├─ IBraceCompletionService.GetBraceCompletion
    │      └─ TextChange生成
    │      └─ LinePosition計算
    │
    └─ IBraceCompletionService.GetTextChangesAfterCompletion
           └─ IndentationOptions適用
```

### データフロー図

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

開き括弧文字    ───▶ CanProvideBraceCompletion    ───▶ 補完可否判定
                      │
ParsedDocument  ───▶ HasBraceCompletionAsync      ───▶ トークン検証結果
                      │
                      ▼
              GetBraceCompletion
                      │
                      ▼
              TextChange（閉じ括弧挿入）+ CaretLocation ───▶ エディタへ適用
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IBraceCompletionService.cs | `src/Features/Core/Portable/BraceCompletion/` | インターフェース | サービスインターフェースと結果型定義 |
| AbstractBraceCompletionService.cs | `src/Features/Core/Portable/BraceCompletion/` | 抽象クラス | 共通ロジック実装 |
| ExportBraceCompletionServiceAttribute.cs | `src/Features/Core/Portable/BraceCompletion/` | 属性 | MEFエクスポート用属性 |
| CurlyBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/` | 実装 | C#波括弧補完 |
| ParenthesisBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/` | 実装 | C#丸括弧補完 |
| BracketBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/` | 実装 | C#角括弧補完 |
| LessAndGreaterThanBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/` | 実装 | C#山括弧補完 |
| StringLiteralBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/` | 実装 | C#ダブルクォート補完 |
| CharLiteralBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/` | 実装 | C#シングルクォート補完 |
| InterpolationBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/` | 実装 | C#補間式括弧補完 |
| InterpolatedStringBraceCompletionService.cs | `src/Features/CSharp/Portable/BraceCompletion/` | 実装 | C#補間文字列補完 |
