# 機能設計書 50-ブラケット位置（bracketSameLine）

## 概要

本ドキュメントは、Prettierのブラケット位置制御機能（bracketSameLine）の設計仕様を定義する。

### 本機能の処理概要

bracketSameLineオプションは、HTML、JSX、Vue、Angularの複数行にわたる開始タグにおいて、閉じブラケット（>）を最後の属性と同じ行に配置するか、新しい行に配置するかを制御する。

**業務上の目的・背景**：
HTMLやJSXで属性が複数行にわたる場合、閉じブラケット（>）の位置がコードの可読性とスタイルに影響する。属性と同じ行に配置することでコンパクトな見た目になり、新しい行に配置することでタグの終わりが視覚的に明確になる。この機能により、プロジェクトやチームの好みに応じたブラケット配置を選択できる。

**機能の利用シーン**：
1. JSXでコンパクトなコードスタイルを好む場合（true）
2. HTMLで属性とタグ終了を明確に分離したい場合（false）
3. 既存のコードベースのスタイルに合わせたい場合
4. Vueコンポーネントのテンプレートスタイルを統一したい場合

**主要な処理内容**：
1. bracketSameLineオプションの値取得（true/false）
2. 複数行開始タグの検出
3. 属性の有無とコメントの確認
4. ブラケット位置の決定
5. 適切な改行・インデントの適用

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

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | 補助機能 | サイドバーからブラケット位置を設定 |
| 19 | Configuration - Options | 主機能 | bracketSameLineオプションの詳細説明 |

## 機能種別

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

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| bracketSameLine | boolean | No | 閉じブラケットを属性と同じ行に配置するかどうか | true/falseのみ |

### 入力データソース

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

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| formatted | string | ブラケット位置が制御されたフォーマット済みコード |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. オプション解析
   └─ bracketSameLineオプションの値を取得（デフォルト: false）
2. 開始タグ検出
   └─ JSXOpeningElement、HTML開始タグを特定
3. 複数行判定
   └─ 属性が複数行にわたるかどうかを確認
4. コメント確認
   └─ 名前や最後の属性にコメントがあるかチェック
5. ブラケット出力
   └─ オプションと条件に基づいて位置を決定
```

### フローチャート

```mermaid
flowchart TD
    A[開始タグ検出] --> B{属性あり?}
    B -->|No| C[属性なし: > を同じ行に]
    B -->|Yes| D{複数行?}
    D -->|No| E[単一行: > を同じ行に]
    D -->|Yes| F{bracketSameLine?}
    F -->|true| G{コメントあり?}
    F -->|false| H[> を新しい行に]
    G -->|No| I[> を最後の属性と同じ行に]
    G -->|Yes| H
    C --> J[出力]
    E --> J
    H --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-50-01 | デフォルト設定 | デフォルトではfalse（新しい行に配置） | bracketSameLine未指定 |
| BR-50-02 | 同じ行 | trueでは閉じブラケットを属性と同じ行に配置 | bracketSameLine: true |
| BR-50-03 | 新しい行 | falseでは閉じブラケットを新しい行に配置 | bracketSameLine: false |
| BR-50-04 | コメント例外 | タグ名や最後の属性にコメントがある場合は新しい行に | 常に適用 |
| BR-50-05 | 属性なし例外 | 属性がなくコメントもない場合は同じ行に維持 | 常に適用 |
| BR-50-06 | 自己終了タグ | 自己終了タグ（/>）には影響しない | selfClosing: true |

### 計算ロジック

ブラケット位置決定ロジック:
```javascript
function shouldPrintBracketSameLine(node, options, nameHasComments) {
  const lastAttrHasTrailingComments =
    node.attributes.length > 0 &&
    hasComment(node.attributes.at(-1), CommentCheckFlags.Trailing);
  return (
    // 属性がなくコメントもない場合は常に同じ行
    (node.attributes.length === 0 && !nameHasComments) ||
    // オプションがtrueで、コメントの条件を満たす場合
    ((options.bracketSameLine || options.jsxBracketSameLine) &&
      (!nameHasComments || node.attributes.length > 0) &&
      !lastAttrHasTrailingComments)
  );
}
```

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

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

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

## エラー処理

### エラーケース一覧

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

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

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

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

特になし

## 備考

- jsxBracketSameLineは非推奨となり、bracketSameLineに統合された
- HTMLとJSXの両方で同一のオプションが適用される
- 自己終了タグ（<br />等）には影響しない

---

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

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

### 推奨読解順序

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

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | common-options.evaluate.js | `src/common/common-options.evaluate.js` | bracketSameLineオプションの定義（55-61行目） |

**読解のコツ**: bracketSameLineはboolean型でデフォルトfalse。Common categoryに属し、複数の言語で共通使用される。

#### Step 2: JSXでの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | jsx.js | `src/language-js/print/jsx.js` | printJsxOpeningElement関数（601-660行目） |
| 2-2 | jsx.js | `src/language-js/print/jsx.js` | shouldPrintBracketSameLine関数（677-698行目） |

**主要処理フロー**:
1. **662-675行目**: printEndOfOpeningTag関数でブラケット位置を決定
2. **666-670行目**: shouldPrintBracketSameLine呼び出し
3. **677-698行目**: コメントの有無と属性の状態を確認して判定

#### Step 3: HTMLでの処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | tag.js | `src/language-html/print/tag.js` | printAttributes関数（221-309行目） |

**主要処理フロー**:
- **297-306行目**: bracketSameLineの値に基づいてスペースまたはソフトラインを出力

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

```
format() / formatWithCursor()
    │
    ├─ core.formatWithCursor()
    │      └─ printToDoc()
    │             └─ printer.print()
    │                    │
    │                    ├─ printJsxOpeningElement() [jsx.js]
    │                    │      │
    │                    │      ├─ printEndOfOpeningTag()
    │                    │      │      └─ shouldPrintBracketSameLine()
    │                    │      │             └─ options.bracketSameLine
    │                    │      │
    │                    │      └─ > or softline + >
    │                    │
    │                    └─ printOpeningTag() [tag.js]
    │                           │
    │                           └─ printAttributes()
    │                                  └─ options.bracketSameLine
```

### データフロー図

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

options.bracketSameLine ──▶ shouldPrintBracketSameLine() ──▶ boolean
                          │
JSXOpeningElement ────────┘
                          │
                          ├─ 属性なし → true
                          │
                          ├─ コメントあり → false
                          │
                          └─ オプション値に従う
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| common-options.evaluate.js | `src/common/common-options.evaluate.js` | ソース | bracketSameLineオプション定義 |
| jsx.js | `src/language-js/print/jsx.js` | ソース | JSX開始タグ出力処理 |
| tag.js | `src/language-html/print/tag.js` | ソース | HTML開始タグ出力処理 |
| options.js | `src/language-js/options.js` | ソース | jsxBracketSameLine（非推奨）定義 |
| options.js | `src/language-html/options.js` | ソース | HTML言語オプション |
