@markuplint/ml-ast 5.0.0-rc.2 → 5.0.0-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ARCHITECTURE.md DELETED
@@ -1,309 +0,0 @@
1
- # @markuplint/ml-ast
2
-
3
- ## Overview
4
-
5
- `@markuplint/ml-ast` is a pure type-definition package that defines the language-independent Abstract Syntax Tree (AST) intermediate representation for markuplint. It contains **zero runtime code** and **zero dependencies** -- only TypeScript type definitions that all parsers must produce and all downstream packages consume.
6
-
7
- Every markup language parser (HTML, JSX, Vue, Svelte, Astro, Pug, etc.) parses source code into the types defined here, enabling markuplint's core and rules to operate on a unified AST regardless of the source language.
8
-
9
- ## Directory Structure
10
-
11
- ```
12
- src/
13
- ├── index.ts — Re-exports all types from types.ts
14
- └── types.ts — All type definitions (~470 lines)
15
- ```
16
-
17
- ## Architecture Diagram
18
-
19
- ```mermaid
20
- flowchart TD
21
- subgraph parsers ["Parsers (upstream)"]
22
- html["@markuplint/html-parser"]
23
- jsx["@markuplint/jsx-parser"]
24
- vue["@markuplint/vue-parser"]
25
- svelte["@markuplint/svelte-parser"]
26
- astro["@markuplint/astro-parser"]
27
- pug["@markuplint/pug-parser"]
28
- parserUtils["@markuplint/parser-utils"]
29
- end
30
-
31
- subgraph ast ["@markuplint/ml-ast"]
32
- types["Type Definitions\n(MLASTDocument, MLASTElement,\nMLASTComment, MLASTText, ...)"]
33
- end
34
-
35
- subgraph downstream ["Downstream"]
36
- mlCore["@markuplint/ml-core\n(AST → DOM mapping)"]
37
- mlConfig["@markuplint/ml-config"]
38
- mlSpec["@markuplint/ml-spec"]
39
- rules["@markuplint/rules"]
40
- fileResolver["@markuplint/file-resolver"]
41
- end
42
-
43
- parsers -->|"produce"| types
44
- types -->|"consumed by"| downstream
45
- mlCore -->|"creates DOM nodes from"| types
46
- ```
47
-
48
- ## Type Inheritance Diagram
49
-
50
- ```mermaid
51
- classDiagram
52
- class MLASTToken {
53
- <<interface>>
54
- +uuid: string
55
- +raw: string
56
- +offset: number
57
- +line: number
58
- +col: number
59
- }
60
-
61
- class MLASTAbstractNode {
62
- <<interface>>
63
- +type: MLASTNodeType
64
- +nodeName: string
65
- +parentNodeUuid: string | null
66
- }
67
-
68
- class MLASTDoctype {
69
- <<interface>>
70
- +type: "doctype"
71
- +depth: number
72
- +name: string
73
- +publicId: string
74
- +systemId: string
75
- }
76
-
77
- class MLASTElement {
78
- <<interface>>
79
- +type: "starttag"
80
- +depth: number
81
- +namespace: string
82
- +elementType: ElementType
83
- +attributes: MLASTAttr[]
84
- +childNodes: MLASTChildNode[]
85
- +blockBehavior: MLASTBlockBehavior | null
86
- +pairNodeUuid: string | null
87
- +isGhost: boolean
88
- +isFragment: boolean
89
- }
90
-
91
- class MLASTElementCloseTag {
92
- <<interface>>
93
- +type: "endtag"
94
- +depth: number
95
- +pairNodeUuid: string | null
96
- }
97
-
98
- class MLASTComment {
99
- <<interface>>
100
- +type: "comment"
101
- +depth: number
102
- +isBogus: boolean
103
- }
104
-
105
- class MLASTText {
106
- <<interface>>
107
- +type: "text"
108
- +depth: number
109
- }
110
-
111
- class MLASTPreprocessorSpecificBlock {
112
- <<interface>>
113
- +type: "psblock"
114
- +blockBehavior: MLASTBlockBehavior | null
115
- +depth: number
116
- +childNodes: MLASTChildNode[]
117
- +isBogus: boolean
118
- }
119
-
120
- class MLASTInvalid {
121
- <<interface>>
122
- +type: "invalid"
123
- +depth: number
124
- +kind: MLASTChildNode type
125
- +isBogus: true
126
- }
127
-
128
- class MLASTHTMLAttr {
129
- <<interface>>
130
- +type: "attr"
131
- +name: MLASTToken
132
- +value: MLASTToken
133
- +isDynamicValue: boolean
134
- +isDirective: boolean
135
- }
136
-
137
- class MLASTSpreadAttr {
138
- <<interface>>
139
- +type: "spread"
140
- }
141
-
142
- MLASTToken <|-- MLASTAbstractNode
143
- MLASTAbstractNode <|-- MLASTDoctype
144
- MLASTAbstractNode <|-- MLASTElement
145
- MLASTAbstractNode <|-- MLASTElementCloseTag
146
- MLASTAbstractNode <|-- MLASTComment
147
- MLASTAbstractNode <|-- MLASTText
148
- MLASTAbstractNode <|-- MLASTPreprocessorSpecificBlock
149
- MLASTAbstractNode <|-- MLASTInvalid
150
- MLASTToken <|-- MLASTHTMLAttr
151
- MLASTToken <|-- MLASTSpreadAttr
152
- ```
153
-
154
- ## Union Types
155
-
156
- ```mermaid
157
- flowchart TD
158
- subgraph MLASTNode ["MLASTNode (all node types)"]
159
- subgraph MLASTNodeTreeItem ["MLASTNodeTreeItem"]
160
- MLASTDoctype["MLASTDoctype"]
161
- subgraph MLASTChildNode ["MLASTChildNode"]
162
- subgraph MLASTTag ["MLASTTag"]
163
- MLASTElement["MLASTElement"]
164
- MLASTElementCloseTag["MLASTElementCloseTag"]
165
- end
166
- MLASTText["MLASTText"]
167
- MLASTComment["MLASTComment"]
168
- MLASTPreprocessorSpecificBlock["MLASTPreprocessorSpecificBlock"]
169
- MLASTInvalid["MLASTInvalid"]
170
- end
171
- end
172
- subgraph MLASTAttr ["MLASTAttr"]
173
- MLASTHTMLAttr["MLASTHTMLAttr"]
174
- MLASTSpreadAttr["MLASTSpreadAttr"]
175
- end
176
- end
177
-
178
- style MLASTElement fill:#e1f5fe
179
- style MLASTPreprocessorSpecificBlock fill:#e1f5fe
180
-
181
- note1["MLASTParentNode = MLASTElement | MLASTPreprocessorSpecificBlock\n(highlighted in blue)"]
182
- ```
183
-
184
- ## Node Types at a Glance
185
-
186
- | Type | `type` Value | Example | Description |
187
- | -------------------------------- | ------------ | ------------------- | -------------------------------------------------------- |
188
- | `MLASTDoctype` | `'doctype'` | `<!DOCTYPE html>` | DOCTYPE declaration |
189
- | `MLASTElement` | `'starttag'` | `<div class="foo">` | Opening element tag with attributes, children, namespace |
190
- | `MLASTElementCloseTag` | `'endtag'` | `</div>` | Closing element tag, paired with its opening tag |
191
- | `MLASTComment` | `'comment'` | `<!-- ... -->` | HTML comment, with bogus flag |
192
- | `MLASTText` | `'text'` | text content | Character data between elements |
193
- | `MLASTPreprocessorSpecificBlock` | `'psblock'` | `{#if}`, `<% %>` | Template engine constructs |
194
- | `MLASTInvalid` | `'invalid'` | unparsable markup | Invalid node with intended kind hint |
195
- | `MLASTHTMLAttr` | `'attr'` | `class="foo"` | Fully decomposed HTML attribute |
196
- | `MLASTSpreadAttr` | `'spread'` | `{...props}` | JSX spread attribute |
197
-
198
- See [Node Reference](docs/node-reference.md) for detailed documentation of each type.
199
-
200
- ## AST to MLDOM Mapping
201
-
202
- Each AST node is ultimately converted into an **MLDOM** node by `@markuplint/ml-core`. MLDOM conforms to the [DOM Standard](https://dom.spec.whatwg.org/) -- each class implements the corresponding DOM interface (`Node`, `Element`, `DocumentType`, `Comment`, `Text`, etc.), so lint rules can use standard DOM APIs for inspection.
203
-
204
- | AST Type (`ml-ast`) | MLDOM Class (`ml-core`) | DOM Interface | `nodeType` |
205
- | ----------------------------------- | ------------------------- | ------------------------ | ---------- |
206
- | `MLASTDoctype` | `MLDocumentType` | `DocumentType` | `10` |
207
- | `MLASTElement` | `MLElement` | `Element`, `HTMLElement` | `1` |
208
- | `MLASTComment` | `MLComment` | `Comment` | `8` |
209
- | `MLASTText` | `MLText` | `Text` | `3` |
210
- | `MLASTPreprocessorSpecificBlock` | `MLBlock` | _(markuplint-specific)_ | `101` |
211
- | `MLASTInvalid` (`kind: 'starttag'`) | `MLElement` (`x-invalid`) | `Element`, `HTMLElement` | `1` |
212
- | `MLASTInvalid` (other) | `MLText` | `Text` | `3` |
213
- | `MLASTHTMLAttr` / `MLASTSpreadAttr` | `MLAttr` | `Attr` | `2` |
214
-
215
- **Special nodes:**
216
-
217
- - **`MLBlock`** (`nodeType: 101`) is a markuplint-specific extension with no DOM Standard equivalent. It acts as a transparent container -- its children are treated as belonging to the parent for tree traversal.
218
- - **`MLElementCloseTag`** is not created by `createNode()`. Instead, `MLElement` internally resolves the `pairNodeUuid` to look up the closing tag's AST node and creates an `MLElementCloseTag` from it. It exists only as a satellite of its paired element and is not part of the DOM tree traversal.
219
- - **`MLASTInvalid`** is a recovery node -- it is never preserved as-is in MLDOM, but converted to either an `MLElement` (with tag name `x-invalid`) or an `MLText`, depending on its `kind` field.
220
-
221
- See [Node Reference -- AST to MLDOM Mapping](docs/node-reference.md#ast-to-mldom-mapping) for details.
222
-
223
- ## Attribute Decomposition Model
224
-
225
- `MLASTHTMLAttr` decomposes each attribute into individual tokens with full positional information:
226
-
227
- ```
228
- ·class="container"
229
- ↑ ↑↑ ↑
230
- │ ││ └─ endQuote
231
- │ │└─ value
232
- │ └─ startQuote
233
- │ equal
234
- └─ spacesBeforeName
235
- name
236
- ```
237
-
238
- This enables lint rules to validate whitespace around `=`, quoting style, and attribute naming conventions with precise source locations. See [Node Reference](docs/node-reference.md#mlasthtmlattr) for complete field documentation.
239
-
240
- ## Parser Interface
241
-
242
- | Type | Description |
243
- | ---------------- | --------------------------------------------- |
244
- | `MLParser` | Interface for a markuplint-compatible parser |
245
- | `MLParserModule` | Module wrapper that exports a parser instance |
246
-
247
- `MLParser` requires a `parse(sourceCode, options?)` method that returns an `MLASTDocument`. Optional fields include `endTag` (end tag handling strategy), `booleanish` (boolean attribute detection), and `tagNameCaseSensitive` (for XHTML/JSX).
248
-
249
- ## Configuration Types
250
-
251
- | Type | Description |
252
- | ----------------------------------------- | ---------------------------------------------------------------------- |
253
- | `MLASTNodeType` | Discriminant union tag for node kinds |
254
- | `ElementType` | Element classification: `'html' \| 'web-component' \| 'authored'` |
255
- | `EndTagType` | End tag strategy: `'xml' \| 'omittable' \| 'never'` |
256
- | `Namespace` | Short namespace identifiers: `'html' \| 'svg' \| 'mml' \| 'xlink'` |
257
- | `NamespaceURI` | Full namespace URIs for HTML, SVG, MathML, XLink |
258
- | `ParserOptions` | Options passed to parsers (`ignoreFrontMatter`, `authoredElementName`) |
259
- | `ParserAuthoredElementNameDistinguishing` | Configuration for distinguishing authored elements |
260
- | `Walker<Node>` | Callback for walking AST nodes |
261
-
262
- ## External Dependencies
263
-
264
- None. This package has zero runtime dependencies. It exports only TypeScript type definitions.
265
-
266
- ## Integration Points
267
-
268
- ```mermaid
269
- flowchart TD
270
- subgraph upstream ["Upstream (Parsers)"]
271
- htmlParser["@markuplint/html-parser"]
272
- parserUtils["@markuplint/parser-utils"]
273
- jsxParser["@markuplint/jsx-parser"]
274
- astroParser["@markuplint/astro-parser"]
275
- vueParser["@markuplint/vue-parser"]
276
- svelteParser["@markuplint/svelte-parser"]
277
- pugParser["@markuplint/pug-parser"]
278
- end
279
-
280
- subgraph pkg ["@markuplint/ml-ast"]
281
- astTypes["Type Definitions"]
282
- end
283
-
284
- subgraph downstream ["Downstream"]
285
- mlCore["@markuplint/ml-core"]
286
- mlConfig["@markuplint/ml-config"]
287
- mlSpec["@markuplint/ml-spec"]
288
- fileResolver["@markuplint/file-resolver"]
289
- end
290
-
291
- upstream -->|"implement MLParser\nproduce MLASTDocument"| astTypes
292
- astTypes -->|"MLASTNode types\nMLParser interface"| downstream
293
- ```
294
-
295
- ### Upstream
296
-
297
- All parsers implement the `MLParser` interface and produce `MLASTDocument` instances containing the AST node types defined in this package.
298
-
299
- ### Downstream
300
-
301
- - **`@markuplint/ml-core`** consumes AST nodes and maps them to DOM nodes via `createNode()`. This is the primary integration point where `MLASTElement` becomes `MLElement`, `MLASTText` becomes `MLText`, etc.
302
- - **`@markuplint/ml-config`** references AST types in configuration schema definitions.
303
- - **`@markuplint/ml-spec`** uses namespace and element type definitions.
304
- - **`@markuplint/file-resolver`** references parser-related types.
305
-
306
- ## Documentation Map
307
-
308
- - [Node Reference](docs/node-reference.md) -- Detailed documentation of each AST node type
309
- - [Maintenance Guide](docs/maintenance.md) -- Commands, recipes, and troubleshooting
package/SKILL.md DELETED
@@ -1,123 +0,0 @@
1
- ---
2
- description: Perform maintenance tasks for @markuplint/ml-ast
3
- ---
4
-
5
- # ml-ast-maintenance
6
-
7
- Perform maintenance tasks for `@markuplint/ml-ast`: add AST node types,
8
- add fields to existing nodes, add conditional type values, and update the parser interface.
9
-
10
- ## Input
11
-
12
- `$ARGUMENTS` specifies the task. Supported tasks:
13
-
14
- | Task | Description |
15
- | ------------------------------ | ---------------------------------------------- |
16
- | `add-node-type <name>` | Add a new AST node type |
17
- | `add-field <node> <field>` | Add a field to an existing node type |
18
- | `add-conditional-type <value>` | Add a conditional type value for psblock nodes |
19
- | `update-parser-interface` | Modify the MLParser interface |
20
-
21
- If omitted, defaults to `add-node-type`.
22
-
23
- ## Reference
24
-
25
- Before executing any task, read `docs/maintenance.md` (or `docs/maintenance.ja.md`)
26
- for the full guide. The recipes there are the source of truth for procedures.
27
-
28
- Also read:
29
-
30
- - `docs/node-reference.md` -- Detailed documentation of each AST node type
31
- - `ARCHITECTURE.md` -- Package overview, type hierarchy, and integration points
32
-
33
- ## Task: add-node-type
34
-
35
- Add a new AST node type. Follow recipe #1 in `docs/maintenance.md`.
36
-
37
- ### Step 1: Define the type
38
-
39
- 1. Read `src/types.ts` to understand the existing type hierarchy
40
- 2. Add the type value to `MLASTNodeType`
41
- 3. Define the interface extending `MLASTAbstractNode`
42
- 4. Add to relevant union types (`MLASTNode`, `MLASTChildNode`, etc.)
43
-
44
- ### Step 2: Update downstream
45
-
46
- 1. Update `ml-core`'s `createNode()` in `packages/@markuplint/ml-core/src/ml-dom/helper/create-node.ts`
47
- 2. Add a `case` for the new type value in the `switch` statement
48
- 3. Create or reuse an appropriate DOM node class
49
-
50
- ### Step 3: Build and verify
51
-
52
- 1. Build: `yarn build --scope @markuplint/ml-ast`
53
- 2. Build: `yarn build --scope @markuplint/ml-core`
54
- 3. Check the downstream impact checklist in `docs/maintenance.md`
55
-
56
- ## Task: add-field
57
-
58
- Add a field to an existing node type. Follow recipe #2 in `docs/maintenance.md`.
59
-
60
- ### Step 1: Add the field
61
-
62
- 1. Read `src/types.ts` and find the target interface
63
- 2. Add the field (prefer optional `?` for backward compatibility)
64
- 3. Add JSDoc documentation for the new field
65
-
66
- ### Step 2: Update consumers
67
-
68
- 1. Update parsers that should populate the new field
69
- 2. Update `ml-core` if the field affects DOM node creation
70
-
71
- ### Step 3: Build and verify
72
-
73
- 1. Build: `yarn build --scope @markuplint/ml-ast`
74
- 2. Build affected packages
75
- 3. Check the downstream impact checklist in `docs/maintenance.md`
76
-
77
- ## Task: add-conditional-type
78
-
79
- Add a conditional type value for preprocessor-specific blocks. Follow recipe #4 in `docs/maintenance.md`.
80
-
81
- ### Step 1: Add the value
82
-
83
- 1. Read `src/types.ts` and find `MLASTPreprocessorSpecificBlockConditionalType`
84
- 2. Add the new value to the union type
85
- 3. Document the value's semantic meaning in the JSDoc comment
86
-
87
- ### Step 2: Update parsers
88
-
89
- 1. Update the parser that produces blocks with this conditional type
90
- 2. Verify the value follows the naming convention (`category:variant`, e.g., `if:elseif`)
91
-
92
- ### Step 3: Build and verify
93
-
94
- 1. Build: `yarn build --scope @markuplint/ml-ast`
95
- 2. Build the affected parser package
96
-
97
- ## Task: update-parser-interface
98
-
99
- Modify the `MLParser` interface. Follow recipe #5 in `docs/maintenance.md`.
100
-
101
- ### Step 1: Make changes
102
-
103
- 1. Read `src/types.ts` and find `MLParser`
104
- 2. Make changes (prefer adding optional fields for backward compatibility)
105
-
106
- ### Step 2: Update all parsers
107
-
108
- 1. Update all parser implementations (see the list in `docs/maintenance.md` recipe #5)
109
- 2. Update `@markuplint/parser-utils` if it provides shared implementation
110
-
111
- ### Step 3: Build and verify
112
-
113
- 1. Build all packages: `yarn build`
114
- 2. Run all tests: `yarn test`
115
-
116
- ## Rules
117
-
118
- 1. **All node types extend `MLASTAbstractNode`** (except attributes which extend `MLASTToken`).
119
- 2. **Use `readonly` for all interface fields.** The AST is immutable after parsing.
120
- 3. **Prefer optional fields** when adding to existing interfaces for backward compatibility.
121
- 4. **Always update `createNode()` in `ml-core`** when adding new node types.
122
- 5. **Follow the discriminated union pattern.** Every node must have a unique `type` literal value.
123
- 6. **Add JSDoc comments** to all new exported types and fields.
@@ -1,213 +0,0 @@
1
- # メンテナンスガイド
2
-
3
- `@markuplint/ml-ast` の実践的な操作・メンテナンスガイドです。
4
-
5
- ## コマンド
6
-
7
- | コマンド | 説明 |
8
- | --------------------------------------------- | --------------------------------- |
9
- | `yarn build --scope @markuplint/ml-ast` | TypeScript を `lib/` にコンパイル |
10
- | `yarn workspace @markuplint/ml-ast run dev` | ウォッチモードコンパイル |
11
- | `yarn workspace @markuplint/ml-ast run clean` | コンパイル出力をクリーン |
12
-
13
- ## テスト
14
-
15
- このパッケージには**テストファイルがありません**。純粋な型定義パッケージのため、正当性はビルド時に TypeScript コンパイラで検証されます。統合テストはこれらの型を消費する下流パッケージで実施されます。
16
-
17
- 型の正当性を検証するには:
18
-
19
- ```bash
20
- yarn build --scope @markuplint/ml-ast
21
- ```
22
-
23
- ## 一般的なレシピ
24
-
25
- ### 1. 新しいノード型の追加
26
-
27
- 新しい AST ノード型(例:仮想的な `MLASTDirective`)を追加する場合:
28
-
29
- 1. **`MLASTNodeType` に型の値を追加**(`src/types.ts`):
30
-
31
- ```typescript
32
- export type MLASTNodeType =
33
- | 'doctype'
34
- | 'starttag'
35
- // ... 既存の値
36
- | 'directive'; // ここに追加
37
- ```
38
-
39
- 2. **`MLASTAbstractNode` を継承するインターフェースを定義**:
40
-
41
- ```typescript
42
- export interface MLASTDirective extends MLASTAbstractNode {
43
- readonly type: 'directive';
44
- readonly depth: number;
45
- // 型固有のフィールドを追加
46
- }
47
- ```
48
-
49
- 3. **関連する共用体型に追加**:
50
- - `MLASTNode` -- 常にこの共用体に追加
51
- - `MLASTChildNode` -- 要素の子になれる場合
52
- - `MLASTNodeTreeItem` -- `nodeList` のトップレベルに出現できる場合
53
- - `MLASTParentNode` -- 子ノードを含むことができる場合
54
-
55
- 4. **`ml-core` の `createNode()` を更新**(`packages/@markuplint/ml-core/src/ml-dom/helper/create-node.ts`):
56
- - `switch` 文に新しい type 値の `case` を追加
57
- - 適切な DOM ノードクラスを作成または再利用
58
-
59
- 5. **このノード型を生成するパーサーを更新**
60
-
61
- 6. **ビルドして検証**:
62
- ```bash
63
- yarn build --scope @markuplint/ml-ast
64
- yarn build --scope @markuplint/ml-core
65
- ```
66
-
67
- ### 2. 既存ノード型へのフィールド追加
68
-
69
- 既存のノードインターフェースに新しいフィールドを追加する場合:
70
-
71
- 1. **`src/types.ts` のインターフェースにフィールドを追加**:
72
-
73
- ```typescript
74
- export interface MLASTElement extends MLASTAbstractNode {
75
- // ... 既存のフィールド
76
- readonly newField: string; // 必須フィールド
77
- readonly optionalField?: boolean; // オプションフィールド(後方互換性のため推奨)
78
- }
79
- ```
80
-
81
- 2. **後方互換性のためオプションフィールド**(`?`)を推奨 -- フィールドがなくても既存のパーサーが壊れません。
82
-
83
- 3. **新しいフィールドを設定するパーサーを更新**
84
-
85
- 4. **フィールドが DOM ノードの作成や動作に影響する場合は `ml-core` を更新**
86
-
87
- 5. **全チェーンをビルド**:
88
- ```bash
89
- yarn build --scope @markuplint/ml-ast
90
- yarn build --scope @markuplint/ml-core
91
- ```
92
-
93
- ### 3. 新しい属性バリアントの追加
94
-
95
- `MLASTHTMLAttr` と `MLASTSpreadAttr` に加えて新しい属性型を追加する場合:
96
-
97
- 1. **`MLASTNodeType` に型の値を追加**(まだない場合)
98
-
99
- 2. **`MLASTToken` を継承するインターフェースを定義**:
100
-
101
- ```typescript
102
- export interface MLASTNewAttr extends MLASTToken {
103
- readonly type: 'newattr';
104
- readonly nodeName: string;
105
- // 属性固有のフィールドを追加
106
- }
107
- ```
108
-
109
- 3. **`MLASTAttr` 共用体に追加**:
110
-
111
- ```typescript
112
- export type MLASTAttr = MLASTHTMLAttr | MLASTSpreadAttr | MLASTNewAttr;
113
- ```
114
-
115
- 4. **属性型で switch する下流の消費者を更新**
116
-
117
- 5. **ビルドして検証**
118
-
119
- ### 4. `MLASTBlockBehaviorType` の値追加
120
-
121
- プリプロセッサブロックの新しいブロック動作種別を追加する場合:
122
-
123
- 1. **`src/types.ts` の `MLASTBlockBehaviorType` に値を追加**:
124
-
125
- ```typescript
126
- export type MLASTBlockBehaviorType =
127
- | 'if'
128
- | 'if:elseif'
129
- // ... 既存の値
130
- | 'newvalue'; // ここに追加
131
- ```
132
-
133
- 2. **この動作種別で `blockBehavior` を設定するパーサーを更新**
134
-
135
- 3. **新しい値が DOM 作成時に特別な処理を必要とする場合は `ml-core` を更新**
136
-
137
- 4. **ビルドして検証**:
138
- ```bash
139
- yarn build --scope @markuplint/ml-ast
140
- ```
141
-
142
- ### 5. `MLParser` インターフェースの変更
143
-
144
- パーサーインターフェースを変更する場合:
145
-
146
- 1. **`src/types.ts` の `MLParser` を変更**
147
-
148
- 2. **後方互換性を考慮**:
149
- - オプションフィールドの追加は安全
150
- - 必須フィールドの追加やシグネチャの変更は破壊的変更
151
-
152
- 3. **すべてのパーサー実装を更新**:
153
- - `@markuplint/html-parser`
154
- - `@markuplint/jsx-parser`
155
- - `@markuplint/vue-parser`
156
- - `@markuplint/svelte-parser`
157
- - `@markuplint/astro-parser`
158
- - `@markuplint/pug-parser`
159
- - `@markuplint/parser-utils`
160
-
161
- 4. **影響を受けるすべてのパッケージをビルド**:
162
- ```bash
163
- yarn build
164
- ```
165
-
166
- ## 下流影響チェックリスト
167
-
168
- このパッケージの型を変更する際、以下の下流パッケージがビルド・テストに通ることを確認してください:
169
-
170
- - [ ] `@markuplint/html-parser` -- HTML パーサー
171
- - [ ] `@markuplint/parser-utils` -- パーサーユーティリティ関数
172
- - [ ] `@markuplint/jsx-parser` -- JSX パーサー
173
- - [ ] `@markuplint/astro-parser` -- Astro パーサー
174
- - [ ] `@markuplint/vue-parser` -- Vue SFC パーサー
175
- - [ ] `@markuplint/svelte-parser` -- Svelte パーサー
176
- - [ ] `@markuplint/pug-parser` -- Pug パーサー
177
- - [ ] `@markuplint/ml-core` -- コア DOM マッピング(最重要)
178
- - [ ] `@markuplint/ml-config` -- 設定型
179
- - [ ] `@markuplint/ml-spec` -- 仕様型
180
- - [ ] `@markuplint/file-resolver` -- ファイル解決
181
-
182
- 最も重要な下流パッケージは `@markuplint/ml-core` で、`createNode()` -- `node.type` に対する `switch` 文で AST ノードを DOM ノードにマッピングする関数を含みます。
183
-
184
- ## トラブルシューティング
185
-
186
- ### 型変更後のビルドエラー
187
-
188
- **症状:** 型の変更後、下流パッケージのビルドが失敗する。
189
-
190
- **診断:**
191
-
192
- 1. まずこのパッケージをビルド:`yarn build --scope @markuplint/ml-ast`
193
- 2. 次に `ml-core` をビルド:`yarn build --scope @markuplint/ml-core`
194
- 3. `switch` の網羅性エラーを確認 -- TypeScript は `node.type` の `switch` で新しい型値のケースが欠けている場合に報告します
195
- 4. 共用体型の不一致を確認 -- 共用体に型を追加すると、既存の絞り込みコードの更新が必要になる場合があります
196
-
197
- ### ml-core の `createNode()` のケース漏れ
198
-
199
- **症状:** 実行時に `TypeError: Invalid AST node types "newtype"` が発生する。
200
-
201
- **原因:** 新しいノード型が `MLASTNodeType` と関連する共用体型に追加されたが、`ml-core` の `createNode()` の switch 文が更新されていない。
202
-
203
- **修正:** `packages/@markuplint/ml-core/src/ml-dom/helper/create-node.ts` に新しい型の `case` を追加してください。
204
-
205
- ### パーサーが期待されるノードを生成しない
206
-
207
- **症状:** パーサーが新しく追加されたフィールドや型のノードを生成しない。
208
-
209
- **診断:**
210
-
211
- 1. パーサーの実装が新しいフィールドを設定するように更新されているか確認
212
- 2. オプションフィールドの場合、フィールドが暗黙的に `undefined` になっていないか検証
213
- 3. パーサーとこのパッケージの両方をビルドして型の整合性を確認