# 機能設計書 7-属性セレクタパーサー（AttributeSelectorParser）

## 概要

本ドキュメントは、CSS属性セレクタを解析するAttributeSelectorParserの機能設計書である。候補の正規化処理（canonicalize）で使用される。

### 本機能の処理概要

**業務上の目的・背景**：Tailwind CSSの候補正規化処理では、属性セレクタ（例: `[data-active]`、`[data-state="open"]`）を解析してその構成要素（属性名、演算子、値、大文字小文字感度）を個別に取得する必要がある。この情報は候補クラス名の正規化やIntelliSense機能で使用される。

**機能の利用シーン**：canonicalize-candidates.tsの正規化処理から呼び出される。属性セレクタを含むバリアント（例: `[data-active]:flex`）の解析に使用される。

**主要な処理内容**：
1. 入力文字列が`[`で始まり`]`で終わることを検証する
2. 属性名（`data-foo`等）を解析する
3. 演算子（`=`、`~=`、`|=`、`^=`、`$=`、`*=`）を解析する
4. 値を解析する（引用符付き/なし両方に対応）
5. 大文字小文字感度（`i`/`s`フラグ）を解析する
6. 各部分の間のホワイトスペースをスキップする
7. 解析結果をAttributeSelector構造体として返却する

**関連システム・外部連携**：特になし。純粋な文字列処理。

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 候補正規化処理の内部で間接的に使用される |

## 機能種別

データ変換処理（属性セレクタ文字列 -> AttributeSelector構造体）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| input | string | Yes | CSS属性セレクタ文字列（`[`で始まり`]`で終わる） | `[`開始・`]`終了でない場合はnullを返却 |

### 入力データソース

- canonicalize-candidates.tsから属性セレクタ文字列が渡される

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| attribute | string | 属性名 |
| operator | string \| null | 演算子（=, ~=, \|=, ^=, $=, *=）またはnull |
| quote | '"' \| "'" \| null | 値の引用符文字またはnull |
| value | string \| null | 値文字列またはnull |
| sensitivity | 'i' \| 's' \| null | 大文字小文字感度フラグまたはnull |

### 出力先

- canonicalize-candidates.tsに返却される

## 処理フロー

### 処理シーケンス

```
1. 入力検証
   └─ [で始まり]で終わることを確認（不正ならnull返却）
2. 属性名の解析
   ├─ ホワイトスペーススキップ
   ├─ 英数字・ハイフン・アンダースコア・エスケープ文字を属性名として収集
   └─ 属性名が空ならnull返却
3. 演算子の解析
   ├─ ホワイトスペーススキップ
   ├─ ここで終端なら演算子なしで返却（属性存在チェック型: [data-foo]）
   ├─ =のみ: 完全一致演算子
   └─ ~/|/^/$/*のいずれか + =: 各種マッチング演算子
4. 値の解析
   ├─ ホワイトスペーススキップ
   ├─ 引用符付き値: 開始引用符と同じ引用符で終端
   └─ 引用符なし値: ホワイトスペースまたは終端まで
5. 大文字小文字感度の解析
   ├─ ホワイトスペーススキップ
   ├─ i/I: case-insensitive
   └─ s/S: case-sensitive
6. 終端確認
   └─ 残りの文字があればnull返却（不正な構文）
```

### フローチャート

```mermaid
flowchart TD
    A[属性セレクタ文字列入力] --> B{[で始まり]で終わる?}
    B -->|No| C[null返却]
    B -->|Yes| D[属性名解析]
    D --> E{属性名が空?}
    E -->|Yes| C
    E -->|No| F{終端?}
    F -->|Yes| G[演算子なしで返却]
    F -->|No| H[演算子解析]
    H --> I{有効な演算子?}
    I -->|No| C
    I -->|Yes| J{値が存在?}
    J -->|No| C
    J -->|Yes| K[値解析]
    K --> L{終端?}
    L -->|Yes| M[感度なしで返却]
    L -->|No| N[感度フラグ解析]
    N --> O{終端?}
    O -->|Yes| P[全項目で返却]
    O -->|No| C
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 属性存在チェック型 | 演算子なしの場合は属性の存在チェック型として解釈（例: `[data-foo]`） | 属性名の後に演算子がない場合 |
| BR-02 | 演算子の種類 | 6種類の演算子に対応: `=`、`~=`、`\|=`、`^=`、`$=`、`*=` | 演算子位置に該当文字がある場合 |
| BR-03 | 引用符の保持 | 値を囲む引用符の種類（シングル/ダブル）を記録する | 引用符付き値の場合 |
| BR-04 | 感度フラグの大小文字 | `i`/`I`はcase-insensitive、`s`/`S`はcase-sensitive | 感度フラグ位置にi/sがある場合 |
| BR-05 | 厳密な構文検証 | 各パート間のバランスが崩れた場合はnullを返却する | 不正な構文の場合 |

### 計算ロジック

特になし。

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

該当なし

## エラー処理

### エラーケース一覧

本パーサーはエラーをスローせず、不正な入力に対してnullを返却する。

| 返却値 | 発生条件 |
|--------|---------|
| null | `[`で始まらない、または`]`で終わらない |
| null | 属性名が空 |
| null | 無効な演算子 |
| null | 演算子あり・値なし |
| null | 無効な感度フラグ |
| null | 感度フラグの後に余分な文字がある |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- charCodeAtによる数値比較で高速な文字種判定を実現
- インデックスベースの逐次パースで文字列の再アロケーションを最小化

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

特になし。

## 備考

- 本パーサーは不正入力に対してnullを返却するフェイルセーフ設計になっている
- エスケープ文字（`\`）は属性名の解析時にスキップされる

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | attribute-selector-parser.ts | `packages/tailwindcss/src/attribute-selector-parser.ts` | AttributeSelector インターフェース（27-33行目）の構造 |

**読解のコツ**: `operator`、`value`、`quote`、`sensitivity`は全てnull許容であり、属性セレクタの種類に応じて設定される。最もシンプルな`[data-foo]`では`operator`以降は全てnullとなる。

#### Step 2: parse関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | attribute-selector-parser.ts | `packages/tailwindcss/src/attribute-selector-parser.ts` | `parse`関数（35-216行目）。逐次パース処理 |

**主要処理フロー**:
1. **37-39行目**: 入力検証（`[`と`]`の確認）
2. **47-71行目**: 属性名の解析（英数字・ハイフン・アンダースコア・エスケープ）
3. **79-87行目**: 演算子なし（属性存在チェック型）の早期リターン
4. **92-108行目**: 演算子の解析（6種類の演算子パターン）
5. **122-156行目**: 値の解析（引用符付き/なし両対応）
6. **163-171行目**: 演算子+値の結果を返却
7. **176-195行目**: 感度フラグの解析（i/I/s/S）
8. **201-202行目**: 終端確認と最終null判定

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

```
AttributeSelectorParser.parse(input)
    |
    +-- isAsciiWhitespace()     ... ホワイトスペース判定
    |
    +-- 結果: AttributeSelector | null
```

### データフロー図

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

"[data-state='open' i]"
                          ──▶  parse()           ──▶  {
                                                        attribute: 'data-state',
                                                        operator: '=',
                                                        quote: "'",
                                                        value: 'open',
                                                        sensitivity: 'i'
                                                      }
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| attribute-selector-parser.ts | `packages/tailwindcss/src/attribute-selector-parser.ts` | ソース | AttributeSelectorParser本体 |
| canonicalize-candidates.ts | `packages/tailwindcss/src/canonicalize-candidates.ts` | ソース | 主要な利用元（候補正規化処理） |
