# 機能設計書 40-セミコロン出力（semi）

## 概要

本ドキュメントは、PrettierのJavaScript言語オプションにおけるセミコロン出力機能について記述する。この機能は、文末にセミコロンを出力するかどうかを制御する。

### 本機能の処理概要

セミコロン出力（semi）は、JavaScript/TypeScriptコードのフォーマット時に、文末にセミコロンを出力するかどうかを制御するオプションである。`semi: true`（デフォルト）の場合は文末にセミコロンを出力し、`semi: false`の場合はセミコロンを省略する。ただし、ASI（Automatic Semicolon Insertion）の曖昧さを避けるため、特定のケースでは先頭にセミコロンを出力する。

**業務上の目的・背景**：JavaScriptコミュニティでは、セミコロンを付ける派と付けない派の両方が存在する。Prettierは両方のスタイルをサポートし、チームやプロジェクトの方針に合わせたフォーマットを可能にしている。また、`semi: false`の場合でも、ASIの問題を回避するための保護セミコロンを自動的に挿入する。

**機能の利用シーン**：
- セミコロンありスタイルでコードをフォーマットする場合（デフォルト）
- セミコロンなしスタイルでコードをフォーマットする場合
- ESLintなどのリンターとの併用で特定のスタイルを強制する場合

**主要な処理内容**：
1. semi: true - 文末にセミコロンを出力
2. semi: false - 文末のセミコロンを省略
3. ASI保護 - 特定のケースで先頭にセミコロンを出力

**関連システム・外部連携**：JavaScript/TypeScriptプリンター

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Playground | 主画面 | サイドバーからセミコロン出力オプションを設定 |
| 19 | Configuration - Options | 主画面 | semiオプションの詳細説明 |

## 機能種別

フォーマットオプション / JavaScript言語オプション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| semi | boolean | No | セミコロンを出力するかどうか | boolean |

### 入力データソース

- Prettier API呼び出し時のオプション
- CLI実行時の--semi/--no-semiオプション
- 設定ファイル（prettierrc等）のsemiプロパティ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| semi: true | フォーマット出力 | 文末にセミコロンを出力 |
| semi: false | フォーマット出力 | 文末のセミコロンを省略（ASI保護は適用） |

### 出力先

フォーマットされたJavaScript/TypeScriptコード

## 処理フロー

### 処理シーケンス

```
1. フォーマットオプションでsemi値を取得
2. ExpressionStatement等の出力時にsemiオプションを参照
3. semi: trueの場合
   └─ 文末にセミコロンを出力
4. semi: falseの場合
   └─ 文末のセミコロンを省略
   └─ ASI保護が必要な場合は先頭にセミコロンを出力
5. ASI保護の判定
   ├─ 配列リテラルで始まる場合
   ├─ 正規表現で始まる場合
   ├─ テンプレートリテラルで始まる場合
   ├─ +/-単項演算子で始まる場合
   └─ その他特定のケース
```

### フローチャート

```mermaid
flowchart TD
    A[ExpressionStatement出力] --> B{semi: true?}
    B -->|Yes| C[文末にセミコロン出力]
    B -->|No| D{ASI保護が必要?}
    D -->|Yes| E[先頭にセミコロン出力]
    D -->|No| F[セミコロンなし出力]
    C --> G[次の文へ]
    E --> G
    F --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-40-01 | semi: trueデフォルト | セミコロン出力はデフォルトでtrue | オプション未指定時 |
| BR-40-02 | 文末セミコロン | semi: trueの場合、文末にセミコロンを出力 | 式文、変数宣言等 |
| BR-40-03 | セミコロン省略 | semi: falseの場合、文末のセミコロンを省略 | 式文、変数宣言等 |
| BR-40-04 | ASI保護（配列） | 配列リテラルで始まる場合は先頭にセミコロン | semi: false時 |
| BR-40-05 | ASI保護（正規表現） | 正規表現で始まる場合は先頭にセミコロン | semi: false時 |
| BR-40-06 | ASI保護（テンプレート） | テンプレートリテラルで始まる場合は先頭にセミコロン | semi: false時 |
| BR-40-07 | ASI保護（単項演算子） | +/-単項演算子で始まる場合は先頭にセミコロン | semi: false時 |
| BR-40-08 | JSX例外 | MarkdownやMDX内の単一JSX要素ではセミコロンを省略 | parentParserがmarkdown/mdx |
| BR-40-09 | Vueイベントバインディング例外 | Vueイベントバインディング式では特別な処理 | parserが__vue_event_binding等 |

### 計算ロジック

オプション定義:
```javascript
semi: {
  category: CATEGORY_JAVASCRIPT,
  type: "boolean",
  default: true,
  description: "Print semicolons.",
  oppositeDescription:
    "Do not print semicolons, except at the beginning of lines which may need them.",
}
```

ASI保護判定:
```javascript
function shouldExpressionStatementPrintLeadingSemicolon(path, options) {
  if (options.semi) {
    return false;
  }
  // 特定の条件で先頭セミコロンが必要か判定
  // ...
}
```

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | - | semiオプション自体はエラーを発生させない | - |

### リトライ仕様

リトライは行わない。

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

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

## パフォーマンス要件

- オプション判定は単純なブール値比較で軽量
- ASI保護判定は必要な場合のみ実行

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

特になし

## 備考

- JavaScriptのASI（Automatic Semicolon Insertion）ルールにより、セミコロンなしでも多くの場合動作するが、特定のケースでは予期しない動作になる
- Prettierはsemi: falseの場合でも、ASIの問題を回避するための保護セミコロンを自動的に挿入する

---

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

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

### 推奨読解順序

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

semiオプションの定義を理解する。

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

**読解のコツ**:
- semiはboolean型でデフォルトtrue
- oppositeDescriptionでfalse時の説明を提供

#### Step 2: オプション定義を理解する

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

**主要処理フロー**:
1. **32-39行目**: semiオプション定義
2. **33行目**: category: CATEGORY_JAVASCRIPT
3. **34行目**: type: "boolean"
4. **35行目**: default: true
5. **36行目**: description - セミコロン出力の説明
6. **37-38行目**: oppositeDescription - セミコロン省略時の説明

#### Step 3: ASI保護ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | semicolon.js | `src/language-js/semicolon/semicolon.js` | ASI保護判定ロジック |

**主要処理フロー**:
- **9-40行目**: shouldExpressionStatementPrintLeadingSemicolon関数
- **10-12行目**: semi: trueの場合はfalseを返却（先頭セミコロン不要）
- **16-23行目**: 特定の例外ケースのチェック
- **28-37行目**: 式がASI保護を必要とするかの判定

#### Step 4: セミコロン出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | expression-statement.js | `src/language-js/print/expression-statement.js` | セミコロン出力処理 |

**主要処理フロー**:
- **23-46行目**: shouldPrintSemicolon関数 - 末尾セミコロン出力判定
- **32-34行目**: semi: falseの場合はfalseを返却
- **48-75行目**: printExpressionStatement関数
- **52-69行目**: 先頭セミコロンの処理
- **70-72行目**: 末尾セミコロンの処理

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

```
printExpressionStatement (expression-statement.js:48)
    │
    ├─ shouldExpressionStatementPrintLeadingSemicolon (semicolon.js:9)
    │      │
    │      ├─ [semi: true] → false
    │      │
    │      └─ [semi: false] → ASI保護判定
    │             │
    │             └─ expressionNeedsAsiProtection (semicolon.js:42)
    │
    └─ shouldPrintSemicolon (expression-statement.js:23)
           │
           ├─ [Vue例外] → 特別処理
           │
           ├─ [semi: false] → false
           │
           ├─ [Markdown/MDX例外] → false
           │
           └─ [通常] → true
```

### データフロー図

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

options.semi          printExpressionStatement          フォーマット文字列
expression ─────────▶ セミコロン判定 ─────────────────▶
                            │
              ┌─────────────┴─────────────┐
              │                           │
         [semi: true]               [semi: false]
              │                           │
              ▼                           ▼
         末尾セミコロン            ASI保護判定
              │                           │
              │              ┌────────────┴────────────┐
              │              │                        │
              │         [保護必要]               [保護不要]
              │              │                        │
              │              ▼                        ▼
              │         先頭セミコロン           セミコロンなし
              │              │                        │
              └──────────────┴────────────────────────┘
                             │
                             ▼
                      フォーマット文字列
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| options.js | `src/language-js/options.js` | ソース | semiオプション定義 |
| semicolon.js | `src/language-js/semicolon/semicolon.js` | ソース | ASI保護判定ロジック |
| expression-statement.js | `src/language-js/print/expression-statement.js` | ソース | セミコロン出力処理 |
| variable-declaration.js | `src/language-js/print/variable-declaration.js` | ソース | 変数宣言のセミコロン |
| module-declaration.js | `src/language-js/print/module-declaration.js` | ソース | import/exportのセミコロン |
| class-body.js | `src/language-js/print/class-body.js` | ソース | クラスフィールドのセミコロン |
| common-options.evaluate.js | `src/common/common-options.evaluate.js` | ソース | 共通オプション定義 |
