Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

Commit

Permalink
feat(rome_js_parser): EcmaScript @decorators #4252
Browse files Browse the repository at this point in the history
  • Loading branch information
denbezrukov committed May 1, 2023
1 parent 01c600b commit 0fb680c
Show file tree
Hide file tree
Showing 51 changed files with 4,600 additions and 555 deletions.
24 changes: 24 additions & 0 deletions crates/rome_js_formatter/src/comments.rs
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -508,6 +510,28 @@ fn handle_method_comment(comment: DecoratedComment<JsLanguage>) -> CommentPlacem
CommentPlacement::Default(comment)
}

fn handle_property_comments(comment: DecoratedComment<JsLanguage>) -> CommentPlacement<JsLanguage> {
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<JsLanguage>) -> CommentPlacement<JsLanguage> {
Expand Down
68 changes: 34 additions & 34 deletions crates/rome_js_formatter/src/generated.rs
Expand Up @@ -4700,6 +4700,40 @@ impl IntoFormat<JsFormatContext> for rome_js_syntax::JsInitializerClause {
)
}
}
impl FormatRule<rome_js_syntax::JsDecorator>
for crate::js::auxiliary::decorator::FormatJsDecorator
{
type Context = JsFormatContext;
#[inline(always)]
fn fmt(&self, node: &rome_js_syntax::JsDecorator, f: &mut JsFormatter) -> FormatResult<()> {
FormatNodeRule::<rome_js_syntax::JsDecorator>::fmt(self, node, f)
}
}
impl AsFormat<JsFormatContext> 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<JsFormatContext> 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<rome_js_syntax::TsOptionalPropertyAnnotation>
for crate::ts::auxiliary::optional_property_annotation::FormatTsOptionalPropertyAnnotation
{
Expand Down Expand Up @@ -6807,40 +6841,6 @@ impl IntoFormat<JsFormatContext> for rome_js_syntax::TsThisParameter {
)
}
}
impl FormatRule<rome_js_syntax::JsDecorator>
for crate::js::auxiliary::decorator::FormatJsDecorator
{
type Context = JsFormatContext;
#[inline(always)]
fn fmt(&self, node: &rome_js_syntax::JsDecorator, f: &mut JsFormatter) -> FormatResult<()> {
FormatNodeRule::<rome_js_syntax::JsDecorator>::fmt(self, node, f)
}
}
impl AsFormat<JsFormatContext> 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<JsFormatContext> 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<rome_js_syntax::TsAnyType> for crate::ts::types::any_type::FormatTsAnyType {
type Context = JsFormatContext;
#[inline(always)]
Expand Down
1 change: 1 addition & 0 deletions crates/rome_js_formatter/src/js/any/method_modifier.rs
Expand Up @@ -10,6 +10,7 @@ impl FormatRule<AnyJsMethodModifier> 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),
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/rome_js_formatter/src/js/any/property_modifier.rs
Expand Up @@ -11,6 +11,7 @@ impl FormatRule<AnyJsPropertyModifier> 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),
}
Expand Down
Expand Up @@ -9,6 +9,7 @@ impl FormatRule<AnyTsMethodSignatureModifier> 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),
Expand Down
Expand Up @@ -11,6 +11,7 @@ impl FormatRule<AnyTsPropertySignatureModifier> 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),
Expand Down
12 changes: 5 additions & 7 deletions crates/rome_js_formatter/tests/quick_test.rs
Expand Up @@ -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();
Expand Down
@@ -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;
};
}
```


@@ -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;
}
```


@@ -1,6 +1,5 @@
---
source: crates/rome_formatter_test/src/snapshot_builder.rs
assertion_line: 212
info: js/decorator-comments/comments.js
---

Expand Down

0 comments on commit 0fb680c

Please sign in to comment.