# 通知設計書 19-循環依存エラー（汎用）

## 概要

本ドキュメントは、Tailwind CSSの`@apply`処理において、汎用的な循環依存が検出された場合に、関連するCSSノードの内容を含むエラーメッセージを出力する通知の設計を記述する。

### 本通知の処理概要

`@apply`ディレクティブの代入処理におけるトポロジカルソートのフェーズで、`@utility`ディレクティブ同士の循環（No.18で処理）以外の一般的な循環依存を検出し、循環に関与する2つのCSSノードのCSS表現を含むエラーメッセージをスローする処理である。

**業務上の目的・背景**：No.18の`@utility`間循環依存エラーでカバーしきれない、あらゆるAST構造間での循環依存を捕捉するフォールバックの役割を果たす。例えば、通常のスタイルルール内で`@apply`を通じて間接的な循環が発生するケースや、`@utility`以外のノード間での循環が該当する。CSS生成時の無限ループを確実に防止するために、すべての循環依存パターンを検出する必要がある。

**通知の送信タイミング**：`substituteAtApply`関数内のトポロジカルソートの`visit`関数で、処理中（wip）のノードが再訪問された場合に、No.18の`@utility`固有チェックを通過した後のフォールバックとしてスローされる。

**通知の受信者**：CSSを記述・ビルドしている開発者。例外は上位のエラーハンドリングでキャッチされ、コンソールに表示される。

**通知内容の概要**：循環依存に関与する2つのCSSノードのCSS表現（`toCss`関数による）を含む構造化されたエラーメッセージが出力される。「Relies on」の表現で依存関係を明示する。

**期待されるアクション**：開発者はエラーメッセージに表示された2つのCSSブロックを確認し、循環依存を解消するために一方の`@apply`を直接CSSプロパティに書き換える。

## 通知種別

@applyエラー（Error例外 / throw）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（throw による例外スロー） |
| 優先度 | 高 |
| リトライ | なし |

### 送信先決定ロジック

例外のスローにより上位の処理層にエラーが伝播する。最終的な出力先は上位のエラーハンドラに依存する。

## 通知テンプレート

### メール通知の場合

該当なし（例外スローのみ）

### 本文テンプレート

```
Circular dependency detected:

{nodeのCSS表現}
Relies on:

{nextのCSS表現}
```

例:
```
Circular dependency detected:

.foo {
  @apply bar;
}

Relies on:

.bar {
  @apply foo;
}
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| node | 循環依存の一方のASTノード | トポロジカルソートの現在ノード | Yes |
| next | 循環依存のもう一方のASTノード | pathから算出（path[(path.indexOf(node) + 1) % path.length]） | Yes |
| toCss([node]) | nodeのCSS文字列表現 | ast.tsのtoCss関数 | Yes |
| toCss([next]) | nextのCSS文字列表現 | ast.tsのtoCss関数 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コンパイル処理 | トポロジカルソートのvisit関数 | wip.has(node)がtrue かつ @utility固有チェックをパスした場合 | apply.ts 131-133行目 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| No.18の@utility固有チェックでエラーがスローされた場合 | @utility間の循環はNo.18のエラーが先にスローされる |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[visit関数呼び出し] --> B{wip.has node?}
    B -->|No| C[通常のDFS処理]
    B -->|Yes| D{node と next が @utility?}
    D -->|Yes| E[No.18: @utility固有エラー処理]
    D -->|No| F[汎用循環依存エラー]
    E -->|エラースロー| G[処理中断]
    E -->|エラー未スロー| F
    F --> H["throw Error: Circular dependency detected"]
```

## データベース参照・更新仕様

### 参照テーブル一覧

該当なし（データベースは使用しない）

### 更新テーブル一覧

該当なし（データベースは使用しない）

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 汎用循環依存 | @utility以外のノード間での循環、または@utility固有チェックで検出されなかった循環 | エラーメッセージのCSSブロックを確認し、一方の@applyを直接CSSに書き換え |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0 |
| リトライ間隔 | N/A |
| リトライ対象エラー | N/A（例外がスローされ処理は中断） |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | なし |
| 1日あたり上限 | なし |

### 配信時間帯

制限なし（CSSコンパイル時に随時発生）

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

CSSの内容がエラーメッセージに含まれるが、CSSファイルの内容であり機密情報は含まれない。ローカル実行のため特段のリスクはない。

## 備考

- このエラーはNo.18（@utility間循環依存エラー）のフォールバックとして機能する
- `toCss`関数によりASTノードがCSS文字列に変換され、エラーメッセージに含まれる
- コメント「Generic fallback error in case we cannot properly detect the origin of the circular dependency.」（129-130行目）に記載の通り、循環の正確な起源が特定できない場合の汎用エラーである
- `path`配列のインデックス計算`(path.indexOf(node) + 1) % path.length`により、循環チェーン内の次のノードが特定される（94行目）

---

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

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

### 推奨読解順序

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

トポロジカルソートの状態管理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | apply.ts | `packages/tailwindcss/src/apply.ts` | 82-84行目: seen, sorted, wipのセット定義 |
| 1-2 | ast.ts | `packages/tailwindcss/src/ast.ts` | toCss関数の定義（ASTノードをCSS文字列に変換） |

**読解のコツ**: `wip`（Work In Progress）セットが現在処理中のノードを追跡し、再訪問時に循環を検出する仕組みを理解することが重要。

#### Step 2: エントリーポイントを理解する

visit関数の循環検出から汎用エラーまでの流れを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | apply.ts | `packages/tailwindcss/src/apply.ts` | 86行目: visit関数定義 |
| 2-2 | apply.ts | `packages/tailwindcss/src/apply.ts` | 92-133行目: 循環検出ブロック全体 |

**主要処理フロー**:
1. **92行目**: `wip.has(node)` - 循環依存の検出
2. **94行目**: `path[(path.indexOf(node) + 1) % path.length]` - 次のノードの特定
3. **96-127行目**: @utility固有チェック（No.18）
4. **129-130行目**: フォールバックコメント
5. **131行目**: `throw new Error(...)` - 汎用循環依存エラー
6. **132行目**: `toCss([node])` - 循環元ノードのCSS表現
7. **132行目**: `toCss([next])` - 循環先ノードのCSS表現

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

```
substituteAtApply(ast, designSystem) [apply.ts:10]
    |
    +-- visit(node, path) [86行目]
            |
            +-- [wip.has(node) = true] [92行目]
                    |
                    +-- next = path[(indexOf + 1) % length] [94行目]
                    |
                    +-- [@utility固有チェック] [96-127行目]
                    |       (No.18のエラーがスローされなかった場合)
                    |
                    +-- throw Error [131-133行目]
                            |
                            +-- toCss([node]) [132行目]
                            +-- toCss([next]) [132行目]
```

### データフロー図

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

CSS AST              --->  トポロジカルソート (DFS)
(循環依存あり)                |
                         visit(node)
                              |
                         wip.has(node) = true
                              |
                         next = path[...]
                              |
                         @utility固有チェック通過
                              |
                              v
                         toCss([node])         --->  CSS文字列 (node)
                         toCss([next])         --->  CSS文字列 (next)
                              |
                              v
                         throw Error           --->  "Circular dependency detected:
                                                      {node CSS}
                                                      Relies on:
                                                      {next CSS}"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| apply.ts | `packages/tailwindcss/src/apply.ts` | ソース | @apply代入処理・トポロジカルソート・汎用循環依存検出 |
| ast.ts | `packages/tailwindcss/src/ast.ts` | ソース | AST型定義、toCss関数（ノードのCSS文字列化） |
| walk.ts | `packages/tailwindcss/src/walk.ts` | ソース | AST走査ユーティリティ |
