Skip to content

Commit eed2eb1

Browse files
committed
fix: ts unary operator only in ts expression
1 parent 9d7285b commit eed2eb1

File tree

6 files changed

+49
-10
lines changed

6 files changed

+49
-10
lines changed

.changeset/khaki-years-mix.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"htmljs-parser": patch
3+
---
4+
5+
Fix regression where typescript unary operators were being used in javascript contexts.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
1╭─ div foo=readonly bar=true
2+
│ │ │ ││ │ │╰─ attrValue.value "true"
3+
│ │ │ ││ │ ╰─ attrValue "=true"
4+
│ │ │ ││ ╰─ attrName "bar"
5+
│ │ │ │╰─ attrValue.value "readonly"
6+
│ │ │ ╰─ attrValue "=readonly"
7+
│ │ ╰─ attrName "foo"
8+
╰─ ╰─ tagName "div"
9+
2╭─ div foo=val as readonly string[] bar=true
10+
│ │ │ ││ │ │╰─ attrValue.value "true"
11+
│ │ │ ││ │ ╰─ attrValue "=true"
12+
│ │ │ ││ ╰─ attrName "bar"
13+
│ │ │ │╰─ attrValue.value "val as readonly string[]"
14+
│ │ │ ╰─ attrValue "=val as readonly string[]"
15+
│ │ ╰─ attrName "foo"
16+
│ ├─ closeTagEnd(div)
17+
│ ├─ openTagEnd
18+
╰─ ╰─ tagName "div"
19+
3╭─
20+
│ ├─ openTagEnd
21+
╰─ ╰─ closeTagEnd(div)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
div foo=readonly bar=true
2+
div foo=val as readonly string[] bar=true

src/states/ATTRIBUTE.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,10 @@ export const ATTRIBUTE: StateDefinition<AttrMeta> = {
105105
attr.stage = ATTR_STAGE.TYPE_PARAMS;
106106
this.pos++; // skip <
107107
this.forward = 0;
108-
this.enterState(STATE.EXPRESSION).shouldTerminate =
109-
matchesCloseAngleBracket;
108+
const expr = this.enterState(STATE.EXPRESSION);
109+
expr.inType = true;
110+
expr.forceType = true;
111+
expr.shouldTerminate = matchesCloseAngleBracket;
110112
} else if (code === CODE.OPEN_CURLY_BRACE && attr.args) {
111113
ensureAttrName(this, attr);
112114
attr.stage = ATTR_STAGE.BLOCK;

src/states/EXPRESSION.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,23 @@ export interface ExpressionMeta extends Meta {
3131
const shouldTerminate = () => false;
3232

3333
const unaryKeywords = [
34-
"asserts",
3534
"async",
3635
"await",
3736
"class",
3837
"function",
38+
"new",
39+
"typeof",
40+
"void",
41+
] as const;
42+
43+
const tsUnaryKeywords = [
44+
...unaryKeywords,
45+
"asserts",
3946
"infer",
4047
"is",
4148
"keyof",
42-
"new",
4349
"readonly",
44-
"typeof",
4550
"unique",
46-
"void",
4751
] as const;
4852

4953
const binaryKeywords = [
@@ -404,7 +408,9 @@ function lookBehindForOperator(
404408
}
405409

406410
default: {
407-
for (const keyword of unaryKeywords) {
411+
for (const keyword of expression.inType
412+
? tsUnaryKeywords
413+
: unaryKeywords) {
408414
const keywordPos = lookBehindFor(data, curPos, keyword);
409415
if (keywordPos !== -1) {
410416
return isWordOrPeriodCode(data.charCodeAt(keywordPos - 1))

src/states/OPEN_TAG.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,12 +343,15 @@ export const OPEN_TAG: StateDefinition<OpenTagMeta> = {
343343
this.enterState(STATE.EXPRESSION).shouldTerminate = matchesPipe;
344344
break;
345345

346-
case CODE.OPEN_ANGLE_BRACKET:
346+
case CODE.OPEN_ANGLE_BRACKET: {
347347
tag.stage = TAG_STAGE.TYPES;
348348
this.pos++; // skip <
349-
this.enterState(STATE.EXPRESSION).shouldTerminate =
350-
matchesCloseAngleBracket;
349+
const expr = this.enterState(STATE.EXPRESSION);
350+
expr.inType = true;
351+
expr.forceType = true;
352+
expr.shouldTerminate = matchesCloseAngleBracket;
351353
break;
354+
}
352355

353356
default:
354357
tag.hasAttrs = true;

0 commit comments

Comments
 (0)