Skip to content

Commit f5b0e8d

Browse files
authored
fix(parse/html): astro fence (#9124)
1 parent 792013e commit f5b0e8d

10 files changed

Lines changed: 896 additions & 71 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@biomejs/biome": patch
3+
---
4+
5+
Fixed [#8882](https://github.com/biomejs/biome/issues/8882) and [#9108](https://github.com/biomejs/biome/issues/9108): The Astro frontmatter lexer now correctly identifies the closing `---` fence when the frontmatter contains multi-line block comments with quote characters, strings that mix quote types (e.g. `"it's"`), or escaped quote characters (e.g. `"\"`).

crates/biome_html_parser/src/lexer/mod.rs

Lines changed: 303 additions & 71 deletions
Large diffs are not rendered by default.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
/*
3+
---
4+
*/
5+
const x = 1;
6+
---
7+
8+
<h1>Hi</h1>
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
source: crates/biome_html_parser/tests/spec_test.rs
3+
expression: snapshot
4+
---
5+
6+
## Input
7+
8+
```astro
9+
---
10+
/*
11+
---
12+
*/
13+
const x = 1;
14+
---
15+
16+
<h1>Hi</h1>
17+
18+
```
19+
20+
21+
## AST
22+
23+
```
24+
HtmlRoot {
25+
bom_token: missing (optional),
26+
frontmatter: AstroFrontmatterElement {
27+
l_fence_token: FENCE@0..3 "---" [] [],
28+
content: AstroEmbeddedContent {
29+
content_token: HTML_LITERAL@3..27 "/*\n---\n*/\nconst x = 1;\n" [Newline("\n")] [],
30+
},
31+
r_fence_token: FENCE@27..30 "---" [] [],
32+
},
33+
directive: missing (optional),
34+
html: HtmlElementList [
35+
HtmlElement {
36+
opening_element: HtmlOpeningElement {
37+
l_angle_token: L_ANGLE@30..33 "<" [Newline("\n"), Newline("\n")] [],
38+
name: HtmlTagName {
39+
value_token: HTML_LITERAL@33..35 "h1" [] [],
40+
},
41+
attributes: HtmlAttributeList [],
42+
r_angle_token: R_ANGLE@35..36 ">" [] [],
43+
},
44+
children: HtmlElementList [
45+
HtmlContent {
46+
value_token: HTML_LITERAL@36..38 "Hi" [] [],
47+
},
48+
],
49+
closing_element: HtmlClosingElement {
50+
l_angle_token: L_ANGLE@38..39 "<" [] [],
51+
slash_token: SLASH@39..40 "/" [] [],
52+
name: HtmlTagName {
53+
value_token: HTML_LITERAL@40..42 "h1" [] [],
54+
},
55+
r_angle_token: R_ANGLE@42..43 ">" [] [],
56+
},
57+
},
58+
],
59+
eof_token: EOF@43..44 "" [Newline("\n")] [],
60+
}
61+
```
62+
63+
## CST
64+
65+
```
66+
0: HTML_ROOT@0..44
67+
0: (empty)
68+
1: ASTRO_FRONTMATTER_ELEMENT@0..30
69+
0: FENCE@0..3 "---" [] []
70+
1: ASTRO_EMBEDDED_CONTENT@3..27
71+
0: HTML_LITERAL@3..27 "/*\n---\n*/\nconst x = 1;\n" [Newline("\n")] []
72+
2: FENCE@27..30 "---" [] []
73+
2: (empty)
74+
3: HTML_ELEMENT_LIST@30..43
75+
0: HTML_ELEMENT@30..43
76+
0: HTML_OPENING_ELEMENT@30..36
77+
0: L_ANGLE@30..33 "<" [Newline("\n"), Newline("\n")] []
78+
1: HTML_TAG_NAME@33..35
79+
0: HTML_LITERAL@33..35 "h1" [] []
80+
2: HTML_ATTRIBUTE_LIST@35..35
81+
3: R_ANGLE@35..36 ">" [] []
82+
1: HTML_ELEMENT_LIST@36..38
83+
0: HTML_CONTENT@36..38
84+
0: HTML_LITERAL@36..38 "Hi" [] []
85+
2: HTML_CLOSING_ELEMENT@38..43
86+
0: L_ANGLE@38..39 "<" [] []
87+
1: SLASH@39..40 "/" [] []
88+
2: HTML_TAG_NAME@40..42
89+
0: HTML_LITERAL@40..42 "h1" [] []
90+
3: R_ANGLE@42..43 ">" [] []
91+
4: EOF@43..44 "" [Newline("\n")] []
92+
93+
```
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
// ---
3+
const x = 1;
4+
---
5+
6+
<h1>Hi</h1>
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
source: crates/biome_html_parser/tests/spec_test.rs
3+
expression: snapshot
4+
---
5+
6+
## Input
7+
8+
```astro
9+
---
10+
// ---
11+
const x = 1;
12+
---
13+
14+
<h1>Hi</h1>
15+
16+
```
17+
18+
19+
## AST
20+
21+
```
22+
HtmlRoot {
23+
bom_token: missing (optional),
24+
frontmatter: AstroFrontmatterElement {
25+
l_fence_token: FENCE@0..3 "---" [] [],
26+
content: AstroEmbeddedContent {
27+
content_token: HTML_LITERAL@3..24 "// ---\nconst x = 1;\n" [Newline("\n")] [],
28+
},
29+
r_fence_token: FENCE@24..27 "---" [] [],
30+
},
31+
directive: missing (optional),
32+
html: HtmlElementList [
33+
HtmlElement {
34+
opening_element: HtmlOpeningElement {
35+
l_angle_token: L_ANGLE@27..30 "<" [Newline("\n"), Newline("\n")] [],
36+
name: HtmlTagName {
37+
value_token: HTML_LITERAL@30..32 "h1" [] [],
38+
},
39+
attributes: HtmlAttributeList [],
40+
r_angle_token: R_ANGLE@32..33 ">" [] [],
41+
},
42+
children: HtmlElementList [
43+
HtmlContent {
44+
value_token: HTML_LITERAL@33..35 "Hi" [] [],
45+
},
46+
],
47+
closing_element: HtmlClosingElement {
48+
l_angle_token: L_ANGLE@35..36 "<" [] [],
49+
slash_token: SLASH@36..37 "/" [] [],
50+
name: HtmlTagName {
51+
value_token: HTML_LITERAL@37..39 "h1" [] [],
52+
},
53+
r_angle_token: R_ANGLE@39..40 ">" [] [],
54+
},
55+
},
56+
],
57+
eof_token: EOF@40..41 "" [Newline("\n")] [],
58+
}
59+
```
60+
61+
## CST
62+
63+
```
64+
0: HTML_ROOT@0..41
65+
0: (empty)
66+
1: ASTRO_FRONTMATTER_ELEMENT@0..27
67+
0: FENCE@0..3 "---" [] []
68+
1: ASTRO_EMBEDDED_CONTENT@3..24
69+
0: HTML_LITERAL@3..24 "// ---\nconst x = 1;\n" [Newline("\n")] []
70+
2: FENCE@24..27 "---" [] []
71+
2: (empty)
72+
3: HTML_ELEMENT_LIST@27..40
73+
0: HTML_ELEMENT@27..40
74+
0: HTML_OPENING_ELEMENT@27..33
75+
0: L_ANGLE@27..30 "<" [Newline("\n"), Newline("\n")] []
76+
1: HTML_TAG_NAME@30..32
77+
0: HTML_LITERAL@30..32 "h1" [] []
78+
2: HTML_ATTRIBUTE_LIST@32..32
79+
3: R_ANGLE@32..33 ">" [] []
80+
1: HTML_ELEMENT_LIST@33..35
81+
0: HTML_CONTENT@33..35
82+
0: HTML_LITERAL@33..35 "Hi" [] []
83+
2: HTML_CLOSING_ELEMENT@35..40
84+
0: L_ANGLE@35..36 "<" [] []
85+
1: SLASH@36..37 "/" [] []
86+
2: HTML_TAG_NAME@37..39
87+
0: HTML_LITERAL@37..39 "h1" [] []
88+
3: R_ANGLE@39..40 ">" [] []
89+
4: EOF@40..41 "" [Newline("\n")] []
90+
91+
```
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
/**
3+
* In this comment, if you add any string opening or closing, such as an apostrophe, the file will show
4+
* a bunch of errors. Doesn't (remove the apostrophe in the previous word to fix) that stink?
5+
*/
6+
import type { HTMLAttributes } from "astro/types";
7+
type Props = HTMLAttributes<"div">;
8+
const { class: className, ...rest } = Astro.props;
9+
---
10+
11+
<div
12+
class="some-classes"
13+
data-state="closed"
14+
style="animation: none;"
15+
data-slot="accordion-content"
16+
{...rest}
17+
>
18+
<div class="pt-0 pb-4">
19+
<slot />
20+
</div>
21+
</div>

0 commit comments

Comments
 (0)