# 機能設計書 21-theme()関数

## 概要

本ドキュメントは、Tailwind CSSにおけるtheme()関数（`--theme()`およびレガシー`theme()`）の仕様・処理フロー・内部構造を記述した機能設計書である。

### 本機能の処理概要

theme()関数は、CSSの宣言値やat-ruleのパラメータ内でテーマ変数を参照するためのカスタムCSS関数である。CSS内で`--theme(--color-blue-500)`や`theme('colors.blue.500')`と記述すると、DesignSystemのテーマに登録された値に解決される。

**業務上の目的・背景**：テーマ変数をCSS内から直接参照する仕組みが必要である。CSSカスタムプロパティとして定義されたテーマ値を、宣言値やメディアクエリ条件などのCSS各所で利用できるようにすることで、デザイントークンの一元管理と一貫した参照が可能になる。v3のドット記法（`theme('colors.blue.500')`）とv4のCSS変数記法（`--theme(--color-blue-500)`）の両方に対応することで、後方互換性を維持しつつ新しい記法への移行をサポートする。

**機能の利用シーン**：CSS宣言値内でテーマ値を参照する場合（例: `color: --theme(--color-blue-500)`）、メディアクエリ内でテーマ値を参照する場合（例: `@media (width >= --theme(--breakpoint-lg))`）、フォールバック値付きの参照（例: `--theme(--color-custom, red)`）、v3互換モードでのテーマ参照（例: `theme('spacing.4')`）などで使用される。

**主要な処理内容**：
1. CSS値パーサーで値文字列をパースし、`--theme()`または`theme()`関数ノードを検出する
2. 引数をカンマで分割し、パスとフォールバック値を分離する
3. DesignSystemの`resolveThemeValue`メソッドでテーマ値を解決する
4. at-rule内で使用されている場合はインライン解決を強制する
5. フォールバック値の処理（`initial`フォールバックの注入を含む）
6. 解決された値でAST上の関数ノードを置換する

**関連システム・外部連携**：DesignSystem（テーマ値解決）、ValueParser（CSS値のパース）、walkユーティリティ（ASTの走査）と連携する。

**権限による制御**：特になし。CSS処理パイプラインの一部として自動的に実行される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はCSS処理パイプラインの内部処理であり、特定の画面とは直接関連しない |

## 機能種別

データ変換処理（CSS関数の値解決・置換）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| designSystem | DesignSystem | Yes | テーマ値の解決に使用するデザインシステム | - |
| source | AstNode | Yes | 関数が使用されているASTノード（at-ruleかdeclarationか判定に使用） | - |
| path | string | Yes | テーマ変数のパス（`--theme`の場合は`--`で始まる必要がある） | `--theme`の場合: `--`で始まること |
| fallback | string[] | No | フォールバック値（カンマ区切りの残り引数） | - |

### 入力データソース

CSSのAST内の宣言値（declaration.value）またはat-ruleのパラメータ（at-rule.params）から抽出される。

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| resolvedValue | string | テーマから解決された値、またはフォールバック値 |

### 出力先

AST上の関数ノードが解決された値で置換される（declaration.valueまたはat-rule.params内）。

## 処理フロー

### 処理シーケンス

```
1. substituteFunctions(ast, designSystem)がASTを走査
   └─ walkで全ノードを巡回
2. declaration.valueまたはat-rule.paramsにtheme関数呼び出しを検出
   └─ THEME_FUNCTION_INVOCATION正規表現でテスト
3. substituteFunctionsInValue(value, source, designSystem)を呼び出し
   └─ ValueParser.parseで値をパース
4. 関数ノードの種別を判定
   └─ --theme → theme関数を呼び出し
   └─ theme → legacyTheme関数を呼び出し
5. theme関数の処理
   └─ パスが--で始まるか検証
   └─ inline修飾子の検出
   └─ at-rule内の場合はinline強制
   └─ designSystem.resolveThemeValue(path, inline)で解決
   └─ フォールバック処理
6. legacyTheme関数の処理
   └─ パスのクォート解除（eventuallyUnquote）
   └─ designSystem.resolveThemeValue(path)で解決
   └─ フォールバック処理
7. 解決された値でASTノードを置換
   └─ WalkAction.Replace(ValueParser.parse(result))
```

### フローチャート

```mermaid
flowchart TD
    A[substituteFunctions開始] --> B[ASTをwalk]
    B --> C{ノード種別}
    C -->|declaration| D{THEME_FUNCTION_INVOCATION?}
    C -->|at-rule| E{@media/@container/@supports?}
    D -->|Yes| F[substituteFunctionsInValue]
    E -->|Yes| G{paramsにtheme関数?}
    G -->|Yes| F
    F --> H[ValueParser.parseで値パース]
    H --> I{関数名は?}
    I -->|--theme| J[theme関数]
    I -->|theme| K[legacyTheme関数]
    J --> L{--で始まる?}
    L -->|No| M[エラー]
    L -->|Yes| N{inline修飾子?}
    N --> O{source.kind === at-rule?}
    O -->|Yes| P[inline = true]
    O -->|No| Q[resolveThemeValue]
    P --> Q
    Q --> R{値が解決できた?}
    R -->|No| S{フォールバックあり?}
    S -->|Yes| T[フォールバック値を返す]
    S -->|No| U[エラー]
    R -->|Yes| V[解決値を返す]
    K --> W[eventuallyUnquote]
    W --> X[resolveThemeValue]
    X --> Y{値が解決できた?}
    Y -->|No| Z{フォールバックあり?}
    Z -->|Yes| T
    Z -->|No| U
    Y -->|Yes| V
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | パスプレフィックス制約 | `--theme()`のパスは`--`で始まる必要がある | `--theme()`使用時 |
| BR-02 | at-ruleインライン強制 | at-rule内での使用時はインライン解決が強制される | source.kind === 'at-rule' |
| BR-03 | inline修飾子 | パス末尾の` inline`でインライン解決を強制できる | `--theme(… inline)` |
| BR-04 | フォールバック初期値注入 | 解決値が`var(`/`theme(`/`--theme(`で始まる場合、`initial`フォールバックの注入処理が行われる | フォールバック付き参照 |
| BR-05 | initialフォールバック処理 | フォールバック値が`initial`の場合は解決値をそのまま返す | fallback === 'initial' |
| BR-06 | レガシーパスクォート解除 | `theme()`関数のパスはシングル/ダブルクォートで囲まれている場合がある | `theme()`使用時 |

### 計算ロジック

フォールバック注入ロジック: 解決値が`var(`/`theme(`/`--theme(`で始まる場合、ValueParserで解析し、内部の`var`/`theme`/`--theme`関数のノードに対して以下の処理を行う：
- ノードの子要素が1つだけの場合: `, {fallback}`を追加
- 最後の子要素の値が`initial`の場合: `initial`をフォールバック値で置換

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

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

本機能はデータベース操作を行わない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Error | `--theme()`のパスが`--`で始まらない | パスを修正する |
| - | Error | テーマ値が解決できずフォールバックもない | 変数名を確認するかフォールバック値を指定する |
| - | Error | レガシー`theme()`でテーマ値が解決できずフォールバックもない | パスを確認するかフォールバック値を指定する |

### リトライ仕様

リトライは行わない。

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

トランザクション管理は不要。ASTのインプレース変換として実行される。

## パフォーマンス要件

- THEME_FUNCTION_INVOCATION正規表現による事前フィルタリングで、theme関数を含まない値のパース処理をスキップする
- 正規表現は`CSS_FUNCTIONS`のキーから動的に構築される

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

特段のセキュリティ考慮事項はない。

## 備考

- `--theme()`はv4ネイティブ形式、`theme()`はv3互換のレガシー形式
- `--theme()`と`theme()`で引数の扱いが異なる（`--theme`はCSS変数名、`theme`はドット記法パス）
- `--alpha()`と`--spacing()`も同じCSS関数置換フレームワーク内で処理される

---

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

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

### 推奨読解順序

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

CSS値パーサーのASTノード型とCSS_FUNCTIONS登録構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | value-parser.ts | `packages/tailwindcss/src/value-parser.ts` | ValueAstNode型（word/function/separator）の構造を理解する |
| 1-2 | css-functions.ts | `packages/tailwindcss/src/css-functions.ts` | **9-17行目**: CSS_FUNCTIONSレコードの定義。`--alpha`, `--spacing`, `--theme`, `theme`の4つの関数が登録されている |

**読解のコツ**: CSS_FUNCTIONSはRecord型で関数名をキーにして実装関数をマッピングしている。`--theme`がv4形式、`theme`がv3レガシー形式。

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

substituteFunctions関数がAST走査のエントリーポイントとなる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | css-functions.ts | `packages/tailwindcss/src/css-functions.ts` | **158-183行目**: substituteFunctions関数。ASTを走査し、declaration値とat-ruleパラメータ内のtheme関数を検出する |

**主要処理フロー**:
1. **152-156行目**: THEME_FUNCTION_INVOCATION正規表現の生成。CSS_FUNCTIONSのキーから`--alpha\(|--spacing\(|--theme\(|theme\(`パターンを構築
2. **160-166行目**: declaration.valueに対するtheme関数の検出と置換
3. **169-179行目**: at-rule（@media/@custom-media/@container/@supports）パラメータに対するtheme関数の検出と置換

#### Step 3: 値置換処理を理解する

substituteFunctionsInValue関数の内部ロジックを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | css-functions.ts | `packages/tailwindcss/src/css-functions.ts` | **185-204行目**: substituteFunctionsInValue関数。ValueParser.parseで値をパースし、関数ノードを検出して対応する実装を呼び出す |

**主要処理フロー**:
- **190行目**: ValueParser.parseで値文字列をASTに変換
- **192行目**: 関数ノードでCSS_FUNCTIONSに登録された関数名かチェック
- **193行目**: 引数をカンマで分割
- **199行目**: WalkAction.Replaceで解決値に置換

#### Step 4: theme関数（v4形式）の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | css-functions.ts | `packages/tailwindcss/src/css-functions.ts` | **68-127行目**: theme関数の実装 |

**主要処理フロー**:
- **74-76行目**: パスが`--`で始まるかの検証
- **81-84行目**: `inline`修飾子の検出と除去
- **88-90行目**: at-rule内使用時のインライン強制
- **92行目**: designSystem.resolveThemeValueでの値解決
- **94-98行目**: 値が解決できない場合のフォールバック処理
- **116-124行目**: var()/theme()/--theme()で始まる解決値への`initial`フォールバック注入

#### Step 5: legacyTheme関数（v3互換形式）の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | css-functions.ts | `packages/tailwindcss/src/css-functions.ts` | **129-150行目**: legacyTheme関数の実装 |
| 5-2 | css-functions.ts | `packages/tailwindcss/src/css-functions.ts` | **206-224行目**: eventuallyUnquote関数。クォート解除処理 |

#### Step 6: フォールバック注入の詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | css-functions.ts | `packages/tailwindcss/src/css-functions.ts` | **226-243行目**: injectFallbackForInitialFallback関数。`var`/`theme`/`--theme`関数ノードに対してフォールバック値を注入する |

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

```
substituteFunctions(ast, designSystem)
    │
    ├─ walk(ast, callback)
    │      │
    │      └─ substituteFunctionsInValue(value, source, designSystem)
    │             │
    │             ├─ ValueParser.parse(value)
    │             │
    │             ├─ segment(args, ',')
    │             │
    │             ├─ CSS_FUNCTIONS[functionName](designSystem, source, ...args)
    │             │      │
    │             │      ├─ theme(designSystem, source, path, ...fallback)
    │             │      │      ├─ designSystem.resolveThemeValue(path, inline)
    │             │      │      └─ injectFallbackForInitialFallback(valueAst, fallback)
    │             │      │
    │             │      └─ legacyTheme(designSystem, source, path, ...fallback)
    │             │             ├─ eventuallyUnquote(path)
    │             │             └─ designSystem.resolveThemeValue(path)
    │             │
    │             └─ ValueParser.toCss(ast)
    │
    └─ Features（フィーチャーフラグの更新）
```

### データフロー図

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

AstNode[]                ──▶ substituteFunctions            ──▶ AstNode[]（変換済み）
(declaration.value             │                                  + Features
 に theme関数を含む)           ├─ THEME_FUNCTION_INVOCATION
                               │    で事前フィルタ
                               │
                               ├─ ValueParser.parse
                               │    で値をAST化
                               │
                               ├─ CSS_FUNCTIONSで
                               │    対応関数を呼び出し
                               │
                               ├─ resolveThemeValue
                               │    でテーマ値解決
                               │
                               └─ WalkAction.Replace
                                    で値を置換
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| css-functions.ts | `packages/tailwindcss/src/css-functions.ts` | ソース | theme()関数の主要実装 |
| value-parser.ts | `packages/tailwindcss/src/value-parser.ts` | ソース | CSS値のパーサー |
| design-system.ts | `packages/tailwindcss/src/design-system.ts` | ソース | resolveThemeValueメソッドの提供元 |
| theme.ts | `packages/tailwindcss/src/theme.ts` | ソース | テーマ値の管理・解決 |
| walk.ts | `packages/tailwindcss/src/walk.ts` | ソース | AST走査ユーティリティ |
| segment.ts | `packages/tailwindcss/src/utils/segment.ts` | ソース | 文字列分割ユーティリティ |
| index.ts | `packages/tailwindcss/src/index.ts` | ソース | コンパイルパイプラインからsubstituteFunctionsを呼び出す |
