# 機能設計書 79-文字列インデント

## 概要

本ドキュメントは、Roslynの文字列インデント（StringIndentation）機能の設計を記載する。この機能は、C# 11で導入された生文字列リテラル（Raw String Literals）などの複数行文字列において、インデント位置を視覚的に示す垂直線を表示する。

### 本機能の処理概要

**業務上の目的・背景**：C# 11の生文字列リテラルでは、終了の`"""`のインデント位置が文字列内容の基準インデントを決定する。この仕組みは強力だが、開発者が意図したインデント位置を視覚的に把握することが困難な場合がある。文字列インデント機能は、このインデント位置をエディタ上に垂直線として表示することで、開発者が文字列の構造を正確に理解できるよう支援する。

**機能の利用シーン**：コードエディタで生文字列リテラルや補間生文字列リテラルを含むファイルを開いたとき、自動的にインデントガイドラインが表示される。

**主要な処理内容**：
1. 指定されたテキスト範囲内の文字列リテラルを検出
2. 生文字列リテラルのインデント位置を計算
3. インデント領域（IndentSpan）と穴領域（HoleSpans）を返却
4. エディタがインデントガイドラインを描画

**関連システム・外部連携**：Visual Studioエディタ、Language Server Protocol (LSP)、エディタの装飾レイヤーと連携する。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | コードエディタ | 主画面 | 複数行文字列のインデント表示 |

## 機能種別

エディタ支援機能（視覚的フィードバック）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| document | Document | Yes | 対象ドキュメント | null不可 |
| textSpan | TextSpan | Yes | 検索対象のテキスト範囲 | 有効な範囲 |
| cancellationToken | CancellationToken | No | キャンセルトークン | - |

### 入力データソース

- エディタからの表示範囲情報
- ドキュメントの構文木

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| IndentSpan | TextSpan | インデント領域全体のスパン |
| OrderedHoleSpans | ImmutableArray<TextSpan> | 穴領域（補間式など）のスパン配列 |

### 出力先

- StringIndentationRegionのコレクションとして返却
- エディタの装飾レイヤー（垂直線描画）

## 処理フロー

### 処理シーケンス

```
1. サービスの取得
   └─ IStringIndentationServiceを言語に応じて取得
2. インデント領域の取得
   └─ GetStringIndentationRegionsAsyncを呼び出し
3. 文字列リテラルの検出
   ├─ 構文木を解析
   └─ 生文字列リテラル、補間生文字列を特定
4. インデント位置の計算
   ├─ 終了`"""`のインデント位置を基準に計算
   └─ 補間式の穴領域を特定
5. 結果返却
   └─ StringIndentationRegionのコレクションを返却
6. エディタ描画
   └─ 各領域にインデントガイドラインを描画
```

### フローチャート

```mermaid
flowchart TD
    A[表示範囲変更] --> B[GetStringIndentationRegionsAsync呼び出し]
    B --> C[構文木取得]
    C --> D[文字列リテラル検出]
    D --> E{生文字列あり?}
    E -->|No| F[空配列返却]
    E -->|Yes| G[インデント位置計算]
    G --> H[穴領域特定]
    H --> I[StringIndentationRegion生成]
    I --> J[結果返却]
    J --> K[エディタでガイドライン描画]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-79-1 | 生文字列対象 | 生文字列リテラル（`"""`）と補間生文字列（`$"""`）が対象 | C# 11以降 |
| BR-79-2 | インデント基準 | 終了`"""`の開始位置がインデントの基準 | 常時 |
| BR-79-3 | 穴領域除外 | 補間式の穴領域ではガイドラインを描画しない | 補間文字列 |
| BR-79-4 | スパン計算 | IndentSpanは文字列開始行から終了`"""`の直前まで | 常時 |

### 計算ロジック

インデントスパンの計算:
- 開始位置: 文字列リテラルが始まる行の先頭
- 終了位置: 終了`"""`の開始位置

穴領域の計算:
- 補間式`{...}`の開始から終了までのスパン
- 複数の補間式がある場合は順序付きで返却

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | CancellationException | ユーザーがキャンセル | 処理中断 |

### リトライ仕様

リトライなし。失敗時は空の配列を返却。

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

トランザクションなし。読み取り専用操作。

## パフォーマンス要件

- スクロール時にもスムーズに動作
- 表示範囲限定により不要な計算をスキップ
- 構文木のキャッシュを活用

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

特になし。ローカルの読み取り専用操作のみ。

## 備考

- C# 11以降の生文字列リテラル機能に対応
- Visual Basicには生文字列リテラルがないため、主にC#で使用
- エディタ描画はEditorFeatures層で実装

---

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

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

### 推奨読解順序

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

まず、文字列インデント機能で使用されるデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | IStringIndentationService.cs | `src/Features/Core/Portable/StringIndentation/IStringIndentationService.cs` | サービスインターフェースとStringIndentationRegion構造体 |

**読解のコツ**:
- **13-16行目**: `IStringIndentationService`インターフェース定義
- **18-110行目**: `StringIndentationRegion`構造体の詳細なドキュメント
- **22-55行目**: `IndentSpan`プロパティの説明（コード例付き）
- **57-107行目**: `OrderedHoleSpans`プロパティの説明（補間式の穴領域）

#### Step 2: 言語固有実装を理解する

言語固有の実装は以下のパスに存在する:
- C#: `src/Features/CSharp/Portable/StringIndentation/`

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

```
エディタ（表示範囲変更）
    │
    └─ IStringIndentationService.GetStringIndentationRegionsAsync
           │
           ├─ Document.GetSyntaxRootAsync
           │
           ├─ 文字列リテラル検出（言語固有実装）
           │      ├─ 生文字列リテラル（"""）
           │      └─ 補間生文字列リテラル（$"""）
           │
           ├─ インデント位置計算
           │      └─ 終了"""の開始位置を基準
           │
           ├─ 穴領域特定（補間式）
           │      └─ 各{...}のスパンを収集
           │
           └─ ImmutableArray<StringIndentationRegion>生成
```

### データフロー図

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

Document        ───▶ GetStringIndentationRegionsAsync ───▶ ImmutableArray<StringIndentationRegion>
TextSpan        ───▶                                       ├─ IndentSpan
                      │                                    └─ OrderedHoleSpans
                      ├─ 構文木取得
                      │
                      ├─ 生文字列リテラル検出
                      │
                      ├─ インデント位置計算
                      │
                      └─ 穴領域特定
                                                         │
                                                         ▼
                                                  エディタ装飾レイヤー
                                                  （垂直線描画）

描画イメージ:
var x = """
       |x      ← 垂直線がインデント位置に表示
       |y
        """;
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| IStringIndentationService.cs | `src/Features/Core/Portable/StringIndentation/` | インターフェース | サービスインターフェースと結果型定義 |
