From 2716986cd4e6828f13719e5d6ed796c0579a25f6 Mon Sep 17 00:00:00 2001 From: Denis Bezrukov <6227442+denbezrukov@users.noreply.github.com> Date: Mon, 10 Jul 2023 19:32:37 +0300 Subject: [PATCH] fix(rome_js_parser): Crash at @ character in class name / body #4669 (#4677) --- crates/rome_js_parser/src/syntax/class.rs | 19 +- .../err/ts_broken_class_member_modifiers.rast | 259 ++++++++++++++++++ .../err/ts_broken_class_member_modifiers.ts | 8 + .../err/ts_decorator_object.options.json | 2 +- ...decorator_on_ambient_function.options.json | 2 +- ...s_decorator_on_arrow_function.options.json | 2 +- ...decorator_on_constructor_type.options.json | 2 +- ...rator_on_function_declaration.options.json | 2 +- ...orator_on_function_expression.options.json | 2 +- ...ts_decorator_on_function_type.options.json | 2 +- ...decorator_on_signature_member.options.json | 2 +- ...corator_this_parameter_option.options.json | 2 +- ...ts_formal_parameter_decorator.options.json | 2 +- .../ok/ts_decorator_constructor.options.json | 2 +- .../ts_decorator_on_class_method.options.json | 2 +- .../ts_decorator_on_class_setter.options.json | 2 +- ...ts_formal_parameter_decorator.options.json | 2 +- 17 files changed, 295 insertions(+), 19 deletions(-) create mode 100644 crates/rome_js_parser/test_data/inline/err/ts_broken_class_member_modifiers.rast create mode 100644 crates/rome_js_parser/test_data/inline/err/ts_broken_class_member_modifiers.ts diff --git a/crates/rome_js_parser/src/syntax/class.rs b/crates/rome_js_parser/src/syntax/class.rs index 8a81421f909..dc7cdcd7234 100644 --- a/crates/rome_js_parser/src/syntax/class.rs +++ b/crates/rome_js_parser/src/syntax/class.rs @@ -561,7 +561,20 @@ fn parse_class_member(p: &mut JsParser, inside_abstract_class: bool) -> ParsedSy Present(member) } Absent => { - debug_assert!(modifiers.is_empty()); + // If the modifier list contains a modifier other than a decorator, such modifiers can also be valid member names. + debug_assert!(!modifiers + .flags + .contains(ModifierFlags::ALL_MODIFIERS_EXCEPT_DECORATOR)); + + // test_err ts ts_broken_class_member_modifiers + // class C { + // @decorator + // } + // class CC { + // @ + // } + // class @ + // class C@ modifiers.abandon(p); Absent } @@ -2024,11 +2037,7 @@ impl ClassMemberModifiers { } /// Abandons the marker for the modifier list - /// - /// ## Panics - /// If the modifier list isn't empty fn abandon(mut self, p: &mut JsParser) { - debug_assert!(self.is_empty()); self.list_marker.undo_completion(p).abandon(p); self.bomb.defuse(); } diff --git a/crates/rome_js_parser/test_data/inline/err/ts_broken_class_member_modifiers.rast b/crates/rome_js_parser/test_data/inline/err/ts_broken_class_member_modifiers.rast new file mode 100644 index 00000000000..d6c2356ee46 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/ts_broken_class_member_modifiers.rast @@ -0,0 +1,259 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsBogusStatement { + items: [ + JsDecoratorList [], + CLASS_KW@0..6 "class" [] [Whitespace(" ")], + JsIdentifierBinding { + name_token: IDENT@6..8 "C" [] [Whitespace(" ")], + }, + L_CURLY@8..9 "{" [] [], + JsBogus { + items: [ + JsDecorator { + at_token: AT@9..12 "@" [Newline("\n"), Whitespace("\t")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@12..21 "decorator" [] [], + }, + }, + }, + ], + }, + R_CURLY@21..24 "}" [Newline("\n"), Whitespace("\t")] [], + ], + }, + JsBogusStatement { + items: [ + JsDecoratorList [], + CLASS_KW@24..31 "class" [Newline("\n")] [Whitespace(" ")], + JsIdentifierBinding { + name_token: IDENT@31..34 "CC" [] [Whitespace(" ")], + }, + L_CURLY@34..35 "{" [] [], + JsBogus { + items: [ + JsDecorator { + at_token: AT@35..38 "@" [Newline("\n"), Whitespace("\t")] [], + expression: missing (required), + }, + ], + }, + R_CURLY@38..41 "}" [Newline("\n"), Whitespace("\t")] [], + ], + }, + JsBogusStatement { + items: [ + JsDecoratorList [], + CLASS_KW@41..48 "class" [Newline("\n")] [Whitespace(" ")], + JsBogus { + items: [ + JsDecorator { + at_token: AT@48..49 "@" [] [], + expression: JsBogusExpression { + items: [ + JsDecoratorList [], + CLASS_KW@49..56 "class" [Newline("\n")] [Whitespace(" ")], + JsIdentifierBinding { + name_token: IDENT@56..57 "C" [] [], + }, + JsBogus { + items: [ + JsDecorator { + at_token: AT@57..58 "@" [] [], + expression: missing (required), + }, + ], + }, + ], + }, + }, + ], + }, + ], + }, + ], + eof_token: EOF@58..59 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..59 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..58 + 0: JS_BOGUS_STATEMENT@0..24 + 0: JS_DECORATOR_LIST@0..0 + 1: CLASS_KW@0..6 "class" [] [Whitespace(" ")] + 2: JS_IDENTIFIER_BINDING@6..8 + 0: IDENT@6..8 "C" [] [Whitespace(" ")] + 3: L_CURLY@8..9 "{" [] [] + 4: JS_BOGUS@9..21 + 0: JS_DECORATOR@9..21 + 0: AT@9..12 "@" [Newline("\n"), Whitespace("\t")] [] + 1: JS_IDENTIFIER_EXPRESSION@12..21 + 0: JS_REFERENCE_IDENTIFIER@12..21 + 0: IDENT@12..21 "decorator" [] [] + 5: R_CURLY@21..24 "}" [Newline("\n"), Whitespace("\t")] [] + 1: JS_BOGUS_STATEMENT@24..41 + 0: JS_DECORATOR_LIST@24..24 + 1: CLASS_KW@24..31 "class" [Newline("\n")] [Whitespace(" ")] + 2: JS_IDENTIFIER_BINDING@31..34 + 0: IDENT@31..34 "CC" [] [Whitespace(" ")] + 3: L_CURLY@34..35 "{" [] [] + 4: JS_BOGUS@35..38 + 0: JS_DECORATOR@35..38 + 0: AT@35..38 "@" [Newline("\n"), Whitespace("\t")] [] + 1: (empty) + 5: R_CURLY@38..41 "}" [Newline("\n"), Whitespace("\t")] [] + 2: JS_BOGUS_STATEMENT@41..58 + 0: JS_DECORATOR_LIST@41..41 + 1: CLASS_KW@41..48 "class" [Newline("\n")] [Whitespace(" ")] + 2: JS_BOGUS@48..58 + 0: JS_DECORATOR@48..58 + 0: AT@48..49 "@" [] [] + 1: JS_BOGUS_EXPRESSION@49..58 + 0: JS_DECORATOR_LIST@49..49 + 1: CLASS_KW@49..56 "class" [Newline("\n")] [Whitespace(" ")] + 2: JS_IDENTIFIER_BINDING@56..57 + 0: IDENT@56..57 "C" [] [] + 3: JS_BOGUS@57..58 + 0: JS_DECORATOR@57..58 + 0: AT@57..58 "@" [] [] + 1: (empty) + 3: EOF@58..59 "" [Newline("\n")] [] +-- +ts_broken_class_member_modifiers.ts:3:2 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found '}' + + 1 │ class C { + 2 │ @decorator + > 3 │ } + │ ^ + 4 │ class CC { + 5 │ @ + + i Expected an identifier, a string literal, a number literal, a private field name, or a computed name here + + 1 │ class C { + 2 │ @decorator + > 3 │ } + │ ^ + 4 │ class CC { + 5 │ @ + +-- +ts_broken_class_member_modifiers.ts:6:2 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected an expression but instead found '}' + + 4 │ class CC { + 5 │ @ + > 6 │ } + │ ^ + 7 │ class @ + 8 │ class C@ + + i Expected an expression here + + 4 │ class CC { + 5 │ @ + > 6 │ } + │ ^ + 7 │ class @ + 8 │ class C@ + +-- +ts_broken_class_member_modifiers.ts:7:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × class declarations must have a name + + 5 │ @ + 6 │ } + > 7 │ class @ + │ ^^^^^^ + 8 │ class C@ + 9 │ + +-- +ts_broken_class_member_modifiers.ts:7:7 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `{` but instead found `@` + + 5 │ @ + 6 │ } + > 7 │ class @ + │ ^ + 8 │ class C@ + 9 │ + + i Remove @ + +-- +ts_broken_class_member_modifiers.ts:8:8 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected `{` but instead found `@` + + 6 │ } + 7 │ class @ + > 8 │ class C@ + │ ^ + 9 │ + + i Remove @ + +-- +ts_broken_class_member_modifiers.ts:9:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected an expression but instead found the end of the file + + 7 │ class @ + 8 │ class C@ + > 9 │ + │ + + i Expected an expression here + + 7 │ class @ + 8 │ class C@ + > 9 │ + │ + +-- +ts_broken_class_member_modifiers.ts:8:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Invalid decorator `class C@` + + 6 │ } + 7 │ class @ + > 8 │ class C@ + │ ^^^^^^^^ + 9 │ + +-- +ts_broken_class_member_modifiers.ts:9:1 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × expected an identifier, a string literal, a number literal, a private field name, or a computed name but instead found the end of the file + + 7 │ class @ + 8 │ class C@ + > 9 │ + │ + + i Expected an identifier, a string literal, a number literal, a private field name, or a computed name here + + 7 │ class @ + 8 │ class C@ + > 9 │ + │ + +-- +class C { + @decorator + } +class CC { + @ + } +class @ +class C@ diff --git a/crates/rome_js_parser/test_data/inline/err/ts_broken_class_member_modifiers.ts b/crates/rome_js_parser/test_data/inline/err/ts_broken_class_member_modifiers.ts new file mode 100644 index 00000000000..a2631e82131 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/ts_broken_class_member_modifiers.ts @@ -0,0 +1,8 @@ +class C { + @decorator + } +class CC { + @ + } +class @ +class C@ diff --git a/crates/rome_js_parser/test_data/inline/err/ts_decorator_object.options.json b/crates/rome_js_parser/test_data/inline/err/ts_decorator_object.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_decorator_object.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_decorator_object.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_ambient_function.options.json b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_ambient_function.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_ambient_function.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_ambient_function.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_arrow_function.options.json b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_arrow_function.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_arrow_function.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_arrow_function.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_constructor_type.options.json b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_constructor_type.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_constructor_type.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_constructor_type.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_declaration.options.json b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_declaration.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_declaration.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_declaration.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_expression.options.json b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_expression.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_expression.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_expression.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_type.options.json b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_type.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_type.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_function_type.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_signature_member.options.json b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_signature_member.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_signature_member.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_decorator_on_signature_member.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/err/ts_decorator_this_parameter_option.options.json b/crates/rome_js_parser/test_data/inline/err/ts_decorator_this_parameter_option.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_decorator_this_parameter_option.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_decorator_this_parameter_option.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/err/ts_formal_parameter_decorator.options.json b/crates/rome_js_parser/test_data/inline/err/ts_formal_parameter_decorator.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_formal_parameter_decorator.options.json +++ b/crates/rome_js_parser/test_data/inline/err/ts_formal_parameter_decorator.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.options.json b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.options.json +++ b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_on_class_method.options.json b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_on_class_method.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_on_class_method.options.json +++ b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_on_class_method.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_on_class_setter.options.json b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_on_class_setter.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_on_class_setter.options.json +++ b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_on_class_setter.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.options.json b/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.options.json index 435ed7fb84f..e58b2dfa5dd 100644 --- a/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.options.json +++ b/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.options.json @@ -1 +1 @@ -{ "parse_class_parameter_decorators": true } +{ "parse_class_parameter_decorators": true } \ No newline at end of file