# 機能設計書 37-候補からCSS変換（candidatesToCss）

## 概要

本ドキュメントは、Tailwind CSSにおける候補クラス名をCSS文字列に変換するcandidatesToCss関数の機能設計を記述する。

### 本機能の処理概要

候補クラス名の配列を受け取り、各クラスに対応するCSS文字列を生成して返す機能である。主にIDEのIntelliSenseにおけるプレビュー表示（クラス名にホバーした際のCSS表示等）に使用される。

**業務上の目的・背景**：Tailwind CSSのIDE統合において、開発者がクラス名にマウスホバーした際に、そのクラスが生成するCSSをプレビュー表示する機能が求められる。本機能は、任意の候補クラス名をCSS文字列に変換することで、IDEの補完ポップアップやホバー情報にCSSプレビューを提供する。ポリフィルを無効にした状態でCSSを生成するため、IntelliSenseの出力が不必要なフォールバックコードで汚染されることを防ぐ。

**機能の利用シーン**：
- IDE拡張機能でのクラス名ホバー時のCSSプレビュー表示
- 補完候補のCSS表示
- DesignSystem.candidatesToCss()メソッドの呼び出し時

**主要な処理内容**：
1. 入力クラス名配列をcandidatesToAstに渡してAST配列を取得する
2. candidatesToAstは各クラスをcompileCandidatesでコンパイルし、ソースロケーションを設定し、ポリフィルなしでAST最適化を行う
3. 各ASTノード配列をtoCssでCSS文字列に変換する
4. 有効なCSSがある場合はCSS文字列を、ない場合はnullを返す

**関連システム・外部連携**：DesignSystem APIの一部として公開される。IDE拡張機能（Tailwind CSS IntelliSense）から利用される。

**権限による制御**：権限による制御はない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面に直接関連しないAPI機能。IDEのプレビューUIに間接的に関連 |

## 機能種別

計算処理（候補クラス名からCSS文字列への変換）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| classes | string[] | Yes | CSS変換対象の候補クラス名の配列 | 空配列も許容 |

### 入力データソース

DesignSystem APIのcandidatesToCssメソッド経由で呼び出される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result | (string \| null)[] | 各クラスに対応するCSS文字列の配列。無効なクラスまたはCSSが生成されない場合はnull |

### 出力先

呼び出し元への戻り値として返される。

## 処理フロー

### 処理シーケンス

```
1. candidatesToAstの呼び出し（内部関数）
   └─ 各クラス名について:
       a. compileCandidates([className], designSystem)でASTを生成
       b. 無効な候補の場合はonInvalidCallbackで検出
       c. utilitiesSrcが設定されている場合、ASTノードにソースロケーションを付与
       d. optimizeAst(astNodes, designSystem, Polyfills.None)でポリフィルなしのAST最適化
       e. 有効な場合はASTノード配列、無効な場合は空配列を返す
2. AST配列からCSS文字列への変換
   └─ nodes.length > 0の場合: toCss(nodes)でCSS文字列化
   └─ nodes.length === 0の場合: nullを返す
3. CSS文字列配列を返す
```

### フローチャート

```mermaid
flowchart TD
    A[開始: classes配列を受け取り] --> B[candidatesToAst呼び出し]
    B --> C[各クラスをループ]
    C --> D[compileCandidates実行]
    D --> E{有効な候補?}
    E -->|No| F[空配列をresultに追加]
    E -->|Yes| G{utilitiesSrcあり?}
    G -->|Yes| H[ASTノードにsrcを設定]
    G -->|No| I[optimizeAst実行（Polyfills.None）]
    H --> I
    I --> J[ASTノード配列をresultに追加]
    F --> C
    J --> C
    C --> K[AST配列をmapで変換]
    K --> L{nodes.length > 0?}
    L -->|Yes| M[toCss変換]
    L -->|No| N[null]
    M --> O[CSS文字列配列を返却]
    N --> O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-37-01 | ポリフィル無効化 | IntelliSense出力のためポリフィルを無効（Polyfills.None）にしてAST最適化する | 常に |
| BR-37-02 | 無効候補 | 無効な候補クラスの場合はnullを返す | compileCandidatesで認識できないクラス |
| BR-37-03 | ソースロケーション | utilitiesSrcが設定されている場合、各ノードにnode.srcを設定（未設定の場合のみ） | utilitiesSrcが非undefined |
| BR-37-04 | CSS生成 | ASTノードが存在する場合のみtoCssでCSS文字列を生成する | ASTノード配列が空でない場合 |
| BR-37-05 | 入力順序保持 | 出力配列の順序は入力classes配列の順序を維持する | 常に |

### 計算ロジック

特別な計算ロジックはない。compileCandidates → optimizeAst → toCssのパイプライン処理である。

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

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

データベース操作なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 無効候補 | クラス名がTailwindユーティリティとして認識できない | nullを返す |

### リトライ仕様

リトライは不要。

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

トランザクション管理なし。

## パフォーマンス要件

- 各クラスに対してcompileCandidatesとoptimizeAstを実行するため、大量のクラスに対する呼び出しにはコストがかかる
- DesignSystem内部でcompileAstNodesのDefaultMapキャッシュが利用されるため、同一クラスの再コンパイルはキャッシュヒットする

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

特になし。

## 備考

- candidatesToCssはcandidatesToAstの薄いラッパーである。ASTが必要な場合はcandidatesToAstを直接使用する
- ポリフィルを無効にする理由は、IntelliSenseの出力が@propertyフォールバックやcolor-mixフォールバックで冗長になることを防ぐため

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ast.ts | `packages/tailwindcss/src/ast.ts` | AstNode型とtoCss関数の理解 |
| 1-2 | design-system.ts | `packages/tailwindcss/src/design-system.ts` | DesignSystem型のcandidatesToCss/candidatesToAstシグネチャ（63-64行目） |

**読解のコツ**: candidatesToCssとcandidatesToAstはdesign-system.ts内のクロージャとして定義されており、utilitiesSrc変数を共有している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | design-system.ts | `packages/tailwindcss/src/design-system.ts` | `candidatesToCss`関数（150-154行目） |
| 2-2 | design-system.ts | `packages/tailwindcss/src/design-system.ts` | `candidatesToAst`関数（118-148行目） |

**主要処理フロー（candidatesToCss）**:
1. **150行目**: `candidatesToCss`関数の定義
2. **151行目**: `candidatesToAst(classes).map(...)`でASTを取得してmapで変換
3. **152行目**: `nodes.length > 0 ? toCss(nodes) : null`で条件分岐

**主要処理フロー（candidatesToAst）**:
1. **118行目**: `candidatesToAst`関数の定義
2. **121-145行目**: 各クラス名のループ処理
3. **124行目**: `compileCandidates([className], designSystem, { onInvalidCandidate })`
4. **131-138行目**: utilitiesSrcがある場合のソースロケーション設定（walk使用）
5. **142行目**: `optimizeAst(astNodes, designSystem, Polyfills.None)`でポリフィルなし最適化
6. **144行目**: 有効ならastNodes、無効なら空配列をpush

#### Step 3: 関連する最適化処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | ast.ts | `packages/tailwindcss/src/ast.ts` | `optimizeAst`関数 - AST最適化処理。Polyfills.Noneの場合の挙動 |
| 3-2 | index.ts | `packages/tailwindcss/src/index.ts` | `Polyfills`列挙型の定義（41-52行目） |

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

```
DesignSystem.candidatesToCss (design-system.ts:164)
    │
    └─ candidatesToCss (design-system.ts:150)
           │
           └─ candidatesToAst (design-system.ts:118)
                  │
                  ├─ compileCandidates() (compile.ts)
                  │      ├─ parseCandidate()
                  │      └─ compileAstNodes()
                  │
                  ├─ walk() (walk.ts)
                  │      └─ node.src設定
                  │
                  ├─ optimizeAst() (ast.ts)
                  │      └─ Polyfills.None指定
                  │
                  └─ toCss() (ast.ts)
                         └─ ASTからCSS文字列生成
```

### データフロー図

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

classes: string[]   ───▶ candidatesToAst()              ───▶ AstNode[][]
["mt-4", "invalid"]        │
                           ├─ compileCandidates("mt-4")
                           │   → ASTノード生成
                           │
                           ├─ optimizeAst(Polyfills.None)
                           │   → 最適化されたAST
                           │
                           ├─ compileCandidates("invalid")
                           │   → 空（無効候補）
                           │
                           └─ toCss(nodes)              ───▶ (string | null)[]
                                                              [".mt-4 {\n  margin-top: ...\n}",
                                                               null]
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| design-system.ts | `packages/tailwindcss/src/design-system.ts` | ソース | メイン処理: candidatesToCss/candidatesToAst関数定義 |
| ast.ts | `packages/tailwindcss/src/ast.ts` | ソース | toCss関数（AST→CSS変換）、optimizeAst関数 |
| compile.ts | `packages/tailwindcss/src/compile.ts` | ソース | compileCandidates関数 |
| index.ts | `packages/tailwindcss/src/index.ts` | ソース | Polyfills列挙型定義 |
| walk.ts | `packages/tailwindcss/src/walk.ts` | ソース | ASTウォーカー |
