# 機能設計書 26 --map オプション

## 概要

本ドキュメントは、CoffeeScript CLIツールの `--map` (`-m`) オプションの機能設計を記述する。このオプションは、コンパイル時にソースマップを生成し、`.js.map` ファイルとして保存する機能を提供する。

### 本機能の処理概要

`--map` オプションは、CoffeeScriptからJavaScriptへのコンパイル時にSource Map V3形式のソースマップを生成し、外部ファイルとして保存する機能を提供する。ソースマップにより、ブラウザのデバッグツールやNode.jsのエラースタックトレースで、コンパイル後のJavaScriptではなく元のCoffeeScriptソースコードの行番号・列番号を表示できるようになる。

**業務上の目的・背景**：CoffeeScriptはJavaScriptにコンパイルされて実行されるため、ランタイムエラーやデバッグ時に表示される行番号はコンパイル後のJavaScriptのものとなる。これは元のCoffeeScriptソースとの対応が分かりにくく、デバッグを困難にする。ソースマップを使用することで、ブラウザの開発者ツールやNode.jsが元のCoffeeScriptファイルの行番号を表示できるようになり、デバッグ効率が大幅に向上する。

**機能の利用シーン**：
- プロダクション環境でのデバッグを容易にしたい場合
- ブラウザの開発者ツールでCoffeeScriptソースを直接デバッグしたい場合
- Node.jsのエラースタックトレースをCoffeeScriptの行番号で表示したい場合
- ソースマップをビルドツールや他のツールと連携させたい場合

**主要な処理内容**：
1. CoffeeScript.compile() でソースマップ生成オプションを有効にしてコンパイル
2. コンパイル結果からv3SourceMapを取得
3. JavaScriptファイル末尾にsourceMappingURLコメントを追加
4. `.js.map` ファイルとしてソースマップを保存

**関連システム・外部連携**：ブラウザ開発者ツール、Node.jsデバッガー

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 15 | Annotated Source - SourceMap | 主機能 | ソースマップ生成sourcemap.litcoffeeのソースコード解説表示 |
| 30 | Annotated Source - SourceMap | 主機能 | ソースマップ生成sourcemap.litcoffeeのソースコード解説表示（v2） |

## 機能種別

ファイル生成 / デバッグ支援

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --map / -m | boolean | No | ソースマップ生成モードを有効にする | オプションの有無で判定 |
| source | string | Yes | コンパイル対象のCoffeeScriptファイル | ファイルが存在すること |

### 入力データソース

- ファイルシステム（CoffeeScriptソースファイル）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| JavaScript file | file | コンパイルされたJavaScriptファイル（.js） |
| Source Map file | file | V3形式のソースマップファイル（.js.map） |

### 出力先

- ファイルシステム（`.js` ファイルと `.js.map` ファイル）

### ソースマップ形式（V3）

```json
{
  "version": 3,
  "file": "example.js",
  "sourceRoot": "",
  "sources": ["example.coffee"],
  "names": [],
  "mappings": "VLQ_ENCODED_MAPPINGS",
  "sourcesContent": ["original CoffeeScript source"]
}
```

## 処理フロー

### 処理シーケンス

```
1. コマンドライン引数をパース
   └─ --map オプションが指定されているか確認

2. compileOptions でソースマップオプションを設定
   └─ sourceMap: true を設定

3. CoffeeScript.compile() でコンパイル
   └─ ソースマップ生成も同時に実行

4. コンパイル結果の分離
   └─ task.output = compiled.js
   └─ task.sourceMap = compiled.v3SourceMap

5. writeJs関数でファイル出力
   └─ .js ファイルにsourceMappingURLを追加して保存
   └─ .js.map ファイルにソースマップを保存
```

### フローチャート

```mermaid
flowchart TD
    A[開始: coffee -m source.coffee] --> B[引数パース]
    B --> C{--map 指定?}
    C -->|No| D[通常コンパイル]
    C -->|Yes| E[compileOptions: sourceMap=true]
    E --> F[CoffeeScript.compile]
    F --> G[コンパイル結果取得]
    G --> H{sourceMap生成?}
    H -->|Yes| I[task.output = compiled.js]
    I --> J[task.sourceMap = compiled.v3SourceMap]
    J --> K[writeJs関数呼び出し]
    K --> L[sourceMappingURLコメント追加]
    L --> M[.jsファイル保存]
    M --> N[.js.mapファイル保存]
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-26-01 | ファイル出力必須 | --map は --compile と併用が必要（暗黙的に有効化） | --map指定時 |
| BR-26-02 | stdio非互換 | --map は --stdio と併用できない | --stdio併用時はエラー |
| BR-26-03 | マップファイル名 | ソースマップファイル名は `{jsファイル名}.map` | ファイル出力時 |
| BR-26-04 | sourceMappingURL | JSファイル末尾に `//# sourceMappingURL=filename.js.map` を追加 | ソースマップ生成時 |
| BR-26-05 | V3形式 | Source Map Version 3形式で出力 | 常時 |

### 計算ロジック

- VLQ（Variable Length Quantity）エンコーディングでマッピング情報を圧縮
- 行・列の差分をエンコードして出力サイズを最小化

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| STDIO_MAP | 引数エラー | --stdio と --map を併用 | エラーメッセージ表示して終了コード1 |
| SyntaxError | 構文エラー | CoffeeScriptの文法エラー | エラーメッセージを表示して終了コード1 |
| ENOENT | ファイル不存在 | 指定されたファイルが存在しない | エラーメッセージを表示して終了コード1 |
| Write Error | 書き込みエラー | ソースマップファイルの書き込み失敗 | エラーメッセージを表示して終了コード1 |

### リトライ仕様

本機能はリトライ処理を行わない。

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

本機能はトランザクション処理を使用しない。

## パフォーマンス要件

- ソースマップ生成はコンパイル時に同時実行されるため、追加の処理時間は最小限

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

- ソースマップにはオリジナルソースコードが含まれる（sourcesContent）
- プロダクション環境では公開しないか、アクセス制御を検討する

## 備考

- `--inline-map` オプションを使用すると、ソースマップをJSファイル内にBase64エンコードで埋め込める
- sourcesContentには元のCoffeeScriptソースコードが含まれる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | command.coffee | `src/command.coffee` | SWITCHESの `--map` 定義（43行目）を確認 |

**読解のコツ**: `['-m', '--map', 'generate source map and save as .js.map files']` の形式で定義されている。

#### Step 2: ソースマップオプション設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | command.coffee | `src/command.coffee` | compileOptions関数（501-527行目） |

**主要処理フロー**:
- **507行目**: `sourceMap: opts.map` でソースマップオプション設定

#### Step 3: コンパイル結果の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | command.coffee | `src/command.coffee` | compileScript関数内のmap処理（225-227行目） |

**主要処理フロー**:
- **225-227行目**: `if opts.map` で結果を分離
- **226行目**: `task.output = compiled.js`
- **227行目**: `task.sourceMap = compiled.v3SourceMap`

#### Step 4: ファイル出力処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | command.coffee | `src/command.coffee` | writeJs関数（407-426行目） |

**主要処理フロー**:
- **408行目**: `sourceMapPath = "#{jsPath}.map"`
- **413行目**: sourceMappingURLコメントの追加
- **420-424行目**: ソースマップファイルの書き込み

#### Step 5: ソースマップ生成の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | sourcemap.litcoffee | `src/sourcemap.litcoffee` | SourceMapクラスの実装 |

**主要処理フロー**:
- **43-55行目**: SourceMapクラスのadd/sourceLocationメソッド
- **89-154行目**: generate関数でV3形式のJSONを生成
- **170-186行目**: VLQエンコーディングの実装

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

```
exports.run (72行目)
    │
    └─ compileScript (202行目)
           │
           ├─ compileOptions (203行目)
           │      └─ sourceMap: opts.map (507行目)
           │
           ├─ CoffeeScript.compile (223行目)
           │      │
           │      └─ coffeescript.coffee: compile (62行目)
           │             │
           │             ├─ SourceMap.add (各フラグメントに対して)
           │             │
           │             └─ SourceMap.generate (140行目)
           │                    └─ V3 JSON生成
           │
           └─ writeJs (237行目)
                  │
                  ├─ sourceMappingURLコメント追加 (413行目)
                  │
                  ├─ fs.writeFile jsPath (414行目)
                  │
                  └─ fs.writeFile sourceMapPath (421行目)
```

### データフロー図

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

CoffeeScriptソース ───▶ CoffeeScript.compile
                              │
                              ├─ tokens → nodes → fragments
                              │
                              └─ SourceMap.add（フラグメントごと）
                                      │
                                      ▼
                              SourceMap.generate
                                      │
                                      ├─ VLQエンコード
                                      │
                                      └─ V3 JSON生成
                                              │
                                              ▼
                        ┌───────────────────────┴────────────────────────┐
                        ▼                                                ▼
                  .jsファイル                                      .js.mapファイル
                  (sourceMappingURL付き)                           (V3ソースマップ)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| command.coffee | `src/command.coffee` | ソース | CLIメイン処理、--map分岐処理、writeJs関数 |
| coffeescript.coffee | `src/coffeescript.coffee` | ソース | compile関数、ソースマップ生成統合 |
| sourcemap.litcoffee | `src/sourcemap.litcoffee` | ソース | SourceMapクラス、V3生成、VLQエンコード |
| optparse.coffee | `src/optparse.coffee` | ソース | コマンドライン引数パーサー |
