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_formatter): class property members as assignment like (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ematipico authored Jun 30, 2022
1 parent 26cab2e commit 9e22611
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 84 deletions.
30 changes: 5 additions & 25 deletions crates/rome_js_formatter/src/js/classes/property_class_member.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,18 @@
use crate::prelude::*;
use rome_formatter::{format_args, write};

use crate::utils::FormatWithSemicolon;

use crate::utils::{FormatWithSemicolon, JsAnyAssignmentLike};
use rome_formatter::write;
use rome_js_syntax::JsPropertyClassMember;
use rome_js_syntax::JsPropertyClassMemberFields;

#[derive(Debug, Clone, Default)]
pub struct FormatJsPropertyClassMember;

impl FormatNodeRule<JsPropertyClassMember> for FormatJsPropertyClassMember {
fn fmt_fields(&self, node: &JsPropertyClassMember, f: &mut JsFormatter) -> FormatResult<()> {
let JsPropertyClassMemberFields {
modifiers,
name,
property_annotation,
value,
semicolon_token,
} = node.as_fields();

let semicolon_token = node.semicolon_token();
let body = format_with(|f| write!(f, [JsAnyAssignmentLike::from(node.clone())]));
write!(
f,
[FormatWithSemicolon::new(
&format_args!(
modifiers.format(),
space_token(),
name.format(),
property_annotation.format(),
value
.format()
.with_or_empty(|node, f| write![f, [space_token(), node]]),
),
semicolon_token.as_ref()
)]
[FormatWithSemicolon::new(&body, semicolon_token.as_ref())]
)
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use crate::prelude::*;
use rome_formatter::{format_args, write};

use crate::utils::FormatWithSemicolon;

use rome_js_syntax::{TsPropertySignatureClassMember, TsPropertySignatureClassMemberFields};
use crate::utils::{FormatWithSemicolon, JsAnyAssignmentLike};
use rome_formatter::write;
use rome_js_syntax::TsPropertySignatureClassMember;

#[derive(Debug, Clone, Default)]
pub struct FormatTsPropertySignatureClassMember;
Expand All @@ -14,24 +12,11 @@ impl FormatNodeRule<TsPropertySignatureClassMember> for FormatTsPropertySignatur
node: &TsPropertySignatureClassMember,
f: &mut JsFormatter,
) -> FormatResult<()> {
let TsPropertySignatureClassMemberFields {
modifiers,
name,
property_annotation,
semicolon_token,
} = node.as_fields();

let semicolon_token = node.semicolon_token();
let body = format_with(|f| write!(f, [JsAnyAssignmentLike::from(node.clone())]));
write!(
f,
[FormatWithSemicolon::new(
&format_args!(
modifiers.format(),
space_token(),
name.format(),
property_annotation.format(),
),
semicolon_token.as_ref()
)]
[FormatWithSemicolon::new(&body, semicolon_token.as_ref())]
)
}
}
99 changes: 88 additions & 11 deletions crates/rome_js_formatter/src/utils/assignment_like.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ use crate::utils::object::write_member_name;
use crate::utils::JsAnyBinaryLikeExpression;
use rome_formatter::{format_args, write, VecBuffer};
use rome_js_syntax::{
JsAnyAssignmentPattern, JsAnyBindingPattern, JsAnyExpression, JsAnyFunctionBody,
JsAnyObjectAssignmentPatternMember, JsAnyObjectBindingPatternMember, JsAnyObjectMemberName,
JsAssignmentExpression, JsInitializerClause, JsObjectAssignmentPattern,
JsObjectAssignmentPatternProperty, JsObjectBindingPattern, JsPropertyObjectMember,
JsSyntaxKind, JsVariableDeclarator, TsAnyVariableAnnotation, TsIdentifierBinding, TsType,
JsAnyAssignmentPattern, JsAnyBindingPattern, JsAnyClassMemberName, JsAnyExpression,
JsAnyFunctionBody, JsAnyObjectAssignmentPatternMember, JsAnyObjectBindingPatternMember,
JsAnyObjectMemberName, JsAssignmentExpression, JsInitializerClause, JsLiteralMemberName,
JsObjectAssignmentPattern, JsObjectAssignmentPatternProperty, JsObjectBindingPattern,
JsPropertyClassMember, JsPropertyClassMemberFields, JsPropertyObjectMember, JsSyntaxKind,
JsVariableDeclarator, TsAnyVariableAnnotation, TsIdentifierBinding,
TsPropertySignatureClassMember, TsPropertySignatureClassMemberFields, TsType,
TsTypeAliasDeclaration,
};
use rome_js_syntax::{JsAnyLiteralExpression, JsSyntaxNode};
Expand All @@ -19,11 +21,19 @@ declare_node_union! {
JsAssignmentExpression |
JsObjectAssignmentPatternProperty |
JsVariableDeclarator |
TsTypeAliasDeclaration
TsTypeAliasDeclaration |
JsPropertyClassMember |
TsPropertySignatureClassMember
}

declare_node_union! {
pub(crate) LeftAssignmentLike = JsAnyAssignmentPattern | JsAnyObjectMemberName | JsAnyBindingPattern | TsIdentifierBinding
pub(crate) LeftAssignmentLike =
JsAnyAssignmentPattern |
JsAnyObjectMemberName |
JsAnyBindingPattern |
TsIdentifierBinding |
JsLiteralMemberName |
JsAnyClassMemberName
}

declare_node_union! {
Expand Down Expand Up @@ -297,12 +307,19 @@ impl JsAnyAssignmentLike {
Ok(assignment_pattern.pattern()?.into())
}
JsAnyAssignmentLike::JsVariableDeclarator(variable_declarator) => {
// SAFETY: Calling `unwrap` here is safe because we check `should_only_left` variant at the beginning of the `layout` function
// SAFETY: Calling `unwrap` here is safe because we check `has_only_left_hand_side` variant at the beginning of the `layout` function
Ok(variable_declarator.initializer().unwrap().into())
}
JsAnyAssignmentLike::TsTypeAliasDeclaration(type_alias_declaration) => {
Ok(type_alias_declaration.ty()?.into())
}
JsAnyAssignmentLike::JsPropertyClassMember(n) => {
// SAFETY: Calling `unwrap` here is safe because we check `has_only_left_hand_side` variant at the beginning of the `layout` function
Ok(n.value().unwrap().into())
}
JsAnyAssignmentLike::TsPropertySignatureClassMember(_) => {
unreachable!("TsPropertySignatureClassMember doesn't have any right side. If you're here, `has_only_left_hand_side` hasn't been called")
}
}
}

Expand All @@ -321,6 +338,12 @@ impl JsAnyAssignmentLike {
JsAnyAssignmentLike::TsTypeAliasDeclaration(type_alias_declaration) => {
Ok(type_alias_declaration.binding_identifier()?.into())
}
JsAnyAssignmentLike::JsPropertyClassMember(property_class_member) => {
Ok(property_class_member.name()?.into())
}
JsAnyAssignmentLike::TsPropertySignatureClassMember(
property_signature_class_member,
) => Ok(property_signature_class_member.name()?.into()),
}
}

Expand All @@ -340,7 +363,7 @@ impl JsAnyAssignmentLike {
fn write_left(&self, f: &mut JsFormatter) -> FormatResult<bool> {
match self {
JsAnyAssignmentLike::JsPropertyObjectMember(property) => {
let width = write_member_name(&property.name()?, f)?;
let width = write_member_name(&property.name()?.into(), f)?;
let text_width_for_break =
(u8::from(f.context().tab_width()) + MIN_OVERLAP_FOR_BREAK) as usize;
Ok(width < text_width_for_break)
Expand All @@ -351,7 +374,7 @@ impl JsAnyAssignmentLike {
Ok(false)
}
JsAnyAssignmentLike::JsObjectAssignmentPatternProperty(property) => {
let width = write_member_name(&property.member()?, f)?;
let width = write_member_name(&property.member()?.into(), f)?;
let text_width_for_break =
(u8::from(f.context().tab_width()) + MIN_OVERLAP_FOR_BREAK) as usize;
Ok(width < text_width_for_break)
Expand All @@ -373,6 +396,40 @@ impl JsAnyAssignmentLike {
}
Ok(false)
}
JsAnyAssignmentLike::JsPropertyClassMember(property_class_member) => {
let JsPropertyClassMemberFields {
modifiers,
name,
property_annotation,
value: _,
semicolon_token: _,
} = property_class_member.as_fields();
write!(f, [modifiers.format(), space_token()])?;
let width = write_member_name(&name?.into(), f)?;
write!(f, [property_annotation.format()])?;
let text_width_for_break =
(u8::from(f.context().tab_width()) + MIN_OVERLAP_FOR_BREAK) as usize;
Ok(width < text_width_for_break)
}
JsAnyAssignmentLike::TsPropertySignatureClassMember(
property_signature_class_member,
) => {
let TsPropertySignatureClassMemberFields {
modifiers,
name,
property_annotation,
semicolon_token: _,
} = property_signature_class_member.as_fields();

write!(f, [modifiers.format(), space_token(),])?;

let width = write_member_name(&name?.into(), f)?;

write!(f, [property_annotation.format()])?;
let text_width_for_break =
(u8::from(f.context().tab_width()) + MIN_OVERLAP_FOR_BREAK) as usize;
Ok(width < text_width_for_break)
}
}
}

Expand Down Expand Up @@ -401,6 +458,15 @@ impl JsAnyAssignmentLike {
let eq_token = type_alias_declaration.eq_token()?;
write!(f, [space_token(), eq_token.format()])
}
JsAnyAssignmentLike::JsPropertyClassMember(property_class_member) => {
if let Some(initializer) = property_class_member.value() {
let eq_token = initializer.eq_token()?;
write!(f, [space_token(), eq_token.format()])?
}
Ok(())
}
// this variant doesn't have any operator
JsAnyAssignmentLike::TsPropertySignatureClassMember(_) => Ok(()),
}
}

Expand Down Expand Up @@ -434,6 +500,15 @@ impl JsAnyAssignmentLike {
let ty = type_alias_declaration.ty()?;
write!(f, [space_token(), ty.format()])
}
JsAnyAssignmentLike::JsPropertyClassMember(property_class_member) => {
if let Some(initializer) = property_class_member.value() {
let expression = initializer.expression()?;
write!(f, [space_token(), expression.format()])?;
}
Ok(())
}
// this variant doesn't have any right part
JsAnyAssignmentLike::TsPropertySignatureClassMember(_) => Ok(()),
}
}

Expand Down Expand Up @@ -482,8 +557,10 @@ impl JsAnyAssignmentLike {
fn has_only_left_hand_side(&self) -> bool {
if let JsAnyAssignmentLike::JsVariableDeclarator(declarator) = self {
declarator.initializer().is_none()
} else if let JsAnyAssignmentLike::JsPropertyClassMember(class_member) = self {
class_member.value().is_none()
} else {
false
matches!(self, JsAnyAssignmentLike::TsPropertySignatureClassMember(_))
}
}

Expand Down
34 changes: 28 additions & 6 deletions crates/rome_js_formatter/src/utils/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,39 @@ use crate::prelude::*;
use crate::utils::FormatLiteralStringToken;
use crate::utils::StringLiteralParentKind;
use rome_formatter::write;
use rome_js_syntax::JsAnyObjectMemberName;
use rome_js_syntax::JsSyntaxKind::JS_STRING_LITERAL;
use rome_rowan::AstNode;
use rome_js_syntax::{JsAnyClassMemberName, JsAnyObjectMemberName};
use rome_rowan::{declare_node_union, AstNode};
use unicode_width::UnicodeWidthStr;

declare_node_union! {
pub(crate) JsAnyMemberName = JsAnyObjectMemberName | JsAnyClassMemberName
}

impl Format<JsFormatContext> for JsAnyMemberName {
fn fmt(&self, f: &mut Formatter<JsFormatContext>) -> FormatResult<()> {
match self {
JsAnyMemberName::JsAnyObjectMemberName(node) => {
write!(f, [node.format()])
}
JsAnyMemberName::JsAnyClassMemberName(node) => {
write!(f, [node.format()])
}
}
}
}

pub(crate) fn write_member_name(
name: &JsAnyObjectMemberName,
name: &JsAnyMemberName,
f: &mut JsFormatter,
) -> FormatResult<usize> {
match name {
name @ JsAnyObjectMemberName::JsLiteralMemberName(literal) => {
name @ JsAnyMemberName::JsAnyClassMemberName(JsAnyClassMemberName::JsLiteralMemberName(
literal,
))
| name @ JsAnyMemberName::JsAnyObjectMemberName(
JsAnyObjectMemberName::JsLiteralMemberName(literal),
) => {
let value = literal.value()?;

if value.kind() == JS_STRING_LITERAL {
Expand All @@ -23,13 +45,13 @@ pub(crate) fn write_member_name(

Ok(cleaned.width())
} else {
write!(f, [name.format()])?;
write!(f, [name])?;

Ok(value.text_trimmed().width())
}
}
name => {
write!(f, [&name.format()])?;
write!(f, [&name])?;
Ok(name.text().width())
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
assertion_line: 182
expression: class-property.js
---
# Input
Expand All @@ -18,10 +19,10 @@ class X {
```js
class X {
TEMPLATE =
// tab index is needed so we can focus, which is needed for keyboard events
'<div class="ag-large-text" tabindex="0">' +
'<div class="ag-large-textarea"></div>' +
"</div>";
// tab index is needed so we can focus, which is needed for keyboard events
'<div class="ag-large-text" tabindex="0">' +
'<div class="ag-large-textarea"></div>' +
"</div>";
}

```
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
assertion_line: 182
expression: with_comments.js
---
# Input
Expand All @@ -18,10 +19,10 @@ class A {
```js
class A {
#foobar =
// comment to break
1 +
// comment to break again
2;
// comment to break
1 +
// comment to break again
2;
}
```
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
assertion_line: 182
expression: property.js
---
# Input
Expand Down Expand Up @@ -29,15 +30,15 @@ class B {
```js
class A {
foobar =
// comment to break
1 +
// comment to break again
2;
// comment to break
1 +
// comment to break again
2;
}
class B {
someInstanceProperty = this.props.foofoofoofoofoofoo && this.props
.barbarbarbar;
someInstanceProperty =
this.props.foofoofoofoofoofoo && this.props.barbarbarbar;
someInstanceProperty2 = {
foo: this.props.foofoofoofoofoofoo && this.props.barbarbarbar,
Expand Down
Loading

0 comments on commit 9e22611

Please sign in to comment.