# 機能設計書 38-条件分岐（ifBreak）

## 概要

本ドキュメントは、PrettierのDocument Builder APIにおける条件分岐機能について記述する。この機能は、グループが折り返されるかどうかに基づいて異なる出力を生成するDocビルダーを提供する。

### 本機能の処理概要

条件分岐機能は、Prettierの中間表現（Doc）において、グループのモード（FLAT/BREAK）に応じて異なる内容を出力する機能である。`ifBreak`関数は、グループがBREAKモードの場合はbreakContentsを、FLATモードの場合はflatContentsを出力する。

**業務上の目的・背景**：コードフォーマットでは、1行で収まる場合と複数行に分割する場合で異なる出力が必要なケースが多い。例えば、配列が1行の場合は末尾カンマを省略し、複数行の場合は末尾カンマを付けるといった処理が必要となる。ifBreak機能により、グループのモードに応じた動的な出力切り替えが可能となる。

**機能の利用シーン**：
- 複数行の配列/オブジェクトで末尾カンマを付ける場合
- 1行の場合はスペース、複数行の場合は改行を出力する場合
- 複数行の場合のみ特定の文字列を出力する場合
- 特定のグループのモードを参照して出力を切り替える場合

**主要な処理内容**：
1. ifBreak: BREAKモードならbreakContents、FLATモードならflatContentsを出力
2. groupIdオプション: 特定のグループのモードを参照して判定

**関連システム・外部連携**：Document Printer（printDocToString）、group関数

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 14 | Usage - Plugins | 主画面 | プラグイン作成時の条件分岐機能を説明 |
| 26 | Misc - Technical Details | 参照画面 | 条件分岐の技術的詳細を説明 |

## 機能種別

Document Builder API / フォーマット制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| breakContents | Doc | Yes | BREAKモード時に出力する内容 | 有効なDocであること |
| flatContents | Doc | No | FLATモード時に出力する内容（デフォルト: ""） | 有効なDocまたは空文字 |
| options | IfBreakOptions | No | オプション | オブジェクトであること |
| options.groupId | symbol | No | 参照するグループのID | symbolであること |

### 入力データソース

- プリンター関数内でDoc構築時に使用
- builders.ifBreakとしてインポート

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ifBreak(breakContents, flatContents, options) | IfBreak | 条件分岐Doc |

### 出力先

Doc構造としてDocument Printerに渡される

## 処理フロー

### 処理シーケンス

```
1. プリンター関数でDoc構築時にifBreakを使用
2. printDocToString関数でDoc処理時にifBreakを評価
3. DOC_TYPE_IF_BREAKの処理
   ├─ groupIdあり → groupModeMapから指定グループのモードを取得
   └─ groupIdなし → 現在のモードを使用
4. モードに応じて出力内容を決定
   ├─ BREAKモード → breakContentsを出力
   └─ FLATモード → flatContentsを出力
```

### フローチャート

```mermaid
flowchart TD
    A[DOC_TYPE_IF_BREAK処理] --> B{groupIdあり?}
    B -->|Yes| C[groupModeMapから取得]
    B -->|No| D[現在のモードを使用]
    C --> E{モードは?}
    D --> E
    E -->|BREAK| F[breakContentsを処理]
    E -->|FLAT| G[flatContentsを処理]
    F --> H{breakContentsあり?}
    G --> I{flatContentsあり?}
    H -->|Yes| J[breakContentsを出力]
    H -->|No| K[何も出力しない]
    I -->|Yes| L[flatContentsを出力]
    I -->|No| M[何も出力しない]
    J --> N[次のDoc処理]
    K --> N
    L --> N
    M --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-38-01 | BREAKモード出力 | BREAKモードの場合はbreakContentsを出力 | モードがBREAKの場合 |
| BR-38-02 | FLATモード出力 | FLATモードの場合はflatContentsを出力 | モードがFLATの場合 |
| BR-38-03 | デフォルトflatContents | flatContentsが未指定の場合は空文字 | flatContents省略時 |
| BR-38-04 | groupId参照 | groupIdが指定された場合はそのグループのモードを参照 | groupId指定時 |
| BR-38-05 | 未登録groupId | groupIdが未登録の場合はFLATモードとして扱う | groupModeMapに未登録の場合 |

### 計算ロジック

ifBreak Doc生成:
```javascript
function ifBreak(breakContents, flatContents = "", options = {}) {
  assertDoc(breakContents);
  if (flatContents !== "") {
    assertDoc(flatContents);
  }

  return {
    type: DOC_TYPE_IF_BREAK,
    breakContents,
    flatContents,
    groupId: options.groupId,
  };
}
```

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

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | AssertionError | 不正なbreakContentsが渡された場合 | 有効なDocを渡す |
| - | AssertionError | 不正なflatContentsが渡された場合 | 有効なDocを渡す |

### リトライ仕様

リトライは行わない。

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

本機能はトランザクション管理を必要としない。

## パフォーマンス要件

- ifBreak Docの生成は軽量なオブジェクト生成
- groupModeMapでのモード参照はO(1)

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

特になし

## 備考

- groupIdは通常Symbol()で生成し、group関数のidオプションと対応付ける
- fits関数内でもifBreakは評価され、適切なコンテンツが幅計算に使用される

---

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

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

### 推奨読解順序

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

ifBreak Docの型定義と構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | if-break.js | `src/document/builders/if-break.js` | IfBreak型定義、ifBreak関数 |

**読解のコツ**:
- `IfBreak`型は`type`、`breakContents`、`flatContents`、`groupId`プロパティを持つ
- `flatContents`のデフォルトは空文字""

#### Step 2: ビルダー関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | if-break.js | `src/document/builders/if-break.js` | ifBreak関数の実装 |

**主要処理フロー**:
1. **22-34行目**: ifBreak関数 - breakContentsとflatContentsを検証してIfBreak Docを生成
2. **23行目**: breakContentsのアサーション
3. **24-26行目**: flatContentsが空文字でなければアサーション
4. **28-33行目**: IfBreak Doc生成

#### Step 3: プリンターでの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | printer.js | `src/document/printer/printer.js` | DOC_TYPE_IF_BREAK処理、fits関数内の処理 |

**主要処理フロー**:
- **136-146行目**: fits関数内のDOC_TYPE_IF_BREAK処理
- **137-139行目**: groupModeからモードを決定
- **140-141行目**: モードに応じてcontentsを選択
- **434-461行目**: printDocToString内のDOC_TYPE_IF_BREAK処理
- **436行目**: groupIdからgroupModeを取得
- **437-446行目**: BREAKモードの場合の処理
- **448-457行目**: FLATモードの場合の処理

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

```
builders.ifBreak (if-break.js:22)
    │
    └─ assertDoc → IfBreak Doc生成
           │
           └─ printDocToString (printer.js:179)
                  │
                  └─ DOC_TYPE_IF_BREAK処理 (printer.js:434)
                         │
                         ├─ groupId確認
                         │      │
                         │      ├─ [あり] → groupModeMap[groupId]
                         │      │
                         │      └─ [なし] → 現在のmode
                         │
                         └─ モード判定
                                │
                                ├─ [BREAK] → breakContentsを処理
                                │
                                └─ [FLAT] → flatContentsを処理

fits関数内のDOC_TYPE_IF_BREAK処理 (printer.js:136)
    │
    ├─ groupIdからgroupModeを取得（デフォルトFLAT）
    │
    └─ モードに応じたcontentsを幅計算に使用
```

### データフロー図

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

breakContents          ifBreak                         IfBreak Doc
flatContents ─────────▶ Doc生成 ──────────────────────▶
groupId                      │
                             ▼
                      printDocToString
                             │
                             ▼
                      DOC_TYPE_IF_BREAK処理
                             │
                    ┌────────┴────────┐
                    │                 │
              [groupId]         [no groupId]
                    │                 │
                    ▼                 ▼
              groupModeMap       現在のmode
                    │                 │
                    └────────┬────────┘
                             │
                    ┌────────┴────────┐
                    │                 │
               [BREAK]            [FLAT]
                    │                 │
                    ▼                 ▼
              breakContents     flatContents
                    │                 │
                    └────────┬────────┘
                             │
                             ▼
                        コンテンツ出力
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| if-break.js | `src/document/builders/if-break.js` | ソース | ifBreak関数の定義 |
| types.js | `src/document/builders/types.js` | ソース | DOC_TYPE_IF_BREAK定数 |
| group.js | `src/document/builders/group.js` | ソース | groupのidオプション（ifBreakと連携） |
| index.js | `src/document/builders/index.js` | ソース | ビルダーのエクスポート |
| public.js | `src/document/public.js` | ソース | 公開APIのエクスポート |
| printer.js | `src/document/printer/printer.js` | ソース | DOC_TYPE_IF_BREAK処理 |
| assert-doc.js | `src/document/utilities/assert-doc.js` | ソース | Docアサーション関数 |
