# 機能設計書 56-Unicodeエスケープ処理

## 概要

本ドキュメントは、CoffeeScriptコンパイラのUnicodeエスケープ処理機能の設計を記述する。Unicode コードポイントエスケープ（`\u{...}`）の処理と変換を行う。

### 本機能の処理概要

Unicodeエスケープ処理機能は、ES2015で導入されたUnicode コードポイントエスケープ構文（`\u{...}`）を処理し、必要に応じて従来の`\uxxxx`形式やサロゲートペアに変換する機能を提供する。

**業務上の目的・背景**：ES2015以降、JavaScriptでは`\u{1F600}`のような波括弧形式でUnicodeコードポイントを表現できるようになった。しかし、古いブラウザやNode.jsバージョンとの互換性を維持するため、正規表現などでは従来の`\uxxxx`形式に変換する必要がある場合がある。本機能は、`u`フラグを持たない正規表現で使用されるUnicodeコードポイントエスケープを、互換性のある形式に変換する。

**機能の利用シーン**：
- 正規表現リテラルでの`\u{...}`構文の使用
- `u`フラグなしの正規表現でのUnicode文字の表現
- BMP（基本多言語面）外の文字（絵文字など）の処理

**主要な処理内容**：
1. `\u{...}`形式のUnicodeエスケープの検出
2. コードポイントの10進数変換
3. 上限値（0x10ffff）のバリデーション
4. BMP内（U+0000〜U+FFFF）の場合は`\uxxxx`形式に変換
5. BMP外（U+10000〜U+10FFFF）の場合はサロゲートペアに変換

**関連システム・外部連携**：
- Lexer（正規表現トークン処理）
- 正規表現リテラル処理

**権限による制御**：該当なし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 17 | Annotated Source - Helpers | 参照画面 | replaceUnicodeCodePointEscapes関数が含まれる |
| 32 | Annotated Source - Helpers | 参照画面 | replaceUnicodeCodePointEscapes関数が含まれる（v2） |

## 機能種別

文字列変換処理 / エスケープ処理

## 入力仕様

### 入力パラメータ

#### replaceUnicodeCodePointEscapes関数
| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| str | String | Yes | 変換対象の文字列 | - |
| options | Object | No | オプション設定 | - |
| options.flags | String | No | 正規表現フラグ（'u'が含まれていなければ変換） | - |
| options.error | Function | No | エラーコールバック関数 | - |
| options.delimiter | String | No | デリミタ文字列（オフセット計算用） | - |

### 入力データソース

- 正規表現リテラル文字列
- Lexerからの正規表現パターン

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | String | 変換後の文字列 |

### 出力先

- 呼び出し元への戻り値

## 処理フロー

### 処理シーケンス

```
1. 入力文字列の解析
   └─ UNICODE_CODE_POINT_ESCAPE正規表現でマッチ検索

2. エスケープ済みバックスラッシュのスキップ
   └─ \\\\ がマッチした場合はそのまま返す

3. コードポイントの抽出と変換
   └─ 16進数文字列をparseIntで10進数に変換

4. 上限値チェック
   └─ 0x10ffffを超える場合はエラーコールバック呼び出し

5. 変換判定
   └─ flagsに'u'が含まれている場合はそのまま返す
   └─ 含まれていない場合は変換処理へ

6. Unicode変換
   └─ 0x10000未満: \uxxxx 形式に変換
   └─ 0x10000以上: サロゲートペアに変換
```

### フローチャート

```mermaid
flowchart TD
    A[replaceUnicodeCodePointEscapes呼び出し] --> B[正規表現でマッチ]
    B --> C{\\\\マッチ?}
    C -->|Yes| D[そのまま返す]
    C -->|No| E[コードポイント抽出]
    E --> F[parseInt 16進→10進]
    F --> G{> 0x10ffff?}
    G -->|Yes| H[error コールバック]
    G -->|No| I{'u' in flags?}
    H --> I
    I -->|Yes| J[マッチをそのまま返す]
    I -->|No| K{< 0x10000?}
    K -->|Yes| L[\uxxxx 形式に変換]
    K -->|No| M[サロゲートペアに変換]
    L --> N[変換結果を返す]
    M --> N
    D --> N
    J --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-56-01 | uフラグ判定 | flagsに'u'が含まれていなければ変換を実行 | replaceUnicodeCodePointEscapes呼び出し時 |
| BR-56-02 | 上限値検証 | 0x10ffffを超えるコードポイントはエラー | 全ケース |
| BR-56-03 | BMP内変換 | U+0000〜U+FFFFは\uxxxx形式に変換 | uフラグなしの場合 |
| BR-56-04 | サロゲートペア | U+10000〜U+10FFFFはサロゲートペアに変換 | uフラグなしの場合 |
| BR-56-05 | エスケープ済みスキップ | \\\\はそのまま保持 | 全ケース |
| BR-56-06 | ゼロパディング | \uxxxx形式は4桁に0パディング | 変換時 |

### 計算ロジック

**サロゲートペア計算**:
```
codePoint = 0x1F600 (例: 笑顔の絵文字)

high = Math.floor((codePoint - 0x10000) / 0x400) + 0xD800
     = Math.floor((128512 - 65536) / 1024) + 55296
     = Math.floor(62976 / 1024) + 55296
     = 61 + 55296
     = 55357 (0xD83D)

low = (codePoint - 0x10000) % 0x400 + 0xDC00
    = (128512 - 65536) % 1024 + 56320
    = 62976 % 1024 + 56320
    = 512 + 56320
    = 56832 (0xDE00)

結果: \uD83D\uDE00
```

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

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 範囲エラー | コードポイントが0x10ffffを超える | errorコールバック呼び出し |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- 文字列置換処理は同期的に実行
- 正規表現のグローバルマッチによる効率的な処理

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

該当なし

## 備考

- UNICODE_CODE_POINT_ESCAPE正規表現: `/( \\\\ ) | \\u\{ ( [\da-fA-F]+ ) \}/g`
- ES2015のUnicode対応と下位互換性の両立を実現

---

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

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

### 推奨読解順序

#### Step 1: 正規表現パターンを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | helpers.coffee | `src/helpers.coffee` | UNICODE_CODE_POINT_ESCAPE正規表現（321-325行目） |

**主要処理フロー**:
- **321-325行目**: 正規表現パターンの定義
  - `( \\\\ )`: エスケープ済みバックスラッシュ
  - `\\u\{ ( [\da-fA-F]+ ) \}`: Unicodeコードポイントエスケープ

**読解のコツ**: 正規表現は`///`ヒアドキュメント形式で記述されており、空白やコメントを含めることができる。

#### Step 2: サロゲートペア変換ロジックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | helpers.coffee | `src/helpers.coffee` | unicodeCodePointToUnicodeEscapes関数（296-304行目） |

**主要処理フロー**:
- **297-299行目**: toUnicodeEscape内部関数 - 4桁の\uxxxx形式に変換
- **300行目**: 0x10000未満はそのまま変換
- **302-304行目**: サロゲートペア計算と結合

#### Step 3: メイン変換関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | helpers.coffee | `src/helpers.coffee` | replaceUnicodeCodePointEscapes関数（307-319行目） |

**主要処理フロー**:
- **308行目**: shouldReplace判定（'u' not in flags）
- **309-319行目**: String.prototype.replaceによる置換処理
- **310行目**: エスケープ済みバックスラッシュのスキップ
- **312行目**: 16進数→10進数変換
- **313-316行目**: 上限値チェックとエラー処理
- **317行目**: 変換不要な場合はそのまま返す
- **319行目**: unicodeCodePointToUnicodeEscapesの呼び出し

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

```
replaceUnicodeCodePointEscapes(str, options)
    │
    ├─ str.replace(UNICODE_CODE_POINT_ESCAPE, callback)
    │      │
    │      ├─ [\\\\の場合] そのまま返す
    │      │
    │      ├─ [コードポイント抽出]
    │      │      └─ parseInt(codePointHex, 16)
    │      │
    │      ├─ [上限値チェック]
    │      │      └─ > 0x10ffff → error()
    │      │
    │      └─ [変換処理]
    │             └─ unicodeCodePointToUnicodeEscapes(codePointDecimal)
    │                    │
    │                    ├─ [< 0x10000] toUnicodeEscape(val)
    │                    │
    │                    └─ [>= 0x10000] サロゲートペア計算
    │                           ├─ high = (val - 0x10000) / 0x400 + 0xD800
    │                           └─ low = (val - 0x10000) % 0x400 + 0xDC00
    │
    └─ 変換結果を返す
```

### データフロー図

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

"\u{1F600}"    ───▶  replaceUnicodeCodePointEscapes  ───▶  "\uD83D\uDE00"
flags: ""               │
                        ▼
                   parseInt("1F600", 16)
                        │
                        ▼
                   128512 (10進)
                        │
                        ▼
                   サロゲートペア計算
                        │
                        ▼
                   high: 0xD83D
                   low:  0xDE00
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| helpers.coffee | `src/helpers.coffee` | ソース | Unicodeエスケープ処理の実装 |
| lexer.coffee | `src/lexer.coffee` | ソース | 正規表現トークン処理（呼び出し元） |
