# 機能設計書 111-テキストエディタ

## 概要

本ドキュメントは、Roslynのテキストエディタコンポーネント（EditorFeatures/Text）の機能設計を定義する。Visual Studioエディタとの統合において、テキストバッファとRoslyn SourceTextの相互変換を提供する基盤機能である。

### 本機能の処理概要

テキストエディタコンポーネントは、Visual StudioのテキストバッファAPIとRoslynのSourceText間のブリッジ機能を提供し、効率的なテキスト操作とドキュメント管理を実現する。

**業務上の目的・背景**：IDEでのコード編集においては、エディタのネイティブなテキストバッファ形式とRoslynの分析エンジンが期待するSourceText形式の間で効率的な変換が必要である。本機能は、メモリ効率を維持しながら高速な変換を可能にし、リアルタイムコード分析のパフォーマンスを確保する。

**機能の利用シーン**：
- ユーザーがエディタでコードを編集する際のテキスト変更の追跡
- IntelliSense、コード補完、診断機能がソースコードにアクセスする際
- コードリファクタリング操作でテキスト変更を適用する際
- 複数ドキュメントにまたがるリンクファイルの同期時

**主要な処理内容**：
1. ITextBuffer/ITextSnapshotからSourceTextへの変換（AsText拡張メソッド）
2. SourceTextからITextBufferへの変換（GetTextBuffer拡張メソッド）
3. テキスト変更範囲の効率的な差分計算（GetChangeRanges）
4. テキストバッファのクローン作成によるパフォーマンス最適化
5. エディタスナップショットとSourceTextの弱参照マッピング管理

**関連システム・外部連携**：Visual Studio Editor API (Microsoft.VisualStudio.Text)、Roslyn Workspace API

**権限による制御**：特になし。エディタが開いているドキュメントに対して動作する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コードエディタ | 主画面 | すべてのテキスト編集操作の基盤 |

## 機能種別

データ変換 / インターフェースブリッジ

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| textBuffer | ITextBuffer | Yes | Visual Studioのテキストバッファ | null不可 |
| textSnapshot | ITextSnapshot | Yes | テキストスナップショット | null不可 |
| sourceText | SourceText | Yes | Roslyn SourceText | null不可 |
| changes | IEnumerable<TextChange> | No | テキスト変更リスト | 空の場合は同一テキストを返す |

### 入力データソース

- Visual Studio Editor: ITextBuffer、ITextSnapshot
- Roslyn Workspace: SourceText、SourceTextContainer

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| SourceText | SourceText | 変換されたRoslyn SourceText |
| ITextBuffer | ITextBuffer | 変換されたVSテキストバッファ |
| TextChangeRange | IReadOnlyList<TextChangeRange> | テキスト変更範囲のリスト |

### 出力先

Roslyn分析エンジン、Visual Studioエディタ

## 処理フロー

### 処理シーケンス

```
1. ITextSnapshot → SourceText変換
   └─ s_textSnapshotMapからキャッシュを検索
   └─ キャッシュなしの場合、SnapshotSourceTextを新規作成
   └─ TextBufferContainerを関連付け

2. テキスト変更の適用（WithChanges）
   └─ ITextBufferCloneServiceが利用可能か確認
   └─ 利用可能：バッファクローンを作成して変更を適用
   └─ 利用不可：基底クラスの実装にフォールバック

3. 変更範囲の計算（GetChangeRanges）
   └─ 同一テキストの場合、NoChangesを返す
   └─ TextBufferContainerから最新のイベント情報を確認
   └─ ITextImageバージョンを比較して差分を計算
```

### フローチャート

```mermaid
flowchart TD
    A[開始: テキスト変換要求] --> B{キャッシュに存在?}
    B -->|Yes| C[キャッシュから取得]
    B -->|No| D[SnapshotSourceText作成]
    D --> E[弱参照マップに登録]
    E --> F[TextBufferContainerと関連付け]
    C --> G[SourceTextを返却]
    F --> G
    G --> H[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | スナップショットキャッシュ | 同一ITextSnapshotに対しては同一SourceTextインスタンスを返す | 常時 |
| BR-002 | 弱参照管理 | エディタスナップショットへの参照は弱参照で保持する | 常時 |
| BR-003 | バージョン同期 | ReiteratedVersionNumberが同一の場合、コンテンツ同一とみなす | 変更範囲計算時 |

### 計算ロジック

- 変更範囲計算：ITextImageのバージョン情報を使用して、最小限の変更範囲を特定

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

該当なし（インメモリ処理のみ）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ArgumentException | 引数エラー | SourceTextContainerがITextBufferから作成されていない | 適切なコンテナを使用 |
| ArgumentNullException | 引数エラー | null引数が渡された | 有効なオブジェクトを渡す |

### リトライ仕様

リトライなし（同期処理）

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

該当なし（読み取り専用操作が主）

## パフォーマンス要件

- スナップショット変換：マイクロ秒オーダー
- キャッシュヒット率：95%以上を期待
- メモリ：弱参照によりGC連携

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

特になし（ローカルメモリ操作のみ）

## 備考

- ConditionalWeakTableを使用してメモリリークを防止
- ITextImage APIを活用してスナップショットとの効率的なマッピングを実現

---

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

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

### 推奨読解順序

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

まず、テキストバッファとSourceTextの関係性を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ContentTypeNames.cs | `src/EditorFeatures/Text/ContentTypeNames.cs` | サポートされるコンテンツタイプ（C#、VB等）の定義 |
| 1-2 | ITextBufferCloneService.cs | `src/EditorFeatures/Text/Implementation/TextBufferFactoryService/ITextBufferCloneService.cs` | バッファクローン機能のインターフェース定義 |

**読解のコツ**: Visual Studio Editor APIの ITextBuffer、ITextSnapshot、ITextImage の違いを理解しておくと、コードの意図が明確になる。

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

拡張メソッド群がエントリーポイントとなる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | Extensions.cs | `src/EditorFeatures/Text/Extensions.cs` | AsText、GetTextBuffer等の公開拡張メソッド |

**主要処理フロー**:
1. **14-15行目**: AsTextContainer - ITextBufferからSourceTextContainerへの変換
2. **17-18行目**: GetTextBuffer - SourceTextContainerからITextBufferへの逆変換
3. **39-43行目**: AsText - ITextSnapshotからSourceTextへの変換（最も頻繁に使用）
4. **51-60行目**: GetWorkspace - テキストバッファから関連Workspaceを取得

#### Step 3: コア実装を理解する

SnapshotSourceTextがSourceTextの実装を提供。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | Extensions.SnapshotSourceText.cs | `src/EditorFeatures/Text/Extensions.SnapshotSourceText.cs` | SnapshotSourceTextクラスの実装 |

**主要処理フロー**:
- **62行目**: s_textSnapshotMap - スナップショットとSourceTextのキャッシュ
- **68行目**: s_textImageToEditorSnapshotMap - 逆引きマップ（弱参照）
- **70-89行目**: From静的メソッド - キャッシュ付きファクトリ
- **184-224行目**: WithChanges - テキスト変更の効率的な適用
- **317-343行目**: GetChangeRanges - 変更範囲の計算

#### Step 4: サポートクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | Extensions.TextBufferContainer.cs | `src/EditorFeatures/Text/Extensions.TextBufferContainer.cs` | SourceTextContainerの実装 |
| 4-2 | ITextImageHelpers.cs | `src/EditorFeatures/Text/ITextImageHelpers.cs` | ITextImage操作のヘルパー |

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

```
Extensions.AsText(ITextSnapshot)
    │
    ├─ SnapshotSourceText.From(ITextBufferCloneService, ITextSnapshot)
    │      ├─ s_textSnapshotMap.GetValue() [キャッシュ検索/作成]
    │      └─ TextBufferContainer.From(ITextBuffer)
    │
    └─ SnapshotSourceText (コンストラクタ)
           ├─ RecordReverseMapAndGetImage()
           └─ GetEncodingOrUTF8()

SnapshotSourceText.WithChanges(IEnumerable<TextChange>)
    │
    ├─ ITextBufferCloneService.CloneWithUnknownContentType()
    │
    └─ ChangedSourceText (新規作成)
           └─ GetChangeRanges() [差分計算]
```

### データフロー図

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

ITextSnapshot ────────▶ SnapshotSourceText.From() ────▶ SourceText
                              │
                              ▼
                       ConditionalWeakTable
                       (キャッシュマップ)

SourceText ───────────▶ Extensions.GetTextBuffer() ───▶ ITextBuffer
                              │
                              ▼
                       TextBufferContainer
                       (弱参照管理)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| Extensions.cs | `src/EditorFeatures/Text/Extensions.cs` | ソース | 公開拡張メソッドのエントリーポイント |
| Extensions.SnapshotSourceText.cs | `src/EditorFeatures/Text/Extensions.SnapshotSourceText.cs` | ソース | SourceTextのITextSnapshot実装 |
| Extensions.TextBufferContainer.cs | `src/EditorFeatures/Text/Extensions.TextBufferContainer.cs` | ソース | SourceTextContainerの実装 |
| ContentTypeNames.cs | `src/EditorFeatures/Text/ContentTypeNames.cs` | ソース | コンテンツタイプ定数定義 |
| ITextBufferCloneService.cs | `src/EditorFeatures/Text/Implementation/TextBufferFactoryService/ITextBufferCloneService.cs` | ソース | バッファクローンインターフェース |
| TextBufferCloneServiceFactory.cs | `src/EditorFeatures/Text/Implementation/TextBufferFactoryService/TextBufferCloneServiceFactory.cs` | ソース | クローンサービスのファクトリ |
| ITextImageHelpers.cs | `src/EditorFeatures/Text/ITextImageHelpers.cs` | ソース | ITextImage操作ヘルパー |
| SnapshotPointExtensions.cs | `src/EditorFeatures/Text/Shared/Extensions/SnapshotPointExtensions.cs` | ソース | SnapshotPoint拡張メソッド |
| TextSpanExtensions.cs | `src/EditorFeatures/Text/Shared/Extensions/TextSpanExtensions.cs` | ソース | TextSpan拡張メソッド |
| ITextSnapshotExtensions.cs | `src/EditorFeatures/Text/Shared/Extensions/ITextSnapshotExtensions.cs` | ソース | ITextSnapshot拡張メソッド |
