Skip to content

Commit 88f6206

Browse files
committed
Allow at-rules to have empty bodies
1 parent 2d1218d commit 88f6206

File tree

6 files changed

+21
-11
lines changed

6 files changed

+21
-11
lines changed

packages/tailwindcss-language-service/src/css/ast.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export type AtRule = {
1616
kind: 'at-rule'
1717
name: string
1818
params: string
19-
nodes: AstNode[]
19+
nodes: AstNode[] | null
2020

2121
src?: SourceLocation
2222
dst?: SourceLocation
@@ -69,7 +69,7 @@ export function styleRule(selector: string, nodes: AstNode[] = []): StyleRule {
6969
}
7070
}
7171

72-
export function atRule(name: string, params: string = '', nodes: AstNode[] = []): AtRule {
72+
export function atRule(name: string, params: string = '', nodes: AstNode[] | null = []): AtRule {
7373
return {
7474
kind: 'at-rule',
7575
name,
@@ -78,12 +78,12 @@ export function atRule(name: string, params: string = '', nodes: AstNode[] = [])
7878
}
7979
}
8080

81-
export function rule(selector: string, nodes: AstNode[] = []): StyleRule | AtRule {
81+
export function rule(selector: string, nodes: AstNode[] | null = []): StyleRule | AtRule {
8282
if (selector.charCodeAt(0) === AT_SIGN) {
8383
return parseAtRule(selector, nodes)
8484
}
8585

86-
return styleRule(selector, nodes)
86+
return styleRule(selector, nodes ?? [])
8787
}
8888

8989
export function decl(property: string, value: string | undefined, important = false): Declaration {

packages/tailwindcss-language-service/src/css/clone-ast-node.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export function cloneAstNode<T extends AstNode>(node: T): T {
1616
kind: node.kind,
1717
name: node.name,
1818
params: node.params,
19-
nodes: node.nodes.map(cloneAstNode),
19+
nodes: node.nodes?.map(cloneAstNode) ?? null,
2020
src: node.src,
2121
dst: node.dst,
2222
} satisfies AtRule as T

packages/tailwindcss-language-service/src/css/from-postcss-ast.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ export function fromPostCSSAst(root: postcss.Root): AstNode[] {
4444

4545
// AtRule
4646
else if (node.type === 'atrule') {
47-
let astNode = atRule(`@${node.name}`, node.params)
47+
let astNode = atRule(`@${node.name}`, node.params, node.nodes ? [] : null)
4848
astNode.src = toSource(node)
49-
node.each((child) => transform(child, astNode.nodes))
49+
node.each((child) => transform(child, astNode.nodes!))
5050
parent.push(astNode)
5151
}
5252

packages/tailwindcss-language-service/src/css/parse.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ export function parse(input: string, opts?: ParseOptions): AstNode[] {
277277
}
278278

279279
if (parent) {
280+
parent.nodes ??= []
280281
parent.nodes.push(declaration)
281282
} else {
282283
ast.push(declaration)
@@ -303,6 +304,7 @@ export function parse(input: string, opts?: ParseOptions): AstNode[] {
303304

304305
// At-rule is nested inside of a rule, attach it to the parent.
305306
if (parent) {
307+
parent.nodes ??= []
306308
parent.nodes.push(node)
307309
}
308310

@@ -343,6 +345,7 @@ export function parse(input: string, opts?: ParseOptions): AstNode[] {
343345
}
344346

345347
if (parent) {
348+
parent.nodes ??= []
346349
parent.nodes.push(declaration)
347350
} else {
348351
ast.push(declaration)
@@ -369,6 +372,7 @@ export function parse(input: string, opts?: ParseOptions): AstNode[] {
369372

370373
// Attach the rule to the parent in case it's nested.
371374
if (parent) {
375+
parent.nodes ??= []
372376
parent.nodes.push(node)
373377
}
374378

@@ -421,6 +425,7 @@ export function parse(input: string, opts?: ParseOptions): AstNode[] {
421425

422426
// At-rule is nested inside of a rule, attach it to the parent.
423427
if (parent) {
428+
parent.nodes ??= []
424429
parent.nodes.push(node)
425430
}
426431

@@ -460,6 +465,7 @@ export function parse(input: string, opts?: ParseOptions): AstNode[] {
460465
node.dst = [source, bufferStart, i]
461466
}
462467

468+
parent.nodes ??= []
463469
parent.nodes.push(node)
464470
}
465471
}
@@ -548,7 +554,7 @@ export function parse(input: string, opts?: ParseOptions): AstNode[] {
548554
return ast
549555
}
550556

551-
export function parseAtRule(buffer: string, nodes: AstNode[] = []): AtRule {
557+
export function parseAtRule(buffer: string, nodes: AstNode[] | null = []): AtRule {
552558
let name = buffer
553559
let params = ''
554560

packages/tailwindcss-language-service/src/css/to-css.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ export function toCss(ast: AstNode[], track?: boolean): string {
9191
// ```css
9292
// @layer base, components, utilities;
9393
// ```
94-
if (node.nodes.length === 0) {
94+
if (!node.nodes) {
9595
let css = `${indent}${node.name} ${node.params};\n`
9696

9797
if (track) {

packages/tailwindcss-language-service/src/css/to-postcss-ast.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,15 @@ export function toPostCSSAst(ast: AstNode[], source?: postcss.Source): postcss.R
8585

8686
// AtRule
8787
else if (node.kind === 'at-rule') {
88-
let astNode = postcss.atRule({ name: node.name.slice(1), params: node.params })
88+
let astNode = postcss.atRule({
89+
name: node.name.slice(1),
90+
params: node.params,
91+
nodes: node.nodes ? [] : undefined,
92+
})
8993
updateSource(astNode, node.src)
9094
astNode.raws.semicolon = true
9195
parent.append(astNode)
92-
for (let child of node.nodes) {
96+
for (let child of node.nodes ?? []) {
9397
transform(child, astNode)
9498
}
9599
}

0 commit comments

Comments
 (0)