From 27ad5dd484e84accfc27661ac02a3561608daa90 Mon Sep 17 00:00:00 2001 From: Denis Bezrukov <6227442+denbezrukov@users.noreply.github.com> Date: Mon, 1 May 2023 10:29:49 +0300 Subject: [PATCH] feat(rome_js_parser): EcmaScript @decorators #4252 --- crates/rome_js_formatter/src/comments.rs | 24 + crates/rome_js_formatter/src/generated.rs | 68 +- .../src/js/any/method_modifier.rs | 1 + .../src/js/any/property_modifier.rs | 1 + .../src/ts/any/method_signature_modifier.rs | 1 + .../src/ts/any/property_signature_modifier.rs | 1 + crates/rome_js_formatter/tests/quick_test.rs | 12 +- .../js/babel-plugins/decorators.js.snap | 92 + .../decorator-auto-accessors/comments.js.snap | 41 + .../js/decorator-comments/comments.js.snap | 1 - .../js/decorators/member-expression.js.snap | 76 +- .../prettier/js/decorators/methods.js.snap | 36 +- .../prettier/js/decorators/mixed.js.snap | 46 + .../specs/prettier/js/decorators/mobx.js.snap | 26 +- .../prettier/js/decorators/multiline.js.snap | 78 - .../prettier/js/decorators/parens.js.snap | 38 + .../decorators-ts/accessor-decorator.ts.snap | 75 + .../decorators-ts/method-decorator.ts.snap | 56 + .../typescript/decorators-ts/multiple.ts.snap | 40 + .../decorators-ts/parameter-decorator.ts.snap | 73 + .../typescript/decorators-ts/typeorm.ts.snap | 53 +- .../decorators/decorators-comments.ts.snap | 73 +- .../decorators/inline-decorators.ts.snap | 58 +- .../tests/specs/ts/decoartors.ts.snap | 19 +- crates/rome_js_parser/src/syntax/class.rs | 226 +- crates/rome_js_parser/src/syntax/function.rs | 7 + .../src/syntax/js_parse_error.rs | 7 + crates/rome_js_parser/src/tests.rs | 14 +- .../inline/err/decorator_class_member.rast | 705 ++++ .../inline/err/decorator_class_member.ts | 18 + .../err/decorator_precede_class_member.rast | 744 +++++ .../err/decorator_precede_class_member.ts | 14 + .../ts_invalid_decorated_class_members.rast | 544 +++- .../err/ts_invalid_decorated_class_members.ts | 4 +- ...lization_block_member_with_decorators.rast | 114 + ...ialization_block_member_with_decorators.ts | 5 + .../inline/ok/decorator_class_member.rast | 2824 +++++++++++++++++ .../inline/ok/decorator_class_member.ts | 42 + .../ok/decorator_class_member_in_ts.rast | 156 + .../inline/ok/decorator_class_member_in_ts.ts | 6 + .../ok/ts_decorate_computed_member.rast | 24 +- .../inline/ok/ts_decorated_class_members.rast | 158 +- .../inline/ok/ts_decorated_class_members.ts | 2 - ..._decorator_call_expression_with_arrow.rast | 84 +- .../inline/ok/ts_decorator_constructor.rast | 104 + .../inline/ok/ts_decorator_constructor.ts | 3 + .../ok/ts_formal_parameter_decorator.rast | 193 ++ .../ok/ts_formal_parameter_decorator.ts | 5 + crates/rome_js_syntax/src/generated/nodes.rs | 79 +- crates/rome_js_syntax/src/modifier_ext.rs | 5 + xtask/codegen/js.ungram | 4 + 51 files changed, 6518 insertions(+), 562 deletions(-) create mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/decorators.js.snap create mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/decorator-auto-accessors/comments.js.snap create mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/decorators/mixed.js.snap delete mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/decorators/multiline.js.snap create mode 100644 crates/rome_js_formatter/tests/specs/prettier/js/decorators/parens.js.snap create mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/accessor-decorator.ts.snap create mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/method-decorator.ts.snap create mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/multiple.ts.snap create mode 100644 crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/parameter-decorator.ts.snap create mode 100644 crates/rome_js_parser/test_data/inline/err/decorator_class_member.rast create mode 100644 crates/rome_js_parser/test_data/inline/err/decorator_class_member.ts create mode 100644 crates/rome_js_parser/test_data/inline/err/decorator_precede_class_member.rast create mode 100644 crates/rome_js_parser/test_data/inline/err/decorator_precede_class_member.ts create mode 100644 crates/rome_js_parser/test_data/inline/err/ts_static_initialization_block_member_with_decorators.rast create mode 100644 crates/rome_js_parser/test_data/inline/err/ts_static_initialization_block_member_with_decorators.ts create mode 100644 crates/rome_js_parser/test_data/inline/ok/decorator_class_member.rast create mode 100644 crates/rome_js_parser/test_data/inline/ok/decorator_class_member.ts create mode 100644 crates/rome_js_parser/test_data/inline/ok/decorator_class_member_in_ts.rast create mode 100644 crates/rome_js_parser/test_data/inline/ok/decorator_class_member_in_ts.ts create mode 100644 crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.rast create mode 100644 crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.ts create mode 100644 crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.rast create mode 100644 crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.ts diff --git a/crates/rome_js_formatter/src/comments.rs b/crates/rome_js_formatter/src/comments.rs index c08535e2b81..8c796935d9a 100644 --- a/crates/rome_js_formatter/src/comments.rs +++ b/crates/rome_js_formatter/src/comments.rs @@ -166,6 +166,7 @@ impl CommentStyle for JsCommentStyle { .or_else(handle_try_comment) .or_else(handle_class_comment) .or_else(handle_method_comment) + .or_else(handle_property_comments) .or_else(handle_for_comment) .or_else(handle_root_comments) .or_else(handle_array_hole_comment) @@ -184,6 +185,7 @@ impl CommentStyle for JsCommentStyle { .or_else(handle_try_comment) .or_else(handle_class_comment) .or_else(handle_method_comment) + .or_else(handle_property_comments) .or_else(handle_for_comment) .or_else(handle_root_comments) .or_else(handle_parameter_comment) @@ -508,6 +510,28 @@ fn handle_method_comment(comment: DecoratedComment) -> CommentPlacem CommentPlacement::Default(comment) } +fn handle_property_comments(comment: DecoratedComment) -> CommentPlacement { + let enclosing = comment.enclosing_node(); + + let is_property = matches!( + enclosing.kind(), + JsSyntaxKind::JS_PROPERTY_OBJECT_MEMBER | JsSyntaxKind::JS_PROPERTY_CLASS_MEMBER + ); + + if !is_property { + return CommentPlacement::Default(comment); + } + + if let (Some(preceding), Some(following)) = (comment.preceding_node(), comment.following_node()) + { + if preceding.kind() == JsSyntaxKind::JS_DECORATOR { + return CommentPlacement::leading(following.clone(), comment); + } + } + + CommentPlacement::Default(comment) +} + /// Handle a all comments document. /// See `blank.js` fn handle_root_comments(comment: DecoratedComment) -> CommentPlacement { diff --git a/crates/rome_js_formatter/src/generated.rs b/crates/rome_js_formatter/src/generated.rs index 0b22ca30504..2645b382328 100644 --- a/crates/rome_js_formatter/src/generated.rs +++ b/crates/rome_js_formatter/src/generated.rs @@ -4700,6 +4700,40 @@ impl IntoFormat for rome_js_syntax::JsInitializerClause { ) } } +impl FormatRule + for crate::js::auxiliary::decorator::FormatJsDecorator +{ + type Context = JsFormatContext; + #[inline(always)] + fn fmt(&self, node: &rome_js_syntax::JsDecorator, f: &mut JsFormatter) -> FormatResult<()> { + FormatNodeRule::::fmt(self, node, f) + } +} +impl AsFormat for rome_js_syntax::JsDecorator { + type Format<'a> = FormatRefWithRule< + 'a, + rome_js_syntax::JsDecorator, + crate::js::auxiliary::decorator::FormatJsDecorator, + >; + fn format(&self) -> Self::Format<'_> { + FormatRefWithRule::new( + self, + crate::js::auxiliary::decorator::FormatJsDecorator::default(), + ) + } +} +impl IntoFormat for rome_js_syntax::JsDecorator { + type Format = FormatOwnedWithRule< + rome_js_syntax::JsDecorator, + crate::js::auxiliary::decorator::FormatJsDecorator, + >; + fn into_format(self) -> Self::Format { + FormatOwnedWithRule::new( + self, + crate::js::auxiliary::decorator::FormatJsDecorator::default(), + ) + } +} impl FormatRule for crate::ts::auxiliary::optional_property_annotation::FormatTsOptionalPropertyAnnotation { @@ -6807,40 +6841,6 @@ impl IntoFormat for rome_js_syntax::TsThisParameter { ) } } -impl FormatRule - for crate::js::auxiliary::decorator::FormatJsDecorator -{ - type Context = JsFormatContext; - #[inline(always)] - fn fmt(&self, node: &rome_js_syntax::JsDecorator, f: &mut JsFormatter) -> FormatResult<()> { - FormatNodeRule::::fmt(self, node, f) - } -} -impl AsFormat for rome_js_syntax::JsDecorator { - type Format<'a> = FormatRefWithRule< - 'a, - rome_js_syntax::JsDecorator, - crate::js::auxiliary::decorator::FormatJsDecorator, - >; - fn format(&self) -> Self::Format<'_> { - FormatRefWithRule::new( - self, - crate::js::auxiliary::decorator::FormatJsDecorator::default(), - ) - } -} -impl IntoFormat for rome_js_syntax::JsDecorator { - type Format = FormatOwnedWithRule< - rome_js_syntax::JsDecorator, - crate::js::auxiliary::decorator::FormatJsDecorator, - >; - fn into_format(self) -> Self::Format { - FormatOwnedWithRule::new( - self, - crate::js::auxiliary::decorator::FormatJsDecorator::default(), - ) - } -} impl FormatRule for crate::ts::types::any_type::FormatTsAnyType { type Context = JsFormatContext; #[inline(always)] diff --git a/crates/rome_js_formatter/src/js/any/method_modifier.rs b/crates/rome_js_formatter/src/js/any/method_modifier.rs index eda202e5a42..2c21c1dec80 100644 --- a/crates/rome_js_formatter/src/js/any/method_modifier.rs +++ b/crates/rome_js_formatter/src/js/any/method_modifier.rs @@ -10,6 +10,7 @@ impl FormatRule for FormatAnyJsMethodModifier { match node { AnyJsMethodModifier::TsAccessibilityModifier(node) => node.format().fmt(f), AnyJsMethodModifier::JsStaticModifier(node) => node.format().fmt(f), + AnyJsMethodModifier::JsDecorator(node) => node.format().fmt(f), AnyJsMethodModifier::TsOverrideModifier(node) => node.format().fmt(f), } } diff --git a/crates/rome_js_formatter/src/js/any/property_modifier.rs b/crates/rome_js_formatter/src/js/any/property_modifier.rs index a2262dd0f2b..4011adbd621 100644 --- a/crates/rome_js_formatter/src/js/any/property_modifier.rs +++ b/crates/rome_js_formatter/src/js/any/property_modifier.rs @@ -11,6 +11,7 @@ impl FormatRule for FormatAnyJsPropertyModifier { AnyJsPropertyModifier::TsAccessibilityModifier(node) => node.format().fmt(f), AnyJsPropertyModifier::JsStaticModifier(node) => node.format().fmt(f), AnyJsPropertyModifier::JsAccessorModifier(node) => node.format().fmt(f), + AnyJsPropertyModifier::JsDecorator(node) => node.format().fmt(f), AnyJsPropertyModifier::TsReadonlyModifier(node) => node.format().fmt(f), AnyJsPropertyModifier::TsOverrideModifier(node) => node.format().fmt(f), } diff --git a/crates/rome_js_formatter/src/ts/any/method_signature_modifier.rs b/crates/rome_js_formatter/src/ts/any/method_signature_modifier.rs index 2a939c36a29..556fbc52445 100644 --- a/crates/rome_js_formatter/src/ts/any/method_signature_modifier.rs +++ b/crates/rome_js_formatter/src/ts/any/method_signature_modifier.rs @@ -9,6 +9,7 @@ impl FormatRule for FormatAnyTsMethodSignatureModi fn fmt(&self, node: &AnyTsMethodSignatureModifier, f: &mut JsFormatter) -> FormatResult<()> { match node { AnyTsMethodSignatureModifier::TsAccessibilityModifier(node) => node.format().fmt(f), + AnyTsMethodSignatureModifier::JsDecorator(node) => node.format().fmt(f), AnyTsMethodSignatureModifier::JsStaticModifier(node) => node.format().fmt(f), AnyTsMethodSignatureModifier::TsOverrideModifier(node) => node.format().fmt(f), AnyTsMethodSignatureModifier::TsAbstractModifier(node) => node.format().fmt(f), diff --git a/crates/rome_js_formatter/src/ts/any/property_signature_modifier.rs b/crates/rome_js_formatter/src/ts/any/property_signature_modifier.rs index 16ff793e5ba..839ea836ac5 100644 --- a/crates/rome_js_formatter/src/ts/any/property_signature_modifier.rs +++ b/crates/rome_js_formatter/src/ts/any/property_signature_modifier.rs @@ -11,6 +11,7 @@ impl FormatRule for FormatAnyTsPropertySignature AnyTsPropertySignatureModifier::TsDeclareModifier(node) => node.format().fmt(f), AnyTsPropertySignatureModifier::TsAccessibilityModifier(node) => node.format().fmt(f), AnyTsPropertySignatureModifier::JsStaticModifier(node) => node.format().fmt(f), + AnyTsPropertySignatureModifier::JsDecorator(node) => node.format().fmt(f), AnyTsPropertySignatureModifier::JsAccessorModifier(node) => node.format().fmt(f), AnyTsPropertySignatureModifier::TsReadonlyModifier(node) => node.format().fmt(f), AnyTsPropertySignatureModifier::TsOverrideModifier(node) => node.format().fmt(f), diff --git a/crates/rome_js_formatter/tests/quick_test.rs b/crates/rome_js_formatter/tests/quick_test.rs index 1fc3d441c91..a7432e4f160 100644 --- a/crates/rome_js_formatter/tests/quick_test.rs +++ b/crates/rome_js_formatter/tests/quick_test.rs @@ -13,13 +13,11 @@ mod language { // use this test check if your snippet prints as you wish, without using a snapshot fn quick_test() { let src = r#" -const bar = - ( - @deco - class { - // - } - ); +class Test2 { + @anotherDecorator() // leading comment + prop: string; +} + "#; let syntax = SourceType::tsx(); diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/decorators.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/decorators.js.snap new file mode 100644 index 00000000000..ab49cc76aac --- /dev/null +++ b/crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/decorators.js.snap @@ -0,0 +1,92 @@ +--- +source: crates/rome_formatter_test/src/snapshot_builder.rs +info: js/babel-plugins/decorators.js +--- + +# Input + +```js +// https://babeljs.io/docs/en/babel-plugin-proposal-decorators + +@annotation +class MyClass { } + +function annotation(target) { + target.annotated = true; +} + +@isTestable(true) +class MyClass { } + +function isTestable(value) { + return function decorator(target) { + target.isTestable = value; + } +} + +class C { + @enumerable(false) + method() { } +} + +function enumerable(value) { + return function (target, key, descriptor) { + descriptor.enumerable = value; + return descriptor; + } +} + +``` + + +# Prettier differences + +```diff +--- Prettier ++++ Rome +@@ -17,8 +17,7 @@ + } + + class C { +- @enumerable(false) +- method() {} ++ @enumerable(false) method() {} + } + + function enumerable(value) { +``` + +# Output + +```js +// https://babeljs.io/docs/en/babel-plugin-proposal-decorators + +@annotation +class MyClass {} + +function annotation(target) { + target.annotated = true; +} + +@isTestable(true) +class MyClass {} + +function isTestable(value) { + return function decorator(target) { + target.isTestable = value; + }; +} + +class C { + @enumerable(false) method() {} +} + +function enumerable(value) { + return function (target, key, descriptor) { + descriptor.enumerable = value; + return descriptor; + }; +} +``` + + diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/decorator-auto-accessors/comments.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/decorator-auto-accessors/comments.js.snap new file mode 100644 index 00000000000..25eb7ff0f60 --- /dev/null +++ b/crates/rome_js_formatter/tests/specs/prettier/js/decorator-auto-accessors/comments.js.snap @@ -0,0 +1,41 @@ +--- +source: crates/rome_formatter_test/src/snapshot_builder.rs +info: js/decorator-auto-accessors/comments.js +--- + +# Input + +```js +class A { + @dec() + // comment + accessor b; +} + +``` + + +# Prettier differences + +```diff +--- Prettier ++++ Rome +@@ -1,5 +1,4 @@ + class A { +- @dec() +- // comment ++ @dec() // comment + accessor b; + } +``` + +# Output + +```js +class A { + @dec() // comment + accessor b; +} +``` + + diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/decorator-comments/comments.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/decorator-comments/comments.js.snap index 7eab2e508bd..1d52fa192ba 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/decorator-comments/comments.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/decorator-comments/comments.js.snap @@ -1,6 +1,5 @@ --- source: crates/rome_formatter_test/src/snapshot_builder.rs -assertion_line: 212 info: js/decorator-comments/comments.js --- diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/member-expression.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/member-expression.js.snap index ac64593e657..9f346cfcf97 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/member-expression.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/member-expression.js.snap @@ -65,52 +65,52 @@ info: js/decorators/member-expression.js ```diff --- Prettier +++ Rome -@@ -1,10 +1,10 @@ +@@ -1,54 +1,42 @@ [ class { - @decorators[0] -+ @(decorators[0]) - method() {} +- method() {} ++ @(decorators[0]) method() {} }, class { -- @decorators [0]; -+ @decorators[0]; + @decorators [0]; method() {} }, class { -@@ -12,7 +12,7 @@ - method() {} +- @(decorators?.[0]) +- method() {} ++ @(decorators?.[0]) method() {} }, class { - @decorators.at(0) -+ @(decorators.at(0)) - method() {} +- method() {} ++ @(decorators.at(0)) method() {} }, class { -@@ -20,7 +20,7 @@ - method() {} +- @(decorators?.at(0)) +- method() {} ++ @(decorators?.at(0)) method() {} ++ }, ++ class { ++ @(decorators.first) method() {} ++ }, ++ class { ++ @(decorators?.first) method() {} }, class { - @decorators.first -+ @(decorators.first) - method() {} +- method() {} ++ @(decorators[first]) method() {} }, class { -@@ -28,27 +28,23 @@ +- @(decorators?.first) ++ @decorators [first]; method() {} }, class { - @decorators[first] -+ @(decorators[first]) -+ method() {} -+ }, -+ class { -+ @decorators[first]; -+ method() {} -+ }, -+ class { -+ @(decorators["first"]) - method() {} +- method() {} ++ @(decorators["first"]) method() {} }, + @(decorators[first]) class { @@ -142,44 +142,36 @@ info: js/decorators/member-expression.js ```js [ class { - @(decorators[0]) - method() {} + @(decorators[0]) method() {} }, class { - @decorators[0]; + @decorators [0]; method() {} }, class { - @(decorators?.[0]) - method() {} + @(decorators?.[0]) method() {} }, class { - @(decorators.at(0)) - method() {} + @(decorators.at(0)) method() {} }, class { - @(decorators?.at(0)) - method() {} + @(decorators?.at(0)) method() {} }, class { - @(decorators.first) - method() {} + @(decorators.first) method() {} }, class { - @(decorators?.first) - method() {} + @(decorators?.first) method() {} }, class { - @(decorators[first]) - method() {} + @(decorators[first]) method() {} }, class { - @decorators[first]; + @decorators [first]; method() {} }, class { - @(decorators["first"]) - method() {} + @(decorators["first"]) method() {} }, @(decorators[first]) class { diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/methods.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/methods.js.snap index 6a0cbac1c91..a547c14df8a 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/methods.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/methods.js.snap @@ -1,6 +1,5 @@ --- source: crates/rome_formatter_test/src/snapshot_builder.rs -assertion_line: 212 info: js/decorators/methods.js --- @@ -26,13 +25,23 @@ class Yo { ```diff --- Prettier +++ Rome -@@ -5,6 +5,5 @@ - @anotherDecoratorWithALongName("and a very long string as a first argument") - async plip() {} +@@ -1,10 +1,11 @@ + class Yo { +- @foo("hello") +- async plop() {} ++ @foo("hello") async plop() {} + +- @anotherDecoratorWithALongName("and a very long string as a first argument") +- async plip() {} ++ @anotherDecoratorWithALongName( ++ "and a very long string as a first argument", ++ ) async plip() {} - @anotherDecoratorWithALongName("another very long string, but now inline") - async plip() {} -+ @anotherDecoratorWithALongName("another very long string, but now inline") async plip() {} ++ @anotherDecoratorWithALongName( ++ "another very long string, but now inline", ++ ) async plip() {} } ``` @@ -40,19 +49,16 @@ class Yo { ```js class Yo { - @foo("hello") - async plop() {} + @foo("hello") async plop() {} - @anotherDecoratorWithALongName("and a very long string as a first argument") - async plip() {} + @anotherDecoratorWithALongName( + "and a very long string as a first argument", + ) async plip() {} - @anotherDecoratorWithALongName("another very long string, but now inline") async plip() {} + @anotherDecoratorWithALongName( + "another very long string, but now inline", + ) async plip() {} } ``` -# Lines exceeding max width of 80 characters -``` - 8: @anotherDecoratorWithALongName("another very long string, but now inline") async plip() {} -``` - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/mixed.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/mixed.js.snap new file mode 100644 index 00000000000..686f9673b3a --- /dev/null +++ b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/mixed.js.snap @@ -0,0 +1,46 @@ +--- +source: crates/rome_formatter_test/src/snapshot_builder.rs +info: js/decorators/mixed.js +--- + +# Input + +```js +// https://github.com/prettier/prettier/issues/6747 + +@foo +export default class MyComponent { + @task + *foo() { + } +} +``` + + +# Prettier differences + +```diff +--- Prettier ++++ Rome +@@ -2,6 +2,5 @@ + + @foo + export default class MyComponent { +- @task +- *foo() {} ++ @task *foo() {} + } +``` + +# Output + +```js +// https://github.com/prettier/prettier/issues/6747 + +@foo +export default class MyComponent { + @task *foo() {} +} +``` + + diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/mobx.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/mobx.js.snap index 2f1c5db09bf..5d8d2458c12 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/mobx.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/mobx.js.snap @@ -62,7 +62,19 @@ import {observable} from "mobx"; constructor(price) { this.price = price; -@@ -27,20 +27,11 @@ +@@ -17,30 +17,19 @@ + this.price = price; + } + +- @computed +- get total() { ++ @computed get total() { + return this.price * this.amount; + } + +- @action.bound +- setPrice(price) { ++ @action.bound setPrice(price) { this.price = price; } @@ -110,13 +122,11 @@ class OrderLine { this.price = price; } - @computed - get total() { + @computed get total() { return this.price * this.amount; } - @action.bound - setPrice(price) { + @action.bound setPrice(price) { this.price = price; } @@ -188,9 +198,9 @@ mobx.js:35:35 parse ━━━━━━━━━━━━━━━━━━━━ # Lines exceeding max width of 80 characters ``` - 30: @computed @computed @computed @computed @computed @computed @computed get total() { - 34: @action handleDecrease = (event: React.ChangeEvent) => this.count--; - 36: @action handleSomething = (event: React.ChangeEvent) => doSomething(); + 28: @computed @computed @computed @computed @computed @computed @computed get total() { + 32: @action handleDecrease = (event: React.ChangeEvent) => this.count--; + 34: @action handleSomething = (event: React.ChangeEvent) => doSomething(); ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/multiline.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/multiline.js.snap deleted file mode 100644 index f28956047f3..00000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/multiline.js.snap +++ /dev/null @@ -1,78 +0,0 @@ ---- -source: crates/rome_formatter_test/src/snapshot_builder.rs -assertion_line: 212 -info: js/decorators/multiline.js ---- - -# Input - -```js -class Foo { - @deco([ - foo, - bar - ]) prop = value; - - @decorator([]) method() {} - - @decorator([ - ]) method() {} - - @decorator({}) method() {} - - @decorator({ - }) method() {} -} - -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -1,11 +1,16 @@ - class Foo { -- @deco([foo, bar]) prop = value; -+ @deco([ -+ foo, -+ bar -+ ]) prop = value; - - @decorator([]) method() {} - -- @decorator([]) method() {} -+ @decorator([ -+ ]) method() {} - - @decorator({}) method() {} - -- @decorator({}) method() {} -+ @decorator({ -+ }) method() {} - } -``` - -# Output - -```js -class Foo { - @deco([ - foo, - bar - ]) prop = value; - - @decorator([]) method() {} - - @decorator([ - ]) method() {} - - @decorator({}) method() {} - - @decorator({ - }) method() {} -} -``` - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/js/decorators/parens.js.snap b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/parens.js.snap new file mode 100644 index 00000000000..6d8f478c33b --- /dev/null +++ b/crates/rome_js_formatter/tests/specs/prettier/js/decorators/parens.js.snap @@ -0,0 +1,38 @@ +--- +source: crates/rome_formatter_test/src/snapshot_builder.rs +info: js/decorators/parens.js +--- + +# Input + +```js +class X { + @(computed().volatile()) + x +} + +``` + + +# Prettier differences + +```diff +--- Prettier ++++ Rome +@@ -1,4 +1,3 @@ + class X { +- @(computed().volatile()) +- x; ++ @(computed().volatile()) x; + } +``` + +# Output + +```js +class X { + @(computed().volatile()) x; +} +``` + + diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/accessor-decorator.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/accessor-decorator.ts.snap new file mode 100644 index 00000000000..5aae442e051 --- /dev/null +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/accessor-decorator.ts.snap @@ -0,0 +1,75 @@ +--- +source: crates/rome_formatter_test/src/snapshot_builder.rs +info: typescript/decorators-ts/accessor-decorator.ts +--- + +# Input + +```ts +class Point { + private _x: number; + private _y: number; + constructor(x: number, y: number) { + this._x = x; + this._y = y; + } + + @configurable(false) + get x() { + return this._x; + } + + @configurable(false) + get y() { + return this._y; + } +} + +``` + + +# Prettier differences + +```diff +--- Prettier ++++ Rome +@@ -6,13 +6,11 @@ + this._y = y; + } + +- @configurable(false) +- get x() { ++ @configurable(false) get x() { + return this._x; + } + +- @configurable(false) +- get y() { ++ @configurable(false) get y() { + return this._y; + } + } +``` + +# Output + +```ts +class Point { + private _x: number; + private _y: number; + constructor(x: number, y: number) { + this._x = x; + this._y = y; + } + + @configurable(false) get x() { + return this._x; + } + + @configurable(false) get y() { + return this._y; + } +} +``` + + diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/method-decorator.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/method-decorator.ts.snap new file mode 100644 index 00000000000..c6153379280 --- /dev/null +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/method-decorator.ts.snap @@ -0,0 +1,56 @@ +--- +source: crates/rome_formatter_test/src/snapshot_builder.rs +info: typescript/decorators-ts/method-decorator.ts +--- + +# Input + +```ts +class Greeter { + greeting: string; + constructor(message: string) { + this.greeting = message; + } + + @enumerable(false) + greet() { + return "Hello, " + this.greeting; + } +} + +``` + + +# Prettier differences + +```diff +--- Prettier ++++ Rome +@@ -4,8 +4,7 @@ + this.greeting = message; + } + +- @enumerable(false) +- greet() { ++ @enumerable(false) greet() { + return "Hello, " + this.greeting; + } + } +``` + +# Output + +```ts +class Greeter { + greeting: string; + constructor(message: string) { + this.greeting = message; + } + + @enumerable(false) greet() { + return "Hello, " + this.greeting; + } +} +``` + + diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/multiple.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/multiple.ts.snap new file mode 100644 index 00000000000..4a1fd584d24 --- /dev/null +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/multiple.ts.snap @@ -0,0 +1,40 @@ +--- +source: crates/rome_formatter_test/src/snapshot_builder.rs +info: typescript/decorators-ts/multiple.ts +--- + +# Input + +```ts +class C { + @f() + @g() + method() {} +} + +``` + + +# Prettier differences + +```diff +--- Prettier ++++ Rome +@@ -1,5 +1,3 @@ + class C { +- @f() +- @g() +- method() {} ++ @f() @g() method() {} + } +``` + +# Output + +```ts +class C { + @f() @g() method() {} +} +``` + + diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/parameter-decorator.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/parameter-decorator.ts.snap new file mode 100644 index 00000000000..59d4114f438 --- /dev/null +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/parameter-decorator.ts.snap @@ -0,0 +1,73 @@ +--- +source: crates/rome_formatter_test/src/snapshot_builder.rs +info: typescript/decorators-ts/parameter-decorator.ts +--- + +# Input + +```ts +class Greeter { + greeting: string; + + constructor(message: string) { + this.greeting = message; + } + + @validate + greet(@required name: string) { + return "Hello " + name + ", " + this.greeting; + } + + @validate + destructured(@required { toString }: Object) { + return Function.prototype.toString.apply(toString); + } +} + +``` + + +# Prettier differences + +```diff +--- Prettier ++++ Rome +@@ -5,13 +5,11 @@ + this.greeting = message; + } + +- @validate +- greet(@required name: string) { ++ @validate greet(@required name: string) { + return "Hello " + name + ", " + this.greeting; + } + +- @validate +- destructured(@required { toString }: Object) { ++ @validate destructured(@required { toString }: Object) { + return Function.prototype.toString.apply(toString); + } + } +``` + +# Output + +```ts +class Greeter { + greeting: string; + + constructor(message: string) { + this.greeting = message; + } + + @validate greet(@required name: string) { + return "Hello " + name + ", " + this.greeting; + } + + @validate destructured(@required { toString }: Object) { + return Function.prototype.toString.apply(toString); + } +} +``` + + diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/typeorm.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/typeorm.ts.snap index 53fd056a4aa..105671c1320 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/typeorm.ts.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators-ts/typeorm.ts.snap @@ -37,13 +37,35 @@ export class Board { ```diff --- Prettier +++ Rome -@@ -15,6 +15,6 @@ - @Column() - description: string; +@@ -1,20 +1,17 @@ + @Entity() + export class Board { +- @PrimaryGeneratedColumn() +- id: number; ++ @PrimaryGeneratedColumn() id: number; + +- @Column() +- slug: string; ++ @Column() slug: string; + +- @Column() +- name: string; ++ @Column() name: string; + +- @Column() +- theme: string; ++ @Column() theme: string; + +- @Column() +- description: string; ++ @Column() description: string; - @OneToMany((type) => Topic, (topic) => topic.board) -+ @OneToMany(type => Topic, topic => topic.board) - topics: Topic[]; +- topics: Topic[]; ++ @OneToMany( ++ (type) => Topic, ++ (topic) => topic.board, ++ ) topics: Topic[]; } ``` @@ -52,23 +74,20 @@ export class Board { ```ts @Entity() export class Board { - @PrimaryGeneratedColumn() - id: number; + @PrimaryGeneratedColumn() id: number; - @Column() - slug: string; + @Column() slug: string; - @Column() - name: string; + @Column() name: string; - @Column() - theme: string; + @Column() theme: string; - @Column() - description: string; + @Column() description: string; - @OneToMany(type => Topic, topic => topic.board) - topics: Topic[]; + @OneToMany( + (type) => Topic, + (topic) => topic.board, + ) topics: Topic[]; } ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators/decorators-comments.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators/decorators-comments.ts.snap index 7beb6c6d6c5..20840a8e540 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators/decorators-comments.ts.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators/decorators-comments.ts.snap @@ -1,6 +1,5 @@ --- source: crates/rome_formatter_test/src/snapshot_builder.rs -assertion_line: 212 info: typescript/decorators/decorators-comments.ts --- @@ -58,7 +57,44 @@ class Something3 { ```diff --- Prettier +++ Rome -@@ -30,12 +30,12 @@ +@@ -1,41 +1,36 @@ + class Foo1 { +- @foo +- // comment +- async method() {} ++ @foo async // comment ++ method() {} + } + + class Foo2 { +- @foo +- // comment ++ @foo // comment + private method() {} + } + + class Foo3 { +- @foo +- // comment +- *method() {} ++ @foo *// comment ++ method() {} + } + + class Foo4 { +- @foo +- // comment +- async *method() {} ++ @foo async *// comment ++ method() {} + } + + class Something { +- @foo() +- // comment ++ @foo() // comment + readonly property: Array; + } class Something2 { @foo() @@ -81,32 +117,27 @@ class Something3 { ```ts class Foo1 { - @foo - // comment - async method() {} + @foo async // comment + method() {} } class Foo2 { - @foo - // comment + @foo // comment private method() {} } class Foo3 { - @foo - // comment - *method() {} + @foo *// comment + method() {} } class Foo4 { - @foo - // comment - async *method() {} + @foo async *// comment + method() {} } class Something { - @foo() - // comment + @foo() // comment readonly property: Array; } @@ -147,6 +178,18 @@ decorators-comments.ts:41:5 parse ━━━━━━━━━━━━━━━ 42 │ } 43 │ +decorators-comments.ts:39:5 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 38 │ class Something3 { + > 39 │ @foo() + │ ^^^^^^ + 40 │ // comment + 41 │ abstract method(): Array + + i Decorators are only valid on class declarations, class expressions, and class methods. + ``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators/inline-decorators.ts.snap b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators/inline-decorators.ts.snap index c889770701e..2adab07208a 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators/inline-decorators.ts.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/typescript/decorators/inline-decorators.ts.snap @@ -64,20 +64,32 @@ class MyContainerComponent { ```diff --- Prettier +++ Rome -@@ -6,9 +6,9 @@ +@@ -5,20 +5,13 @@ + class Class1 {} class Class2 { - @d1 +- @d1 - @d2(foo) - @d3.bar - @d4.baz() -+ @d2(foo) -+ @d3.bar -+ @d4.baz() - method1() {} +- method1() {} ++ @d1 @d2(foo) @d3.bar @d4.baz() method1() {} - @d1 -@@ -30,11 +30,10 @@ +- @d1 +- method2() {} ++ @d1 method2() {} + +- @d2(foo) +- method3() {} ++ @d2(foo) method3() {} + +- @d3.bar +- method4() {} ++ @d3.bar method4() {} + } + + class Class3 { +@@ -30,11 +23,10 @@ constructor( @d1 private x: number, @d2(foo) private y: number, @@ -92,13 +104,15 @@ class MyContainerComponent { ) {} } -@@ -46,6 +45,5 @@ +@@ -46,6 +38,7 @@ } class MyContainerComponent { - @ContentChildren(MyComponent) - components: QueryListSomeBigName; -+ @ContentChildren(MyComponent) components: QueryListSomeBigName; ++ @ContentChildren( ++ MyComponent, ++ ) components: QueryListSomeBigName; } ``` @@ -112,20 +126,13 @@ class MyContainerComponent { class Class1 {} class Class2 { - @d1 - @d2(foo) - @d3.bar - @d4.baz() - method1() {} + @d1 @d2(foo) @d3.bar @d4.baz() method1() {} - @d1 - method2() {} + @d1 method2() {} - @d2(foo) - method3() {} + @d2(foo) method3() {} - @d3.bar - method4() {} + @d3.bar method4() {} } class Class3 { @@ -152,13 +159,10 @@ class Bar { } class MyContainerComponent { - @ContentChildren(MyComponent) components: QueryListSomeBigName; + @ContentChildren( + MyComponent, + ) components: QueryListSomeBigName; } ``` -# Lines exceeding max width of 80 characters -``` - 48: @ContentChildren(MyComponent) components: QueryListSomeBigName; -``` - diff --git a/crates/rome_js_formatter/tests/specs/ts/decoartors.ts.snap b/crates/rome_js_formatter/tests/specs/ts/decoartors.ts.snap index 2c6f2c6c815..6db5ce451da 100644 --- a/crates/rome_js_formatter/tests/specs/ts/decoartors.ts.snap +++ b/crates/rome_js_formatter/tests/specs/ts/decoartors.ts.snap @@ -74,8 +74,7 @@ Semicolons: Always ```ts @sealed class Test { - @readonly - prop: string; + @readonly prop: string; constructor( @param test, @@ -105,9 +104,7 @@ class Test2 { */ @test /* trailing multiline comment - for decorator */ @anotherDecorator() - - // leading comment + for decorator */ @anotherDecorator() // leading comment prop: string; } ``` @@ -116,11 +113,9 @@ class Test2 { ## Unimplemented nodes/tokens -"\t@readonl" => 21..30 -"\t\t@par" => 62..68 -"\t\t@readon" => 77..86 -"\t\t@aVeryLongDecoratorNameLetsSeeWhatHappensWith" => 104..151 -"@param" => 175..181 -"@param" => 219..225 -"\t@test /* trailing multiline comment\n\t for decorator */ @anotherDecorator(" => 449..523 +"\t\t@par" => 61..67 +"\t\t@readon" => 76..85 +"\t\t@aVeryLongDecoratorNameLetsSeeWhatHappensWith" => 103..150 +"@param" => 174..180 +"@param" => 218..224 diff --git a/crates/rome_js_parser/src/syntax/class.rs b/crates/rome_js_parser/src/syntax/class.rs index 7e8b891e361..052ce9e14b2 100644 --- a/crates/rome_js_parser/src/syntax/class.rs +++ b/crates/rome_js_parser/src/syntax/class.rs @@ -14,8 +14,9 @@ use crate::syntax::function::{ }; use crate::syntax::js_parse_error; use crate::syntax::js_parse_error::{ - expected_binding, expected_expression, invalid_decorator_error, modifier_already_seen, - modifier_cannot_be_used_with_modifier, modifier_must_precede_modifier, + decorator_must_precede_modifier, decorators_not_allowed, expected_binding, expected_expression, + invalid_decorator_error, modifier_already_seen, modifier_cannot_be_used_with_modifier, + modifier_must_precede_modifier, }; use crate::syntax::object::{ is_at_literal_member_name, parse_computed_member_name, parse_literal_member_name, @@ -136,17 +137,17 @@ pub(super) fn parse_class_expression( // @test method() {} // @test get getter() {} // @test set setter(a) {} -// @test constructor() {} -// @test declare prop; // } // test_err ts ts_invalid_decorated_class_members // abstract class Test { +// @test constructor() {} +// @test declare prop; // @test method(); // @test [index: string]: string; // @test abstract method2(); // @test abstract get getter(); -// @test abstract set setter(); +// @test abstract set setter(val); // } /// Parses a class declaration if it is valid and otherwise returns [Invalid]. @@ -519,7 +520,6 @@ fn parse_class_member(p: &mut JsParser, inside_abstract_class: bool) -> ParsedSy return Present(member_marker.complete(p, JS_EMPTY_CLASS_MEMBER)); } - skip_ts_decorators(p); let mut modifiers = parse_class_member_modifiers(p, false); if is_at_static_initialization_block_class_member(p) { @@ -1536,11 +1536,15 @@ fn parse_constructor_parameter_list(p: &mut JsParser) -> ParsedSyntax { // // SCRIPT // class A { constructor(readonly, private, protected, public) {} } fn parse_constructor_parameter(p: &mut JsParser, context: ExpressionContext) -> ParsedSyntax { - skip_ts_decorators(p); - // test_err class_constructor_parameter // class B { constructor(protected b) {} } + // test ts ts_decorator_constructor + // class C { + // constructor(@foo readonly x: number) {} + // } + skip_ts_decorators(p); + if is_nth_at_modifier(p, 0, true) { // test ts ts_property_parameter // class A { constructor(private x, protected y, public z) {} } @@ -1688,7 +1692,10 @@ fn parse_class_member_modifiers( // test_err class_member_modifier // class A { abstract foo; } fn parse_modifier(p: &mut JsParser, constructor_parameter: bool) -> Option { - if !is_nth_at_modifier(p, 0, constructor_parameter) { + // decorator modifiers can't be valid member names. + let is_at_decorator_modifier = p.cur() == T![@] || p.nth_at(1, T![@]); + + if !is_nth_at_modifier(p, 0, constructor_parameter) && !is_at_decorator_modifier { // all modifiers can also be valid member names. That's why we shouldn't parse a modifier // if it isn't followed by a valid member name or another modifier return None; @@ -1704,21 +1711,83 @@ fn parse_modifier(p: &mut JsParser, constructor_parameter: bool) -> Option ModifierKind::Accessor, T![readonly] => ModifierKind::Readonly, T![abstract] => ModifierKind::Abstract, + T![@] => ModifierKind::Decorator, _ => { return None; } }; - let m = p.start(); - let range = p.cur_range(); - p.bump_any(); - m.complete(p, modifier_kind.as_syntax_kind()); - - Some(ClassMemberModifier { - start: range.start(), - length: u32::from(range.len()) as u8, - kind: modifier_kind, - }) + match modifier_kind { + ModifierKind::Decorator => { + // test ts decorator_class_member + // class Foo { + // // properties + // @dec foo = 2; + // @dec @(await dec) @dec() foo = 2; + // @dec public foo = 1; + // @dec @(await dec) @dec() public foo = 1; + // @dec static foo = 2; + // @dec @(await dec) @dec() static foo = 2; + // @dec accessor foo = 2; + // @dec @(await dec) @dec() accessor foo = 2; + // @dec readonly foo = 2; + // @dec @(await dec) @dec() readonly foo = 2; + // @dec override foo = 2; + // @dec @(await dec) @dec() override foo = 2; + // // methods + // @dec foo() {} + // @dec @(await dec) @dec() foo() {} + // @dec public foo() {} + // @dec @(await dec) @dec() public foo() {} + // @dec static foo() {} + // @dec @(await dec) @dec() static foo() {} + // @dec override foo() {} + // @dec @(await dec) @dec() override foo() {} + // // getters + // @dec get foo() {} + // @dec @(await dec) @dec() get foo() {} + // @dec public get foo() {} + // @dec @(await dec) @dec() public get foo() {} + // @dec static get foo() {} + // @dec @(await dec) @dec() static get foo() {} + // @dec override get foo() {} + // @dec @(await dec) @dec() override get foo() {} + // // setters + // @dec set foo(val) {} + // @dec @(await dec) @dec() set foo(val) {} + // @dec public set foo(val) {} + // @dec @(await dec) @dec() public set foo(val) {} + // @dec static set foo(val) {} + // @dec @(await dec) @dec() static set foo(val) {} + // @dec override set foo(val) {} + // @dec @(await dec) @dec() override set foo(val) {} + // } + + // SAFETY: Success is guaranteed since the parser is at the @ token. + // The function takes care of handling any potential syntax errors. + let decorator = parse_decorator(p).unwrap(); + + let range = decorator.range(p); + + Some(ClassMemberModifier { + start: range.start(), + length: range.len(), + kind: modifier_kind, + }) + } + _ => { + let m = p.start(); + let range = p.cur_range(); + p.bump_any(); + m.complete(p, modifier_kind.as_syntax_kind()); + + Some(ClassMemberModifier { + start: range.start(), + length: range.len(), + kind: modifier_kind, + }) + } + } } bitflags! { @@ -1736,8 +1805,21 @@ bitflags! { const OVERRIDE = 1 << 7; const PRIVATE_NAME = 1 << 8; const ACCESSOR = 1 << 9; + const DECORATOR = 1 << 10; const ACCESSIBILITY = ModifierFlags::PRIVATE.bits | ModifierFlags::PROTECTED.bits | ModifierFlags::PUBLIC.bits; + + const ALL_MODIFIERS_EXCEPT_DECORATOR = ModifierFlags::DECLARE.bits + | ModifierFlags::PRIVATE.bits + | ModifierFlags::PROTECTED.bits + | ModifierFlags::PUBLIC.bits + | ModifierFlags::STATIC.bits + | ModifierFlags::READONLY.bits + | ModifierFlags::ABSTRACT.bits + | ModifierFlags::OVERRIDE.bits + | ModifierFlags::PRIVATE_NAME.bits + | ModifierFlags::ACCESSOR.bits; + } } @@ -1753,11 +1835,15 @@ enum ModifierKind { Accessor, Readonly, Override, + Decorator, } impl ModifierKind { const fn is_ts_modifier(&self) -> bool { - !matches!(self, ModifierKind::Static | ModifierKind::Accessor) + !matches!( + self, + ModifierKind::Static | ModifierKind::Accessor | ModifierKind::Decorator + ) } const fn as_syntax_kind(&self) -> JsSyntaxKind { @@ -1771,6 +1857,7 @@ impl ModifierKind { ModifierKind::Accessor => JS_ACCESSOR_MODIFIER, ModifierKind::Readonly => TS_READONLY_MODIFIER, ModifierKind::Override => TS_OVERRIDE_MODIFIER, + ModifierKind::Decorator => JS_DECORATOR, } } @@ -1785,6 +1872,7 @@ impl ModifierKind { ModifierKind::Accessor => ModifierFlags::ACCESSOR, ModifierKind::Readonly => ModifierFlags::READONLY, ModifierKind::Override => ModifierFlags::OVERRIDE, + ModifierKind::Decorator => ModifierFlags::DECORATOR, } } } @@ -1797,17 +1885,13 @@ struct ClassMemberModifier { // The start position of the modifier in the source text start: TextSize, - // The length of the modifier text. Storage optimization because none of the modifiers exceeds - // a length of 128 (even if encoded) - length: u8, + // The length of the modifier text. + length: TextSize, } impl ClassMemberModifier { fn as_text_range(&self) -> TextRange { - TextRange::new( - self.start, - self.start.add(TextSize::from(self.length as u32)), - ) + TextRange::new(self.start, self.start.add(self.length)) } } @@ -2064,18 +2148,57 @@ impl ClassMemberModifiers { // protected [a: number]: string; // } - // test_err ts ts_index_signature_class_member_cannot_be_abstract - // abstract class A { - // abstract [a: number]: string; - // } + if modifier.kind == ModifierKind::Decorator + && !matches!( + member_kind, + JS_PROPERTY_CLASS_MEMBER + | JS_METHOD_CLASS_MEMBER + | JS_GETTER_CLASS_MEMBER + | JS_SETTER_CLASS_MEMBER + | TS_PROPERTY_SIGNATURE_CLASS_MEMBER + | TS_INITIALIZED_PROPERTY_SIGNATURE_CLASS_MEMBER + ) + { + // test ts decorator_class_member_in_ts + // abstract class Qux { + // @dec declare static foo: string; + // } + // class Bar { + // @dec readonly foo = '123'; + // } - // test_err ts ts_index_signature_class_member_cannot_be_accessor - // abstract class A { - // accessor [a: number]: string; - // } - if member_kind == TS_INDEX_SIGNATURE_CLASS_MEMBER + // test_err ts decorator_class_member + // class Foo { + // @dec constructor() {} + // @dec [index: string]: { props: string } + // } + // class Quiz { + // @dec public constructor() {} + // } + // class Bar extends Foo { + // @dec + // constructor(); + // constructor(a: String) + // constructor(a?: String) {} + // } + // declare class Baz { + // @dec method(); + // @dec get foo(); + // @dec set foo(a); + // } + return Some(decorators_not_allowed(p, modifier.as_text_range())); + } else if member_kind == TS_INDEX_SIGNATURE_CLASS_MEMBER && !matches!(modifier.kind, ModifierKind::Static | ModifierKind::Readonly) { + // test_err ts ts_index_signature_class_member_cannot_be_abstract + // abstract class A { + // abstract [a: number]: string; + // } + + // test_err ts ts_index_signature_class_member_cannot_be_accessor + // abstract class A { + // accessor [a: number]: string; + // } return Some(p.err_builder( format!( "'{}' modifier cannot appear on an index signature.", @@ -2119,6 +2242,26 @@ impl ClassMemberModifiers { } match modifier.kind { + ModifierKind::Decorator => { + if preceding_modifiers.intersects(ModifierFlags::ALL_MODIFIERS_EXCEPT_DECORATOR) { + // test_err ts decorator_precede_class_member + // class Bar { + // public @dec get foo() {} + // static @dec foo: string; + // readonly @dec test() {} + // private @dec test() {} + // protected @dec test() {} + // } + // class Qux extends Bar { + // public @dec get foo() {} + // static @dec foo: string; + // readonly @dec test() {} + // private @dec test() {} + // accessor @dec test() {} + // } + return Some(decorator_must_precede_modifier(p, modifier.as_text_range())); + } + } ModifierKind::Readonly => { if preceding_modifiers.contains(ModifierFlags::READONLY) { return Some(modifier_already_seen( @@ -2436,6 +2579,12 @@ impl ClassMemberModifiers { // @dec class MyClass {} // } +// test ts ts_decorator_call_expression_with_arrow +// export class Foo { +// @Decorator((val) => val) +// badField!: number +// } + // test_err ts decorator // @'dsads' class MyClass {} // @1 class MyClass {} @@ -2514,11 +2663,6 @@ fn parse_decorator_bogus(p: &mut JsParser) -> ParsedSyntax { if p.at(T![@]) { let m = p.start(); p.bump(T![@]); - // test ts ts_decorator_call_expression_with_arrow - // export class Foo { - // @Decorator((val) => val) - // badField!: number - // } parse_lhs_expr(p, ExpressionContext::default().and_in_decorator(true)) .or_add_diagnostic(p, expected_expression); diff --git a/crates/rome_js_parser/src/syntax/function.rs b/crates/rome_js_parser/src/syntax/function.rs index 6f8cbb11096..30b9afaff93 100644 --- a/crates/rome_js_parser/src/syntax/function.rs +++ b/crates/rome_js_parser/src/syntax/function.rs @@ -1024,7 +1024,14 @@ pub(crate) fn parse_formal_parameter( parameter_context: ParameterContext, expression_context: ExpressionContext, ) -> ParsedSyntax { + // test ts ts_formal_parameter_decorator + // function a(@dec x) {} + // class Foo { + // constructor(@dec x) {} + // method(@dec x) {} + // } skip_ts_decorators(p); + parse_binding_pattern(p, expression_context).map(|binding| { let binding_kind = binding.kind(p); let binding_range = binding.range(p); diff --git a/crates/rome_js_parser/src/syntax/js_parse_error.rs b/crates/rome_js_parser/src/syntax/js_parse_error.rs index b2dd01ed654..0b6e9b96aec 100644 --- a/crates/rome_js_parser/src/syntax/js_parse_error.rs +++ b/crates/rome_js_parser/src/syntax/js_parse_error.rs @@ -288,3 +288,10 @@ pub(crate) fn decorators_not_allowed(p: &JsParser, range: TextRange) -> ParseDia "Decorators are only valid on class declarations, class expressions, and class methods.", ) } + +pub(crate) fn decorator_must_precede_modifier(p: &JsParser, range: TextRange) -> ParseDiagnostic { + p.err_builder( + "Decorators must precede the name and all keywords of property declarations.", + range, + ) +} diff --git a/crates/rome_js_parser/src/tests.rs b/crates/rome_js_parser/src/tests.rs index 0447f71bb69..a746974b507 100644 --- a/crates/rome_js_parser/src/tests.rs +++ b/crates/rome_js_parser/src/tests.rs @@ -393,15 +393,11 @@ fn diagnostics_print_correctly() { #[test] pub fn quick_test() { let code = r#" -[ - @(decorators[first]) - class { - method() {} - }, -] - - -"#; +class Foo { + @decorator declare a: number; + @decorator declare [b]: number; +} + "#; let root = parse(code, SourceType::ts()); let syntax = root.syntax(); diff --git a/crates/rome_js_parser/test_data/inline/err/decorator_class_member.rast b/crates/rome_js_parser/test_data/inline/err/decorator_class_member.rast new file mode 100644 index 00000000000..d3adcb9dcb9 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/decorator_class_member.rast @@ -0,0 +1,705 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@0..6 "class" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@6..10 "Foo" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@10..11 "{" [] [], + members: JsClassMemberList [ + JsBogusMember { + items: [ + JsBogus { + items: [ + JsDecorator { + at_token: AT@11..16 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@16..20 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + JsLiteralMemberName { + value: IDENT@20..31 "constructor" [] [], + }, + JsConstructorParameters { + l_paren_token: L_PAREN@31..32 "(" [] [], + parameters: JsConstructorParameterList [], + r_paren_token: R_PAREN@32..34 ")" [] [Whitespace(" ")], + }, + JsFunctionBody { + l_curly_token: L_CURLY@34..35 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@35..36 "}" [] [], + }, + ], + }, + JsBogusMember { + items: [ + JsBogus { + items: [ + JsDecorator { + at_token: AT@36..41 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@41..45 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + L_BRACK@45..46 "[" [] [], + TsIndexSignatureParameter { + binding: JsIdentifierBinding { + name_token: IDENT@46..51 "index" [] [], + }, + type_annotation: TsTypeAnnotation { + colon_token: COLON@51..53 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@53..59 "string" [] [], + }, + }, + }, + R_BRACK@59..60 "]" [] [], + TsTypeAnnotation { + colon_token: COLON@60..62 ":" [] [Whitespace(" ")], + ty: TsObjectType { + l_curly_token: L_CURLY@62..64 "{" [] [Whitespace(" ")], + members: TsTypeMemberList [ + TsPropertySignatureTypeMember { + readonly_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@64..69 "props" [] [], + }, + optional_token: missing (optional), + type_annotation: TsTypeAnnotation { + colon_token: COLON@69..71 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@71..78 "string" [] [Whitespace(" ")], + }, + }, + separator_token: missing (optional), + }, + ], + r_curly_token: R_CURLY@78..79 "}" [] [], + }, + }, + ], + }, + ], + r_curly_token: R_CURLY@79..81 "}" [Newline("\n")] [], + }, + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@81..88 "class" [Newline("\n")] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@88..93 "Quiz" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@93..94 "{" [] [], + members: JsClassMemberList [ + JsBogusMember { + items: [ + JsBogus { + items: [ + JsDecorator { + at_token: AT@94..99 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@99..103 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@103..110 "public" [] [Whitespace(" ")], + }, + ], + }, + JsLiteralMemberName { + value: IDENT@110..121 "constructor" [] [], + }, + JsConstructorParameters { + l_paren_token: L_PAREN@121..122 "(" [] [], + parameters: JsConstructorParameterList [], + r_paren_token: R_PAREN@122..124 ")" [] [Whitespace(" ")], + }, + JsFunctionBody { + l_curly_token: L_CURLY@124..125 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@125..126 "}" [] [], + }, + ], + }, + ], + r_curly_token: R_CURLY@126..128 "}" [Newline("\n")] [], + }, + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@128..135 "class" [Newline("\n")] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@135..139 "Bar" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: JsExtendsClause { + extends_token: EXTENDS_KW@139..147 "extends" [] [Whitespace(" ")], + super_class: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@147..151 "Foo" [] [Whitespace(" ")], + }, + }, + type_arguments: missing (optional), + }, + implements_clause: missing (optional), + l_curly_token: L_CURLY@151..152 "{" [] [], + members: JsClassMemberList [ + JsBogusMember { + items: [ + JsBogus { + items: [ + JsDecorator { + at_token: AT@152..157 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@157..160 "dec" [] [], + }, + }, + }, + ], + }, + JsLiteralMemberName { + value: IDENT@160..175 "constructor" [Newline("\n"), Whitespace(" ")] [], + }, + JsConstructorParameters { + l_paren_token: L_PAREN@175..176 "(" [] [], + parameters: JsConstructorParameterList [], + r_paren_token: R_PAREN@176..177 ")" [] [], + }, + SEMICOLON@177..178 ";" [] [], + ], + }, + TsConstructorSignatureClassMember { + modifiers: JsConstructorModifierList [], + name: JsLiteralMemberName { + value: IDENT@178..193 "constructor" [Newline("\n"), Whitespace(" ")] [], + }, + parameters: JsConstructorParameters { + l_paren_token: L_PAREN@193..194 "(" [] [], + parameters: JsConstructorParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@194..195 "a" [] [], + }, + question_mark_token: missing (optional), + type_annotation: TsTypeAnnotation { + colon_token: COLON@195..197 ":" [] [Whitespace(" ")], + ty: TsReferenceType { + name: JsReferenceIdentifier { + value_token: IDENT@197..203 "String" [] [], + }, + type_arguments: missing (optional), + }, + }, + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@203..204 ")" [] [], + }, + semicolon_token: missing (optional), + }, + JsConstructorClassMember { + modifiers: JsConstructorModifierList [], + name: JsLiteralMemberName { + value: IDENT@204..219 "constructor" [Newline("\n"), Whitespace(" ")] [], + }, + parameters: JsConstructorParameters { + l_paren_token: L_PAREN@219..220 "(" [] [], + parameters: JsConstructorParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@220..221 "a" [] [], + }, + question_mark_token: QUESTION@221..222 "?" [] [], + type_annotation: TsTypeAnnotation { + colon_token: COLON@222..224 ":" [] [Whitespace(" ")], + ty: TsReferenceType { + name: JsReferenceIdentifier { + value_token: IDENT@224..230 "String" [] [], + }, + type_arguments: missing (optional), + }, + }, + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@230..232 ")" [] [Whitespace(" ")], + }, + body: JsFunctionBody { + l_curly_token: L_CURLY@232..233 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@233..234 "}" [] [], + }, + }, + ], + r_curly_token: R_CURLY@234..236 "}" [Newline("\n")] [], + }, + TsDeclareStatement { + declare_token: DECLARE_KW@236..245 "declare" [Newline("\n")] [Whitespace(" ")], + declaration: JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@245..251 "class" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@251..255 "Baz" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@255..256 "{" [] [], + members: JsClassMemberList [ + JsBogusMember { + items: [ + TsMethodSignatureModifierList [ + JsDecorator { + at_token: AT@256..260 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@260..264 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + JsLiteralMemberName { + value: IDENT@264..270 "method" [] [], + }, + JsParameters { + l_paren_token: L_PAREN@270..271 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@271..272 ")" [] [], + }, + SEMICOLON@272..273 ";" [] [], + ], + }, + JsBogusMember { + items: [ + TsMethodSignatureModifierList [ + JsDecorator { + at_token: AT@273..277 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@277..281 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + GET_KW@281..285 "get" [] [Whitespace(" ")], + JsLiteralMemberName { + value: IDENT@285..288 "foo" [] [], + }, + L_PAREN@288..289 "(" [] [], + R_PAREN@289..290 ")" [] [], + SEMICOLON@290..291 ";" [] [], + ], + }, + JsBogusMember { + items: [ + TsMethodSignatureModifierList [ + JsDecorator { + at_token: AT@291..295 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@295..299 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + SET_KW@299..303 "set" [] [Whitespace(" ")], + JsLiteralMemberName { + value: IDENT@303..306 "foo" [] [], + }, + L_PAREN@306..307 "(" [] [], + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@307..308 "a" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + R_PAREN@308..309 ")" [] [], + SEMICOLON@309..310 ";" [] [], + ], + }, + ], + r_curly_token: R_CURLY@310..312 "}" [Newline("\n")] [], + }, + }, + ], + eof_token: EOF@312..313 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..313 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..312 + 0: JS_CLASS_DECLARATION@0..81 + 0: JS_DECORATOR_LIST@0..0 + 1: (empty) + 2: CLASS_KW@0..6 "class" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@6..10 + 0: IDENT@6..10 "Foo" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@10..11 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@11..79 + 0: JS_BOGUS_MEMBER@11..36 + 0: JS_BOGUS@11..20 + 0: JS_DECORATOR@11..20 + 0: AT@11..16 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@16..20 + 0: JS_REFERENCE_IDENTIFIER@16..20 + 0: IDENT@16..20 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@20..31 + 0: IDENT@20..31 "constructor" [] [] + 2: JS_CONSTRUCTOR_PARAMETERS@31..34 + 0: L_PAREN@31..32 "(" [] [] + 1: JS_CONSTRUCTOR_PARAMETER_LIST@32..32 + 2: R_PAREN@32..34 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@34..36 + 0: L_CURLY@34..35 "{" [] [] + 1: JS_DIRECTIVE_LIST@35..35 + 2: JS_STATEMENT_LIST@35..35 + 3: R_CURLY@35..36 "}" [] [] + 1: JS_BOGUS_MEMBER@36..79 + 0: JS_BOGUS@36..45 + 0: JS_DECORATOR@36..45 + 0: AT@36..41 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@41..45 + 0: JS_REFERENCE_IDENTIFIER@41..45 + 0: IDENT@41..45 "dec" [] [Whitespace(" ")] + 1: L_BRACK@45..46 "[" [] [] + 2: TS_INDEX_SIGNATURE_PARAMETER@46..59 + 0: JS_IDENTIFIER_BINDING@46..51 + 0: IDENT@46..51 "index" [] [] + 1: TS_TYPE_ANNOTATION@51..59 + 0: COLON@51..53 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@53..59 + 0: STRING_KW@53..59 "string" [] [] + 3: R_BRACK@59..60 "]" [] [] + 4: TS_TYPE_ANNOTATION@60..79 + 0: COLON@60..62 ":" [] [Whitespace(" ")] + 1: TS_OBJECT_TYPE@62..79 + 0: L_CURLY@62..64 "{" [] [Whitespace(" ")] + 1: TS_TYPE_MEMBER_LIST@64..78 + 0: TS_PROPERTY_SIGNATURE_TYPE_MEMBER@64..78 + 0: (empty) + 1: JS_LITERAL_MEMBER_NAME@64..69 + 0: IDENT@64..69 "props" [] [] + 2: (empty) + 3: TS_TYPE_ANNOTATION@69..78 + 0: COLON@69..71 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@71..78 + 0: STRING_KW@71..78 "string" [] [Whitespace(" ")] + 4: (empty) + 2: R_CURLY@78..79 "}" [] [] + 9: R_CURLY@79..81 "}" [Newline("\n")] [] + 1: JS_CLASS_DECLARATION@81..128 + 0: JS_DECORATOR_LIST@81..81 + 1: (empty) + 2: CLASS_KW@81..88 "class" [Newline("\n")] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@88..93 + 0: IDENT@88..93 "Quiz" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@93..94 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@94..126 + 0: JS_BOGUS_MEMBER@94..126 + 0: JS_BOGUS@94..110 + 0: JS_DECORATOR@94..103 + 0: AT@94..99 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@99..103 + 0: JS_REFERENCE_IDENTIFIER@99..103 + 0: IDENT@99..103 "dec" [] [Whitespace(" ")] + 1: TS_ACCESSIBILITY_MODIFIER@103..110 + 0: PUBLIC_KW@103..110 "public" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@110..121 + 0: IDENT@110..121 "constructor" [] [] + 2: JS_CONSTRUCTOR_PARAMETERS@121..124 + 0: L_PAREN@121..122 "(" [] [] + 1: JS_CONSTRUCTOR_PARAMETER_LIST@122..122 + 2: R_PAREN@122..124 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@124..126 + 0: L_CURLY@124..125 "{" [] [] + 1: JS_DIRECTIVE_LIST@125..125 + 2: JS_STATEMENT_LIST@125..125 + 3: R_CURLY@125..126 "}" [] [] + 9: R_CURLY@126..128 "}" [Newline("\n")] [] + 2: JS_CLASS_DECLARATION@128..236 + 0: JS_DECORATOR_LIST@128..128 + 1: (empty) + 2: CLASS_KW@128..135 "class" [Newline("\n")] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@135..139 + 0: IDENT@135..139 "Bar" [] [Whitespace(" ")] + 4: (empty) + 5: JS_EXTENDS_CLAUSE@139..151 + 0: EXTENDS_KW@139..147 "extends" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@147..151 + 0: JS_REFERENCE_IDENTIFIER@147..151 + 0: IDENT@147..151 "Foo" [] [Whitespace(" ")] + 2: (empty) + 6: (empty) + 7: L_CURLY@151..152 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@152..234 + 0: JS_BOGUS_MEMBER@152..178 + 0: JS_BOGUS@152..160 + 0: JS_DECORATOR@152..160 + 0: AT@152..157 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@157..160 + 0: JS_REFERENCE_IDENTIFIER@157..160 + 0: IDENT@157..160 "dec" [] [] + 1: JS_LITERAL_MEMBER_NAME@160..175 + 0: IDENT@160..175 "constructor" [Newline("\n"), Whitespace(" ")] [] + 2: JS_CONSTRUCTOR_PARAMETERS@175..177 + 0: L_PAREN@175..176 "(" [] [] + 1: JS_CONSTRUCTOR_PARAMETER_LIST@176..176 + 2: R_PAREN@176..177 ")" [] [] + 3: SEMICOLON@177..178 ";" [] [] + 1: TS_CONSTRUCTOR_SIGNATURE_CLASS_MEMBER@178..204 + 0: JS_CONSTRUCTOR_MODIFIER_LIST@178..178 + 1: JS_LITERAL_MEMBER_NAME@178..193 + 0: IDENT@178..193 "constructor" [Newline("\n"), Whitespace(" ")] [] + 2: JS_CONSTRUCTOR_PARAMETERS@193..204 + 0: L_PAREN@193..194 "(" [] [] + 1: JS_CONSTRUCTOR_PARAMETER_LIST@194..203 + 0: JS_FORMAL_PARAMETER@194..203 + 0: JS_IDENTIFIER_BINDING@194..195 + 0: IDENT@194..195 "a" [] [] + 1: (empty) + 2: TS_TYPE_ANNOTATION@195..203 + 0: COLON@195..197 ":" [] [Whitespace(" ")] + 1: TS_REFERENCE_TYPE@197..203 + 0: JS_REFERENCE_IDENTIFIER@197..203 + 0: IDENT@197..203 "String" [] [] + 1: (empty) + 3: (empty) + 2: R_PAREN@203..204 ")" [] [] + 3: (empty) + 2: JS_CONSTRUCTOR_CLASS_MEMBER@204..234 + 0: JS_CONSTRUCTOR_MODIFIER_LIST@204..204 + 1: JS_LITERAL_MEMBER_NAME@204..219 + 0: IDENT@204..219 "constructor" [Newline("\n"), Whitespace(" ")] [] + 2: JS_CONSTRUCTOR_PARAMETERS@219..232 + 0: L_PAREN@219..220 "(" [] [] + 1: JS_CONSTRUCTOR_PARAMETER_LIST@220..230 + 0: JS_FORMAL_PARAMETER@220..230 + 0: JS_IDENTIFIER_BINDING@220..221 + 0: IDENT@220..221 "a" [] [] + 1: QUESTION@221..222 "?" [] [] + 2: TS_TYPE_ANNOTATION@222..230 + 0: COLON@222..224 ":" [] [Whitespace(" ")] + 1: TS_REFERENCE_TYPE@224..230 + 0: JS_REFERENCE_IDENTIFIER@224..230 + 0: IDENT@224..230 "String" [] [] + 1: (empty) + 3: (empty) + 2: R_PAREN@230..232 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@232..234 + 0: L_CURLY@232..233 "{" [] [] + 1: JS_DIRECTIVE_LIST@233..233 + 2: JS_STATEMENT_LIST@233..233 + 3: R_CURLY@233..234 "}" [] [] + 9: R_CURLY@234..236 "}" [Newline("\n")] [] + 3: TS_DECLARE_STATEMENT@236..312 + 0: DECLARE_KW@236..245 "declare" [Newline("\n")] [Whitespace(" ")] + 1: JS_CLASS_DECLARATION@245..312 + 0: JS_DECORATOR_LIST@245..245 + 1: (empty) + 2: CLASS_KW@245..251 "class" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@251..255 + 0: IDENT@251..255 "Baz" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@255..256 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@256..310 + 0: JS_BOGUS_MEMBER@256..273 + 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@256..264 + 0: JS_DECORATOR@256..264 + 0: AT@256..260 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@260..264 + 0: JS_REFERENCE_IDENTIFIER@260..264 + 0: IDENT@260..264 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@264..270 + 0: IDENT@264..270 "method" [] [] + 2: JS_PARAMETERS@270..272 + 0: L_PAREN@270..271 "(" [] [] + 1: JS_PARAMETER_LIST@271..271 + 2: R_PAREN@271..272 ")" [] [] + 3: SEMICOLON@272..273 ";" [] [] + 1: JS_BOGUS_MEMBER@273..291 + 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@273..281 + 0: JS_DECORATOR@273..281 + 0: AT@273..277 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@277..281 + 0: JS_REFERENCE_IDENTIFIER@277..281 + 0: IDENT@277..281 "dec" [] [Whitespace(" ")] + 1: GET_KW@281..285 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@285..288 + 0: IDENT@285..288 "foo" [] [] + 3: L_PAREN@288..289 "(" [] [] + 4: R_PAREN@289..290 ")" [] [] + 5: SEMICOLON@290..291 ";" [] [] + 2: JS_BOGUS_MEMBER@291..310 + 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@291..299 + 0: JS_DECORATOR@291..299 + 0: AT@291..295 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@295..299 + 0: JS_REFERENCE_IDENTIFIER@295..299 + 0: IDENT@295..299 "dec" [] [Whitespace(" ")] + 1: SET_KW@299..303 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@303..306 + 0: IDENT@303..306 "foo" [] [] + 3: L_PAREN@306..307 "(" [] [] + 4: JS_FORMAL_PARAMETER@307..308 + 0: JS_IDENTIFIER_BINDING@307..308 + 0: IDENT@307..308 "a" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@308..309 ")" [] [] + 6: SEMICOLON@309..310 ";" [] [] + 9: R_CURLY@310..312 "}" [Newline("\n")] [] + 3: EOF@312..313 "" [Newline("\n")] [] +-- +decorator_class_member.ts:2:4 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 1 │ class Foo { + > 2 │ @dec constructor() {} + │ ^^^^ + 3 │ @dec [index: string]: { props: string } + 4 │ } + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +decorator_class_member.ts:3:4 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 1 │ class Foo { + 2 │ @dec constructor() {} + > 3 │ @dec [index: string]: { props: string } + │ ^^^^ + 4 │ } + 5 │ class Quiz { + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +decorator_class_member.ts:6:4 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 4 │ } + 5 │ class Quiz { + > 6 │ @dec public constructor() {} + │ ^^^^ + 7 │ } + 8 │ class Bar extends Foo { + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +decorator_class_member.ts:9:4 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 7 │ } + 8 │ class Bar extends Foo { + > 9 │ @dec + │ ^^^^ + 10 │ constructor(); + 11 │ constructor(a: String) + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +decorator_class_member.ts:15:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 13 │ } + 14 │ declare class Baz { + > 15 │ @dec method(); + │ ^^^^ + 16 │ @dec get foo(); + 17 │ @dec set foo(a); + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +decorator_class_member.ts:16:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 14 │ declare class Baz { + 15 │ @dec method(); + > 16 │ @dec get foo(); + │ ^^^^ + 17 │ @dec set foo(a); + 18 │ } + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +decorator_class_member.ts:17:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 15 │ @dec method(); + 16 │ @dec get foo(); + > 17 │ @dec set foo(a); + │ ^^^^ + 18 │ } + 19 │ + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +class Foo { + @dec constructor() {} + @dec [index: string]: { props: string } +} +class Quiz { + @dec public constructor() {} +} +class Bar extends Foo { + @dec + constructor(); + constructor(a: String) + constructor(a?: String) {} +} +declare class Baz { + @dec method(); + @dec get foo(); + @dec set foo(a); +} diff --git a/crates/rome_js_parser/test_data/inline/err/decorator_class_member.ts b/crates/rome_js_parser/test_data/inline/err/decorator_class_member.ts new file mode 100644 index 00000000000..3992060aa08 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/decorator_class_member.ts @@ -0,0 +1,18 @@ +class Foo { + @dec constructor() {} + @dec [index: string]: { props: string } +} +class Quiz { + @dec public constructor() {} +} +class Bar extends Foo { + @dec + constructor(); + constructor(a: String) + constructor(a?: String) {} +} +declare class Baz { + @dec method(); + @dec get foo(); + @dec set foo(a); +} diff --git a/crates/rome_js_parser/test_data/inline/err/decorator_precede_class_member.rast b/crates/rome_js_parser/test_data/inline/err/decorator_precede_class_member.rast new file mode 100644 index 00000000000..44587a49bda --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/decorator_precede_class_member.rast @@ -0,0 +1,744 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@0..6 "class" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@6..10 "Bar" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@10..11 "{" [] [], + members: JsClassMemberList [ + JsBogusMember { + items: [ + JsMethodModifierList [ + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@11..21 "public" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@21..22 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@22..26 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + GET_KW@26..30 "get" [] [Whitespace(" ")], + JsLiteralMemberName { + value: IDENT@30..33 "foo" [] [], + }, + L_PAREN@33..34 "(" [] [], + R_PAREN@34..36 ")" [] [Whitespace(" ")], + JsFunctionBody { + l_curly_token: L_CURLY@36..37 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@37..38 "}" [] [], + }, + ], + }, + JsBogusMember { + items: [ + JsPropertyModifierList [ + JsStaticModifier { + modifier_token: STATIC_KW@38..48 "static" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@48..49 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@49..53 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + JsLiteralMemberName { + value: IDENT@53..56 "foo" [] [], + }, + TsTypeAnnotation { + colon_token: COLON@56..58 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@58..64 "string" [] [], + }, + }, + SEMICOLON@64..65 ";" [] [], + ], + }, + JsBogusMember { + items: [ + JsBogus { + items: [ + TsReadonlyModifier { + modifier_token: READONLY_KW@65..77 "readonly" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@77..78 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@78..82 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + JsLiteralMemberName { + value: IDENT@82..86 "test" [] [], + }, + JsParameters { + l_paren_token: L_PAREN@86..87 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@87..89 ")" [] [Whitespace(" ")], + }, + JsFunctionBody { + l_curly_token: L_CURLY@89..90 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@90..91 "}" [] [], + }, + ], + }, + JsBogusMember { + items: [ + JsMethodModifierList [ + TsAccessibilityModifier { + modifier_token: PRIVATE_KW@91..102 "private" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@102..103 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@103..107 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + JsLiteralMemberName { + value: IDENT@107..111 "test" [] [], + }, + JsParameters { + l_paren_token: L_PAREN@111..112 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@112..114 ")" [] [Whitespace(" ")], + }, + JsFunctionBody { + l_curly_token: L_CURLY@114..115 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@115..116 "}" [] [], + }, + ], + }, + JsBogusMember { + items: [ + JsMethodModifierList [ + TsAccessibilityModifier { + modifier_token: PROTECTED_KW@116..129 "protected" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@129..130 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@130..134 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + JsLiteralMemberName { + value: IDENT@134..138 "test" [] [], + }, + JsParameters { + l_paren_token: L_PAREN@138..139 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@139..141 ")" [] [Whitespace(" ")], + }, + JsFunctionBody { + l_curly_token: L_CURLY@141..142 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@142..143 "}" [] [], + }, + ], + }, + ], + r_curly_token: R_CURLY@143..145 "}" [Newline("\n")] [], + }, + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@145..152 "class" [Newline("\n")] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@152..156 "Qux" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: JsExtendsClause { + extends_token: EXTENDS_KW@156..164 "extends" [] [Whitespace(" ")], + super_class: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@164..168 "Bar" [] [Whitespace(" ")], + }, + }, + type_arguments: missing (optional), + }, + implements_clause: missing (optional), + l_curly_token: L_CURLY@168..169 "{" [] [], + members: JsClassMemberList [ + JsBogusMember { + items: [ + JsMethodModifierList [ + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@169..179 "public" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@179..180 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@180..184 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + GET_KW@184..188 "get" [] [Whitespace(" ")], + JsLiteralMemberName { + value: IDENT@188..191 "foo" [] [], + }, + L_PAREN@191..192 "(" [] [], + R_PAREN@192..194 ")" [] [Whitespace(" ")], + JsFunctionBody { + l_curly_token: L_CURLY@194..195 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@195..196 "}" [] [], + }, + ], + }, + JsBogusMember { + items: [ + JsPropertyModifierList [ + JsStaticModifier { + modifier_token: STATIC_KW@196..206 "static" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@206..207 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@207..211 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + JsLiteralMemberName { + value: IDENT@211..214 "foo" [] [], + }, + TsTypeAnnotation { + colon_token: COLON@214..216 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@216..222 "string" [] [], + }, + }, + SEMICOLON@222..223 ";" [] [], + ], + }, + JsBogusMember { + items: [ + JsBogus { + items: [ + TsReadonlyModifier { + modifier_token: READONLY_KW@223..235 "readonly" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@235..236 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@236..240 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + JsLiteralMemberName { + value: IDENT@240..244 "test" [] [], + }, + JsParameters { + l_paren_token: L_PAREN@244..245 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@245..247 ")" [] [Whitespace(" ")], + }, + JsFunctionBody { + l_curly_token: L_CURLY@247..248 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@248..249 "}" [] [], + }, + ], + }, + JsBogusMember { + items: [ + JsMethodModifierList [ + TsAccessibilityModifier { + modifier_token: PRIVATE_KW@249..260 "private" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@260..261 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@261..265 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + JsLiteralMemberName { + value: IDENT@265..269 "test" [] [], + }, + JsParameters { + l_paren_token: L_PAREN@269..270 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@270..272 ")" [] [Whitespace(" ")], + }, + JsFunctionBody { + l_curly_token: L_CURLY@272..273 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@273..274 "}" [] [], + }, + ], + }, + JsBogusMember { + items: [ + JsBogus { + items: [ + JsAccessorModifier { + modifier_token: ACCESSOR_KW@274..286 "accessor" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")], + }, + JsDecorator { + at_token: AT@286..287 "@" [] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@287..291 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + JsLiteralMemberName { + value: IDENT@291..295 "test" [] [], + }, + JsParameters { + l_paren_token: L_PAREN@295..296 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@296..298 ")" [] [Whitespace(" ")], + }, + JsFunctionBody { + l_curly_token: L_CURLY@298..299 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@299..300 "}" [] [], + }, + ], + }, + ], + r_curly_token: R_CURLY@300..302 "}" [Newline("\n")] [], + }, + ], + eof_token: EOF@302..303 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..303 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..302 + 0: JS_CLASS_DECLARATION@0..145 + 0: JS_DECORATOR_LIST@0..0 + 1: (empty) + 2: CLASS_KW@0..6 "class" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@6..10 + 0: IDENT@6..10 "Bar" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@10..11 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@11..143 + 0: JS_BOGUS_MEMBER@11..38 + 0: JS_METHOD_MODIFIER_LIST@11..26 + 0: TS_ACCESSIBILITY_MODIFIER@11..21 + 0: PUBLIC_KW@11..21 "public" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@21..26 + 0: AT@21..22 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@22..26 + 0: JS_REFERENCE_IDENTIFIER@22..26 + 0: IDENT@22..26 "dec" [] [Whitespace(" ")] + 1: GET_KW@26..30 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@30..33 + 0: IDENT@30..33 "foo" [] [] + 3: L_PAREN@33..34 "(" [] [] + 4: R_PAREN@34..36 ")" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@36..38 + 0: L_CURLY@36..37 "{" [] [] + 1: JS_DIRECTIVE_LIST@37..37 + 2: JS_STATEMENT_LIST@37..37 + 3: R_CURLY@37..38 "}" [] [] + 1: JS_BOGUS_MEMBER@38..65 + 0: JS_PROPERTY_MODIFIER_LIST@38..53 + 0: JS_STATIC_MODIFIER@38..48 + 0: STATIC_KW@38..48 "static" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@48..53 + 0: AT@48..49 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@49..53 + 0: JS_REFERENCE_IDENTIFIER@49..53 + 0: IDENT@49..53 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@53..56 + 0: IDENT@53..56 "foo" [] [] + 2: TS_TYPE_ANNOTATION@56..64 + 0: COLON@56..58 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@58..64 + 0: STRING_KW@58..64 "string" [] [] + 3: SEMICOLON@64..65 ";" [] [] + 2: JS_BOGUS_MEMBER@65..91 + 0: JS_BOGUS@65..82 + 0: TS_READONLY_MODIFIER@65..77 + 0: READONLY_KW@65..77 "readonly" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@77..82 + 0: AT@77..78 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@78..82 + 0: JS_REFERENCE_IDENTIFIER@78..82 + 0: IDENT@78..82 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@82..86 + 0: IDENT@82..86 "test" [] [] + 2: JS_PARAMETERS@86..89 + 0: L_PAREN@86..87 "(" [] [] + 1: JS_PARAMETER_LIST@87..87 + 2: R_PAREN@87..89 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@89..91 + 0: L_CURLY@89..90 "{" [] [] + 1: JS_DIRECTIVE_LIST@90..90 + 2: JS_STATEMENT_LIST@90..90 + 3: R_CURLY@90..91 "}" [] [] + 3: JS_BOGUS_MEMBER@91..116 + 0: JS_METHOD_MODIFIER_LIST@91..107 + 0: TS_ACCESSIBILITY_MODIFIER@91..102 + 0: PRIVATE_KW@91..102 "private" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@102..107 + 0: AT@102..103 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@103..107 + 0: JS_REFERENCE_IDENTIFIER@103..107 + 0: IDENT@103..107 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@107..111 + 0: IDENT@107..111 "test" [] [] + 2: JS_PARAMETERS@111..114 + 0: L_PAREN@111..112 "(" [] [] + 1: JS_PARAMETER_LIST@112..112 + 2: R_PAREN@112..114 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@114..116 + 0: L_CURLY@114..115 "{" [] [] + 1: JS_DIRECTIVE_LIST@115..115 + 2: JS_STATEMENT_LIST@115..115 + 3: R_CURLY@115..116 "}" [] [] + 4: JS_BOGUS_MEMBER@116..143 + 0: JS_METHOD_MODIFIER_LIST@116..134 + 0: TS_ACCESSIBILITY_MODIFIER@116..129 + 0: PROTECTED_KW@116..129 "protected" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@129..134 + 0: AT@129..130 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@130..134 + 0: JS_REFERENCE_IDENTIFIER@130..134 + 0: IDENT@130..134 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@134..138 + 0: IDENT@134..138 "test" [] [] + 2: JS_PARAMETERS@138..141 + 0: L_PAREN@138..139 "(" [] [] + 1: JS_PARAMETER_LIST@139..139 + 2: R_PAREN@139..141 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@141..143 + 0: L_CURLY@141..142 "{" [] [] + 1: JS_DIRECTIVE_LIST@142..142 + 2: JS_STATEMENT_LIST@142..142 + 3: R_CURLY@142..143 "}" [] [] + 9: R_CURLY@143..145 "}" [Newline("\n")] [] + 1: JS_CLASS_DECLARATION@145..302 + 0: JS_DECORATOR_LIST@145..145 + 1: (empty) + 2: CLASS_KW@145..152 "class" [Newline("\n")] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@152..156 + 0: IDENT@152..156 "Qux" [] [Whitespace(" ")] + 4: (empty) + 5: JS_EXTENDS_CLAUSE@156..168 + 0: EXTENDS_KW@156..164 "extends" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@164..168 + 0: JS_REFERENCE_IDENTIFIER@164..168 + 0: IDENT@164..168 "Bar" [] [Whitespace(" ")] + 2: (empty) + 6: (empty) + 7: L_CURLY@168..169 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@169..300 + 0: JS_BOGUS_MEMBER@169..196 + 0: JS_METHOD_MODIFIER_LIST@169..184 + 0: TS_ACCESSIBILITY_MODIFIER@169..179 + 0: PUBLIC_KW@169..179 "public" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@179..184 + 0: AT@179..180 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@180..184 + 0: JS_REFERENCE_IDENTIFIER@180..184 + 0: IDENT@180..184 "dec" [] [Whitespace(" ")] + 1: GET_KW@184..188 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@188..191 + 0: IDENT@188..191 "foo" [] [] + 3: L_PAREN@191..192 "(" [] [] + 4: R_PAREN@192..194 ")" [] [Whitespace(" ")] + 5: JS_FUNCTION_BODY@194..196 + 0: L_CURLY@194..195 "{" [] [] + 1: JS_DIRECTIVE_LIST@195..195 + 2: JS_STATEMENT_LIST@195..195 + 3: R_CURLY@195..196 "}" [] [] + 1: JS_BOGUS_MEMBER@196..223 + 0: JS_PROPERTY_MODIFIER_LIST@196..211 + 0: JS_STATIC_MODIFIER@196..206 + 0: STATIC_KW@196..206 "static" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@206..211 + 0: AT@206..207 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@207..211 + 0: JS_REFERENCE_IDENTIFIER@207..211 + 0: IDENT@207..211 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@211..214 + 0: IDENT@211..214 "foo" [] [] + 2: TS_TYPE_ANNOTATION@214..222 + 0: COLON@214..216 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@216..222 + 0: STRING_KW@216..222 "string" [] [] + 3: SEMICOLON@222..223 ";" [] [] + 2: JS_BOGUS_MEMBER@223..249 + 0: JS_BOGUS@223..240 + 0: TS_READONLY_MODIFIER@223..235 + 0: READONLY_KW@223..235 "readonly" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@235..240 + 0: AT@235..236 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@236..240 + 0: JS_REFERENCE_IDENTIFIER@236..240 + 0: IDENT@236..240 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@240..244 + 0: IDENT@240..244 "test" [] [] + 2: JS_PARAMETERS@244..247 + 0: L_PAREN@244..245 "(" [] [] + 1: JS_PARAMETER_LIST@245..245 + 2: R_PAREN@245..247 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@247..249 + 0: L_CURLY@247..248 "{" [] [] + 1: JS_DIRECTIVE_LIST@248..248 + 2: JS_STATEMENT_LIST@248..248 + 3: R_CURLY@248..249 "}" [] [] + 3: JS_BOGUS_MEMBER@249..274 + 0: JS_METHOD_MODIFIER_LIST@249..265 + 0: TS_ACCESSIBILITY_MODIFIER@249..260 + 0: PRIVATE_KW@249..260 "private" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@260..265 + 0: AT@260..261 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@261..265 + 0: JS_REFERENCE_IDENTIFIER@261..265 + 0: IDENT@261..265 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@265..269 + 0: IDENT@265..269 "test" [] [] + 2: JS_PARAMETERS@269..272 + 0: L_PAREN@269..270 "(" [] [] + 1: JS_PARAMETER_LIST@270..270 + 2: R_PAREN@270..272 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@272..274 + 0: L_CURLY@272..273 "{" [] [] + 1: JS_DIRECTIVE_LIST@273..273 + 2: JS_STATEMENT_LIST@273..273 + 3: R_CURLY@273..274 "}" [] [] + 4: JS_BOGUS_MEMBER@274..300 + 0: JS_BOGUS@274..291 + 0: JS_ACCESSOR_MODIFIER@274..286 + 0: ACCESSOR_KW@274..286 "accessor" [Newline("\n"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_DECORATOR@286..291 + 0: AT@286..287 "@" [] [] + 1: JS_IDENTIFIER_EXPRESSION@287..291 + 0: JS_REFERENCE_IDENTIFIER@287..291 + 0: IDENT@287..291 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@291..295 + 0: IDENT@291..295 "test" [] [] + 2: JS_PARAMETERS@295..298 + 0: L_PAREN@295..296 "(" [] [] + 1: JS_PARAMETER_LIST@296..296 + 2: R_PAREN@296..298 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@298..300 + 0: L_CURLY@298..299 "{" [] [] + 1: JS_DIRECTIVE_LIST@299..299 + 2: JS_STATEMENT_LIST@299..299 + 3: R_CURLY@299..300 "}" [] [] + 9: R_CURLY@300..302 "}" [Newline("\n")] [] + 3: EOF@302..303 "" [Newline("\n")] [] +-- +decorator_precede_class_member.ts:2:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 1 │ class Bar { + > 2 │ public @dec get foo() {} + │ ^^^^ + 3 │ static @dec foo: string; + 4 │ readonly @dec test() {} + +-- +decorator_precede_class_member.ts:3:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 1 │ class Bar { + 2 │ public @dec get foo() {} + > 3 │ static @dec foo: string; + │ ^^^^ + 4 │ readonly @dec test() {} + 5 │ private @dec test() {} + +-- +decorator_precede_class_member.ts:4:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Readonly can only appear on a property declaration or index signature. + + 2 │ public @dec get foo() {} + 3 │ static @dec foo: string; + > 4 │ readonly @dec test() {} + │ ^^^^^^^^ + 5 │ private @dec test() {} + 6 │ protected @dec test() {} + +-- +decorator_precede_class_member.ts:4:12 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 2 │ public @dec get foo() {} + 3 │ static @dec foo: string; + > 4 │ readonly @dec test() {} + │ ^^^^ + 5 │ private @dec test() {} + 6 │ protected @dec test() {} + +-- +decorator_precede_class_member.ts:5:11 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 3 │ static @dec foo: string; + 4 │ readonly @dec test() {} + > 5 │ private @dec test() {} + │ ^^^^ + 6 │ protected @dec test() {} + 7 │ } + +-- +decorator_precede_class_member.ts:6:13 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 4 │ readonly @dec test() {} + 5 │ private @dec test() {} + > 6 │ protected @dec test() {} + │ ^^^^ + 7 │ } + 8 │ class Qux extends Bar { + +-- +decorator_precede_class_member.ts:9:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 7 │ } + 8 │ class Qux extends Bar { + > 9 │ public @dec get foo() {} + │ ^^^^ + 10 │ static @dec foo: string; + 11 │ readonly @dec test() {} + +-- +decorator_precede_class_member.ts:10:10 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 8 │ class Qux extends Bar { + 9 │ public @dec get foo() {} + > 10 │ static @dec foo: string; + │ ^^^^ + 11 │ readonly @dec test() {} + 12 │ private @dec test() {} + +-- +decorator_precede_class_member.ts:11:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Readonly can only appear on a property declaration or index signature. + + 9 │ public @dec get foo() {} + 10 │ static @dec foo: string; + > 11 │ readonly @dec test() {} + │ ^^^^^^^^ + 12 │ private @dec test() {} + 13 │ accessor @dec test() {} + +-- +decorator_precede_class_member.ts:11:12 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 9 │ public @dec get foo() {} + 10 │ static @dec foo: string; + > 11 │ readonly @dec test() {} + │ ^^^^ + 12 │ private @dec test() {} + 13 │ accessor @dec test() {} + +-- +decorator_precede_class_member.ts:12:11 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 10 │ static @dec foo: string; + 11 │ readonly @dec test() {} + > 12 │ private @dec test() {} + │ ^^^^ + 13 │ accessor @dec test() {} + 14 │ } + +-- +decorator_precede_class_member.ts:13:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × 'accessor' modifier is only allowed on properties. + + 11 │ readonly @dec test() {} + 12 │ private @dec test() {} + > 13 │ accessor @dec test() {} + │ ^^^^^^^^ + 14 │ } + 15 │ + +-- +decorator_precede_class_member.ts:13:12 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators must precede the name and all keywords of property declarations. + + 11 │ readonly @dec test() {} + 12 │ private @dec test() {} + > 13 │ accessor @dec test() {} + │ ^^^^ + 14 │ } + 15 │ + +-- +class Bar { + public @dec get foo() {} + static @dec foo: string; + readonly @dec test() {} + private @dec test() {} + protected @dec test() {} +} +class Qux extends Bar { + public @dec get foo() {} + static @dec foo: string; + readonly @dec test() {} + private @dec test() {} + accessor @dec test() {} +} diff --git a/crates/rome_js_parser/test_data/inline/err/decorator_precede_class_member.ts b/crates/rome_js_parser/test_data/inline/err/decorator_precede_class_member.ts new file mode 100644 index 00000000000..956408c4301 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/decorator_precede_class_member.ts @@ -0,0 +1,14 @@ +class Bar { + public @dec get foo() {} + static @dec foo: string; + readonly @dec test() {} + private @dec test() {} + protected @dec test() {} +} +class Qux extends Bar { + public @dec get foo() {} + static @dec foo: string; + readonly @dec test() {} + private @dec test() {} + accessor @dec test() {} +} diff --git a/crates/rome_js_parser/test_data/inline/err/ts_invalid_decorated_class_members.rast b/crates/rome_js_parser/test_data/inline/err/ts_invalid_decorated_class_members.rast index 59b8ea7430c..df37c5345d8 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_invalid_decorated_class_members.rast +++ b/crates/rome_js_parser/test_data/inline/err/ts_invalid_decorated_class_members.rast @@ -14,107 +14,209 @@ JsModule { implements_clause: missing (optional), l_curly_token: L_CURLY@20..21 "{" [] [], members: JsClassMemberList [ - TsMethodSignatureClassMember { - modifiers: TsMethodSignatureModifierList [], - async_token: missing (optional), + JsBogusMember { + items: [ + JsBogus { + items: [ + JsDecorator { + at_token: AT@21..25 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@25..30 "test" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + JsLiteralMemberName { + value: IDENT@30..41 "constructor" [] [], + }, + JsConstructorParameters { + l_paren_token: L_PAREN@41..42 "(" [] [], + parameters: JsConstructorParameterList [], + r_paren_token: R_PAREN@42..44 ")" [] [Whitespace(" ")], + }, + JsFunctionBody { + l_curly_token: L_CURLY@44..45 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@45..46 "}" [] [], + }, + ], + }, + TsPropertySignatureClassMember { + modifiers: TsPropertySignatureModifierList [ + JsDecorator { + at_token: AT@46..50 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@50..55 "test" [] [Whitespace(" ")], + }, + }, + }, + TsDeclareModifier { + modifier_token: DECLARE_KW@55..63 "declare" [] [Whitespace(" ")], + }, + ], name: JsLiteralMemberName { - value: IDENT@21..36 "method" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [], + value: IDENT@63..67 "prop" [] [], }, - question_mark_token: missing (optional), - type_parameters: missing (optional), - parameters: JsParameters { - l_paren_token: L_PAREN@36..37 "(" [] [], - items: JsParameterList [], - r_paren_token: R_PAREN@37..38 ")" [] [], - }, - return_type_annotation: missing (optional), - semicolon_token: SEMICOLON@38..39 ";" [] [], + property_annotation: missing (optional), + semicolon_token: SEMICOLON@67..68 ";" [] [], }, - TsIndexSignatureClassMember { - modifiers: TsIndexSignatureModifierList [], - l_brack_token: L_BRACK@39..49 "[" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [], - parameter: TsIndexSignatureParameter { - binding: JsIdentifierBinding { - name_token: IDENT@49..54 "index" [] [], - }, - type_annotation: TsTypeAnnotation { - colon_token: COLON@54..56 ":" [] [Whitespace(" ")], - ty: TsStringType { - string_token: STRING_KW@56..62 "string" [] [], + JsBogusMember { + items: [ + TsMethodSignatureModifierList [ + JsDecorator { + at_token: AT@68..72 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@72..77 "test" [] [Whitespace(" ")], + }, + }, }, + ], + JsLiteralMemberName { + value: IDENT@77..83 "method" [] [], }, - }, - r_brack_token: R_BRACK@62..63 "]" [] [], - type_annotation: TsTypeAnnotation { - colon_token: COLON@63..65 ":" [] [Whitespace(" ")], - ty: TsStringType { - string_token: STRING_KW@65..71 "string" [] [], + JsParameters { + l_paren_token: L_PAREN@83..84 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@84..85 ")" [] [], }, - }, - semicolon_token: SEMICOLON@71..72 ";" [] [], + SEMICOLON@85..86 ";" [] [], + ], }, - TsMethodSignatureClassMember { - modifiers: TsMethodSignatureModifierList [ - TsAbstractModifier { - modifier_token: ABSTRACT_KW@72..90 "abstract" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")], + JsBogusMember { + items: [ + JsBogus { + items: [ + JsDecorator { + at_token: AT@86..90 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@90..95 "test" [] [Whitespace(" ")], + }, + }, + }, + ], + }, + L_BRACK@95..96 "[" [] [], + TsIndexSignatureParameter { + binding: JsIdentifierBinding { + name_token: IDENT@96..101 "index" [] [], + }, + type_annotation: TsTypeAnnotation { + colon_token: COLON@101..103 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@103..109 "string" [] [], + }, + }, + }, + R_BRACK@109..110 "]" [] [], + TsTypeAnnotation { + colon_token: COLON@110..112 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@112..118 "string" [] [], + }, }, + SEMICOLON@118..119 ";" [] [], ], - async_token: missing (optional), - name: JsLiteralMemberName { - value: IDENT@90..97 "method2" [] [], - }, - question_mark_token: missing (optional), - type_parameters: missing (optional), - parameters: JsParameters { - l_paren_token: L_PAREN@97..98 "(" [] [], - items: JsParameterList [], - r_paren_token: R_PAREN@98..99 ")" [] [], - }, - return_type_annotation: missing (optional), - semicolon_token: SEMICOLON@99..100 ";" [] [], }, - TsGetterSignatureClassMember { - modifiers: TsMethodSignatureModifierList [ - TsAbstractModifier { - modifier_token: ABSTRACT_KW@100..118 "abstract" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")], + JsBogusMember { + items: [ + TsMethodSignatureModifierList [ + JsDecorator { + at_token: AT@119..123 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@123..128 "test" [] [Whitespace(" ")], + }, + }, + }, + TsAbstractModifier { + modifier_token: ABSTRACT_KW@128..137 "abstract" [] [Whitespace(" ")], + }, + ], + JsLiteralMemberName { + value: IDENT@137..144 "method2" [] [], }, + JsParameters { + l_paren_token: L_PAREN@144..145 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@145..146 ")" [] [], + }, + SEMICOLON@146..147 ";" [] [], ], - get_token: GET_KW@118..122 "get" [] [Whitespace(" ")], - name: JsLiteralMemberName { - value: IDENT@122..128 "getter" [] [], - }, - l_paren_token: L_PAREN@128..129 "(" [] [], - r_paren_token: R_PAREN@129..130 ")" [] [], - return_type: missing (optional), - semicolon_token: SEMICOLON@130..131 ";" [] [], }, - TsSetterSignatureClassMember { - modifiers: TsMethodSignatureModifierList [ - TsAbstractModifier { - modifier_token: ABSTRACT_KW@131..149 "abstract" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")], + JsBogusMember { + items: [ + TsMethodSignatureModifierList [ + JsDecorator { + at_token: AT@147..151 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@151..156 "test" [] [Whitespace(" ")], + }, + }, + }, + TsAbstractModifier { + modifier_token: ABSTRACT_KW@156..165 "abstract" [] [Whitespace(" ")], + }, + ], + GET_KW@165..169 "get" [] [Whitespace(" ")], + JsLiteralMemberName { + value: IDENT@169..175 "getter" [] [], }, + L_PAREN@175..176 "(" [] [], + R_PAREN@176..177 ")" [] [], + SEMICOLON@177..178 ";" [] [], + ], + }, + JsBogusMember { + items: [ + TsMethodSignatureModifierList [ + JsDecorator { + at_token: AT@178..182 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@182..187 "test" [] [Whitespace(" ")], + }, + }, + }, + TsAbstractModifier { + modifier_token: ABSTRACT_KW@187..196 "abstract" [] [Whitespace(" ")], + }, + ], + SET_KW@196..200 "set" [] [Whitespace(" ")], + JsLiteralMemberName { + value: IDENT@200..206 "setter" [] [], + }, + L_PAREN@206..207 "(" [] [], + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@207..210 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + R_PAREN@210..211 ")" [] [], + SEMICOLON@211..212 ";" [] [], ], - set_token: SET_KW@149..153 "set" [] [Whitespace(" ")], - name: JsLiteralMemberName { - value: IDENT@153..159 "setter" [] [], - }, - l_paren_token: L_PAREN@159..160 "(" [] [], - parameter: missing (required), - r_paren_token: R_PAREN@160..161 ")" [] [], - semicolon_token: SEMICOLON@161..162 ";" [] [], }, ], - r_curly_token: R_CURLY@162..164 "}" [Newline("\n")] [], + r_curly_token: R_CURLY@212..214 "}" [Newline("\n")] [], }, ], - eof_token: EOF@164..165 "" [Newline("\n")] [], + eof_token: EOF@214..215 "" [Newline("\n")] [], } -0: JS_MODULE@0..165 +0: JS_MODULE@0..215 0: (empty) 1: JS_DIRECTIVE_LIST@0..0 - 2: JS_MODULE_ITEM_LIST@0..164 - 0: JS_CLASS_DECLARATION@0..164 + 2: JS_MODULE_ITEM_LIST@0..214 + 0: JS_CLASS_DECLARATION@0..214 0: JS_DECORATOR_LIST@0..0 1: ABSTRACT_KW@0..9 "abstract" [] [Whitespace(" ")] 2: CLASS_KW@9..15 "class" [] [Whitespace(" ")] @@ -124,101 +226,217 @@ JsModule { 5: (empty) 6: (empty) 7: L_CURLY@20..21 "{" [] [] - 8: JS_CLASS_MEMBER_LIST@21..162 - 0: TS_METHOD_SIGNATURE_CLASS_MEMBER@21..39 - 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@21..21 - 1: (empty) - 2: JS_LITERAL_MEMBER_NAME@21..36 - 0: IDENT@21..36 "method" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [] - 3: (empty) - 4: (empty) - 5: JS_PARAMETERS@36..38 - 0: L_PAREN@36..37 "(" [] [] - 1: JS_PARAMETER_LIST@37..37 - 2: R_PAREN@37..38 ")" [] [] - 6: (empty) - 7: SEMICOLON@38..39 ";" [] [] - 1: TS_INDEX_SIGNATURE_CLASS_MEMBER@39..72 - 0: TS_INDEX_SIGNATURE_MODIFIER_LIST@39..39 - 1: L_BRACK@39..49 "[" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [] - 2: TS_INDEX_SIGNATURE_PARAMETER@49..62 - 0: JS_IDENTIFIER_BINDING@49..54 - 0: IDENT@49..54 "index" [] [] - 1: TS_TYPE_ANNOTATION@54..62 - 0: COLON@54..56 ":" [] [Whitespace(" ")] - 1: TS_STRING_TYPE@56..62 - 0: STRING_KW@56..62 "string" [] [] - 3: R_BRACK@62..63 "]" [] [] - 4: TS_TYPE_ANNOTATION@63..71 - 0: COLON@63..65 ":" [] [Whitespace(" ")] - 1: TS_STRING_TYPE@65..71 - 0: STRING_KW@65..71 "string" [] [] - 5: SEMICOLON@71..72 ";" [] [] - 2: TS_METHOD_SIGNATURE_CLASS_MEMBER@72..100 - 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@72..90 - 0: TS_ABSTRACT_MODIFIER@72..90 - 0: ABSTRACT_KW@72..90 "abstract" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")] - 1: (empty) - 2: JS_LITERAL_MEMBER_NAME@90..97 - 0: IDENT@90..97 "method2" [] [] - 3: (empty) - 4: (empty) - 5: JS_PARAMETERS@97..99 - 0: L_PAREN@97..98 "(" [] [] - 1: JS_PARAMETER_LIST@98..98 - 2: R_PAREN@98..99 ")" [] [] - 6: (empty) - 7: SEMICOLON@99..100 ";" [] [] - 3: TS_GETTER_SIGNATURE_CLASS_MEMBER@100..131 - 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@100..118 - 0: TS_ABSTRACT_MODIFIER@100..118 - 0: ABSTRACT_KW@100..118 "abstract" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")] - 1: GET_KW@118..122 "get" [] [Whitespace(" ")] - 2: JS_LITERAL_MEMBER_NAME@122..128 - 0: IDENT@122..128 "getter" [] [] - 3: L_PAREN@128..129 "(" [] [] - 4: R_PAREN@129..130 ")" [] [] - 5: (empty) - 6: SEMICOLON@130..131 ";" [] [] - 4: TS_SETTER_SIGNATURE_CLASS_MEMBER@131..162 - 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@131..149 - 0: TS_ABSTRACT_MODIFIER@131..149 - 0: ABSTRACT_KW@131..149 "abstract" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")] - 1: SET_KW@149..153 "set" [] [Whitespace(" ")] - 2: JS_LITERAL_MEMBER_NAME@153..159 - 0: IDENT@153..159 "setter" [] [] - 3: L_PAREN@159..160 "(" [] [] - 4: (empty) - 5: R_PAREN@160..161 ")" [] [] - 6: SEMICOLON@161..162 ";" [] [] - 9: R_CURLY@162..164 "}" [Newline("\n")] [] - 3: EOF@164..165 "" [Newline("\n")] [] + 8: JS_CLASS_MEMBER_LIST@21..212 + 0: JS_BOGUS_MEMBER@21..46 + 0: JS_BOGUS@21..30 + 0: JS_DECORATOR@21..30 + 0: AT@21..25 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@25..30 + 0: JS_REFERENCE_IDENTIFIER@25..30 + 0: IDENT@25..30 "test" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@30..41 + 0: IDENT@30..41 "constructor" [] [] + 2: JS_CONSTRUCTOR_PARAMETERS@41..44 + 0: L_PAREN@41..42 "(" [] [] + 1: JS_CONSTRUCTOR_PARAMETER_LIST@42..42 + 2: R_PAREN@42..44 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@44..46 + 0: L_CURLY@44..45 "{" [] [] + 1: JS_DIRECTIVE_LIST@45..45 + 2: JS_STATEMENT_LIST@45..45 + 3: R_CURLY@45..46 "}" [] [] + 1: TS_PROPERTY_SIGNATURE_CLASS_MEMBER@46..68 + 0: TS_PROPERTY_SIGNATURE_MODIFIER_LIST@46..63 + 0: JS_DECORATOR@46..55 + 0: AT@46..50 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@50..55 + 0: JS_REFERENCE_IDENTIFIER@50..55 + 0: IDENT@50..55 "test" [] [Whitespace(" ")] + 1: TS_DECLARE_MODIFIER@55..63 + 0: DECLARE_KW@55..63 "declare" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@63..67 + 0: IDENT@63..67 "prop" [] [] + 2: (empty) + 3: SEMICOLON@67..68 ";" [] [] + 2: JS_BOGUS_MEMBER@68..86 + 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@68..77 + 0: JS_DECORATOR@68..77 + 0: AT@68..72 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@72..77 + 0: JS_REFERENCE_IDENTIFIER@72..77 + 0: IDENT@72..77 "test" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@77..83 + 0: IDENT@77..83 "method" [] [] + 2: JS_PARAMETERS@83..85 + 0: L_PAREN@83..84 "(" [] [] + 1: JS_PARAMETER_LIST@84..84 + 2: R_PAREN@84..85 ")" [] [] + 3: SEMICOLON@85..86 ";" [] [] + 3: JS_BOGUS_MEMBER@86..119 + 0: JS_BOGUS@86..95 + 0: JS_DECORATOR@86..95 + 0: AT@86..90 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@90..95 + 0: JS_REFERENCE_IDENTIFIER@90..95 + 0: IDENT@90..95 "test" [] [Whitespace(" ")] + 1: L_BRACK@95..96 "[" [] [] + 2: TS_INDEX_SIGNATURE_PARAMETER@96..109 + 0: JS_IDENTIFIER_BINDING@96..101 + 0: IDENT@96..101 "index" [] [] + 1: TS_TYPE_ANNOTATION@101..109 + 0: COLON@101..103 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@103..109 + 0: STRING_KW@103..109 "string" [] [] + 3: R_BRACK@109..110 "]" [] [] + 4: TS_TYPE_ANNOTATION@110..118 + 0: COLON@110..112 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@112..118 + 0: STRING_KW@112..118 "string" [] [] + 5: SEMICOLON@118..119 ";" [] [] + 4: JS_BOGUS_MEMBER@119..147 + 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@119..137 + 0: JS_DECORATOR@119..128 + 0: AT@119..123 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@123..128 + 0: JS_REFERENCE_IDENTIFIER@123..128 + 0: IDENT@123..128 "test" [] [Whitespace(" ")] + 1: TS_ABSTRACT_MODIFIER@128..137 + 0: ABSTRACT_KW@128..137 "abstract" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@137..144 + 0: IDENT@137..144 "method2" [] [] + 2: JS_PARAMETERS@144..146 + 0: L_PAREN@144..145 "(" [] [] + 1: JS_PARAMETER_LIST@145..145 + 2: R_PAREN@145..146 ")" [] [] + 3: SEMICOLON@146..147 ";" [] [] + 5: JS_BOGUS_MEMBER@147..178 + 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@147..165 + 0: JS_DECORATOR@147..156 + 0: AT@147..151 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@151..156 + 0: JS_REFERENCE_IDENTIFIER@151..156 + 0: IDENT@151..156 "test" [] [Whitespace(" ")] + 1: TS_ABSTRACT_MODIFIER@156..165 + 0: ABSTRACT_KW@156..165 "abstract" [] [Whitespace(" ")] + 1: GET_KW@165..169 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@169..175 + 0: IDENT@169..175 "getter" [] [] + 3: L_PAREN@175..176 "(" [] [] + 4: R_PAREN@176..177 ")" [] [] + 5: SEMICOLON@177..178 ";" [] [] + 6: JS_BOGUS_MEMBER@178..212 + 0: TS_METHOD_SIGNATURE_MODIFIER_LIST@178..196 + 0: JS_DECORATOR@178..187 + 0: AT@178..182 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@182..187 + 0: JS_REFERENCE_IDENTIFIER@182..187 + 0: IDENT@182..187 "test" [] [Whitespace(" ")] + 1: TS_ABSTRACT_MODIFIER@187..196 + 0: ABSTRACT_KW@187..196 "abstract" [] [Whitespace(" ")] + 1: SET_KW@196..200 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@200..206 + 0: IDENT@200..206 "setter" [] [] + 3: L_PAREN@206..207 "(" [] [] + 4: JS_FORMAL_PARAMETER@207..210 + 0: JS_IDENTIFIER_BINDING@207..210 + 0: IDENT@207..210 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@210..211 ")" [] [] + 6: SEMICOLON@211..212 ";" [] [] + 9: R_CURLY@212..214 "}" [Newline("\n")] [] + 3: EOF@214..215 "" [Newline("\n")] [] +-- +ts_invalid_decorated_class_members.ts:2:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 1 │ abstract class Test { + > 2 │ @test constructor() {} + │ ^^^^^ + 3 │ @test declare prop; + 4 │ @test method(); + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +ts_invalid_decorated_class_members.ts:4:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 2 │ @test constructor() {} + 3 │ @test declare prop; + > 4 │ @test method(); + │ ^^^^^ + 5 │ @test [index: string]: string; + 6 │ @test abstract method2(); + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +ts_invalid_decorated_class_members.ts:5:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 3 │ @test declare prop; + 4 │ @test method(); + > 5 │ @test [index: string]: string; + │ ^^^^^ + 6 │ @test abstract method2(); + 7 │ @test abstract get getter(); + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +ts_invalid_decorated_class_members.ts:6:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. + + 4 │ @test method(); + 5 │ @test [index: string]: string; + > 6 │ @test abstract method2(); + │ ^^^^^ + 7 │ @test abstract get getter(); + 8 │ @test abstract set setter(val); + + i Decorators are only valid on class declarations, class expressions, and class methods. + -- -ts_invalid_decorated_class_members.ts:6:29 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +ts_invalid_decorated_class_members.ts:7:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - × expected a parameter but instead found ')' + × Decorators are not valid here. - 4 │ @test abstract method2(); - 5 │ @test abstract get getter(); - > 6 │ @test abstract set setter(); - │ ^ - 7 │ } - 8 │ + 5 │ @test [index: string]: string; + 6 │ @test abstract method2(); + > 7 │ @test abstract get getter(); + │ ^^^^^ + 8 │ @test abstract set setter(val); + 9 │ } + + i Decorators are only valid on class declarations, class expressions, and class methods. + +-- +ts_invalid_decorated_class_members.ts:8:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Decorators are not valid here. - i Expected a parameter here + 6 │ @test abstract method2(); + 7 │ @test abstract get getter(); + > 8 │ @test abstract set setter(val); + │ ^^^^^ + 9 │ } + 10 │ - 4 │ @test abstract method2(); - 5 │ @test abstract get getter(); - > 6 │ @test abstract set setter(); - │ ^ - 7 │ } - 8 │ + i Decorators are only valid on class declarations, class expressions, and class methods. -- abstract class Test { + @test constructor() {} + @test declare prop; @test method(); @test [index: string]: string; @test abstract method2(); @test abstract get getter(); - @test abstract set setter(); + @test abstract set setter(val); } diff --git a/crates/rome_js_parser/test_data/inline/err/ts_invalid_decorated_class_members.ts b/crates/rome_js_parser/test_data/inline/err/ts_invalid_decorated_class_members.ts index 79f9fb08f9b..e2a28626e21 100644 --- a/crates/rome_js_parser/test_data/inline/err/ts_invalid_decorated_class_members.ts +++ b/crates/rome_js_parser/test_data/inline/err/ts_invalid_decorated_class_members.ts @@ -1,7 +1,9 @@ abstract class Test { + @test constructor() {} + @test declare prop; @test method(); @test [index: string]: string; @test abstract method2(); @test abstract get getter(); - @test abstract set setter(); + @test abstract set setter(val); } diff --git a/crates/rome_js_parser/test_data/inline/err/ts_static_initialization_block_member_with_decorators.rast b/crates/rome_js_parser/test_data/inline/err/ts_static_initialization_block_member_with_decorators.rast new file mode 100644 index 00000000000..e784c923f8d --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/ts_static_initialization_block_member_with_decorators.rast @@ -0,0 +1,114 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@0..6 "class" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@6..10 "Foo" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@10..11 "{" [] [], + members: JsClassMemberList [ + JsBogusMember { + items: [ + JsDecorator { + at_token: AT@11..15 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@15..19 "dec" [] [Whitespace(" ")], + }, + }, + }, + STATIC_KW@19..26 "static" [] [Whitespace(" ")], + L_CURLY@26..27 "{" [] [], + JsStatementList [ + JsExpressionStatement { + expression: JsAssignmentExpression { + left: JsStaticMemberAssignment { + object: JsThisExpression { + this_token: THIS_KW@27..36 "this" [Newline("\n"), Whitespace(" ")] [], + }, + dot_token: DOT@36..37 "." [] [], + member: JsName { + value_token: IDENT@37..39 "a" [] [Whitespace(" ")], + }, + }, + operator_token: EQ@39..41 "=" [] [Whitespace(" ")], + right: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@41..47 "\"test\"" [] [], + }, + }, + semicolon_token: SEMICOLON@47..48 ";" [] [], + }, + ], + R_CURLY@48..52 "}" [Newline("\n"), Whitespace(" ")] [], + ], + }, + ], + r_curly_token: R_CURLY@52..54 "}" [Newline("\n")] [], + }, + ], + eof_token: EOF@54..55 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..55 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..54 + 0: JS_CLASS_DECLARATION@0..54 + 0: JS_DECORATOR_LIST@0..0 + 1: (empty) + 2: CLASS_KW@0..6 "class" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@6..10 + 0: IDENT@6..10 "Foo" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@10..11 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@11..52 + 0: JS_BOGUS_MEMBER@11..52 + 0: JS_DECORATOR@11..19 + 0: AT@11..15 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@15..19 + 0: JS_REFERENCE_IDENTIFIER@15..19 + 0: IDENT@15..19 "dec" [] [Whitespace(" ")] + 1: STATIC_KW@19..26 "static" [] [Whitespace(" ")] + 2: L_CURLY@26..27 "{" [] [] + 3: JS_STATEMENT_LIST@27..48 + 0: JS_EXPRESSION_STATEMENT@27..48 + 0: JS_ASSIGNMENT_EXPRESSION@27..47 + 0: JS_STATIC_MEMBER_ASSIGNMENT@27..39 + 0: JS_THIS_EXPRESSION@27..36 + 0: THIS_KW@27..36 "this" [Newline("\n"), Whitespace(" ")] [] + 1: DOT@36..37 "." [] [] + 2: JS_NAME@37..39 + 0: IDENT@37..39 "a" [] [Whitespace(" ")] + 1: EQ@39..41 "=" [] [Whitespace(" ")] + 2: JS_STRING_LITERAL_EXPRESSION@41..47 + 0: JS_STRING_LITERAL@41..47 "\"test\"" [] [] + 1: SEMICOLON@47..48 ";" [] [] + 4: R_CURLY@48..52 "}" [Newline("\n"), Whitespace(" ")] [] + 9: R_CURLY@52..54 "}" [Newline("\n")] [] + 3: EOF@54..55 "" [Newline("\n")] [] +-- +ts_static_initialization_block_member_with_decorators.ts:2:3 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + × Static class blocks cannot have any modifier. + + 1 │ class Foo { + > 2 │ @dec static { + │ ^^^^ + 3 │ this.a = "test"; + 4 │ } + +-- +class Foo { + @dec static { + this.a = "test"; + } +} diff --git a/crates/rome_js_parser/test_data/inline/err/ts_static_initialization_block_member_with_decorators.ts b/crates/rome_js_parser/test_data/inline/err/ts_static_initialization_block_member_with_decorators.ts new file mode 100644 index 00000000000..94a4c192376 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/err/ts_static_initialization_block_member_with_decorators.ts @@ -0,0 +1,5 @@ +class Foo { + @dec static { + this.a = "test"; + } +} diff --git a/crates/rome_js_parser/test_data/inline/ok/decorator_class_member.rast b/crates/rome_js_parser/test_data/inline/ok/decorator_class_member.rast new file mode 100644 index 00000000000..2339dcb8725 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/decorator_class_member.rast @@ -0,0 +1,2824 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@0..6 "class" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@6..10 "Foo" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@10..11 "{" [] [], + members: JsClassMemberList [ + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@11..27 "@" [Newline("\n"), Comments("// properties"), Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@27..31 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + name: JsLiteralMemberName { + value: IDENT@31..35 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@35..37 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@37..38 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@38..39 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@39..41 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@41..45 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@45..46 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@46..47 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@47..53 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@53..56 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@56..58 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@58..59 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@59..62 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@62..63 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@63..65 ")" [] [Whitespace(" ")], + }, + }, + }, + ], + name: JsLiteralMemberName { + value: IDENT@65..69 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@69..71 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@71..72 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@72..73 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@73..75 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@75..79 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@79..86 "public" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@86..90 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@90..92 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@92..93 "1" [] [], + }, + }, + semicolon_token: SEMICOLON@93..94 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@94..96 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@96..100 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@100..101 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@101..102 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@102..108 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@108..111 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@111..113 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@113..114 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@114..117 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@117..118 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@118..120 ")" [] [Whitespace(" ")], + }, + }, + }, + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@120..127 "public" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@127..131 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@131..133 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@133..134 "1" [] [], + }, + }, + semicolon_token: SEMICOLON@134..135 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@135..137 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@137..141 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsStaticModifier { + modifier_token: STATIC_KW@141..148 "static" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@148..152 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@152..154 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@154..155 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@155..156 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@156..158 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@158..162 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@162..163 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@163..164 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@164..170 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@170..173 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@173..175 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@175..176 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@176..179 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@179..180 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@180..182 ")" [] [Whitespace(" ")], + }, + }, + }, + JsStaticModifier { + modifier_token: STATIC_KW@182..189 "static" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@189..193 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@193..195 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@195..196 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@196..197 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@197..199 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@199..203 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsAccessorModifier { + modifier_token: ACCESSOR_KW@203..212 "accessor" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@212..216 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@216..218 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@218..219 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@219..220 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@220..222 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@222..226 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@226..227 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@227..228 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@228..234 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@234..237 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@237..239 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@239..240 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@240..243 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@243..244 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@244..246 ")" [] [Whitespace(" ")], + }, + }, + }, + JsAccessorModifier { + modifier_token: ACCESSOR_KW@246..255 "accessor" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@255..259 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@259..261 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@261..262 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@262..263 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@263..265 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@265..269 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsReadonlyModifier { + modifier_token: READONLY_KW@269..278 "readonly" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@278..282 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@282..284 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@284..285 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@285..286 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@286..288 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@288..292 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@292..293 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@293..294 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@294..300 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@300..303 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@303..305 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@305..306 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@306..309 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@309..310 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@310..312 ")" [] [Whitespace(" ")], + }, + }, + }, + TsReadonlyModifier { + modifier_token: READONLY_KW@312..321 "readonly" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@321..325 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@325..327 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@327..328 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@328..329 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@329..331 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@331..335 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsOverrideModifier { + modifier_token: OVERRIDE_KW@335..344 "override" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@344..348 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@348..350 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@350..351 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@351..352 ";" [] [], + }, + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@352..354 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@354..358 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@358..359 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@359..360 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@360..366 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@366..369 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@369..371 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@371..372 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@372..375 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@375..376 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@376..378 ")" [] [Whitespace(" ")], + }, + }, + }, + TsOverrideModifier { + modifier_token: OVERRIDE_KW@378..387 "override" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@387..391 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@391..393 "=" [] [Whitespace(" ")], + expression: JsNumberLiteralExpression { + value_token: JS_NUMBER_LITERAL@393..394 "2" [] [], + }, + }, + semicolon_token: SEMICOLON@394..395 ";" [] [], + }, + JsMethodClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@395..408 "@" [Newline("\n"), Comments("// methods"), Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@408..412 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + async_token: missing (optional), + star_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@412..415 "foo" [] [], + }, + question_mark_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@415..416 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@416..418 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@418..419 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@419..420 "}" [] [], + }, + }, + JsMethodClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@420..422 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@422..426 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@426..427 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@427..428 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@428..434 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@434..437 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@437..439 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@439..440 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@440..443 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@443..444 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@444..446 ")" [] [Whitespace(" ")], + }, + }, + }, + ], + async_token: missing (optional), + star_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@446..449 "foo" [] [], + }, + question_mark_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@449..450 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@450..452 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@452..453 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@453..454 "}" [] [], + }, + }, + JsMethodClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@454..456 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@456..460 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@460..467 "public" [] [Whitespace(" ")], + }, + ], + async_token: missing (optional), + star_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@467..470 "foo" [] [], + }, + question_mark_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@470..471 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@471..473 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@473..474 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@474..475 "}" [] [], + }, + }, + JsMethodClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@475..477 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@477..481 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@481..482 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@482..483 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@483..489 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@489..492 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@492..494 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@494..495 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@495..498 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@498..499 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@499..501 ")" [] [Whitespace(" ")], + }, + }, + }, + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@501..508 "public" [] [Whitespace(" ")], + }, + ], + async_token: missing (optional), + star_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@508..511 "foo" [] [], + }, + question_mark_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@511..512 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@512..514 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@514..515 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@515..516 "}" [] [], + }, + }, + JsMethodClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@516..518 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@518..522 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsStaticModifier { + modifier_token: STATIC_KW@522..529 "static" [] [Whitespace(" ")], + }, + ], + async_token: missing (optional), + star_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@529..532 "foo" [] [], + }, + question_mark_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@532..533 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@533..535 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@535..536 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@536..537 "}" [] [], + }, + }, + JsMethodClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@537..539 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@539..543 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@543..544 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@544..545 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@545..551 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@551..554 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@554..556 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@556..557 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@557..560 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@560..561 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@561..563 ")" [] [Whitespace(" ")], + }, + }, + }, + JsStaticModifier { + modifier_token: STATIC_KW@563..570 "static" [] [Whitespace(" ")], + }, + ], + async_token: missing (optional), + star_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@570..573 "foo" [] [], + }, + question_mark_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@573..574 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@574..576 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@576..577 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@577..578 "}" [] [], + }, + }, + JsMethodClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@578..580 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@580..584 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsOverrideModifier { + modifier_token: OVERRIDE_KW@584..593 "override" [] [Whitespace(" ")], + }, + ], + async_token: missing (optional), + star_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@593..596 "foo" [] [], + }, + question_mark_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@596..597 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@597..599 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@599..600 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@600..601 "}" [] [], + }, + }, + JsMethodClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@601..603 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@603..607 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@607..608 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@608..609 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@609..615 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@615..618 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@618..620 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@620..621 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@621..624 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@624..625 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@625..627 ")" [] [Whitespace(" ")], + }, + }, + }, + TsOverrideModifier { + modifier_token: OVERRIDE_KW@627..636 "override" [] [Whitespace(" ")], + }, + ], + async_token: missing (optional), + star_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@636..639 "foo" [] [], + }, + question_mark_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@639..640 "(" [] [], + items: JsParameterList [], + r_paren_token: R_PAREN@640..642 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@642..643 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@643..644 "}" [] [], + }, + }, + JsGetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@644..657 "@" [Newline("\n"), Comments("// getters"), Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@657..661 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + get_token: GET_KW@661..665 "get" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@665..668 "foo" [] [], + }, + l_paren_token: L_PAREN@668..669 "(" [] [], + r_paren_token: R_PAREN@669..671 ")" [] [Whitespace(" ")], + return_type: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@671..672 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@672..673 "}" [] [], + }, + }, + JsGetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@673..675 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@675..679 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@679..680 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@680..681 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@681..687 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@687..690 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@690..692 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@692..693 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@693..696 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@696..697 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@697..699 ")" [] [Whitespace(" ")], + }, + }, + }, + ], + get_token: GET_KW@699..703 "get" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@703..706 "foo" [] [], + }, + l_paren_token: L_PAREN@706..707 "(" [] [], + r_paren_token: R_PAREN@707..709 ")" [] [Whitespace(" ")], + return_type: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@709..710 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@710..711 "}" [] [], + }, + }, + JsGetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@711..713 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@713..717 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@717..724 "public" [] [Whitespace(" ")], + }, + ], + get_token: GET_KW@724..728 "get" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@728..731 "foo" [] [], + }, + l_paren_token: L_PAREN@731..732 "(" [] [], + r_paren_token: R_PAREN@732..734 ")" [] [Whitespace(" ")], + return_type: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@734..735 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@735..736 "}" [] [], + }, + }, + JsGetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@736..738 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@738..742 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@742..743 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@743..744 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@744..750 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@750..753 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@753..755 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@755..756 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@756..759 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@759..760 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@760..762 ")" [] [Whitespace(" ")], + }, + }, + }, + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@762..769 "public" [] [Whitespace(" ")], + }, + ], + get_token: GET_KW@769..773 "get" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@773..776 "foo" [] [], + }, + l_paren_token: L_PAREN@776..777 "(" [] [], + r_paren_token: R_PAREN@777..779 ")" [] [Whitespace(" ")], + return_type: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@779..780 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@780..781 "}" [] [], + }, + }, + JsGetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@781..783 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@783..787 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsStaticModifier { + modifier_token: STATIC_KW@787..794 "static" [] [Whitespace(" ")], + }, + ], + get_token: GET_KW@794..798 "get" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@798..801 "foo" [] [], + }, + l_paren_token: L_PAREN@801..802 "(" [] [], + r_paren_token: R_PAREN@802..804 ")" [] [Whitespace(" ")], + return_type: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@804..805 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@805..806 "}" [] [], + }, + }, + JsGetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@806..808 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@808..812 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@812..813 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@813..814 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@814..820 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@820..823 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@823..825 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@825..826 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@826..829 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@829..830 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@830..832 ")" [] [Whitespace(" ")], + }, + }, + }, + JsStaticModifier { + modifier_token: STATIC_KW@832..839 "static" [] [Whitespace(" ")], + }, + ], + get_token: GET_KW@839..843 "get" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@843..846 "foo" [] [], + }, + l_paren_token: L_PAREN@846..847 "(" [] [], + r_paren_token: R_PAREN@847..849 ")" [] [Whitespace(" ")], + return_type: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@849..850 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@850..851 "}" [] [], + }, + }, + JsGetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@851..853 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@853..857 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsOverrideModifier { + modifier_token: OVERRIDE_KW@857..866 "override" [] [Whitespace(" ")], + }, + ], + get_token: GET_KW@866..870 "get" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@870..873 "foo" [] [], + }, + l_paren_token: L_PAREN@873..874 "(" [] [], + r_paren_token: R_PAREN@874..876 ")" [] [Whitespace(" ")], + return_type: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@876..877 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@877..878 "}" [] [], + }, + }, + JsGetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@878..880 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@880..884 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@884..885 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@885..886 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@886..892 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@892..895 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@895..897 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@897..898 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@898..901 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@901..902 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@902..904 ")" [] [Whitespace(" ")], + }, + }, + }, + TsOverrideModifier { + modifier_token: OVERRIDE_KW@904..913 "override" [] [Whitespace(" ")], + }, + ], + get_token: GET_KW@913..917 "get" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@917..920 "foo" [] [], + }, + l_paren_token: L_PAREN@920..921 "(" [] [], + r_paren_token: R_PAREN@921..923 ")" [] [Whitespace(" ")], + return_type: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@923..924 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@924..925 "}" [] [], + }, + }, + JsSetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@925..938 "@" [Newline("\n"), Comments("// setters"), Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@938..942 "dec" [] [Whitespace(" ")], + }, + }, + }, + ], + set_token: SET_KW@942..946 "set" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@946..949 "foo" [] [], + }, + l_paren_token: L_PAREN@949..950 "(" [] [], + parameter: JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@950..953 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + r_paren_token: R_PAREN@953..955 ")" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@955..956 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@956..957 "}" [] [], + }, + }, + JsSetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@957..959 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@959..963 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@963..964 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@964..965 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@965..971 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@971..974 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@974..976 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@976..977 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@977..980 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@980..981 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@981..983 ")" [] [Whitespace(" ")], + }, + }, + }, + ], + set_token: SET_KW@983..987 "set" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@987..990 "foo" [] [], + }, + l_paren_token: L_PAREN@990..991 "(" [] [], + parameter: JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@991..994 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + r_paren_token: R_PAREN@994..996 ")" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@996..997 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@997..998 "}" [] [], + }, + }, + JsSetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@998..1000 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1000..1004 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@1004..1011 "public" [] [Whitespace(" ")], + }, + ], + set_token: SET_KW@1011..1015 "set" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@1015..1018 "foo" [] [], + }, + l_paren_token: L_PAREN@1018..1019 "(" [] [], + parameter: JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@1019..1022 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + r_paren_token: R_PAREN@1022..1024 ")" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@1024..1025 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@1025..1026 "}" [] [], + }, + }, + JsSetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@1026..1028 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1028..1032 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@1032..1033 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@1033..1034 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@1034..1040 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1040..1043 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@1043..1045 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@1045..1046 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1046..1049 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@1049..1050 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@1050..1052 ")" [] [Whitespace(" ")], + }, + }, + }, + TsAccessibilityModifier { + modifier_token: PUBLIC_KW@1052..1059 "public" [] [Whitespace(" ")], + }, + ], + set_token: SET_KW@1059..1063 "set" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@1063..1066 "foo" [] [], + }, + l_paren_token: L_PAREN@1066..1067 "(" [] [], + parameter: JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@1067..1070 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + r_paren_token: R_PAREN@1070..1072 ")" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@1072..1073 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@1073..1074 "}" [] [], + }, + }, + JsSetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@1074..1076 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1076..1080 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsStaticModifier { + modifier_token: STATIC_KW@1080..1087 "static" [] [Whitespace(" ")], + }, + ], + set_token: SET_KW@1087..1091 "set" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@1091..1094 "foo" [] [], + }, + l_paren_token: L_PAREN@1094..1095 "(" [] [], + parameter: JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@1095..1098 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + r_paren_token: R_PAREN@1098..1100 ")" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@1100..1101 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@1101..1102 "}" [] [], + }, + }, + JsSetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@1102..1104 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1104..1108 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@1108..1109 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@1109..1110 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@1110..1116 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1116..1119 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@1119..1121 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@1121..1122 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1122..1125 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@1125..1126 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@1126..1128 ")" [] [Whitespace(" ")], + }, + }, + }, + JsStaticModifier { + modifier_token: STATIC_KW@1128..1135 "static" [] [Whitespace(" ")], + }, + ], + set_token: SET_KW@1135..1139 "set" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@1139..1142 "foo" [] [], + }, + l_paren_token: L_PAREN@1142..1143 "(" [] [], + parameter: JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@1143..1146 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + r_paren_token: R_PAREN@1146..1148 ")" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@1148..1149 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@1149..1150 "}" [] [], + }, + }, + JsSetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@1150..1152 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1152..1156 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsOverrideModifier { + modifier_token: OVERRIDE_KW@1156..1165 "override" [] [Whitespace(" ")], + }, + ], + set_token: SET_KW@1165..1169 "set" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@1169..1172 "foo" [] [], + }, + l_paren_token: L_PAREN@1172..1173 "(" [] [], + parameter: JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@1173..1176 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + r_paren_token: R_PAREN@1176..1178 ")" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@1178..1179 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@1179..1180 "}" [] [], + }, + }, + JsSetterClassMember { + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@1180..1182 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1182..1186 "dec" [] [Whitespace(" ")], + }, + }, + }, + JsDecorator { + at_token: AT@1186..1187 "@" [] [], + expression: JsParenthesizedExpression { + l_paren_token: L_PAREN@1187..1188 "(" [] [], + expression: JsAwaitExpression { + await_token: AWAIT_KW@1188..1194 "await" [] [Whitespace(" ")], + argument: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1194..1197 "dec" [] [], + }, + }, + }, + r_paren_token: R_PAREN@1197..1199 ")" [] [Whitespace(" ")], + }, + }, + JsDecorator { + at_token: AT@1199..1200 "@" [] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@1200..1203 "dec" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@1203..1204 "(" [] [], + args: JsCallArgumentList [], + r_paren_token: R_PAREN@1204..1206 ")" [] [Whitespace(" ")], + }, + }, + }, + TsOverrideModifier { + modifier_token: OVERRIDE_KW@1206..1215 "override" [] [Whitespace(" ")], + }, + ], + set_token: SET_KW@1215..1219 "set" [] [Whitespace(" ")], + name: JsLiteralMemberName { + value: IDENT@1219..1222 "foo" [] [], + }, + l_paren_token: L_PAREN@1222..1223 "(" [] [], + parameter: JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@1223..1226 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + r_paren_token: R_PAREN@1226..1228 ")" [] [Whitespace(" ")], + body: JsFunctionBody { + l_curly_token: L_CURLY@1228..1229 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@1229..1230 "}" [] [], + }, + }, + ], + r_curly_token: R_CURLY@1230..1232 "}" [Newline("\n")] [], + }, + ], + eof_token: EOF@1232..1233 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..1233 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..1232 + 0: JS_CLASS_DECLARATION@0..1232 + 0: JS_DECORATOR_LIST@0..0 + 1: (empty) + 2: CLASS_KW@0..6 "class" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@6..10 + 0: IDENT@6..10 "Foo" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@10..11 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@11..1230 + 0: JS_PROPERTY_CLASS_MEMBER@11..39 + 0: JS_PROPERTY_MODIFIER_LIST@11..31 + 0: JS_DECORATOR@11..31 + 0: AT@11..27 "@" [Newline("\n"), Comments("// properties"), Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@27..31 + 0: JS_REFERENCE_IDENTIFIER@27..31 + 0: IDENT@27..31 "dec" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@31..35 + 0: IDENT@31..35 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@35..38 + 0: EQ@35..37 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@37..38 + 0: JS_NUMBER_LITERAL@37..38 "2" [] [] + 4: SEMICOLON@38..39 ";" [] [] + 1: JS_PROPERTY_CLASS_MEMBER@39..73 + 0: JS_PROPERTY_MODIFIER_LIST@39..65 + 0: JS_DECORATOR@39..45 + 0: AT@39..41 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@41..45 + 0: JS_REFERENCE_IDENTIFIER@41..45 + 0: IDENT@41..45 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@45..58 + 0: AT@45..46 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@46..58 + 0: L_PAREN@46..47 "(" [] [] + 1: JS_AWAIT_EXPRESSION@47..56 + 0: AWAIT_KW@47..53 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@53..56 + 0: JS_REFERENCE_IDENTIFIER@53..56 + 0: IDENT@53..56 "dec" [] [] + 2: R_PAREN@56..58 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@58..65 + 0: AT@58..59 "@" [] [] + 1: JS_CALL_EXPRESSION@59..65 + 0: JS_IDENTIFIER_EXPRESSION@59..62 + 0: JS_REFERENCE_IDENTIFIER@59..62 + 0: IDENT@59..62 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@62..65 + 0: L_PAREN@62..63 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@63..63 + 2: R_PAREN@63..65 ")" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@65..69 + 0: IDENT@65..69 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@69..72 + 0: EQ@69..71 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@71..72 + 0: JS_NUMBER_LITERAL@71..72 "2" [] [] + 4: SEMICOLON@72..73 ";" [] [] + 2: JS_PROPERTY_CLASS_MEMBER@73..94 + 0: JS_PROPERTY_MODIFIER_LIST@73..86 + 0: JS_DECORATOR@73..79 + 0: AT@73..75 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@75..79 + 0: JS_REFERENCE_IDENTIFIER@75..79 + 0: IDENT@75..79 "dec" [] [Whitespace(" ")] + 1: TS_ACCESSIBILITY_MODIFIER@79..86 + 0: PUBLIC_KW@79..86 "public" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@86..90 + 0: IDENT@86..90 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@90..93 + 0: EQ@90..92 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@92..93 + 0: JS_NUMBER_LITERAL@92..93 "1" [] [] + 4: SEMICOLON@93..94 ";" [] [] + 3: JS_PROPERTY_CLASS_MEMBER@94..135 + 0: JS_PROPERTY_MODIFIER_LIST@94..127 + 0: JS_DECORATOR@94..100 + 0: AT@94..96 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@96..100 + 0: JS_REFERENCE_IDENTIFIER@96..100 + 0: IDENT@96..100 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@100..113 + 0: AT@100..101 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@101..113 + 0: L_PAREN@101..102 "(" [] [] + 1: JS_AWAIT_EXPRESSION@102..111 + 0: AWAIT_KW@102..108 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@108..111 + 0: JS_REFERENCE_IDENTIFIER@108..111 + 0: IDENT@108..111 "dec" [] [] + 2: R_PAREN@111..113 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@113..120 + 0: AT@113..114 "@" [] [] + 1: JS_CALL_EXPRESSION@114..120 + 0: JS_IDENTIFIER_EXPRESSION@114..117 + 0: JS_REFERENCE_IDENTIFIER@114..117 + 0: IDENT@114..117 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@117..120 + 0: L_PAREN@117..118 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@118..118 + 2: R_PAREN@118..120 ")" [] [Whitespace(" ")] + 3: TS_ACCESSIBILITY_MODIFIER@120..127 + 0: PUBLIC_KW@120..127 "public" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@127..131 + 0: IDENT@127..131 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@131..134 + 0: EQ@131..133 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@133..134 + 0: JS_NUMBER_LITERAL@133..134 "1" [] [] + 4: SEMICOLON@134..135 ";" [] [] + 4: JS_PROPERTY_CLASS_MEMBER@135..156 + 0: JS_PROPERTY_MODIFIER_LIST@135..148 + 0: JS_DECORATOR@135..141 + 0: AT@135..137 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@137..141 + 0: JS_REFERENCE_IDENTIFIER@137..141 + 0: IDENT@137..141 "dec" [] [Whitespace(" ")] + 1: JS_STATIC_MODIFIER@141..148 + 0: STATIC_KW@141..148 "static" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@148..152 + 0: IDENT@148..152 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@152..155 + 0: EQ@152..154 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@154..155 + 0: JS_NUMBER_LITERAL@154..155 "2" [] [] + 4: SEMICOLON@155..156 ";" [] [] + 5: JS_PROPERTY_CLASS_MEMBER@156..197 + 0: JS_PROPERTY_MODIFIER_LIST@156..189 + 0: JS_DECORATOR@156..162 + 0: AT@156..158 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@158..162 + 0: JS_REFERENCE_IDENTIFIER@158..162 + 0: IDENT@158..162 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@162..175 + 0: AT@162..163 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@163..175 + 0: L_PAREN@163..164 "(" [] [] + 1: JS_AWAIT_EXPRESSION@164..173 + 0: AWAIT_KW@164..170 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@170..173 + 0: JS_REFERENCE_IDENTIFIER@170..173 + 0: IDENT@170..173 "dec" [] [] + 2: R_PAREN@173..175 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@175..182 + 0: AT@175..176 "@" [] [] + 1: JS_CALL_EXPRESSION@176..182 + 0: JS_IDENTIFIER_EXPRESSION@176..179 + 0: JS_REFERENCE_IDENTIFIER@176..179 + 0: IDENT@176..179 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@179..182 + 0: L_PAREN@179..180 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@180..180 + 2: R_PAREN@180..182 ")" [] [Whitespace(" ")] + 3: JS_STATIC_MODIFIER@182..189 + 0: STATIC_KW@182..189 "static" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@189..193 + 0: IDENT@189..193 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@193..196 + 0: EQ@193..195 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@195..196 + 0: JS_NUMBER_LITERAL@195..196 "2" [] [] + 4: SEMICOLON@196..197 ";" [] [] + 6: JS_PROPERTY_CLASS_MEMBER@197..220 + 0: JS_PROPERTY_MODIFIER_LIST@197..212 + 0: JS_DECORATOR@197..203 + 0: AT@197..199 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@199..203 + 0: JS_REFERENCE_IDENTIFIER@199..203 + 0: IDENT@199..203 "dec" [] [Whitespace(" ")] + 1: JS_ACCESSOR_MODIFIER@203..212 + 0: ACCESSOR_KW@203..212 "accessor" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@212..216 + 0: IDENT@212..216 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@216..219 + 0: EQ@216..218 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@218..219 + 0: JS_NUMBER_LITERAL@218..219 "2" [] [] + 4: SEMICOLON@219..220 ";" [] [] + 7: JS_PROPERTY_CLASS_MEMBER@220..263 + 0: JS_PROPERTY_MODIFIER_LIST@220..255 + 0: JS_DECORATOR@220..226 + 0: AT@220..222 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@222..226 + 0: JS_REFERENCE_IDENTIFIER@222..226 + 0: IDENT@222..226 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@226..239 + 0: AT@226..227 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@227..239 + 0: L_PAREN@227..228 "(" [] [] + 1: JS_AWAIT_EXPRESSION@228..237 + 0: AWAIT_KW@228..234 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@234..237 + 0: JS_REFERENCE_IDENTIFIER@234..237 + 0: IDENT@234..237 "dec" [] [] + 2: R_PAREN@237..239 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@239..246 + 0: AT@239..240 "@" [] [] + 1: JS_CALL_EXPRESSION@240..246 + 0: JS_IDENTIFIER_EXPRESSION@240..243 + 0: JS_REFERENCE_IDENTIFIER@240..243 + 0: IDENT@240..243 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@243..246 + 0: L_PAREN@243..244 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@244..244 + 2: R_PAREN@244..246 ")" [] [Whitespace(" ")] + 3: JS_ACCESSOR_MODIFIER@246..255 + 0: ACCESSOR_KW@246..255 "accessor" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@255..259 + 0: IDENT@255..259 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@259..262 + 0: EQ@259..261 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@261..262 + 0: JS_NUMBER_LITERAL@261..262 "2" [] [] + 4: SEMICOLON@262..263 ";" [] [] + 8: JS_PROPERTY_CLASS_MEMBER@263..286 + 0: JS_PROPERTY_MODIFIER_LIST@263..278 + 0: JS_DECORATOR@263..269 + 0: AT@263..265 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@265..269 + 0: JS_REFERENCE_IDENTIFIER@265..269 + 0: IDENT@265..269 "dec" [] [Whitespace(" ")] + 1: TS_READONLY_MODIFIER@269..278 + 0: READONLY_KW@269..278 "readonly" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@278..282 + 0: IDENT@278..282 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@282..285 + 0: EQ@282..284 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@284..285 + 0: JS_NUMBER_LITERAL@284..285 "2" [] [] + 4: SEMICOLON@285..286 ";" [] [] + 9: JS_PROPERTY_CLASS_MEMBER@286..329 + 0: JS_PROPERTY_MODIFIER_LIST@286..321 + 0: JS_DECORATOR@286..292 + 0: AT@286..288 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@288..292 + 0: JS_REFERENCE_IDENTIFIER@288..292 + 0: IDENT@288..292 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@292..305 + 0: AT@292..293 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@293..305 + 0: L_PAREN@293..294 "(" [] [] + 1: JS_AWAIT_EXPRESSION@294..303 + 0: AWAIT_KW@294..300 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@300..303 + 0: JS_REFERENCE_IDENTIFIER@300..303 + 0: IDENT@300..303 "dec" [] [] + 2: R_PAREN@303..305 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@305..312 + 0: AT@305..306 "@" [] [] + 1: JS_CALL_EXPRESSION@306..312 + 0: JS_IDENTIFIER_EXPRESSION@306..309 + 0: JS_REFERENCE_IDENTIFIER@306..309 + 0: IDENT@306..309 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@309..312 + 0: L_PAREN@309..310 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@310..310 + 2: R_PAREN@310..312 ")" [] [Whitespace(" ")] + 3: TS_READONLY_MODIFIER@312..321 + 0: READONLY_KW@312..321 "readonly" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@321..325 + 0: IDENT@321..325 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@325..328 + 0: EQ@325..327 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@327..328 + 0: JS_NUMBER_LITERAL@327..328 "2" [] [] + 4: SEMICOLON@328..329 ";" [] [] + 10: JS_PROPERTY_CLASS_MEMBER@329..352 + 0: JS_PROPERTY_MODIFIER_LIST@329..344 + 0: JS_DECORATOR@329..335 + 0: AT@329..331 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@331..335 + 0: JS_REFERENCE_IDENTIFIER@331..335 + 0: IDENT@331..335 "dec" [] [Whitespace(" ")] + 1: TS_OVERRIDE_MODIFIER@335..344 + 0: OVERRIDE_KW@335..344 "override" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@344..348 + 0: IDENT@344..348 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@348..351 + 0: EQ@348..350 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@350..351 + 0: JS_NUMBER_LITERAL@350..351 "2" [] [] + 4: SEMICOLON@351..352 ";" [] [] + 11: JS_PROPERTY_CLASS_MEMBER@352..395 + 0: JS_PROPERTY_MODIFIER_LIST@352..387 + 0: JS_DECORATOR@352..358 + 0: AT@352..354 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@354..358 + 0: JS_REFERENCE_IDENTIFIER@354..358 + 0: IDENT@354..358 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@358..371 + 0: AT@358..359 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@359..371 + 0: L_PAREN@359..360 "(" [] [] + 1: JS_AWAIT_EXPRESSION@360..369 + 0: AWAIT_KW@360..366 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@366..369 + 0: JS_REFERENCE_IDENTIFIER@366..369 + 0: IDENT@366..369 "dec" [] [] + 2: R_PAREN@369..371 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@371..378 + 0: AT@371..372 "@" [] [] + 1: JS_CALL_EXPRESSION@372..378 + 0: JS_IDENTIFIER_EXPRESSION@372..375 + 0: JS_REFERENCE_IDENTIFIER@372..375 + 0: IDENT@372..375 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@375..378 + 0: L_PAREN@375..376 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@376..376 + 2: R_PAREN@376..378 ")" [] [Whitespace(" ")] + 3: TS_OVERRIDE_MODIFIER@378..387 + 0: OVERRIDE_KW@378..387 "override" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@387..391 + 0: IDENT@387..391 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@391..394 + 0: EQ@391..393 "=" [] [Whitespace(" ")] + 1: JS_NUMBER_LITERAL_EXPRESSION@393..394 + 0: JS_NUMBER_LITERAL@393..394 "2" [] [] + 4: SEMICOLON@394..395 ";" [] [] + 12: JS_METHOD_CLASS_MEMBER@395..420 + 0: JS_METHOD_MODIFIER_LIST@395..412 + 0: JS_DECORATOR@395..412 + 0: AT@395..408 "@" [Newline("\n"), Comments("// methods"), Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@408..412 + 0: JS_REFERENCE_IDENTIFIER@408..412 + 0: IDENT@408..412 "dec" [] [Whitespace(" ")] + 1: (empty) + 2: (empty) + 3: JS_LITERAL_MEMBER_NAME@412..415 + 0: IDENT@412..415 "foo" [] [] + 4: (empty) + 5: (empty) + 6: JS_PARAMETERS@415..418 + 0: L_PAREN@415..416 "(" [] [] + 1: JS_PARAMETER_LIST@416..416 + 2: R_PAREN@416..418 ")" [] [Whitespace(" ")] + 7: (empty) + 8: JS_FUNCTION_BODY@418..420 + 0: L_CURLY@418..419 "{" [] [] + 1: JS_DIRECTIVE_LIST@419..419 + 2: JS_STATEMENT_LIST@419..419 + 3: R_CURLY@419..420 "}" [] [] + 13: JS_METHOD_CLASS_MEMBER@420..454 + 0: JS_METHOD_MODIFIER_LIST@420..446 + 0: JS_DECORATOR@420..426 + 0: AT@420..422 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@422..426 + 0: JS_REFERENCE_IDENTIFIER@422..426 + 0: IDENT@422..426 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@426..439 + 0: AT@426..427 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@427..439 + 0: L_PAREN@427..428 "(" [] [] + 1: JS_AWAIT_EXPRESSION@428..437 + 0: AWAIT_KW@428..434 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@434..437 + 0: JS_REFERENCE_IDENTIFIER@434..437 + 0: IDENT@434..437 "dec" [] [] + 2: R_PAREN@437..439 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@439..446 + 0: AT@439..440 "@" [] [] + 1: JS_CALL_EXPRESSION@440..446 + 0: JS_IDENTIFIER_EXPRESSION@440..443 + 0: JS_REFERENCE_IDENTIFIER@440..443 + 0: IDENT@440..443 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@443..446 + 0: L_PAREN@443..444 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@444..444 + 2: R_PAREN@444..446 ")" [] [Whitespace(" ")] + 1: (empty) + 2: (empty) + 3: JS_LITERAL_MEMBER_NAME@446..449 + 0: IDENT@446..449 "foo" [] [] + 4: (empty) + 5: (empty) + 6: JS_PARAMETERS@449..452 + 0: L_PAREN@449..450 "(" [] [] + 1: JS_PARAMETER_LIST@450..450 + 2: R_PAREN@450..452 ")" [] [Whitespace(" ")] + 7: (empty) + 8: JS_FUNCTION_BODY@452..454 + 0: L_CURLY@452..453 "{" [] [] + 1: JS_DIRECTIVE_LIST@453..453 + 2: JS_STATEMENT_LIST@453..453 + 3: R_CURLY@453..454 "}" [] [] + 14: JS_METHOD_CLASS_MEMBER@454..475 + 0: JS_METHOD_MODIFIER_LIST@454..467 + 0: JS_DECORATOR@454..460 + 0: AT@454..456 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@456..460 + 0: JS_REFERENCE_IDENTIFIER@456..460 + 0: IDENT@456..460 "dec" [] [Whitespace(" ")] + 1: TS_ACCESSIBILITY_MODIFIER@460..467 + 0: PUBLIC_KW@460..467 "public" [] [Whitespace(" ")] + 1: (empty) + 2: (empty) + 3: JS_LITERAL_MEMBER_NAME@467..470 + 0: IDENT@467..470 "foo" [] [] + 4: (empty) + 5: (empty) + 6: JS_PARAMETERS@470..473 + 0: L_PAREN@470..471 "(" [] [] + 1: JS_PARAMETER_LIST@471..471 + 2: R_PAREN@471..473 ")" [] [Whitespace(" ")] + 7: (empty) + 8: JS_FUNCTION_BODY@473..475 + 0: L_CURLY@473..474 "{" [] [] + 1: JS_DIRECTIVE_LIST@474..474 + 2: JS_STATEMENT_LIST@474..474 + 3: R_CURLY@474..475 "}" [] [] + 15: JS_METHOD_CLASS_MEMBER@475..516 + 0: JS_METHOD_MODIFIER_LIST@475..508 + 0: JS_DECORATOR@475..481 + 0: AT@475..477 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@477..481 + 0: JS_REFERENCE_IDENTIFIER@477..481 + 0: IDENT@477..481 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@481..494 + 0: AT@481..482 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@482..494 + 0: L_PAREN@482..483 "(" [] [] + 1: JS_AWAIT_EXPRESSION@483..492 + 0: AWAIT_KW@483..489 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@489..492 + 0: JS_REFERENCE_IDENTIFIER@489..492 + 0: IDENT@489..492 "dec" [] [] + 2: R_PAREN@492..494 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@494..501 + 0: AT@494..495 "@" [] [] + 1: JS_CALL_EXPRESSION@495..501 + 0: JS_IDENTIFIER_EXPRESSION@495..498 + 0: JS_REFERENCE_IDENTIFIER@495..498 + 0: IDENT@495..498 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@498..501 + 0: L_PAREN@498..499 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@499..499 + 2: R_PAREN@499..501 ")" [] [Whitespace(" ")] + 3: TS_ACCESSIBILITY_MODIFIER@501..508 + 0: PUBLIC_KW@501..508 "public" [] [Whitespace(" ")] + 1: (empty) + 2: (empty) + 3: JS_LITERAL_MEMBER_NAME@508..511 + 0: IDENT@508..511 "foo" [] [] + 4: (empty) + 5: (empty) + 6: JS_PARAMETERS@511..514 + 0: L_PAREN@511..512 "(" [] [] + 1: JS_PARAMETER_LIST@512..512 + 2: R_PAREN@512..514 ")" [] [Whitespace(" ")] + 7: (empty) + 8: JS_FUNCTION_BODY@514..516 + 0: L_CURLY@514..515 "{" [] [] + 1: JS_DIRECTIVE_LIST@515..515 + 2: JS_STATEMENT_LIST@515..515 + 3: R_CURLY@515..516 "}" [] [] + 16: JS_METHOD_CLASS_MEMBER@516..537 + 0: JS_METHOD_MODIFIER_LIST@516..529 + 0: JS_DECORATOR@516..522 + 0: AT@516..518 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@518..522 + 0: JS_REFERENCE_IDENTIFIER@518..522 + 0: IDENT@518..522 "dec" [] [Whitespace(" ")] + 1: JS_STATIC_MODIFIER@522..529 + 0: STATIC_KW@522..529 "static" [] [Whitespace(" ")] + 1: (empty) + 2: (empty) + 3: JS_LITERAL_MEMBER_NAME@529..532 + 0: IDENT@529..532 "foo" [] [] + 4: (empty) + 5: (empty) + 6: JS_PARAMETERS@532..535 + 0: L_PAREN@532..533 "(" [] [] + 1: JS_PARAMETER_LIST@533..533 + 2: R_PAREN@533..535 ")" [] [Whitespace(" ")] + 7: (empty) + 8: JS_FUNCTION_BODY@535..537 + 0: L_CURLY@535..536 "{" [] [] + 1: JS_DIRECTIVE_LIST@536..536 + 2: JS_STATEMENT_LIST@536..536 + 3: R_CURLY@536..537 "}" [] [] + 17: JS_METHOD_CLASS_MEMBER@537..578 + 0: JS_METHOD_MODIFIER_LIST@537..570 + 0: JS_DECORATOR@537..543 + 0: AT@537..539 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@539..543 + 0: JS_REFERENCE_IDENTIFIER@539..543 + 0: IDENT@539..543 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@543..556 + 0: AT@543..544 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@544..556 + 0: L_PAREN@544..545 "(" [] [] + 1: JS_AWAIT_EXPRESSION@545..554 + 0: AWAIT_KW@545..551 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@551..554 + 0: JS_REFERENCE_IDENTIFIER@551..554 + 0: IDENT@551..554 "dec" [] [] + 2: R_PAREN@554..556 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@556..563 + 0: AT@556..557 "@" [] [] + 1: JS_CALL_EXPRESSION@557..563 + 0: JS_IDENTIFIER_EXPRESSION@557..560 + 0: JS_REFERENCE_IDENTIFIER@557..560 + 0: IDENT@557..560 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@560..563 + 0: L_PAREN@560..561 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@561..561 + 2: R_PAREN@561..563 ")" [] [Whitespace(" ")] + 3: JS_STATIC_MODIFIER@563..570 + 0: STATIC_KW@563..570 "static" [] [Whitespace(" ")] + 1: (empty) + 2: (empty) + 3: JS_LITERAL_MEMBER_NAME@570..573 + 0: IDENT@570..573 "foo" [] [] + 4: (empty) + 5: (empty) + 6: JS_PARAMETERS@573..576 + 0: L_PAREN@573..574 "(" [] [] + 1: JS_PARAMETER_LIST@574..574 + 2: R_PAREN@574..576 ")" [] [Whitespace(" ")] + 7: (empty) + 8: JS_FUNCTION_BODY@576..578 + 0: L_CURLY@576..577 "{" [] [] + 1: JS_DIRECTIVE_LIST@577..577 + 2: JS_STATEMENT_LIST@577..577 + 3: R_CURLY@577..578 "}" [] [] + 18: JS_METHOD_CLASS_MEMBER@578..601 + 0: JS_METHOD_MODIFIER_LIST@578..593 + 0: JS_DECORATOR@578..584 + 0: AT@578..580 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@580..584 + 0: JS_REFERENCE_IDENTIFIER@580..584 + 0: IDENT@580..584 "dec" [] [Whitespace(" ")] + 1: TS_OVERRIDE_MODIFIER@584..593 + 0: OVERRIDE_KW@584..593 "override" [] [Whitespace(" ")] + 1: (empty) + 2: (empty) + 3: JS_LITERAL_MEMBER_NAME@593..596 + 0: IDENT@593..596 "foo" [] [] + 4: (empty) + 5: (empty) + 6: JS_PARAMETERS@596..599 + 0: L_PAREN@596..597 "(" [] [] + 1: JS_PARAMETER_LIST@597..597 + 2: R_PAREN@597..599 ")" [] [Whitespace(" ")] + 7: (empty) + 8: JS_FUNCTION_BODY@599..601 + 0: L_CURLY@599..600 "{" [] [] + 1: JS_DIRECTIVE_LIST@600..600 + 2: JS_STATEMENT_LIST@600..600 + 3: R_CURLY@600..601 "}" [] [] + 19: JS_METHOD_CLASS_MEMBER@601..644 + 0: JS_METHOD_MODIFIER_LIST@601..636 + 0: JS_DECORATOR@601..607 + 0: AT@601..603 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@603..607 + 0: JS_REFERENCE_IDENTIFIER@603..607 + 0: IDENT@603..607 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@607..620 + 0: AT@607..608 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@608..620 + 0: L_PAREN@608..609 "(" [] [] + 1: JS_AWAIT_EXPRESSION@609..618 + 0: AWAIT_KW@609..615 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@615..618 + 0: JS_REFERENCE_IDENTIFIER@615..618 + 0: IDENT@615..618 "dec" [] [] + 2: R_PAREN@618..620 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@620..627 + 0: AT@620..621 "@" [] [] + 1: JS_CALL_EXPRESSION@621..627 + 0: JS_IDENTIFIER_EXPRESSION@621..624 + 0: JS_REFERENCE_IDENTIFIER@621..624 + 0: IDENT@621..624 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@624..627 + 0: L_PAREN@624..625 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@625..625 + 2: R_PAREN@625..627 ")" [] [Whitespace(" ")] + 3: TS_OVERRIDE_MODIFIER@627..636 + 0: OVERRIDE_KW@627..636 "override" [] [Whitespace(" ")] + 1: (empty) + 2: (empty) + 3: JS_LITERAL_MEMBER_NAME@636..639 + 0: IDENT@636..639 "foo" [] [] + 4: (empty) + 5: (empty) + 6: JS_PARAMETERS@639..642 + 0: L_PAREN@639..640 "(" [] [] + 1: JS_PARAMETER_LIST@640..640 + 2: R_PAREN@640..642 ")" [] [Whitespace(" ")] + 7: (empty) + 8: JS_FUNCTION_BODY@642..644 + 0: L_CURLY@642..643 "{" [] [] + 1: JS_DIRECTIVE_LIST@643..643 + 2: JS_STATEMENT_LIST@643..643 + 3: R_CURLY@643..644 "}" [] [] + 20: JS_GETTER_CLASS_MEMBER@644..673 + 0: JS_METHOD_MODIFIER_LIST@644..661 + 0: JS_DECORATOR@644..661 + 0: AT@644..657 "@" [Newline("\n"), Comments("// getters"), Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@657..661 + 0: JS_REFERENCE_IDENTIFIER@657..661 + 0: IDENT@657..661 "dec" [] [Whitespace(" ")] + 1: GET_KW@661..665 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@665..668 + 0: IDENT@665..668 "foo" [] [] + 3: L_PAREN@668..669 "(" [] [] + 4: R_PAREN@669..671 ")" [] [Whitespace(" ")] + 5: (empty) + 6: JS_FUNCTION_BODY@671..673 + 0: L_CURLY@671..672 "{" [] [] + 1: JS_DIRECTIVE_LIST@672..672 + 2: JS_STATEMENT_LIST@672..672 + 3: R_CURLY@672..673 "}" [] [] + 21: JS_GETTER_CLASS_MEMBER@673..711 + 0: JS_METHOD_MODIFIER_LIST@673..699 + 0: JS_DECORATOR@673..679 + 0: AT@673..675 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@675..679 + 0: JS_REFERENCE_IDENTIFIER@675..679 + 0: IDENT@675..679 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@679..692 + 0: AT@679..680 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@680..692 + 0: L_PAREN@680..681 "(" [] [] + 1: JS_AWAIT_EXPRESSION@681..690 + 0: AWAIT_KW@681..687 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@687..690 + 0: JS_REFERENCE_IDENTIFIER@687..690 + 0: IDENT@687..690 "dec" [] [] + 2: R_PAREN@690..692 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@692..699 + 0: AT@692..693 "@" [] [] + 1: JS_CALL_EXPRESSION@693..699 + 0: JS_IDENTIFIER_EXPRESSION@693..696 + 0: JS_REFERENCE_IDENTIFIER@693..696 + 0: IDENT@693..696 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@696..699 + 0: L_PAREN@696..697 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@697..697 + 2: R_PAREN@697..699 ")" [] [Whitespace(" ")] + 1: GET_KW@699..703 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@703..706 + 0: IDENT@703..706 "foo" [] [] + 3: L_PAREN@706..707 "(" [] [] + 4: R_PAREN@707..709 ")" [] [Whitespace(" ")] + 5: (empty) + 6: JS_FUNCTION_BODY@709..711 + 0: L_CURLY@709..710 "{" [] [] + 1: JS_DIRECTIVE_LIST@710..710 + 2: JS_STATEMENT_LIST@710..710 + 3: R_CURLY@710..711 "}" [] [] + 22: JS_GETTER_CLASS_MEMBER@711..736 + 0: JS_METHOD_MODIFIER_LIST@711..724 + 0: JS_DECORATOR@711..717 + 0: AT@711..713 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@713..717 + 0: JS_REFERENCE_IDENTIFIER@713..717 + 0: IDENT@713..717 "dec" [] [Whitespace(" ")] + 1: TS_ACCESSIBILITY_MODIFIER@717..724 + 0: PUBLIC_KW@717..724 "public" [] [Whitespace(" ")] + 1: GET_KW@724..728 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@728..731 + 0: IDENT@728..731 "foo" [] [] + 3: L_PAREN@731..732 "(" [] [] + 4: R_PAREN@732..734 ")" [] [Whitespace(" ")] + 5: (empty) + 6: JS_FUNCTION_BODY@734..736 + 0: L_CURLY@734..735 "{" [] [] + 1: JS_DIRECTIVE_LIST@735..735 + 2: JS_STATEMENT_LIST@735..735 + 3: R_CURLY@735..736 "}" [] [] + 23: JS_GETTER_CLASS_MEMBER@736..781 + 0: JS_METHOD_MODIFIER_LIST@736..769 + 0: JS_DECORATOR@736..742 + 0: AT@736..738 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@738..742 + 0: JS_REFERENCE_IDENTIFIER@738..742 + 0: IDENT@738..742 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@742..755 + 0: AT@742..743 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@743..755 + 0: L_PAREN@743..744 "(" [] [] + 1: JS_AWAIT_EXPRESSION@744..753 + 0: AWAIT_KW@744..750 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@750..753 + 0: JS_REFERENCE_IDENTIFIER@750..753 + 0: IDENT@750..753 "dec" [] [] + 2: R_PAREN@753..755 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@755..762 + 0: AT@755..756 "@" [] [] + 1: JS_CALL_EXPRESSION@756..762 + 0: JS_IDENTIFIER_EXPRESSION@756..759 + 0: JS_REFERENCE_IDENTIFIER@756..759 + 0: IDENT@756..759 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@759..762 + 0: L_PAREN@759..760 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@760..760 + 2: R_PAREN@760..762 ")" [] [Whitespace(" ")] + 3: TS_ACCESSIBILITY_MODIFIER@762..769 + 0: PUBLIC_KW@762..769 "public" [] [Whitespace(" ")] + 1: GET_KW@769..773 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@773..776 + 0: IDENT@773..776 "foo" [] [] + 3: L_PAREN@776..777 "(" [] [] + 4: R_PAREN@777..779 ")" [] [Whitespace(" ")] + 5: (empty) + 6: JS_FUNCTION_BODY@779..781 + 0: L_CURLY@779..780 "{" [] [] + 1: JS_DIRECTIVE_LIST@780..780 + 2: JS_STATEMENT_LIST@780..780 + 3: R_CURLY@780..781 "}" [] [] + 24: JS_GETTER_CLASS_MEMBER@781..806 + 0: JS_METHOD_MODIFIER_LIST@781..794 + 0: JS_DECORATOR@781..787 + 0: AT@781..783 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@783..787 + 0: JS_REFERENCE_IDENTIFIER@783..787 + 0: IDENT@783..787 "dec" [] [Whitespace(" ")] + 1: JS_STATIC_MODIFIER@787..794 + 0: STATIC_KW@787..794 "static" [] [Whitespace(" ")] + 1: GET_KW@794..798 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@798..801 + 0: IDENT@798..801 "foo" [] [] + 3: L_PAREN@801..802 "(" [] [] + 4: R_PAREN@802..804 ")" [] [Whitespace(" ")] + 5: (empty) + 6: JS_FUNCTION_BODY@804..806 + 0: L_CURLY@804..805 "{" [] [] + 1: JS_DIRECTIVE_LIST@805..805 + 2: JS_STATEMENT_LIST@805..805 + 3: R_CURLY@805..806 "}" [] [] + 25: JS_GETTER_CLASS_MEMBER@806..851 + 0: JS_METHOD_MODIFIER_LIST@806..839 + 0: JS_DECORATOR@806..812 + 0: AT@806..808 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@808..812 + 0: JS_REFERENCE_IDENTIFIER@808..812 + 0: IDENT@808..812 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@812..825 + 0: AT@812..813 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@813..825 + 0: L_PAREN@813..814 "(" [] [] + 1: JS_AWAIT_EXPRESSION@814..823 + 0: AWAIT_KW@814..820 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@820..823 + 0: JS_REFERENCE_IDENTIFIER@820..823 + 0: IDENT@820..823 "dec" [] [] + 2: R_PAREN@823..825 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@825..832 + 0: AT@825..826 "@" [] [] + 1: JS_CALL_EXPRESSION@826..832 + 0: JS_IDENTIFIER_EXPRESSION@826..829 + 0: JS_REFERENCE_IDENTIFIER@826..829 + 0: IDENT@826..829 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@829..832 + 0: L_PAREN@829..830 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@830..830 + 2: R_PAREN@830..832 ")" [] [Whitespace(" ")] + 3: JS_STATIC_MODIFIER@832..839 + 0: STATIC_KW@832..839 "static" [] [Whitespace(" ")] + 1: GET_KW@839..843 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@843..846 + 0: IDENT@843..846 "foo" [] [] + 3: L_PAREN@846..847 "(" [] [] + 4: R_PAREN@847..849 ")" [] [Whitespace(" ")] + 5: (empty) + 6: JS_FUNCTION_BODY@849..851 + 0: L_CURLY@849..850 "{" [] [] + 1: JS_DIRECTIVE_LIST@850..850 + 2: JS_STATEMENT_LIST@850..850 + 3: R_CURLY@850..851 "}" [] [] + 26: JS_GETTER_CLASS_MEMBER@851..878 + 0: JS_METHOD_MODIFIER_LIST@851..866 + 0: JS_DECORATOR@851..857 + 0: AT@851..853 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@853..857 + 0: JS_REFERENCE_IDENTIFIER@853..857 + 0: IDENT@853..857 "dec" [] [Whitespace(" ")] + 1: TS_OVERRIDE_MODIFIER@857..866 + 0: OVERRIDE_KW@857..866 "override" [] [Whitespace(" ")] + 1: GET_KW@866..870 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@870..873 + 0: IDENT@870..873 "foo" [] [] + 3: L_PAREN@873..874 "(" [] [] + 4: R_PAREN@874..876 ")" [] [Whitespace(" ")] + 5: (empty) + 6: JS_FUNCTION_BODY@876..878 + 0: L_CURLY@876..877 "{" [] [] + 1: JS_DIRECTIVE_LIST@877..877 + 2: JS_STATEMENT_LIST@877..877 + 3: R_CURLY@877..878 "}" [] [] + 27: JS_GETTER_CLASS_MEMBER@878..925 + 0: JS_METHOD_MODIFIER_LIST@878..913 + 0: JS_DECORATOR@878..884 + 0: AT@878..880 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@880..884 + 0: JS_REFERENCE_IDENTIFIER@880..884 + 0: IDENT@880..884 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@884..897 + 0: AT@884..885 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@885..897 + 0: L_PAREN@885..886 "(" [] [] + 1: JS_AWAIT_EXPRESSION@886..895 + 0: AWAIT_KW@886..892 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@892..895 + 0: JS_REFERENCE_IDENTIFIER@892..895 + 0: IDENT@892..895 "dec" [] [] + 2: R_PAREN@895..897 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@897..904 + 0: AT@897..898 "@" [] [] + 1: JS_CALL_EXPRESSION@898..904 + 0: JS_IDENTIFIER_EXPRESSION@898..901 + 0: JS_REFERENCE_IDENTIFIER@898..901 + 0: IDENT@898..901 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@901..904 + 0: L_PAREN@901..902 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@902..902 + 2: R_PAREN@902..904 ")" [] [Whitespace(" ")] + 3: TS_OVERRIDE_MODIFIER@904..913 + 0: OVERRIDE_KW@904..913 "override" [] [Whitespace(" ")] + 1: GET_KW@913..917 "get" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@917..920 + 0: IDENT@917..920 "foo" [] [] + 3: L_PAREN@920..921 "(" [] [] + 4: R_PAREN@921..923 ")" [] [Whitespace(" ")] + 5: (empty) + 6: JS_FUNCTION_BODY@923..925 + 0: L_CURLY@923..924 "{" [] [] + 1: JS_DIRECTIVE_LIST@924..924 + 2: JS_STATEMENT_LIST@924..924 + 3: R_CURLY@924..925 "}" [] [] + 28: JS_SETTER_CLASS_MEMBER@925..957 + 0: JS_METHOD_MODIFIER_LIST@925..942 + 0: JS_DECORATOR@925..942 + 0: AT@925..938 "@" [Newline("\n"), Comments("// setters"), Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@938..942 + 0: JS_REFERENCE_IDENTIFIER@938..942 + 0: IDENT@938..942 "dec" [] [Whitespace(" ")] + 1: SET_KW@942..946 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@946..949 + 0: IDENT@946..949 "foo" [] [] + 3: L_PAREN@949..950 "(" [] [] + 4: JS_FORMAL_PARAMETER@950..953 + 0: JS_IDENTIFIER_BINDING@950..953 + 0: IDENT@950..953 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@953..955 ")" [] [Whitespace(" ")] + 6: JS_FUNCTION_BODY@955..957 + 0: L_CURLY@955..956 "{" [] [] + 1: JS_DIRECTIVE_LIST@956..956 + 2: JS_STATEMENT_LIST@956..956 + 3: R_CURLY@956..957 "}" [] [] + 29: JS_SETTER_CLASS_MEMBER@957..998 + 0: JS_METHOD_MODIFIER_LIST@957..983 + 0: JS_DECORATOR@957..963 + 0: AT@957..959 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@959..963 + 0: JS_REFERENCE_IDENTIFIER@959..963 + 0: IDENT@959..963 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@963..976 + 0: AT@963..964 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@964..976 + 0: L_PAREN@964..965 "(" [] [] + 1: JS_AWAIT_EXPRESSION@965..974 + 0: AWAIT_KW@965..971 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@971..974 + 0: JS_REFERENCE_IDENTIFIER@971..974 + 0: IDENT@971..974 "dec" [] [] + 2: R_PAREN@974..976 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@976..983 + 0: AT@976..977 "@" [] [] + 1: JS_CALL_EXPRESSION@977..983 + 0: JS_IDENTIFIER_EXPRESSION@977..980 + 0: JS_REFERENCE_IDENTIFIER@977..980 + 0: IDENT@977..980 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@980..983 + 0: L_PAREN@980..981 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@981..981 + 2: R_PAREN@981..983 ")" [] [Whitespace(" ")] + 1: SET_KW@983..987 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@987..990 + 0: IDENT@987..990 "foo" [] [] + 3: L_PAREN@990..991 "(" [] [] + 4: JS_FORMAL_PARAMETER@991..994 + 0: JS_IDENTIFIER_BINDING@991..994 + 0: IDENT@991..994 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@994..996 ")" [] [Whitespace(" ")] + 6: JS_FUNCTION_BODY@996..998 + 0: L_CURLY@996..997 "{" [] [] + 1: JS_DIRECTIVE_LIST@997..997 + 2: JS_STATEMENT_LIST@997..997 + 3: R_CURLY@997..998 "}" [] [] + 30: JS_SETTER_CLASS_MEMBER@998..1026 + 0: JS_METHOD_MODIFIER_LIST@998..1011 + 0: JS_DECORATOR@998..1004 + 0: AT@998..1000 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@1000..1004 + 0: JS_REFERENCE_IDENTIFIER@1000..1004 + 0: IDENT@1000..1004 "dec" [] [Whitespace(" ")] + 1: TS_ACCESSIBILITY_MODIFIER@1004..1011 + 0: PUBLIC_KW@1004..1011 "public" [] [Whitespace(" ")] + 1: SET_KW@1011..1015 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@1015..1018 + 0: IDENT@1015..1018 "foo" [] [] + 3: L_PAREN@1018..1019 "(" [] [] + 4: JS_FORMAL_PARAMETER@1019..1022 + 0: JS_IDENTIFIER_BINDING@1019..1022 + 0: IDENT@1019..1022 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@1022..1024 ")" [] [Whitespace(" ")] + 6: JS_FUNCTION_BODY@1024..1026 + 0: L_CURLY@1024..1025 "{" [] [] + 1: JS_DIRECTIVE_LIST@1025..1025 + 2: JS_STATEMENT_LIST@1025..1025 + 3: R_CURLY@1025..1026 "}" [] [] + 31: JS_SETTER_CLASS_MEMBER@1026..1074 + 0: JS_METHOD_MODIFIER_LIST@1026..1059 + 0: JS_DECORATOR@1026..1032 + 0: AT@1026..1028 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@1028..1032 + 0: JS_REFERENCE_IDENTIFIER@1028..1032 + 0: IDENT@1028..1032 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@1032..1045 + 0: AT@1032..1033 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@1033..1045 + 0: L_PAREN@1033..1034 "(" [] [] + 1: JS_AWAIT_EXPRESSION@1034..1043 + 0: AWAIT_KW@1034..1040 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@1040..1043 + 0: JS_REFERENCE_IDENTIFIER@1040..1043 + 0: IDENT@1040..1043 "dec" [] [] + 2: R_PAREN@1043..1045 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@1045..1052 + 0: AT@1045..1046 "@" [] [] + 1: JS_CALL_EXPRESSION@1046..1052 + 0: JS_IDENTIFIER_EXPRESSION@1046..1049 + 0: JS_REFERENCE_IDENTIFIER@1046..1049 + 0: IDENT@1046..1049 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@1049..1052 + 0: L_PAREN@1049..1050 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@1050..1050 + 2: R_PAREN@1050..1052 ")" [] [Whitespace(" ")] + 3: TS_ACCESSIBILITY_MODIFIER@1052..1059 + 0: PUBLIC_KW@1052..1059 "public" [] [Whitespace(" ")] + 1: SET_KW@1059..1063 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@1063..1066 + 0: IDENT@1063..1066 "foo" [] [] + 3: L_PAREN@1066..1067 "(" [] [] + 4: JS_FORMAL_PARAMETER@1067..1070 + 0: JS_IDENTIFIER_BINDING@1067..1070 + 0: IDENT@1067..1070 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@1070..1072 ")" [] [Whitespace(" ")] + 6: JS_FUNCTION_BODY@1072..1074 + 0: L_CURLY@1072..1073 "{" [] [] + 1: JS_DIRECTIVE_LIST@1073..1073 + 2: JS_STATEMENT_LIST@1073..1073 + 3: R_CURLY@1073..1074 "}" [] [] + 32: JS_SETTER_CLASS_MEMBER@1074..1102 + 0: JS_METHOD_MODIFIER_LIST@1074..1087 + 0: JS_DECORATOR@1074..1080 + 0: AT@1074..1076 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@1076..1080 + 0: JS_REFERENCE_IDENTIFIER@1076..1080 + 0: IDENT@1076..1080 "dec" [] [Whitespace(" ")] + 1: JS_STATIC_MODIFIER@1080..1087 + 0: STATIC_KW@1080..1087 "static" [] [Whitespace(" ")] + 1: SET_KW@1087..1091 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@1091..1094 + 0: IDENT@1091..1094 "foo" [] [] + 3: L_PAREN@1094..1095 "(" [] [] + 4: JS_FORMAL_PARAMETER@1095..1098 + 0: JS_IDENTIFIER_BINDING@1095..1098 + 0: IDENT@1095..1098 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@1098..1100 ")" [] [Whitespace(" ")] + 6: JS_FUNCTION_BODY@1100..1102 + 0: L_CURLY@1100..1101 "{" [] [] + 1: JS_DIRECTIVE_LIST@1101..1101 + 2: JS_STATEMENT_LIST@1101..1101 + 3: R_CURLY@1101..1102 "}" [] [] + 33: JS_SETTER_CLASS_MEMBER@1102..1150 + 0: JS_METHOD_MODIFIER_LIST@1102..1135 + 0: JS_DECORATOR@1102..1108 + 0: AT@1102..1104 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@1104..1108 + 0: JS_REFERENCE_IDENTIFIER@1104..1108 + 0: IDENT@1104..1108 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@1108..1121 + 0: AT@1108..1109 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@1109..1121 + 0: L_PAREN@1109..1110 "(" [] [] + 1: JS_AWAIT_EXPRESSION@1110..1119 + 0: AWAIT_KW@1110..1116 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@1116..1119 + 0: JS_REFERENCE_IDENTIFIER@1116..1119 + 0: IDENT@1116..1119 "dec" [] [] + 2: R_PAREN@1119..1121 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@1121..1128 + 0: AT@1121..1122 "@" [] [] + 1: JS_CALL_EXPRESSION@1122..1128 + 0: JS_IDENTIFIER_EXPRESSION@1122..1125 + 0: JS_REFERENCE_IDENTIFIER@1122..1125 + 0: IDENT@1122..1125 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@1125..1128 + 0: L_PAREN@1125..1126 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@1126..1126 + 2: R_PAREN@1126..1128 ")" [] [Whitespace(" ")] + 3: JS_STATIC_MODIFIER@1128..1135 + 0: STATIC_KW@1128..1135 "static" [] [Whitespace(" ")] + 1: SET_KW@1135..1139 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@1139..1142 + 0: IDENT@1139..1142 "foo" [] [] + 3: L_PAREN@1142..1143 "(" [] [] + 4: JS_FORMAL_PARAMETER@1143..1146 + 0: JS_IDENTIFIER_BINDING@1143..1146 + 0: IDENT@1143..1146 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@1146..1148 ")" [] [Whitespace(" ")] + 6: JS_FUNCTION_BODY@1148..1150 + 0: L_CURLY@1148..1149 "{" [] [] + 1: JS_DIRECTIVE_LIST@1149..1149 + 2: JS_STATEMENT_LIST@1149..1149 + 3: R_CURLY@1149..1150 "}" [] [] + 34: JS_SETTER_CLASS_MEMBER@1150..1180 + 0: JS_METHOD_MODIFIER_LIST@1150..1165 + 0: JS_DECORATOR@1150..1156 + 0: AT@1150..1152 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@1152..1156 + 0: JS_REFERENCE_IDENTIFIER@1152..1156 + 0: IDENT@1152..1156 "dec" [] [Whitespace(" ")] + 1: TS_OVERRIDE_MODIFIER@1156..1165 + 0: OVERRIDE_KW@1156..1165 "override" [] [Whitespace(" ")] + 1: SET_KW@1165..1169 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@1169..1172 + 0: IDENT@1169..1172 "foo" [] [] + 3: L_PAREN@1172..1173 "(" [] [] + 4: JS_FORMAL_PARAMETER@1173..1176 + 0: JS_IDENTIFIER_BINDING@1173..1176 + 0: IDENT@1173..1176 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@1176..1178 ")" [] [Whitespace(" ")] + 6: JS_FUNCTION_BODY@1178..1180 + 0: L_CURLY@1178..1179 "{" [] [] + 1: JS_DIRECTIVE_LIST@1179..1179 + 2: JS_STATEMENT_LIST@1179..1179 + 3: R_CURLY@1179..1180 "}" [] [] + 35: JS_SETTER_CLASS_MEMBER@1180..1230 + 0: JS_METHOD_MODIFIER_LIST@1180..1215 + 0: JS_DECORATOR@1180..1186 + 0: AT@1180..1182 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@1182..1186 + 0: JS_REFERENCE_IDENTIFIER@1182..1186 + 0: IDENT@1182..1186 "dec" [] [Whitespace(" ")] + 1: JS_DECORATOR@1186..1199 + 0: AT@1186..1187 "@" [] [] + 1: JS_PARENTHESIZED_EXPRESSION@1187..1199 + 0: L_PAREN@1187..1188 "(" [] [] + 1: JS_AWAIT_EXPRESSION@1188..1197 + 0: AWAIT_KW@1188..1194 "await" [] [Whitespace(" ")] + 1: JS_IDENTIFIER_EXPRESSION@1194..1197 + 0: JS_REFERENCE_IDENTIFIER@1194..1197 + 0: IDENT@1194..1197 "dec" [] [] + 2: R_PAREN@1197..1199 ")" [] [Whitespace(" ")] + 2: JS_DECORATOR@1199..1206 + 0: AT@1199..1200 "@" [] [] + 1: JS_CALL_EXPRESSION@1200..1206 + 0: JS_IDENTIFIER_EXPRESSION@1200..1203 + 0: JS_REFERENCE_IDENTIFIER@1200..1203 + 0: IDENT@1200..1203 "dec" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@1203..1206 + 0: L_PAREN@1203..1204 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@1204..1204 + 2: R_PAREN@1204..1206 ")" [] [Whitespace(" ")] + 3: TS_OVERRIDE_MODIFIER@1206..1215 + 0: OVERRIDE_KW@1206..1215 "override" [] [Whitespace(" ")] + 1: SET_KW@1215..1219 "set" [] [Whitespace(" ")] + 2: JS_LITERAL_MEMBER_NAME@1219..1222 + 0: IDENT@1219..1222 "foo" [] [] + 3: L_PAREN@1222..1223 "(" [] [] + 4: JS_FORMAL_PARAMETER@1223..1226 + 0: JS_IDENTIFIER_BINDING@1223..1226 + 0: IDENT@1223..1226 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 5: R_PAREN@1226..1228 ")" [] [Whitespace(" ")] + 6: JS_FUNCTION_BODY@1228..1230 + 0: L_CURLY@1228..1229 "{" [] [] + 1: JS_DIRECTIVE_LIST@1229..1229 + 2: JS_STATEMENT_LIST@1229..1229 + 3: R_CURLY@1229..1230 "}" [] [] + 9: R_CURLY@1230..1232 "}" [Newline("\n")] [] + 3: EOF@1232..1233 "" [Newline("\n")] [] diff --git a/crates/rome_js_parser/test_data/inline/ok/decorator_class_member.ts b/crates/rome_js_parser/test_data/inline/ok/decorator_class_member.ts new file mode 100644 index 00000000000..55f85e1c02d --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/decorator_class_member.ts @@ -0,0 +1,42 @@ +class Foo { +// properties +@dec foo = 2; +@dec @(await dec) @dec() foo = 2; +@dec public foo = 1; +@dec @(await dec) @dec() public foo = 1; +@dec static foo = 2; +@dec @(await dec) @dec() static foo = 2; +@dec accessor foo = 2; +@dec @(await dec) @dec() accessor foo = 2; +@dec readonly foo = 2; +@dec @(await dec) @dec() readonly foo = 2; +@dec override foo = 2; +@dec @(await dec) @dec() override foo = 2; +// methods +@dec foo() {} +@dec @(await dec) @dec() foo() {} +@dec public foo() {} +@dec @(await dec) @dec() public foo() {} +@dec static foo() {} +@dec @(await dec) @dec() static foo() {} +@dec override foo() {} +@dec @(await dec) @dec() override foo() {} +// getters +@dec get foo() {} +@dec @(await dec) @dec() get foo() {} +@dec public get foo() {} +@dec @(await dec) @dec() public get foo() {} +@dec static get foo() {} +@dec @(await dec) @dec() static get foo() {} +@dec override get foo() {} +@dec @(await dec) @dec() override get foo() {} +// setters +@dec set foo(val) {} +@dec @(await dec) @dec() set foo(val) {} +@dec public set foo(val) {} +@dec @(await dec) @dec() public set foo(val) {} +@dec static set foo(val) {} +@dec @(await dec) @dec() static set foo(val) {} +@dec override set foo(val) {} +@dec @(await dec) @dec() override set foo(val) {} +} diff --git a/crates/rome_js_parser/test_data/inline/ok/decorator_class_member_in_ts.rast b/crates/rome_js_parser/test_data/inline/ok/decorator_class_member_in_ts.rast new file mode 100644 index 00000000000..ee4e9a0b232 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/decorator_class_member_in_ts.rast @@ -0,0 +1,156 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: ABSTRACT_KW@0..9 "abstract" [] [Whitespace(" ")], + class_token: CLASS_KW@9..15 "class" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@15..19 "Qux" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@19..20 "{" [] [], + members: JsClassMemberList [ + TsPropertySignatureClassMember { + modifiers: TsPropertySignatureModifierList [ + JsDecorator { + at_token: AT@20..24 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@24..28 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsDeclareModifier { + modifier_token: DECLARE_KW@28..36 "declare" [] [Whitespace(" ")], + }, + JsStaticModifier { + modifier_token: STATIC_KW@36..43 "static" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@43..46 "foo" [] [], + }, + property_annotation: TsTypeAnnotation { + colon_token: COLON@46..48 ":" [] [Whitespace(" ")], + ty: TsStringType { + string_token: STRING_KW@48..54 "string" [] [], + }, + }, + semicolon_token: SEMICOLON@54..55 ";" [] [], + }, + ], + r_curly_token: R_CURLY@55..57 "}" [Newline("\n")] [], + }, + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@57..64 "class" [Newline("\n")] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@64..68 "Bar" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@68..69 "{" [] [], + members: JsClassMemberList [ + JsPropertyClassMember { + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@69..74 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@74..78 "dec" [] [Whitespace(" ")], + }, + }, + }, + TsReadonlyModifier { + modifier_token: READONLY_KW@78..87 "readonly" [] [Whitespace(" ")], + }, + ], + name: JsLiteralMemberName { + value: IDENT@87..91 "foo" [] [Whitespace(" ")], + }, + property_annotation: missing (optional), + value: JsInitializerClause { + eq_token: EQ@91..93 "=" [] [Whitespace(" ")], + expression: JsStringLiteralExpression { + value_token: JS_STRING_LITERAL@93..98 "'123'" [] [], + }, + }, + semicolon_token: SEMICOLON@98..99 ";" [] [], + }, + ], + r_curly_token: R_CURLY@99..101 "}" [Newline("\n")] [], + }, + ], + eof_token: EOF@101..102 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..102 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..101 + 0: JS_CLASS_DECLARATION@0..57 + 0: JS_DECORATOR_LIST@0..0 + 1: ABSTRACT_KW@0..9 "abstract" [] [Whitespace(" ")] + 2: CLASS_KW@9..15 "class" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@15..19 + 0: IDENT@15..19 "Qux" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@19..20 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@20..55 + 0: TS_PROPERTY_SIGNATURE_CLASS_MEMBER@20..55 + 0: TS_PROPERTY_SIGNATURE_MODIFIER_LIST@20..43 + 0: JS_DECORATOR@20..28 + 0: AT@20..24 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@24..28 + 0: JS_REFERENCE_IDENTIFIER@24..28 + 0: IDENT@24..28 "dec" [] [Whitespace(" ")] + 1: TS_DECLARE_MODIFIER@28..36 + 0: DECLARE_KW@28..36 "declare" [] [Whitespace(" ")] + 2: JS_STATIC_MODIFIER@36..43 + 0: STATIC_KW@36..43 "static" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@43..46 + 0: IDENT@43..46 "foo" [] [] + 2: TS_TYPE_ANNOTATION@46..54 + 0: COLON@46..48 ":" [] [Whitespace(" ")] + 1: TS_STRING_TYPE@48..54 + 0: STRING_KW@48..54 "string" [] [] + 3: SEMICOLON@54..55 ";" [] [] + 9: R_CURLY@55..57 "}" [Newline("\n")] [] + 1: JS_CLASS_DECLARATION@57..101 + 0: JS_DECORATOR_LIST@57..57 + 1: (empty) + 2: CLASS_KW@57..64 "class" [Newline("\n")] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@64..68 + 0: IDENT@64..68 "Bar" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@68..69 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@69..99 + 0: JS_PROPERTY_CLASS_MEMBER@69..99 + 0: JS_PROPERTY_MODIFIER_LIST@69..87 + 0: JS_DECORATOR@69..78 + 0: AT@69..74 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@74..78 + 0: JS_REFERENCE_IDENTIFIER@74..78 + 0: IDENT@74..78 "dec" [] [Whitespace(" ")] + 1: TS_READONLY_MODIFIER@78..87 + 0: READONLY_KW@78..87 "readonly" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@87..91 + 0: IDENT@87..91 "foo" [] [Whitespace(" ")] + 2: (empty) + 3: JS_INITIALIZER_CLAUSE@91..98 + 0: EQ@91..93 "=" [] [Whitespace(" ")] + 1: JS_STRING_LITERAL_EXPRESSION@93..98 + 0: JS_STRING_LITERAL@93..98 "'123'" [] [] + 4: SEMICOLON@98..99 ";" [] [] + 9: R_CURLY@99..101 "}" [Newline("\n")] [] + 3: EOF@101..102 "" [Newline("\n")] [] diff --git a/crates/rome_js_parser/test_data/inline/ok/decorator_class_member_in_ts.ts b/crates/rome_js_parser/test_data/inline/ok/decorator_class_member_in_ts.ts new file mode 100644 index 00000000000..8f3d4ebd87a --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/decorator_class_member_in_ts.ts @@ -0,0 +1,6 @@ +abstract class Qux { + @dec declare static foo: string; +} +class Bar { + @dec readonly foo = '123'; +} diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_decorate_computed_member.rast b/crates/rome_js_parser/test_data/inline/ok/ts_decorate_computed_member.rast index 40324e43030..b12820f6eed 100644 --- a/crates/rome_js_parser/test_data/inline/ok/ts_decorate_computed_member.rast +++ b/crates/rome_js_parser/test_data/inline/ok/ts_decorate_computed_member.rast @@ -15,9 +15,18 @@ JsModule { l_curly_token: L_CURLY@11..12 "{" [] [], members: JsClassMemberList [ JsPropertyClassMember { - modifiers: JsPropertyModifierList [], + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@12..14 "@" [Newline("\n")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@14..18 "test" [] [], + }, + }, + }, + ], name: JsComputedMemberName { - l_brack_token: L_BRACK@12..20 "[" [Newline("\n"), Skipped("@"), Skipped("test"), Newline("\n")] [], + l_brack_token: L_BRACK@18..20 "[" [Newline("\n")] [], expression: JsStringLiteralExpression { value_token: JS_STRING_LITERAL@20..23 "'a'" [] [], }, @@ -55,9 +64,14 @@ JsModule { 7: L_CURLY@11..12 "{" [] [] 8: JS_CLASS_MEMBER_LIST@12..33 0: JS_PROPERTY_CLASS_MEMBER@12..33 - 0: JS_PROPERTY_MODIFIER_LIST@12..12 - 1: JS_COMPUTED_MEMBER_NAME@12..24 - 0: L_BRACK@12..20 "[" [Newline("\n"), Skipped("@"), Skipped("test"), Newline("\n")] [] + 0: JS_PROPERTY_MODIFIER_LIST@12..18 + 0: JS_DECORATOR@12..18 + 0: AT@12..14 "@" [Newline("\n")] [] + 1: JS_IDENTIFIER_EXPRESSION@14..18 + 0: JS_REFERENCE_IDENTIFIER@14..18 + 0: IDENT@14..18 "test" [] [] + 1: JS_COMPUTED_MEMBER_NAME@18..24 + 0: L_BRACK@18..20 "[" [Newline("\n")] [] 1: JS_STRING_LITERAL_EXPRESSION@20..23 0: JS_STRING_LITERAL@20..23 "'a'" [] [] 2: R_BRACK@23..24 "]" [] [] diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_decorated_class_members.rast b/crates/rome_js_parser/test_data/inline/ok/ts_decorated_class_members.rast index c8c0907cdae..301d0dd9258 100644 --- a/crates/rome_js_parser/test_data/inline/ok/ts_decorated_class_members.rast +++ b/crates/rome_js_parser/test_data/inline/ok/ts_decorated_class_members.rast @@ -15,9 +15,18 @@ JsModule { l_curly_token: L_CURLY@11..12 "{" [] [], members: JsClassMemberList [ JsPropertyClassMember { - modifiers: JsPropertyModifierList [], + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@12..16 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@16..21 "test" [] [Whitespace(" ")], + }, + }, + }, + ], name: JsLiteralMemberName { - value: IDENT@12..25 "prop" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [], + value: IDENT@21..25 "prop" [] [], }, property_annotation: TsTypeAnnotation { colon_token: COLON@25..27 ":" [] [Whitespace(" ")], @@ -29,11 +38,20 @@ JsModule { semicolon_token: SEMICOLON@33..34 ";" [] [], }, JsMethodClassMember { - modifiers: JsMethodModifierList [], + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@34..38 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@38..43 "test" [] [Whitespace(" ")], + }, + }, + }, + ], async_token: missing (optional), star_token: missing (optional), name: JsLiteralMemberName { - value: IDENT@34..49 "method" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [], + value: IDENT@43..49 "method" [] [], }, question_mark_token: missing (optional), type_parameters: missing (optional), @@ -51,8 +69,17 @@ JsModule { }, }, JsGetterClassMember { - modifiers: JsMethodModifierList [], - get_token: GET_KW@54..67 "get" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")], + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@54..58 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@58..63 "test" [] [Whitespace(" ")], + }, + }, + }, + ], + get_token: GET_KW@63..67 "get" [] [Whitespace(" ")], name: JsLiteralMemberName { value: IDENT@67..73 "getter" [] [], }, @@ -67,8 +94,17 @@ JsModule { }, }, JsSetterClassMember { - modifiers: JsMethodModifierList [], - set_token: SET_KW@78..91 "set" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")], + modifiers: JsMethodModifierList [ + JsDecorator { + at_token: AT@78..82 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@82..87 "test" [] [Whitespace(" ")], + }, + }, + }, + ], + set_token: SET_KW@87..91 "set" [] [Whitespace(" ")], name: JsLiteralMemberName { value: IDENT@91..97 "setter" [] [], }, @@ -89,47 +125,18 @@ JsModule { r_curly_token: R_CURLY@102..103 "}" [] [], }, }, - JsConstructorClassMember { - modifiers: JsConstructorModifierList [], - name: JsLiteralMemberName { - value: IDENT@103..123 "constructor" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [], - }, - parameters: JsConstructorParameters { - l_paren_token: L_PAREN@123..124 "(" [] [], - parameters: JsConstructorParameterList [], - r_paren_token: R_PAREN@124..126 ")" [] [Whitespace(" ")], - }, - body: JsFunctionBody { - l_curly_token: L_CURLY@126..127 "{" [] [], - directives: JsDirectiveList [], - statements: JsStatementList [], - r_curly_token: R_CURLY@127..128 "}" [] [], - }, - }, - TsPropertySignatureClassMember { - modifiers: TsPropertySignatureModifierList [ - TsDeclareModifier { - modifier_token: DECLARE_KW@128..145 "declare" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")], - }, - ], - name: JsLiteralMemberName { - value: IDENT@145..149 "prop" [] [], - }, - property_annotation: missing (optional), - semicolon_token: SEMICOLON@149..150 ";" [] [], - }, ], - r_curly_token: R_CURLY@150..152 "}" [Newline("\n")] [], + r_curly_token: R_CURLY@103..105 "}" [Newline("\n")] [], }, ], - eof_token: EOF@152..153 "" [Newline("\n")] [], + eof_token: EOF@105..106 "" [Newline("\n")] [], } -0: JS_MODULE@0..153 +0: JS_MODULE@0..106 0: (empty) 1: JS_DIRECTIVE_LIST@0..0 - 2: JS_MODULE_ITEM_LIST@0..152 - 0: JS_CLASS_DECLARATION@0..152 + 2: JS_MODULE_ITEM_LIST@0..105 + 0: JS_CLASS_DECLARATION@0..105 0: JS_DECORATOR_LIST@0..0 1: (empty) 2: CLASS_KW@0..6 "class" [] [Whitespace(" ")] @@ -139,11 +146,16 @@ JsModule { 5: (empty) 6: (empty) 7: L_CURLY@11..12 "{" [] [] - 8: JS_CLASS_MEMBER_LIST@12..150 + 8: JS_CLASS_MEMBER_LIST@12..103 0: JS_PROPERTY_CLASS_MEMBER@12..34 - 0: JS_PROPERTY_MODIFIER_LIST@12..12 - 1: JS_LITERAL_MEMBER_NAME@12..25 - 0: IDENT@12..25 "prop" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [] + 0: JS_PROPERTY_MODIFIER_LIST@12..21 + 0: JS_DECORATOR@12..21 + 0: AT@12..16 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@16..21 + 0: JS_REFERENCE_IDENTIFIER@16..21 + 0: IDENT@16..21 "test" [] [Whitespace(" ")] + 1: JS_LITERAL_MEMBER_NAME@21..25 + 0: IDENT@21..25 "prop" [] [] 2: TS_TYPE_ANNOTATION@25..33 0: COLON@25..27 ":" [] [Whitespace(" ")] 1: TS_STRING_TYPE@27..33 @@ -151,11 +163,16 @@ JsModule { 3: (empty) 4: SEMICOLON@33..34 ";" [] [] 1: JS_METHOD_CLASS_MEMBER@34..54 - 0: JS_METHOD_MODIFIER_LIST@34..34 + 0: JS_METHOD_MODIFIER_LIST@34..43 + 0: JS_DECORATOR@34..43 + 0: AT@34..38 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@38..43 + 0: JS_REFERENCE_IDENTIFIER@38..43 + 0: IDENT@38..43 "test" [] [Whitespace(" ")] 1: (empty) 2: (empty) - 3: JS_LITERAL_MEMBER_NAME@34..49 - 0: IDENT@34..49 "method" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [] + 3: JS_LITERAL_MEMBER_NAME@43..49 + 0: IDENT@43..49 "method" [] [] 4: (empty) 5: (empty) 6: JS_PARAMETERS@49..52 @@ -169,8 +186,13 @@ JsModule { 2: JS_STATEMENT_LIST@53..53 3: R_CURLY@53..54 "}" [] [] 2: JS_GETTER_CLASS_MEMBER@54..78 - 0: JS_METHOD_MODIFIER_LIST@54..54 - 1: GET_KW@54..67 "get" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")] + 0: JS_METHOD_MODIFIER_LIST@54..63 + 0: JS_DECORATOR@54..63 + 0: AT@54..58 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@58..63 + 0: JS_REFERENCE_IDENTIFIER@58..63 + 0: IDENT@58..63 "test" [] [Whitespace(" ")] + 1: GET_KW@63..67 "get" [] [Whitespace(" ")] 2: JS_LITERAL_MEMBER_NAME@67..73 0: IDENT@67..73 "getter" [] [] 3: L_PAREN@73..74 "(" [] [] @@ -182,8 +204,13 @@ JsModule { 2: JS_STATEMENT_LIST@77..77 3: R_CURLY@77..78 "}" [] [] 3: JS_SETTER_CLASS_MEMBER@78..103 - 0: JS_METHOD_MODIFIER_LIST@78..78 - 1: SET_KW@78..91 "set" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")] + 0: JS_METHOD_MODIFIER_LIST@78..87 + 0: JS_DECORATOR@78..87 + 0: AT@78..82 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_IDENTIFIER_EXPRESSION@82..87 + 0: JS_REFERENCE_IDENTIFIER@82..87 + 0: IDENT@82..87 "test" [] [Whitespace(" ")] + 1: SET_KW@87..91 "set" [] [Whitespace(" ")] 2: JS_LITERAL_MEMBER_NAME@91..97 0: IDENT@91..97 "setter" [] [] 3: L_PAREN@97..98 "(" [] [] @@ -199,26 +226,5 @@ JsModule { 1: JS_DIRECTIVE_LIST@102..102 2: JS_STATEMENT_LIST@102..102 3: R_CURLY@102..103 "}" [] [] - 4: JS_CONSTRUCTOR_CLASS_MEMBER@103..128 - 0: JS_CONSTRUCTOR_MODIFIER_LIST@103..103 - 1: JS_LITERAL_MEMBER_NAME@103..123 - 0: IDENT@103..123 "constructor" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [] - 2: JS_CONSTRUCTOR_PARAMETERS@123..126 - 0: L_PAREN@123..124 "(" [] [] - 1: JS_CONSTRUCTOR_PARAMETER_LIST@124..124 - 2: R_PAREN@124..126 ")" [] [Whitespace(" ")] - 3: JS_FUNCTION_BODY@126..128 - 0: L_CURLY@126..127 "{" [] [] - 1: JS_DIRECTIVE_LIST@127..127 - 2: JS_STATEMENT_LIST@127..127 - 3: R_CURLY@127..128 "}" [] [] - 5: TS_PROPERTY_SIGNATURE_CLASS_MEMBER@128..150 - 0: TS_PROPERTY_SIGNATURE_MODIFIER_LIST@128..145 - 0: TS_DECLARE_MODIFIER@128..145 - 0: DECLARE_KW@128..145 "declare" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("test"), Whitespace(" ")] [Whitespace(" ")] - 1: JS_LITERAL_MEMBER_NAME@145..149 - 0: IDENT@145..149 "prop" [] [] - 2: (empty) - 3: SEMICOLON@149..150 ";" [] [] - 9: R_CURLY@150..152 "}" [Newline("\n")] [] - 3: EOF@152..153 "" [Newline("\n")] [] + 9: R_CURLY@103..105 "}" [Newline("\n")] [] + 3: EOF@105..106 "" [Newline("\n")] [] diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_decorated_class_members.ts b/crates/rome_js_parser/test_data/inline/ok/ts_decorated_class_members.ts index 5e2841ae19c..9ef84561eca 100644 --- a/crates/rome_js_parser/test_data/inline/ok/ts_decorated_class_members.ts +++ b/crates/rome_js_parser/test_data/inline/ok/ts_decorated_class_members.ts @@ -3,6 +3,4 @@ class Test { @test method() {} @test get getter() {} @test set setter(a) {} - @test constructor() {} - @test declare prop; } diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_call_expression_with_arrow.rast b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_call_expression_with_arrow.rast index 19ee51e12fc..957fd595b1c 100644 --- a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_call_expression_with_arrow.rast +++ b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_call_expression_with_arrow.rast @@ -18,9 +18,53 @@ JsModule { l_curly_token: L_CURLY@17..18 "{" [] [], members: JsClassMemberList [ JsPropertyClassMember { - modifiers: JsPropertyModifierList [], + modifiers: JsPropertyModifierList [ + JsDecorator { + at_token: AT@18..21 "@" [Newline("\n"), Whitespace(" ")] [], + expression: JsCallExpression { + callee: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@21..30 "Decorator" [] [], + }, + }, + optional_chain_token: missing (optional), + type_arguments: missing (optional), + arguments: JsCallArguments { + l_paren_token: L_PAREN@30..31 "(" [] [], + args: JsCallArgumentList [ + JsArrowFunctionExpression { + async_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@31..32 "(" [] [], + items: JsParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@32..35 "val" [] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@35..37 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + fat_arrow_token: FAT_ARROW@37..40 "=>" [] [Whitespace(" ")], + body: JsIdentifierExpression { + name: JsReferenceIdentifier { + value_token: IDENT@40..43 "val" [] [], + }, + }, + }, + ], + r_paren_token: R_PAREN@43..44 ")" [] [], + }, + }, + }, + ], name: JsLiteralMemberName { - value: IDENT@18..54 "badField" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("Decorator"), Skipped("("), Skipped("("), Skipped("val"), Skipped(")"), Whitespace(" "), Skipped("=>"), Whitespace(" "), Skipped("val"), Skipped(")"), Newline("\n"), Whitespace(" ")] [], + value: IDENT@44..54 "badField" [Newline("\n"), Whitespace(" ")] [], }, property_annotation: TsDefinitePropertyAnnotation { excl_token: BANG@54..55 "!" [] [], @@ -61,9 +105,39 @@ JsModule { 7: L_CURLY@17..18 "{" [] [] 8: JS_CLASS_MEMBER_LIST@18..63 0: JS_PROPERTY_CLASS_MEMBER@18..63 - 0: JS_PROPERTY_MODIFIER_LIST@18..18 - 1: JS_LITERAL_MEMBER_NAME@18..54 - 0: IDENT@18..54 "badField" [Newline("\n"), Whitespace(" "), Skipped("@"), Skipped("Decorator"), Skipped("("), Skipped("("), Skipped("val"), Skipped(")"), Whitespace(" "), Skipped("=>"), Whitespace(" "), Skipped("val"), Skipped(")"), Newline("\n"), Whitespace(" ")] [] + 0: JS_PROPERTY_MODIFIER_LIST@18..44 + 0: JS_DECORATOR@18..44 + 0: AT@18..21 "@" [Newline("\n"), Whitespace(" ")] [] + 1: JS_CALL_EXPRESSION@21..44 + 0: JS_IDENTIFIER_EXPRESSION@21..30 + 0: JS_REFERENCE_IDENTIFIER@21..30 + 0: IDENT@21..30 "Decorator" [] [] + 1: (empty) + 2: (empty) + 3: JS_CALL_ARGUMENTS@30..44 + 0: L_PAREN@30..31 "(" [] [] + 1: JS_CALL_ARGUMENT_LIST@31..43 + 0: JS_ARROW_FUNCTION_EXPRESSION@31..43 + 0: (empty) + 1: (empty) + 2: JS_PARAMETERS@31..37 + 0: L_PAREN@31..32 "(" [] [] + 1: JS_PARAMETER_LIST@32..35 + 0: JS_FORMAL_PARAMETER@32..35 + 0: JS_IDENTIFIER_BINDING@32..35 + 0: IDENT@32..35 "val" [] [] + 1: (empty) + 2: (empty) + 3: (empty) + 2: R_PAREN@35..37 ")" [] [Whitespace(" ")] + 3: (empty) + 4: FAT_ARROW@37..40 "=>" [] [Whitespace(" ")] + 5: JS_IDENTIFIER_EXPRESSION@40..43 + 0: JS_REFERENCE_IDENTIFIER@40..43 + 0: IDENT@40..43 "val" [] [] + 2: R_PAREN@43..44 ")" [] [] + 1: JS_LITERAL_MEMBER_NAME@44..54 + 0: IDENT@44..54 "badField" [Newline("\n"), Whitespace(" ")] [] 2: TS_DEFINITE_PROPERTY_ANNOTATION@54..63 0: BANG@54..55 "!" [] [] 1: TS_TYPE_ANNOTATION@55..63 diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.rast b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.rast new file mode 100644 index 00000000000..657ff63b44a --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.rast @@ -0,0 +1,104 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@0..6 "class" [] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@6..8 "C" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@8..9 "{" [] [], + members: JsClassMemberList [ + JsConstructorClassMember { + modifiers: JsConstructorModifierList [], + name: JsLiteralMemberName { + value: IDENT@9..25 "constructor" [Newline("\n"), Whitespace(" ")] [], + }, + parameters: JsConstructorParameters { + l_paren_token: L_PAREN@25..26 "(" [] [], + parameters: JsConstructorParameterList [ + TsPropertyParameter { + modifiers: TsPropertyParameterModifierList [ + TsReadonlyModifier { + modifier_token: READONLY_KW@26..40 "readonly" [Skipped("@"), Skipped("foo"), Whitespace(" ")] [Whitespace(" ")], + }, + ], + formal_parameter: JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@40..41 "x" [] [], + }, + question_mark_token: missing (optional), + type_annotation: TsTypeAnnotation { + colon_token: COLON@41..43 ":" [] [Whitespace(" ")], + ty: TsNumberType { + number_token: NUMBER_KW@43..49 "number" [] [], + }, + }, + initializer: missing (optional), + }, + }, + ], + r_paren_token: R_PAREN@49..51 ")" [] [Whitespace(" ")], + }, + body: JsFunctionBody { + l_curly_token: L_CURLY@51..52 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@52..53 "}" [] [], + }, + }, + ], + r_curly_token: R_CURLY@53..55 "}" [Newline("\n")] [], + }, + ], + eof_token: EOF@55..56 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..56 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..55 + 0: JS_CLASS_DECLARATION@0..55 + 0: JS_DECORATOR_LIST@0..0 + 1: (empty) + 2: CLASS_KW@0..6 "class" [] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@6..8 + 0: IDENT@6..8 "C" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@8..9 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@9..53 + 0: JS_CONSTRUCTOR_CLASS_MEMBER@9..53 + 0: JS_CONSTRUCTOR_MODIFIER_LIST@9..9 + 1: JS_LITERAL_MEMBER_NAME@9..25 + 0: IDENT@9..25 "constructor" [Newline("\n"), Whitespace(" ")] [] + 2: JS_CONSTRUCTOR_PARAMETERS@25..51 + 0: L_PAREN@25..26 "(" [] [] + 1: JS_CONSTRUCTOR_PARAMETER_LIST@26..49 + 0: TS_PROPERTY_PARAMETER@26..49 + 0: TS_PROPERTY_PARAMETER_MODIFIER_LIST@26..40 + 0: TS_READONLY_MODIFIER@26..40 + 0: READONLY_KW@26..40 "readonly" [Skipped("@"), Skipped("foo"), Whitespace(" ")] [Whitespace(" ")] + 1: JS_FORMAL_PARAMETER@40..49 + 0: JS_IDENTIFIER_BINDING@40..41 + 0: IDENT@40..41 "x" [] [] + 1: (empty) + 2: TS_TYPE_ANNOTATION@41..49 + 0: COLON@41..43 ":" [] [Whitespace(" ")] + 1: TS_NUMBER_TYPE@43..49 + 0: NUMBER_KW@43..49 "number" [] [] + 3: (empty) + 2: R_PAREN@49..51 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@51..53 + 0: L_CURLY@51..52 "{" [] [] + 1: JS_DIRECTIVE_LIST@52..52 + 2: JS_STATEMENT_LIST@52..52 + 3: R_CURLY@52..53 "}" [] [] + 9: R_CURLY@53..55 "}" [Newline("\n")] [] + 3: EOF@55..56 "" [Newline("\n")] [] diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.ts b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.ts new file mode 100644 index 00000000000..c5e8d315dbe --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_decorator_constructor.ts @@ -0,0 +1,3 @@ +class C { + constructor(@foo readonly x: number) {} +} diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.rast b/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.rast new file mode 100644 index 00000000000..eb286327685 --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.rast @@ -0,0 +1,193 @@ +JsModule { + interpreter_token: missing (optional), + directives: JsDirectiveList [], + items: JsModuleItemList [ + JsFunctionDeclaration { + async_token: missing (optional), + function_token: FUNCTION_KW@0..9 "function" [] [Whitespace(" ")], + star_token: missing (optional), + id: JsIdentifierBinding { + name_token: IDENT@9..10 "a" [] [], + }, + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@10..11 "(" [] [], + items: JsParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@11..17 "x" [Skipped("@"), Skipped("dec"), Whitespace(" ")] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@17..19 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@19..20 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@20..21 "}" [] [], + }, + }, + JsClassDeclaration { + decorators: JsDecoratorList [], + abstract_token: missing (optional), + class_token: CLASS_KW@21..28 "class" [Newline("\n")] [Whitespace(" ")], + id: JsIdentifierBinding { + name_token: IDENT@28..32 "Foo" [] [Whitespace(" ")], + }, + type_parameters: missing (optional), + extends_clause: missing (optional), + implements_clause: missing (optional), + l_curly_token: L_CURLY@32..33 "{" [] [], + members: JsClassMemberList [ + JsConstructorClassMember { + modifiers: JsConstructorModifierList [], + name: JsLiteralMemberName { + value: IDENT@33..48 "constructor" [Newline("\n"), Whitespace(" ")] [], + }, + parameters: JsConstructorParameters { + l_paren_token: L_PAREN@48..49 "(" [] [], + parameters: JsConstructorParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@49..55 "x" [Skipped("@"), Skipped("dec"), Whitespace(" ")] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@55..57 ")" [] [Whitespace(" ")], + }, + body: JsFunctionBody { + l_curly_token: L_CURLY@57..58 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@58..59 "}" [] [], + }, + }, + JsMethodClassMember { + modifiers: JsMethodModifierList [], + async_token: missing (optional), + star_token: missing (optional), + name: JsLiteralMemberName { + value: IDENT@59..69 "method" [Newline("\n"), Whitespace(" ")] [], + }, + question_mark_token: missing (optional), + type_parameters: missing (optional), + parameters: JsParameters { + l_paren_token: L_PAREN@69..70 "(" [] [], + items: JsParameterList [ + JsFormalParameter { + binding: JsIdentifierBinding { + name_token: IDENT@70..76 "x" [Skipped("@"), Skipped("dec"), Whitespace(" ")] [], + }, + question_mark_token: missing (optional), + type_annotation: missing (optional), + initializer: missing (optional), + }, + ], + r_paren_token: R_PAREN@76..78 ")" [] [Whitespace(" ")], + }, + return_type_annotation: missing (optional), + body: JsFunctionBody { + l_curly_token: L_CURLY@78..79 "{" [] [], + directives: JsDirectiveList [], + statements: JsStatementList [], + r_curly_token: R_CURLY@79..80 "}" [] [], + }, + }, + ], + r_curly_token: R_CURLY@80..82 "}" [Newline("\n")] [], + }, + ], + eof_token: EOF@82..83 "" [Newline("\n")] [], +} + +0: JS_MODULE@0..83 + 0: (empty) + 1: JS_DIRECTIVE_LIST@0..0 + 2: JS_MODULE_ITEM_LIST@0..82 + 0: JS_FUNCTION_DECLARATION@0..21 + 0: (empty) + 1: FUNCTION_KW@0..9 "function" [] [Whitespace(" ")] + 2: (empty) + 3: JS_IDENTIFIER_BINDING@9..10 + 0: IDENT@9..10 "a" [] [] + 4: (empty) + 5: JS_PARAMETERS@10..19 + 0: L_PAREN@10..11 "(" [] [] + 1: JS_PARAMETER_LIST@11..17 + 0: JS_FORMAL_PARAMETER@11..17 + 0: JS_IDENTIFIER_BINDING@11..17 + 0: IDENT@11..17 "x" [Skipped("@"), Skipped("dec"), Whitespace(" ")] [] + 1: (empty) + 2: (empty) + 3: (empty) + 2: R_PAREN@17..19 ")" [] [Whitespace(" ")] + 6: (empty) + 7: JS_FUNCTION_BODY@19..21 + 0: L_CURLY@19..20 "{" [] [] + 1: JS_DIRECTIVE_LIST@20..20 + 2: JS_STATEMENT_LIST@20..20 + 3: R_CURLY@20..21 "}" [] [] + 1: JS_CLASS_DECLARATION@21..82 + 0: JS_DECORATOR_LIST@21..21 + 1: (empty) + 2: CLASS_KW@21..28 "class" [Newline("\n")] [Whitespace(" ")] + 3: JS_IDENTIFIER_BINDING@28..32 + 0: IDENT@28..32 "Foo" [] [Whitespace(" ")] + 4: (empty) + 5: (empty) + 6: (empty) + 7: L_CURLY@32..33 "{" [] [] + 8: JS_CLASS_MEMBER_LIST@33..80 + 0: JS_CONSTRUCTOR_CLASS_MEMBER@33..59 + 0: JS_CONSTRUCTOR_MODIFIER_LIST@33..33 + 1: JS_LITERAL_MEMBER_NAME@33..48 + 0: IDENT@33..48 "constructor" [Newline("\n"), Whitespace(" ")] [] + 2: JS_CONSTRUCTOR_PARAMETERS@48..57 + 0: L_PAREN@48..49 "(" [] [] + 1: JS_CONSTRUCTOR_PARAMETER_LIST@49..55 + 0: JS_FORMAL_PARAMETER@49..55 + 0: JS_IDENTIFIER_BINDING@49..55 + 0: IDENT@49..55 "x" [Skipped("@"), Skipped("dec"), Whitespace(" ")] [] + 1: (empty) + 2: (empty) + 3: (empty) + 2: R_PAREN@55..57 ")" [] [Whitespace(" ")] + 3: JS_FUNCTION_BODY@57..59 + 0: L_CURLY@57..58 "{" [] [] + 1: JS_DIRECTIVE_LIST@58..58 + 2: JS_STATEMENT_LIST@58..58 + 3: R_CURLY@58..59 "}" [] [] + 1: JS_METHOD_CLASS_MEMBER@59..80 + 0: JS_METHOD_MODIFIER_LIST@59..59 + 1: (empty) + 2: (empty) + 3: JS_LITERAL_MEMBER_NAME@59..69 + 0: IDENT@59..69 "method" [Newline("\n"), Whitespace(" ")] [] + 4: (empty) + 5: (empty) + 6: JS_PARAMETERS@69..78 + 0: L_PAREN@69..70 "(" [] [] + 1: JS_PARAMETER_LIST@70..76 + 0: JS_FORMAL_PARAMETER@70..76 + 0: JS_IDENTIFIER_BINDING@70..76 + 0: IDENT@70..76 "x" [Skipped("@"), Skipped("dec"), Whitespace(" ")] [] + 1: (empty) + 2: (empty) + 3: (empty) + 2: R_PAREN@76..78 ")" [] [Whitespace(" ")] + 7: (empty) + 8: JS_FUNCTION_BODY@78..80 + 0: L_CURLY@78..79 "{" [] [] + 1: JS_DIRECTIVE_LIST@79..79 + 2: JS_STATEMENT_LIST@79..79 + 3: R_CURLY@79..80 "}" [] [] + 9: R_CURLY@80..82 "}" [Newline("\n")] [] + 3: EOF@82..83 "" [Newline("\n")] [] diff --git a/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.ts b/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.ts new file mode 100644 index 00000000000..404841bfa8a --- /dev/null +++ b/crates/rome_js_parser/test_data/inline/ok/ts_formal_parameter_decorator.ts @@ -0,0 +1,5 @@ +function a(@dec x) {} +class Foo { + constructor(@dec x) {} + method(@dec x) {} +} diff --git a/crates/rome_js_syntax/src/generated/nodes.rs b/crates/rome_js_syntax/src/generated/nodes.rs index 6789ad17ea9..3ab91f8e2d3 100644 --- a/crates/rome_js_syntax/src/generated/nodes.rs +++ b/crates/rome_js_syntax/src/generated/nodes.rs @@ -13639,11 +13639,18 @@ impl AnyJsLiteralExpression { #[derive(Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize))] pub enum AnyJsMethodModifier { + JsDecorator(JsDecorator), JsStaticModifier(JsStaticModifier), TsAccessibilityModifier(TsAccessibilityModifier), TsOverrideModifier(TsOverrideModifier), } impl AnyJsMethodModifier { + pub fn as_js_decorator(&self) -> Option<&JsDecorator> { + match &self { + AnyJsMethodModifier::JsDecorator(item) => Some(item), + _ => None, + } + } pub fn as_js_static_modifier(&self) -> Option<&JsStaticModifier> { match &self { AnyJsMethodModifier::JsStaticModifier(item) => Some(item), @@ -13947,6 +13954,7 @@ impl AnyJsParameter { #[cfg_attr(feature = "serde", derive(Serialize))] pub enum AnyJsPropertyModifier { JsAccessorModifier(JsAccessorModifier), + JsDecorator(JsDecorator), JsStaticModifier(JsStaticModifier), TsAccessibilityModifier(TsAccessibilityModifier), TsOverrideModifier(TsOverrideModifier), @@ -13959,6 +13967,12 @@ impl AnyJsPropertyModifier { _ => None, } } + pub fn as_js_decorator(&self) -> Option<&JsDecorator> { + match &self { + AnyJsPropertyModifier::JsDecorator(item) => Some(item), + _ => None, + } + } pub fn as_js_static_modifier(&self) -> Option<&JsStaticModifier> { match &self { AnyJsPropertyModifier::JsStaticModifier(item) => Some(item), @@ -14551,12 +14565,19 @@ impl AnyTsIndexSignatureModifier { #[derive(Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(Serialize))] pub enum AnyTsMethodSignatureModifier { + JsDecorator(JsDecorator), JsStaticModifier(JsStaticModifier), TsAbstractModifier(TsAbstractModifier), TsAccessibilityModifier(TsAccessibilityModifier), TsOverrideModifier(TsOverrideModifier), } impl AnyTsMethodSignatureModifier { + pub fn as_js_decorator(&self) -> Option<&JsDecorator> { + match &self { + AnyTsMethodSignatureModifier::JsDecorator(item) => Some(item), + _ => None, + } + } pub fn as_js_static_modifier(&self) -> Option<&JsStaticModifier> { match &self { AnyTsMethodSignatureModifier::JsStaticModifier(item) => Some(item), @@ -14720,6 +14741,7 @@ impl AnyTsPropertySignatureAnnotation { #[cfg_attr(feature = "serde", derive(Serialize))] pub enum AnyTsPropertySignatureModifier { JsAccessorModifier(JsAccessorModifier), + JsDecorator(JsDecorator), JsStaticModifier(JsStaticModifier), TsAbstractModifier(TsAbstractModifier), TsAccessibilityModifier(TsAccessibilityModifier), @@ -14734,6 +14756,12 @@ impl AnyTsPropertySignatureModifier { _ => None, } } + pub fn as_js_decorator(&self) -> Option<&JsDecorator> { + match &self { + AnyTsPropertySignatureModifier::JsDecorator(item) => Some(item), + _ => None, + } + } pub fn as_js_static_modifier(&self) -> Option<&JsStaticModifier> { match &self { AnyTsPropertySignatureModifier::JsStaticModifier(item) => Some(item), @@ -28709,6 +28737,9 @@ impl From for SyntaxElement { node.into() } } +impl From for AnyJsMethodModifier { + fn from(node: JsDecorator) -> AnyJsMethodModifier { AnyJsMethodModifier::JsDecorator(node) } +} impl From for AnyJsMethodModifier { fn from(node: JsStaticModifier) -> AnyJsMethodModifier { AnyJsMethodModifier::JsStaticModifier(node) @@ -28726,17 +28757,19 @@ impl From for AnyJsMethodModifier { } impl AstNode for AnyJsMethodModifier { type Language = Language; - const KIND_SET: SyntaxKindSet = JsStaticModifier::KIND_SET + const KIND_SET: SyntaxKindSet = JsDecorator::KIND_SET + .union(JsStaticModifier::KIND_SET) .union(TsAccessibilityModifier::KIND_SET) .union(TsOverrideModifier::KIND_SET); fn can_cast(kind: SyntaxKind) -> bool { matches!( kind, - JS_STATIC_MODIFIER | TS_ACCESSIBILITY_MODIFIER | TS_OVERRIDE_MODIFIER + JS_DECORATOR | JS_STATIC_MODIFIER | TS_ACCESSIBILITY_MODIFIER | TS_OVERRIDE_MODIFIER ) } fn cast(syntax: SyntaxNode) -> Option { let res = match syntax.kind() { + JS_DECORATOR => AnyJsMethodModifier::JsDecorator(JsDecorator { syntax }), JS_STATIC_MODIFIER => { AnyJsMethodModifier::JsStaticModifier(JsStaticModifier { syntax }) } @@ -28752,6 +28785,7 @@ impl AstNode for AnyJsMethodModifier { } fn syntax(&self) -> &SyntaxNode { match self { + AnyJsMethodModifier::JsDecorator(it) => &it.syntax, AnyJsMethodModifier::JsStaticModifier(it) => &it.syntax, AnyJsMethodModifier::TsAccessibilityModifier(it) => &it.syntax, AnyJsMethodModifier::TsOverrideModifier(it) => &it.syntax, @@ -28759,6 +28793,7 @@ impl AstNode for AnyJsMethodModifier { } fn into_syntax(self) -> SyntaxNode { match self { + AnyJsMethodModifier::JsDecorator(it) => it.syntax, AnyJsMethodModifier::JsStaticModifier(it) => it.syntax, AnyJsMethodModifier::TsAccessibilityModifier(it) => it.syntax, AnyJsMethodModifier::TsOverrideModifier(it) => it.syntax, @@ -28768,6 +28803,7 @@ impl AstNode for AnyJsMethodModifier { impl std::fmt::Debug for AnyJsMethodModifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + AnyJsMethodModifier::JsDecorator(it) => std::fmt::Debug::fmt(it, f), AnyJsMethodModifier::JsStaticModifier(it) => std::fmt::Debug::fmt(it, f), AnyJsMethodModifier::TsAccessibilityModifier(it) => std::fmt::Debug::fmt(it, f), AnyJsMethodModifier::TsOverrideModifier(it) => std::fmt::Debug::fmt(it, f), @@ -28777,6 +28813,7 @@ impl std::fmt::Debug for AnyJsMethodModifier { impl From for SyntaxNode { fn from(n: AnyJsMethodModifier) -> SyntaxNode { match n { + AnyJsMethodModifier::JsDecorator(it) => it.into(), AnyJsMethodModifier::JsStaticModifier(it) => it.into(), AnyJsMethodModifier::TsAccessibilityModifier(it) => it.into(), AnyJsMethodModifier::TsOverrideModifier(it) => it.into(), @@ -29574,6 +29611,9 @@ impl From for AnyJsPropertyModifier { AnyJsPropertyModifier::JsAccessorModifier(node) } } +impl From for AnyJsPropertyModifier { + fn from(node: JsDecorator) -> AnyJsPropertyModifier { AnyJsPropertyModifier::JsDecorator(node) } +} impl From for AnyJsPropertyModifier { fn from(node: JsStaticModifier) -> AnyJsPropertyModifier { AnyJsPropertyModifier::JsStaticModifier(node) @@ -29597,6 +29637,7 @@ impl From for AnyJsPropertyModifier { impl AstNode for AnyJsPropertyModifier { type Language = Language; const KIND_SET: SyntaxKindSet = JsAccessorModifier::KIND_SET + .union(JsDecorator::KIND_SET) .union(JsStaticModifier::KIND_SET) .union(TsAccessibilityModifier::KIND_SET) .union(TsOverrideModifier::KIND_SET) @@ -29605,6 +29646,7 @@ impl AstNode for AnyJsPropertyModifier { matches!( kind, JS_ACCESSOR_MODIFIER + | JS_DECORATOR | JS_STATIC_MODIFIER | TS_ACCESSIBILITY_MODIFIER | TS_OVERRIDE_MODIFIER @@ -29616,6 +29658,7 @@ impl AstNode for AnyJsPropertyModifier { JS_ACCESSOR_MODIFIER => { AnyJsPropertyModifier::JsAccessorModifier(JsAccessorModifier { syntax }) } + JS_DECORATOR => AnyJsPropertyModifier::JsDecorator(JsDecorator { syntax }), JS_STATIC_MODIFIER => { AnyJsPropertyModifier::JsStaticModifier(JsStaticModifier { syntax }) } @@ -29635,6 +29678,7 @@ impl AstNode for AnyJsPropertyModifier { fn syntax(&self) -> &SyntaxNode { match self { AnyJsPropertyModifier::JsAccessorModifier(it) => &it.syntax, + AnyJsPropertyModifier::JsDecorator(it) => &it.syntax, AnyJsPropertyModifier::JsStaticModifier(it) => &it.syntax, AnyJsPropertyModifier::TsAccessibilityModifier(it) => &it.syntax, AnyJsPropertyModifier::TsOverrideModifier(it) => &it.syntax, @@ -29644,6 +29688,7 @@ impl AstNode for AnyJsPropertyModifier { fn into_syntax(self) -> SyntaxNode { match self { AnyJsPropertyModifier::JsAccessorModifier(it) => it.syntax, + AnyJsPropertyModifier::JsDecorator(it) => it.syntax, AnyJsPropertyModifier::JsStaticModifier(it) => it.syntax, AnyJsPropertyModifier::TsAccessibilityModifier(it) => it.syntax, AnyJsPropertyModifier::TsOverrideModifier(it) => it.syntax, @@ -29655,6 +29700,7 @@ impl std::fmt::Debug for AnyJsPropertyModifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { AnyJsPropertyModifier::JsAccessorModifier(it) => std::fmt::Debug::fmt(it, f), + AnyJsPropertyModifier::JsDecorator(it) => std::fmt::Debug::fmt(it, f), AnyJsPropertyModifier::JsStaticModifier(it) => std::fmt::Debug::fmt(it, f), AnyJsPropertyModifier::TsAccessibilityModifier(it) => std::fmt::Debug::fmt(it, f), AnyJsPropertyModifier::TsOverrideModifier(it) => std::fmt::Debug::fmt(it, f), @@ -29666,6 +29712,7 @@ impl From for SyntaxNode { fn from(n: AnyJsPropertyModifier) -> SyntaxNode { match n { AnyJsPropertyModifier::JsAccessorModifier(it) => it.into(), + AnyJsPropertyModifier::JsDecorator(it) => it.into(), AnyJsPropertyModifier::JsStaticModifier(it) => it.into(), AnyJsPropertyModifier::TsAccessibilityModifier(it) => it.into(), AnyJsPropertyModifier::TsOverrideModifier(it) => it.into(), @@ -30993,6 +31040,11 @@ impl From for SyntaxElement { node.into() } } +impl From for AnyTsMethodSignatureModifier { + fn from(node: JsDecorator) -> AnyTsMethodSignatureModifier { + AnyTsMethodSignatureModifier::JsDecorator(node) + } +} impl From for AnyTsMethodSignatureModifier { fn from(node: JsStaticModifier) -> AnyTsMethodSignatureModifier { AnyTsMethodSignatureModifier::JsStaticModifier(node) @@ -31015,14 +31067,16 @@ impl From for AnyTsMethodSignatureModifier { } impl AstNode for AnyTsMethodSignatureModifier { type Language = Language; - const KIND_SET: SyntaxKindSet = JsStaticModifier::KIND_SET + const KIND_SET: SyntaxKindSet = JsDecorator::KIND_SET + .union(JsStaticModifier::KIND_SET) .union(TsAbstractModifier::KIND_SET) .union(TsAccessibilityModifier::KIND_SET) .union(TsOverrideModifier::KIND_SET); fn can_cast(kind: SyntaxKind) -> bool { matches!( kind, - JS_STATIC_MODIFIER + JS_DECORATOR + | JS_STATIC_MODIFIER | TS_ABSTRACT_MODIFIER | TS_ACCESSIBILITY_MODIFIER | TS_OVERRIDE_MODIFIER @@ -31030,6 +31084,7 @@ impl AstNode for AnyTsMethodSignatureModifier { } fn cast(syntax: SyntaxNode) -> Option { let res = match syntax.kind() { + JS_DECORATOR => AnyTsMethodSignatureModifier::JsDecorator(JsDecorator { syntax }), JS_STATIC_MODIFIER => { AnyTsMethodSignatureModifier::JsStaticModifier(JsStaticModifier { syntax }) } @@ -31050,6 +31105,7 @@ impl AstNode for AnyTsMethodSignatureModifier { } fn syntax(&self) -> &SyntaxNode { match self { + AnyTsMethodSignatureModifier::JsDecorator(it) => &it.syntax, AnyTsMethodSignatureModifier::JsStaticModifier(it) => &it.syntax, AnyTsMethodSignatureModifier::TsAbstractModifier(it) => &it.syntax, AnyTsMethodSignatureModifier::TsAccessibilityModifier(it) => &it.syntax, @@ -31058,6 +31114,7 @@ impl AstNode for AnyTsMethodSignatureModifier { } fn into_syntax(self) -> SyntaxNode { match self { + AnyTsMethodSignatureModifier::JsDecorator(it) => it.syntax, AnyTsMethodSignatureModifier::JsStaticModifier(it) => it.syntax, AnyTsMethodSignatureModifier::TsAbstractModifier(it) => it.syntax, AnyTsMethodSignatureModifier::TsAccessibilityModifier(it) => it.syntax, @@ -31068,6 +31125,7 @@ impl AstNode for AnyTsMethodSignatureModifier { impl std::fmt::Debug for AnyTsMethodSignatureModifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { + AnyTsMethodSignatureModifier::JsDecorator(it) => std::fmt::Debug::fmt(it, f), AnyTsMethodSignatureModifier::JsStaticModifier(it) => std::fmt::Debug::fmt(it, f), AnyTsMethodSignatureModifier::TsAbstractModifier(it) => std::fmt::Debug::fmt(it, f), AnyTsMethodSignatureModifier::TsAccessibilityModifier(it) => { @@ -31080,6 +31138,7 @@ impl std::fmt::Debug for AnyTsMethodSignatureModifier { impl From for SyntaxNode { fn from(n: AnyTsMethodSignatureModifier) -> SyntaxNode { match n { + AnyTsMethodSignatureModifier::JsDecorator(it) => it.into(), AnyTsMethodSignatureModifier::JsStaticModifier(it) => it.into(), AnyTsMethodSignatureModifier::TsAbstractModifier(it) => it.into(), AnyTsMethodSignatureModifier::TsAccessibilityModifier(it) => it.into(), @@ -31527,6 +31586,11 @@ impl From for AnyTsPropertySignatureModifier { AnyTsPropertySignatureModifier::JsAccessorModifier(node) } } +impl From for AnyTsPropertySignatureModifier { + fn from(node: JsDecorator) -> AnyTsPropertySignatureModifier { + AnyTsPropertySignatureModifier::JsDecorator(node) + } +} impl From for AnyTsPropertySignatureModifier { fn from(node: JsStaticModifier) -> AnyTsPropertySignatureModifier { AnyTsPropertySignatureModifier::JsStaticModifier(node) @@ -31560,6 +31624,7 @@ impl From for AnyTsPropertySignatureModifier { impl AstNode for AnyTsPropertySignatureModifier { type Language = Language; const KIND_SET: SyntaxKindSet = JsAccessorModifier::KIND_SET + .union(JsDecorator::KIND_SET) .union(JsStaticModifier::KIND_SET) .union(TsAbstractModifier::KIND_SET) .union(TsAccessibilityModifier::KIND_SET) @@ -31570,6 +31635,7 @@ impl AstNode for AnyTsPropertySignatureModifier { matches!( kind, JS_ACCESSOR_MODIFIER + | JS_DECORATOR | JS_STATIC_MODIFIER | TS_ABSTRACT_MODIFIER | TS_ACCESSIBILITY_MODIFIER @@ -31583,6 +31649,7 @@ impl AstNode for AnyTsPropertySignatureModifier { JS_ACCESSOR_MODIFIER => { AnyTsPropertySignatureModifier::JsAccessorModifier(JsAccessorModifier { syntax }) } + JS_DECORATOR => AnyTsPropertySignatureModifier::JsDecorator(JsDecorator { syntax }), JS_STATIC_MODIFIER => { AnyTsPropertySignatureModifier::JsStaticModifier(JsStaticModifier { syntax }) } @@ -31610,6 +31677,7 @@ impl AstNode for AnyTsPropertySignatureModifier { fn syntax(&self) -> &SyntaxNode { match self { AnyTsPropertySignatureModifier::JsAccessorModifier(it) => &it.syntax, + AnyTsPropertySignatureModifier::JsDecorator(it) => &it.syntax, AnyTsPropertySignatureModifier::JsStaticModifier(it) => &it.syntax, AnyTsPropertySignatureModifier::TsAbstractModifier(it) => &it.syntax, AnyTsPropertySignatureModifier::TsAccessibilityModifier(it) => &it.syntax, @@ -31621,6 +31689,7 @@ impl AstNode for AnyTsPropertySignatureModifier { fn into_syntax(self) -> SyntaxNode { match self { AnyTsPropertySignatureModifier::JsAccessorModifier(it) => it.syntax, + AnyTsPropertySignatureModifier::JsDecorator(it) => it.syntax, AnyTsPropertySignatureModifier::JsStaticModifier(it) => it.syntax, AnyTsPropertySignatureModifier::TsAbstractModifier(it) => it.syntax, AnyTsPropertySignatureModifier::TsAccessibilityModifier(it) => it.syntax, @@ -31634,6 +31703,7 @@ impl std::fmt::Debug for AnyTsPropertySignatureModifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { AnyTsPropertySignatureModifier::JsAccessorModifier(it) => std::fmt::Debug::fmt(it, f), + AnyTsPropertySignatureModifier::JsDecorator(it) => std::fmt::Debug::fmt(it, f), AnyTsPropertySignatureModifier::JsStaticModifier(it) => std::fmt::Debug::fmt(it, f), AnyTsPropertySignatureModifier::TsAbstractModifier(it) => std::fmt::Debug::fmt(it, f), AnyTsPropertySignatureModifier::TsAccessibilityModifier(it) => { @@ -31649,6 +31719,7 @@ impl From for SyntaxNode { fn from(n: AnyTsPropertySignatureModifier) -> SyntaxNode { match n { AnyTsPropertySignatureModifier::JsAccessorModifier(it) => it.into(), + AnyTsPropertySignatureModifier::JsDecorator(it) => it.into(), AnyTsPropertySignatureModifier::JsStaticModifier(it) => it.into(), AnyTsPropertySignatureModifier::TsAbstractModifier(it) => it.into(), AnyTsPropertySignatureModifier::TsAccessibilityModifier(it) => it.into(), diff --git a/crates/rome_js_syntax/src/modifier_ext.rs b/crates/rome_js_syntax/src/modifier_ext.rs index e29bd1b3449..129dff5f3ef 100644 --- a/crates/rome_js_syntax/src/modifier_ext.rs +++ b/crates/rome_js_syntax/src/modifier_ext.rs @@ -8,6 +8,7 @@ use crate::{ #[derive(Debug, Ord, PartialOrd, Eq, PartialEq)] pub enum Modifiers { // modifiers must be sorted by precedence. + Decorator, Accessibility, Declare, Static, @@ -29,6 +30,7 @@ impl From<&AnyTsIndexSignatureModifier> for Modifiers { impl From<&AnyJsMethodModifier> for Modifiers { fn from(modifier: &AnyJsMethodModifier) -> Self { match modifier { + AnyJsMethodModifier::JsDecorator(_) => Modifiers::Decorator, AnyJsMethodModifier::JsStaticModifier(_) => Modifiers::Static, AnyJsMethodModifier::TsAccessibilityModifier(_) => Modifiers::Accessibility, AnyJsMethodModifier::TsOverrideModifier(_) => Modifiers::Override, @@ -39,6 +41,7 @@ impl From<&AnyJsMethodModifier> for Modifiers { impl From<&AnyTsMethodSignatureModifier> for Modifiers { fn from(modifier: &AnyTsMethodSignatureModifier) -> Self { match modifier { + AnyTsMethodSignatureModifier::JsDecorator(_) => Modifiers::Decorator, AnyTsMethodSignatureModifier::JsStaticModifier(_) => Modifiers::Static, AnyTsMethodSignatureModifier::TsAbstractModifier(_) => Modifiers::Abstract, AnyTsMethodSignatureModifier::TsAccessibilityModifier(_) => Modifiers::Accessibility, @@ -50,6 +53,7 @@ impl From<&AnyTsMethodSignatureModifier> for Modifiers { impl From<&AnyJsPropertyModifier> for Modifiers { fn from(modifier: &AnyJsPropertyModifier) -> Self { match modifier { + AnyJsPropertyModifier::JsDecorator(_) => Modifiers::Decorator, AnyJsPropertyModifier::JsStaticModifier(_) => Modifiers::Static, AnyJsPropertyModifier::JsAccessorModifier(_) => Modifiers::Accessor, AnyJsPropertyModifier::TsAccessibilityModifier(_) => Modifiers::Accessibility, @@ -72,6 +76,7 @@ impl From<&AnyTsPropertyParameterModifier> for Modifiers { impl From<&AnyTsPropertySignatureModifier> for Modifiers { fn from(modifier: &AnyTsPropertySignatureModifier) -> Self { match modifier { + AnyTsPropertySignatureModifier::JsDecorator(_) => Modifiers::Decorator, AnyTsPropertySignatureModifier::TsAccessibilityModifier(_) => Modifiers::Accessibility, AnyTsPropertySignatureModifier::TsDeclareModifier(_) => Modifiers::Declare, AnyTsPropertySignatureModifier::JsStaticModifier(_) => Modifiers::Static, diff --git a/xtask/codegen/js.ungram b/xtask/codegen/js.ungram index 92a8008285d..5d11a76dd76 100644 --- a/xtask/codegen/js.ungram +++ b/xtask/codegen/js.ungram @@ -720,6 +720,7 @@ AnyJsPropertyModifier = TsAccessibilityModifier | JsStaticModifier | JsAccessorModifier + | JsDecorator | TsReadonlyModifier | TsOverrideModifier @@ -744,6 +745,7 @@ AnyTsPropertySignatureModifier = TsDeclareModifier | TsAccessibilityModifier | JsStaticModifier + | JsDecorator | JsAccessorModifier | TsReadonlyModifier | TsOverrideModifier @@ -782,6 +784,7 @@ JsMethodClassMember = AnyJsMethodModifier = TsAccessibilityModifier | JsStaticModifier + | JsDecorator | TsOverrideModifier JsMethodModifierList = AnyJsMethodModifier* @@ -799,6 +802,7 @@ TsMethodSignatureClassMember = TsMethodSignatureModifierList = AnyTsMethodSignatureModifier* AnyTsMethodSignatureModifier = TsAccessibilityModifier + | JsDecorator | JsStaticModifier | TsOverrideModifier | TsAbstractModifier