# 機能設計書 45-JSXクォートスタイル（jsxSingleQuote）

## 概要

本ドキュメントは、PrettierのJSXクォートスタイル制御機能（jsxSingleQuote）の設計仕様を定義する。

### 本機能の処理概要

jsxSingleQuoteオプションは、JSX属性値のクォート文字（引用符）をダブルクォート（"）からシングルクォート（'）に変更するかどうかを制御する。HTMLの慣習に従いダブルクォートを使用するか、JavaScript側のsingleQuoteオプションと統一感を持たせるためにシングルクォートを使用するかを選択できる。

**業務上の目的・背景**：
JSXはHTMLに似た構文を持つが、JavaScript内で使用されるため、クォートスタイルについてはHTMLの慣習（ダブルクォート）とJavaScriptの慣習（プロジェクトによってはシングルクォート）の間で議論が生じることがある。この機能により、JSX属性のクォートスタイルをJavaScriptの文字列リテラルとは独立して設定でき、プロジェクトのスタイルガイドに合わせた一貫した出力が可能になる。

**機能の利用シーン**：
1. HTMLの慣習に従いJSX属性にダブルクォートを使用したい場合（false）
2. JavaScriptのsingleQuoteオプションと統一感を持たせたい場合（true）
3. ReactやVueプロジェクトでJSXスタイルを統一したい場合
4. コードベース全体で一貫したクォートスタイルを適用したい場合

**主要な処理内容**：
1. jsxSingleQuoteオプションの値取得（true/false）
2. JSX属性の検出
3. 文字列リテラル属性値の抽出
4. 優先クォートの決定（getPreferredQuote関数使用）
5. HTMLエンティティの変換（&apos; / &quot;）

**関連システム・外部連携**：
- JavaScript/TypeScriptパーサー
- JSXプリンター
- CLI、API、エディタプラグインからの呼び出し

**権限による制御**：
特になし。全てのユーザーが同一の機能を使用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | 補助機能 | サイドバーからJSXクォートスタイルを設定 |
| 19 | Configuration - Options | 主機能 | jsxSingleQuoteオプションの詳細説明 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| jsxSingleQuote | boolean | No | JSX属性でシングルクォートを使用するかどうか | true/falseのみ |

### 入力データソース

- 設定ファイル（.prettierrc、prettier.config.js、package.json等）
- CLI引数（--jsx-single-quote）
- API呼び出し時のオプションオブジェクト

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| formatted | string | JSXクォートスタイルが適用されたフォーマット済みコード |

### 出力先

- 標準出力（CLIの場合）
- ファイル（--write オプション使用時）
- API戻り値

## 処理フロー

### 処理シーケンス

```
1. オプション解析
   └─ jsxSingleQuoteオプションの値を取得（デフォルト: false）
2. JSX属性検出
   └─ JSXAttribute ノードで StringLiteral 値を特定
3. HTMLエンティティ処理
   └─ &apos; と &quot; をアンエスケープ
4. 優先クォート決定
   └─ getPreferredQuote関数でエスケープ最小のクォートを選択
5. エンティティ変換
   └─ 選択したクォートに応じて適切なエンティティに変換
6. 出力生成
   └─ クォートと変換済み文字列を結合
```

### フローチャート

```mermaid
flowchart TD
    A[JSXAttribute検出] --> B{StringLiteral値?}
    B -->|No| C[そのまま出力]
    B -->|Yes| D[HTMLエンティティをアンエスケープ]
    D --> E{jsxSingleQuoteの値}
    E -->|true| F[シングルクォート優先]
    E -->|false| G[ダブルクォート優先]
    F --> H[getPreferredQuote]
    G --> H
    H --> I{選択されたクォート}
    I -->|'| J[" を &quot; に変換しない]
    I -->|"| K[' を &apos; に変換しない]
    J --> L[' + final + ' 出力]
    K --> M[" + final + " 出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-45-01 | デフォルト設定 | デフォルトではfalse（ダブルクォート） | jsxSingleQuote未指定 |
| BR-45-02 | シングルクォート使用 | trueではJSX属性にシングルクォートを使用 | jsxSingleQuote: true |
| BR-45-03 | ダブルクォート使用 | falseではJSX属性にダブルクォートを使用 | jsxSingleQuote: false |
| BR-45-04 | エスケープ最小化 | エスケープが少なくて済むクォートを優先して選択 | 常に適用 |
| BR-45-05 | HTMLエンティティ変換 | 使用クォートに応じて適切なHTMLエンティティに変換 | 常に適用 |

### 計算ロジック

JSX属性クォート選択アルゴリズム（printJsxAttribute関数）:
```javascript
const quote = getPreferredQuote(final, options.jsxSingleQuote);
final = quote === '"'
  ? final.replaceAll('"', "&quot;")
  : final.replaceAll("'", "&apos;");
```

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

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

該当なし（本機能はデータベース操作を行わない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | バリデーションエラー | jsxSingleQuoteに不正な値が指定された場合 | 正しいboolean値を指定する |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 処理時間への影響は軽微
- 既存のJSX処理に統合されている

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

特になし

## 備考

- singleQuoteオプションとは独立して設定可能
- JSX式内の文字列リテラル（{" "} 等）には影響しない

---

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

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

### 推奨読解順序

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

オプション定義を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | options.js | `src/language-js/options.js` | jsxSingleQuoteオプションの定義（66-70行目） |

**読解のコツ**: jsxSingleQuoteはboolean型でデフォルトfalse。singleQuoteとは別のオプションとして定義されている。

#### Step 2: JSX属性出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | jsx.js | `src/language-js/print/jsx.js` | printJsxAttribute関数（535-566行目） |

**主要処理フロー**:
1. **541-548行目**: StringLiteral値の場合の処理
2. **545-548行目**: &apos;と&quot;のアンエスケープ
3. **549行目**: `getPreferredQuote(final, options.jsxSingleQuote)`
4. **550-553行目**: クォートに応じたHTMLエンティティ変換

#### Step 3: クォート決定ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | get-preferred-quote.js | `src/utilities/get-preferred-quote.js` | getPreferredQuote関数（31-53行目） |

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

```
format() / formatWithCursor()
    │
    ├─ core.formatWithCursor()
    │      └─ printToDoc()
    │             └─ printer.print()
    │                    │
    │                    └─ printJsx() [jsx.js]
    │                           │
    │                           └─ printJsxAttribute() [jsx.js]
    │                                  │
    │                                  ├─ getPreferredQuote() [get-preferred-quote.js]
    │                                  │      └─ options.jsxSingleQuote
    │                                  │
    │                                  └─ HTMLエンティティ変換
```

### データフロー図

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

options.jsxSingleQuote ──▶ printJsxAttribute() ────▶ <div attr="value" />
                         │                          or
raw属性値 ───────────────┘                          <div attr='value' />
                         │
                         ├─ &apos; / &quot; アンエスケープ
                         │
                         ├─ getPreferredQuote()
                         │
                         └─ HTMLエンティティ変換
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| options.js | `src/language-js/options.js` | ソース | jsxSingleQuoteオプション定義 |
| jsx.js | `src/language-js/print/jsx.js` | ソース | JSX出力処理 |
| get-preferred-quote.js | `src/utilities/get-preferred-quote.js` | ソース | 優先クォート決定ロジック |
