# 機能設計書 57-クラス定義

## 概要

本ドキュメントは、CoffeeScriptのクラス定義機能の設計を記述する。ES6互換のクラス定義構文（class、extends、super）を提供する。

### 本機能の処理概要

クラス定義機能は、CoffeeScriptでオブジェクト指向プログラミングを行うためのクラス構文を提供する。ES6のクラス構文と互換性を持ち、継承、コンストラクタ、メソッド定義、静的メソッドなどをサポートする。

**業務上の目的・背景**：オブジェクト指向プログラミングはソフトウェア開発において広く採用されているパラダイムである。CoffeeScriptは、JavaScriptのプロトタイプベースの継承をより直感的なクラスベースの構文で表現できるようにし、開発者の生産性と可読性を向上させる。ES6の登場以降は、ES6クラス構文と互換性のあるJavaScriptを生成することで、モダンなJavaScript環境との相互運用性を確保している。

**機能の利用シーン**：
- オブジェクト指向設計によるアプリケーション構築
- 継承を使用したコードの再利用
- フレームワーク（React、Backbone等）との連携
- TypeScriptやES6コードとの相互運用

**主要な処理内容**：
1. クラス宣言の解析と構文木ノード生成
2. 継承（extends）の処理
3. コンストラクタの生成とsuper呼び出し
4. インスタンスメソッドと静的メソッドの定義
5. バウンドメソッド（=>）の処理
6. ES6クラス構文へのコード生成

**関連システム・外部連携**：
- Grammar（文法定義）
- Nodes（コード生成）
- Lexer（トークン解析）

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 専用の画面なし（言語機能として全般的に使用） |

## 機能種別

言語機能 / コード生成

## 入力仕様

### 入力パラメータ

#### Classノード（文法定義）
| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| variable | SimpleAssignable | No | クラス名 | 有効な識別子 |
| parent | Expression | No | 継承元クラス | - |
| body | Block | No | クラス本体 | - |

### 入力データソース

- CoffeeScriptソースコード内のクラス定義

### 構文例

```coffeescript
# 基本的なクラス
class Animal
  constructor: (@name) ->

  move: (meters) ->
    console.log "#{@name} moved #{meters}m"

# 継承
class Snake extends Animal
  move: ->
    console.log "Slithering..."
    super 5

# 静的メソッド
class MyClass
  @staticMethod: ->
    console.log "Static method"

# バウンドメソッド
class Button
  onClick: =>
    console.log "Clicked!"
```

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| compiledCode | String | ES6クラス構文のJavaScriptコード |

### 出力先

- コンパイル済みJavaScriptファイル

### 出力例

```javascript
class Animal {
  constructor(name) {
    this.name = name;
  }

  move(meters) {
    return console.log(`${this.name} moved ${meters}m`);
  }
}

class Snake extends Animal {
  move() {
    console.log("Slithering...");
    return super.move(5);
  }
}
```

## 処理フロー

### 処理シーケンス

```
1. クラス宣言の解析
   └─ CLASS トークン検出
   └─ クラス名（variable）の取得
   └─ EXTENDS トークン検出（継承の場合）
   └─ クラス本体（Block）の解析

2. クラスノードの生成
   └─ new Class(variable, parent, body)
   └─ 本体が未定義の場合は空のBlockを生成

3. クラス名の決定
   └─ determineName() でクラス名を解決
   └─ JS予約語の場合はプレフィックス"_"を追加

4. クラス本体の走査
   └─ walkBody() でメソッドと初期化式を処理
   └─ コンストラクタの検出と設定
   └─ バウンドメソッドの収集
   └─ 静的メソッドの処理

5. コード生成
   └─ compileClassDeclaration() でES6クラス構文を生成
   └─ 必要に応じてデフォルトコンストラクタを生成
   └─ バウンドメソッドのプロキシ処理
```

### フローチャート

```mermaid
flowchart TD
    A[CLASS トークン] --> B{クラス名あり?}
    B -->|Yes| C[variable設定]
    B -->|No| D[匿名クラス]
    C --> E{EXTENDS あり?}
    D --> E
    E -->|Yes| F[parent設定]
    E -->|No| G[parent = null]
    F --> H[Body解析]
    G --> H
    H --> I[Classノード生成]
    I --> J[determineName]
    J --> K[walkBody]
    K --> L{コンストラクタ検出?}
    L -->|Yes| M[ctorに設定]
    L -->|No| N[スキップ]
    M --> O{バウンドメソッドあり?}
    N --> O
    O -->|Yes| P[boundMethodsに追加]
    O -->|No| Q[スキップ]
    P --> R[compileClassDeclaration]
    Q --> R
    R --> S[ES6クラス出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-57-01 | コンストラクタ唯一性 | クラス内にコンストラクタは1つのみ定義可能 | コンストラクタ定義時 |
| BR-57-02 | バウンドコンストラクタ禁止 | コンストラクタを=>で定義することは不可 | コンストラクタ定義時 |
| BR-57-03 | super呼び出し | 派生クラスのコンストラクタではthis使用前にsuper()呼び出しが必要 | 継承クラスのコンストラクタ内 |
| BR-57-04 | 予約語クラス名 | JS予約語がクラス名の場合はプレフィックス"_"を追加 | クラス名解決時 |
| BR-57-05 | 静的メソッド判定 | `@methodName`または`ClassName.methodName`形式で静的メソッド | メソッド定義時 |
| BR-57-06 | 匿名クラス式 | 匿名クラスはトップレベルではParensでラップ | トップレベルの匿名クラス |

### 計算ロジック

該当なし

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

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 構文エラー | コンストラクタの重複定義 | "Cannot define more than one constructor in a class" |
| - | 構文エラー | バウンドコンストラクタ | "Cannot define a constructor as a bound (fat arrow) function" |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- クラス定義のコンパイルは同期的に実行
- 大規模なクラス階層でも効率的にコード生成

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

該当なし

## 備考

- CoffeeScript 2以降はES6クラス構文を直接出力
- CoffeeScript 1.xはプロトタイプベースのコードを生成していた

---

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

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

### 推奨読解順序

#### Step 1: 文法定義を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | grammar.coffee | `src/grammar.coffee` | Class文法規則（472-481行目） |

**主要処理フロー**:
- **473行目**: `CLASS` - 空のクラス
- **474行目**: `CLASS Block` - 本体のみ
- **475-476行目**: `CLASS EXTENDS Expression [Block]` - 継承
- **477-480行目**: `CLASS SimpleAssignable [EXTENDS Expression] [Block]` - 名前付きクラス

**読解のコツ**: 各パターンで`new Class(...)`を呼び出し、引数の組み合わせでvariable、parent、bodyを設定。

#### Step 2: Classノードクラスを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | nodes.coffee | `src/nodes.coffee` | Classクラス（2793-2992行目） |

**主要処理フロー**:
- **2793-2800行目**: constructor - variable、parent、bodyの初期化
- **2802-2829行目**: compileNode - コンパイルのエントリーポイント
- **2831-2854行目**: compileClassDeclaration - ES6クラス出力
- **2856-2870行目**: determineName - クラス名の決定
- **2872-2918行目**: walkBody - クラス本体の走査

#### Step 3: クラス本体の処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | nodes.coffee | `src/nodes.coffee` | walkBody、addInitializerMethod関数 |

**主要処理フロー**:
- **2872-2918行目**: walkBody
  - ctor（コンストラクタ）の初期化
  - boundMethods配列の初期化
  - 各式のaddInitializerExpression呼び出し
  - コンストラクタとバウンドメソッドの収集
- **2954-2974行目**: addInitializerMethod
  - isMethod = yes の設定
  - isStatic の判定
  - コンストラクタ判定（'constructor'）

#### Step 4: コード生成を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | nodes.coffee | `src/nodes.coffee` | compileClassDeclaration関数（2831-2854行目） |

**主要処理フロー**:
- **2832-2833行目**: デフォルトコンストラクタの生成条件
- **2835行目**: バウンドメソッドのプロキシ処理
- **2840行目**: "class "の出力
- **2841行目**: クラス名の出力
- **2844行目**: "extends "と親クラスの出力
- **2846-2852行目**: クラス本体の出力

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

```
Grammar: Class規則
    │
    └─ new Class(variable, parent, body)
           │
           ├─ constructor
           │      └─ body = new Block if !body
           │
           ├─ compileNode(o)
           │      ├─ determineName()
           │      ├─ walkBody(o)
           │      │      ├─ addInitializerExpression
           │      │      │      ├─ validInitializerMethod
           │      │      │      └─ addInitializerMethod
           │      │      ├─ ctor 設定
           │      │      └─ boundMethods 収集
           │      │
           │      ├─ ExecutableClassBody [if needed]
           │      └─ Assign [if variable]
           │
           └─ compileClassDeclaration(o)
                  ├─ makeDefaultConstructor [if needed]
                  ├─ proxyBoundMethods [if boundMethods]
                  ├─ "class " + name
                  ├─ "extends " + parent
                  └─ body.compileToFragments
```

### データフロー図

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

class Animal             ───▶  Grammar解析  ───▶  Classノード
  constructor: (@name) ->        │
  move: (meters) ->              │
                                 ▼
                           compileNode
                                 │
                                 ▼
                           walkBody
                                 │
                                 ▼
                           compileClassDeclaration
                                 │
                                 ▼
                           class Animal {
                             constructor(name) { ... }
                             move(meters) { ... }
                           }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| grammar.coffee | `src/grammar.coffee` | ソース | Class文法規則の定義 |
| nodes.coffee | `src/nodes.coffee` | ソース | Classノードクラスの実装 |
| lexer.coffee | `src/lexer.coffee` | ソース | CLASS、EXTENDSトークンの生成 |
