mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(parser): parse escaped class field names after initializers (#28061)
The Babel class-field fixtures added in #28057 use escaped `in` and `instanceof` names after an initializer. Oxc consumes these names as binary operators and rejects valid class members. Stop binary-expression parsing at these escaped names after a newline so ASI can end the initializer and class-member parsing can consume the name. Preserve escaped-keyword diagnostics for same-line operator expressions and after ASI, with diagnostic fixtures for both newline cases.
This commit is contained in:
1 parent
90c58ac971
commit
83633a7a64
8 files changed
+61
-42
No files matched your search
@@ -83,6 +83,9 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
// allow `await` and `yield`, let semantic analysis report error
|
||||
let kind = self.cur_kind();
|
||||
if !kind.is_identifier_reference(false, false) {
|
||||
if self.cur_token().escaped() && matches!(kind, Kind::In | Kind::Instanceof) {
|
||||
return self.fatal_error(diagnostics::escaped_keyword(self.cur_token().span()));
|
||||
}
|
||||
return self.unexpected();
|
||||
}
|
||||
// Track await identifier for potential reparsing in unambiguous mode
|
||||
@@ -1350,6 +1353,13 @@ impl<'a, C: Config> ParserImpl<'a, C> {
|
||||
break;
|
||||
}
|
||||
|
||||
if matches!(kind, Kind::In | Kind::Instanceof)
|
||||
&& self.cur_token().escaped()
|
||||
&& self.cur_token().is_on_new_line()
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if matches!(kind, Kind::As | Kind::Satisfies) {
|
||||
if self.cur_token().is_on_new_line() {
|
||||
break;
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
a
|
||||
\u{69}n b;
|
||||
@@ -0,0 +1,2 @@
|
||||
a
|
||||
\u{69}nstanceof b;
|
||||
@@ -2,7 +2,7 @@ commit: a56fe4a4
|
||||
|
||||
formatter_babel Summary:
|
||||
AST Parsed : 2280/2280 (100.00%)
|
||||
Positive Passed: 2271/2280 (99.61%)
|
||||
Positive Passed: 2269/2280 (99.52%)
|
||||
Mismatch: tasks/coverage/babel/packages/babel-parser/test/fixtures/annex-b/enabled/1.1-html-comments-close-let-declaration/input.js
|
||||
|
||||
Mismatch: tasks/coverage/babel/packages/babel-parser/test/fixtures/annex-b/enabled/1.1-html-comments-close-let-declaration-cr/input.js
|
||||
@@ -21,3 +21,7 @@ Mismatch: tasks/coverage/babel/packages/babel-parser/test/fixtures/comments/basi
|
||||
|
||||
Mismatch: tasks/coverage/babel/packages/babel-parser/test/fixtures/comments/basic/sequence-expression/input.js
|
||||
|
||||
Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/escaped-in-after-initializer/input.js
|
||||
Cannot assign to this expression
|
||||
Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/class/escaped-in-after-initializer/input.ts
|
||||
Cannot assign to this expression
|
||||
@@ -1,3 +1,3 @@
|
||||
lexer_misc Summary:
|
||||
AST Parsed : 367/367 (100.00%)
|
||||
Positive Passed: 367/367 (100.00%)
|
||||
AST Parsed : 369/369 (100.00%)
|
||||
Positive Passed: 369/369 (100.00%)
|
||||
@@ -1,8 +1,8 @@
|
||||
commit: a56fe4a4
|
||||
|
||||
parser_babel Summary:
|
||||
AST Parsed : 2278/2280 (99.91%)
|
||||
Positive Passed: 2259/2280 (99.08%)
|
||||
AST Parsed : 2280/2280 (100.00%)
|
||||
Positive Passed: 2260/2280 (99.12%)
|
||||
Negative Passed: 1789/1804 (99.17%)
|
||||
Expect Syntax Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/cast/unparenthesized-assert-and-assign/input.ts
|
||||
|
||||
@@ -63,25 +63,6 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/annex-
|
||||
· ╰── `g` has already been declared here
|
||||
╰────
|
||||
|
||||
Fatal error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/escaped-in-after-initializer/input.js
|
||||
|
||||
× Keywords cannot contain escape characters
|
||||
╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/escaped-in-after-initializer/input.js:3:3]
|
||||
2 │ x = 1
|
||||
3 │ \u{69}n
|
||||
· ───────
|
||||
4 │ y = a
|
||||
╰────
|
||||
|
||||
× Cannot assign to this expression
|
||||
╭─[babel/packages/babel-parser/test/fixtures/es2022/class-properties/escaped-in-after-initializer/input.js:2:7]
|
||||
1 │ class C {
|
||||
2 │ ╭─▶ x = 1
|
||||
3 │ │ \u{69}n
|
||||
4 │ ╰─▶ y = a
|
||||
5 │ \u{69}nstanceof
|
||||
╰────
|
||||
|
||||
Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/estree/class-private-method/typescript-invalid-abstract/input.ts
|
||||
|
||||
× TS(18019): 'abstract' modifier cannot be used with a private identifier.
|
||||
@@ -120,23 +101,33 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
|
||||
5 │ f();
|
||||
╰────
|
||||
|
||||
Fatal error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/class/escaped-in-after-initializer/input.ts
|
||||
Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/class/escaped-in-after-initializer/input.ts
|
||||
|
||||
× Keywords cannot contain escape characters
|
||||
× Identifier `\u{69}n` has already been declared
|
||||
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/escaped-in-after-initializer/input.ts:3:3]
|
||||
2 │ x = 1
|
||||
3 │ \u{69}n
|
||||
· ───────
|
||||
· ───┬───
|
||||
· ╰── `\u{69}n` has already been declared here
|
||||
4 │ y = () => a
|
||||
5 │ \u{69}nstanceof
|
||||
6 │ z = 1
|
||||
7 │ \u{69}n() {}
|
||||
· ───┬───
|
||||
· ╰── It can not be redeclared here
|
||||
8 │ \u{69}n = 1
|
||||
╰────
|
||||
|
||||
× Cannot assign to this expression
|
||||
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/escaped-in-after-initializer/input.ts:2:7]
|
||||
1 │ class C {
|
||||
2 │ ╭─▶ x = 1
|
||||
3 │ │ \u{69}n
|
||||
4 │ ╰─▶ y = () => a
|
||||
5 │ \u{69}nstanceof
|
||||
× Identifier `\u{69}n` has already been declared
|
||||
╭─[babel/packages/babel-parser/test/fixtures/typescript/class/escaped-in-after-initializer/input.ts:7:3]
|
||||
6 │ z = 1
|
||||
7 │ \u{69}n() {}
|
||||
· ───┬───
|
||||
· ╰── `\u{69}n` has already been declared here
|
||||
8 │ \u{69}n = 1
|
||||
· ───┬───
|
||||
· ╰── It can not be redeclared here
|
||||
9 │ }
|
||||
╰────
|
||||
|
||||
Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/class/members-with-modifier-names/input.ts
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
parser_misc Summary:
|
||||
AST Parsed : 114/114 (100.00%)
|
||||
Positive Passed: 114/114 (100.00%)
|
||||
Negative Passed: 255/255 (100.00%)
|
||||
Negative Passed: 257/257 (100.00%)
|
||||
|
||||
× TS(1275): 'accessor' modifier can only appear on a property declaration.
|
||||
╭─[misc/fail/accessor-modifier-abstract-method.ts:1:29]
|
||||
@@ -573,6 +573,20 @@ Negative Passed: 255/255 (100.00%)
|
||||
· ───────────
|
||||
╰────
|
||||
|
||||
× Keywords cannot contain escape characters
|
||||
╭─[misc/fail/escaped-in-after-newline.js:2:1]
|
||||
1 │ a
|
||||
2 │ \u{69}n b;
|
||||
· ───────
|
||||
╰────
|
||||
|
||||
× Keywords cannot contain escape characters
|
||||
╭─[misc/fail/escaped-instanceof-after-newline.js:2:1]
|
||||
1 │ a
|
||||
2 │ \u{69}nstanceof b;
|
||||
· ───────────────
|
||||
╰────
|
||||
|
||||
× Keywords cannot contain escape characters
|
||||
╭─[misc/fail/escaped-type-import.ts:1:8]
|
||||
1 │ import t\u0079pe Foo = require("m");
|
||||
|
||||
@@ -2,7 +2,7 @@ commit: a56fe4a4
|
||||
|
||||
semantic_babel Summary:
|
||||
AST Parsed : 2280/2280 (100.00%)
|
||||
Positive Passed: 2185/2280 (95.83%)
|
||||
Positive Passed: 2186/2280 (95.88%)
|
||||
semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/annex-b/enabled/1.1-html-comments-open-export-default-from/input.js
|
||||
Cannot use export statement outside a module
|
||||
|
||||
@@ -42,10 +42,6 @@ Symbol scope ID mismatch for "_await":
|
||||
after transform: SymbolId(3): ScopeId(2)
|
||||
rebuilt : SymbolId(2): ScopeId(0)
|
||||
|
||||
semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2022/class-properties/escaped-in-after-initializer/input.js
|
||||
Keywords cannot contain escape characters
|
||||
Cannot assign to this expression
|
||||
|
||||
semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/es2026/async-explicit-resource-management/valid-for-using-binding-of-of/input.js
|
||||
Symbol reference IDs mismatch for "of":
|
||||
after transform: SymbolId(1): [ReferenceId(0)]
|
||||
@@ -108,8 +104,8 @@ after transform: ["a"]
|
||||
rebuilt : []
|
||||
|
||||
semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/class/escaped-in-after-initializer/input.ts
|
||||
Keywords cannot contain escape characters
|
||||
Cannot assign to this expression
|
||||
Identifier `\u{69}n` has already been declared
|
||||
Identifier `\u{69}n` has already been declared
|
||||
|
||||
semantic Error: tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/class/get-generic/input.ts
|
||||
Bindings mismatch:
|
||||
|
||||
Reference in new issue
Block a user