# 機能設計書 60-Pragma挿入（insertPragma）

## 概要

本ドキュメントは、Prettierの`insertPragma`オプションに関する機能設計書である。このオプションは、フォーマット実行時にファイルの先頭に`@format`プラグマを自動的に挿入する。`requirePragma`オプションと組み合わせて使用することで、段階的なPrettier導入を支援する。

### 本機能の処理概要

**業務上の目的・背景**：大規模なコードベースにPrettierを段階的に導入する際、フォーマット済みファイルを識別するためのマーカーが必要になる。`insertPragma`を使用すると、フォーマット実行時に自動的に`@format`プラグマが挿入され、そのファイルがPrettierでフォーマット済みであることを示せる。これにより、`requirePragma`と組み合わせて段階的導入が可能になる。

**機能の利用シーン**：大規模プロジェクトへのPrettier段階導入、フォーマット済みファイルの識別、CIでの一貫性チェックに使用される。

**主要な処理内容**：
1. オプション値（true/false）の読み込み
2. trueの場合、ファイルにPragmaがまだないことを確認
3. printer.insertPragma関数でPragmaを挿入
4. フォーマット済みコードの先頭にPragmaを追加

**関連システム・外部連携**：すべての言語プリンターのinsertPragma関数と連携して動作する。

**権限による制御**：権限による制御は存在しない。設定ファイルまたはCLIオプションで指定する。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | 補助機能 | サイドバーからPragma挿入オプションを設定 |
| 19 | Configuration - Options | 主機能 | insertPragmaオプションの詳細説明 |

## 機能種別

設定オプション / フォーマット制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| insertPragma | boolean | No | Pragmaを挿入するかどうか | true/falseのブール値のみ許可 |

### 入力データソース

- 設定ファイル（.prettierrc、prettier.config.js等）
- CLIオプション（--insert-pragma）
- プログラマティックAPI呼び出し時のオプションオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| formattedCode | string | Pragma挿入が適用されたフォーマット済みコード |

### 出力先

フォーマット結果は呼び出し元に返却される（標準出力、ファイル、API戻り値）。

## 処理フロー

### 処理シーケンス

```
1. オプション解析
   └─ insertPragmaオプションの値を取得（デフォルト: false）
2. 前提条件チェック
   └─ requirePragma=falseかつinsertPragma=trueかつprinter.insertPragmaが存在
3. Pragma存在チェック
   └─ hasPragma関数で既にPragmaがあるか確認
4. Pragma挿入
   └─ Pragmaがない場合、printer.insertPragma関数で挿入
5. フォーマット実行
   └─ Pragma挿入済みテキストをフォーマット
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B{insertPragma?}
    B -->|false| C[通常フォーマット]
    B -->|true| D{requirePragma?}
    D -->|true| C
    D -->|false| E{printer.insertPragmaあり?}
    E -->|No| C
    E -->|Yes| F{既にPragmaあり?}
    F -->|Yes| C
    F -->|No| G[printer.insertPragma実行]
    G --> H[Pragma挿入済みテキスト]
    H --> I[フォーマット実行]
    C --> J[フォーマット済みテキスト]
    I --> J
    J --> K[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-60-1 | デフォルト動作 | Pragmaを挿入しない | insertPragma = false（デフォルト） |
| BR-60-2 | Pragma挿入 | @formatプラグマをファイル先頭に挿入 | insertPragma = true |
| BR-60-3 | 重複防止 | 既にPragmaがある場合は挿入しない | hasPragma() = true |
| BR-60-4 | requirePragma除外 | requirePragma=trueの場合は挿入しない | requirePragma = true |
| BR-60-5 | printer依存 | printer.insertPragmaが必要 | 常時 |
| BR-60-6 | 挿入形式 | 言語に応じた適切なコメント形式で挿入 | 言語固有実装 |

### 計算ロジック

```javascript
// Pragma挿入ロジック（core.js）
if (
  !options.requirePragma &&
  options.insertPragma &&
  options.printer.insertPragma &&
  !(await hasPragma(text, options))
) {
  text = options.printer.insertPragma(text);
}
```

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

データベース操作は発生しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 型エラー | boolean以外の値が指定された場合 | Prettierのオプション検証でエラーが発生 |

### リトライ仕様

リトライは不要（同期的な設定適用処理）。

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

トランザクション管理は不要。

## パフォーマンス要件

Docblockの解析と文字列操作のみであり、パフォーマンスへの影響は軽微。

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

セキュリティに関する特別な考慮事項は存在しない。

## 備考

- `requirePragma`オプションと組み合わせて段階的導入に使用される。
- 言語ごとにinsertPragma関数の実装が異なる（JavaScript: Docblock、CSS: コメント等）。
- 挿入されるPragmaは`@format`（FORMAT_PRAGMA_TO_INSERT）。

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | core-options.evaluate.js | `src/main/core-options.evaluate.js` | insertPragmaオプションの定義 |

**読解のコツ**: このファイルでは、insertPragmaがboolean型でデフォルトfalse、Specialカテゴリ（CLI表示ではOther）に属することを確認する。

#### Step 2: コア処理での使用を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | core.js | `src/main/core.js` | formatWithCursor関数でのinsertPragma使用 |

**主要処理フロー**:
1. **347-354行目**: insertPragma条件チェックと実行
2. **348行目**: `!options.requirePragma`の条件
3. **349行目**: `options.insertPragma`の条件
4. **350行目**: `options.printer.insertPragma`の存在チェック
5. **351行目**: `!(await hasPragma(text, options))`の条件
6. **353行目**: `options.printer.insertPragma(text)`の呼び出し

#### Step 3: JavaScript固有のPragma挿入を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | pragma.js | `src/language-js/pragma.js` | JavaScriptのinsertPragma実装 |

**主要処理フロー**:
- **32-57行目**: insertPragma関数の実装
- **33行目**: parseDocBlockでDocblockを解析
- **36-42行目**: 新しいDocblockを構築
- **38行目**: FORMAT_PRAGMA_TO_INSERT（@format）を追加

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

```
formatWithCursor (core.js)
    │
    ├─ 条件チェック (347-351行目)
    │      ├─ !options.requirePragma
    │      ├─ options.insertPragma
    │      ├─ options.printer.insertPragma存在
    │      └─ !(await hasPragma(text, options))
    │
    └─ options.printer.insertPragma (353行目)
           │
           └─ JavaScript: pragma.js:32
                  ├─ parseDocBlock (33行目)
                  ├─ strip (34行目)
                  ├─ print (36-42行目)
                  │      └─ FORMAT_PRAGMA_TO_INSERT追加
                  └─ normalizeEndOfLine (47-49行目)
```

### データフロー図

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

オプション設定 ───▶ formatWithCursor関数 ───▶ フォーマット結果
(insertPragma)        (core.js)
        │
        ▼
ソースコード ───▶ 条件チェック ───▶ 条件満たす場合
        │                              │
        │                              ▼
        │                    printer.insertPragma
        │                              │
        │                              ▼
        └──────────────────▶ フォーマット実行
                                       │
                                       ▼
                              Pragma付きフォーマット済みテキスト
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| core-options.evaluate.js | `src/main/core-options.evaluate.js` | ソース | オプション定義（100-106行目） |
| core.js | `src/main/core.js` | ソース | insertPragma使用箇所（347-354行目） |
| pragma.js | `src/language-js/pragma.js` | ソース | JavaScriptのinsertPragma実装（32-57行目） |
| pragma.js | `src/language-css/pragma.js` | ソース | CSSのinsertPragma実装 |
| pragma.js | `src/language-graphql/pragma.js` | ソース | GraphQLのinsertPragma実装 |
| pragma.js | `src/language-markdown/pragma.js` | ソース | MarkdownのinsertPragma実装 |
| pragma.js | `src/language-yaml/pragma.js` | ソース | YAMLのinsertPragma実装 |
| pragma.js | `src/language-html/pragma.js` | ソース | HTMLのinsertPragma実装 |
| printers.js | `src/language-js/printers.js` | ソース | insertPragmaのexport（32行目） |
| printer-html.js | `src/language-html/printer-html.js` | ソース | insertPragmaのimport/export |
| index.d.ts | `src/index.d.ts` | 型定義 | TypeScript型定義（387行目） |
| index.d.ts | `src/index.d.ts` | 型定義 | Printer.insertPragma型（519行目） |
