fix(rome_js_formatter): Fix dropped initializer comments
MODIFY
crates/rome_js_formatter/src/comments.rs
crates/rome_js_formatter/src/comments.rs
@@ -951,10 +951,13 @@ fn handle_variable_declarator_comment(
// key: 'val'
// }
// ```
- Some(initializer) if initializer.syntax() == following => {
- if let Ok(expression) = initializer.expression() {
- return CommentPlacement::leading(expression.into_syntax(), comment);
- }
+ Some(initializer)
+ if initializer.syntax() == following
+ && initializer
+ .expression()
+ .map_or(false, |expression| is_complex_value(expression.syntax())) =>
+ {
+ return CommentPlacement::leading(initializer.into_syntax(), comment);
}
_ => {
// fall through
@@ -962,22 +965,29 @@ fn handle_variable_declarator_comment(
}
}
JsSyntaxKind::JS_INITIALIZER_CLAUSE => {
- if let Some(variable_declarator) =
- enclosing.parent().and_then(JsVariableDeclarator::cast)
- {
+ let parent_kind = enclosing.parent().map(|p| p.kind());
+
+ if matches!(
+ parent_kind,
+ Some(JsSyntaxKind::JS_VARIABLE_DECLARATOR | JsSyntaxKind::JS_PROPERTY_CLASS_MEMBER)
+ ) {
+ let not_complex =
+ matches!(parent_kind, Some(JsSyntaxKind::JS_PROPERTY_CLASS_MEMBER))
+ || !is_complex_value(following);
+
// Keep trailing comments with the id for variable declarators. Necessary because the value is wrapped
// inside of an initializer clause.
// ```javascript
// let a = // comment
// b;
// ```
- if !is_complex_value(following)
+ if not_complex
&& !JsCommentStyle::is_suppression(comment.piece().text())
&& comment.kind().is_line()
&& comment.preceding_node().is_none()
{
- if let Ok(id) = variable_declarator.id() {
- return CommentPlacement::trailing(id.into_syntax(), comment);
+ if let Some(prev_node) = enclosing.prev_sibling() {
+ return CommentPlacement::trailing(prev_node, comment);
}
}
}

MODIFY
crates/rome_js_formatter/src/utils/assignment_like.rs
crates/rome_js_formatter/src/utils/assignment_like.rs
@@ -538,7 +538,12 @@ impl JsAnyAssignmentLike {
let expression = initializer.expression()?;
write!(
f,
- [space(), with_assignment_layout(&expression, Some(layout))]
+ [
+ space(),
+ format_leading_comments(initializer.syntax()),
+ with_assignment_layout(&expression, Some(layout)),
+ format_trailing_comments(initializer.syntax())
+ ]
)?;
}
Ok(())
@@ -552,7 +557,12 @@ impl JsAnyAssignmentLike {
let expression = initializer.expression()?;
write!(
f,
- [space(), with_assignment_layout(&expression, Some(layout))]
+ [
+ space(),
+ format_leading_comments(initializer.syntax()),
+ with_assignment_layout(&expression, Some(layout)),
+ format_trailing_comments(initializer.syntax())
+ ]
)?;
}
Ok(())
@@ -826,7 +836,8 @@ impl JsAnyAssignmentLike {
should_break_after_operator(expression, comments)?
}
RightAssignmentLike::JsInitializerClause(initializer) => {
- should_break_after_operator(&initializer.expression()?, comments)?
+ comments.has_leading_own_line_comment(initializer.syntax())
+ || should_break_after_operator(&initializer.expression()?, comments)?
}
RightAssignmentLike::TsType(TsType::TsUnionType(ty)) => {
comments.has_leading_comments(ty.syntax())

ADD
crates/rome_js_formatter/tests/specs/ts/assignment/assignment_comments.ts
+const a = // test
+ 1;
+
+const b =
+ /* leading */
+ 2;
+
+const c
+ /* leading */
+ = 3;
+
+
+const d: string // 1
+ = // 2
+ 4;
+
+
+const e: string // 1
+ = // 2
+ { object: 5 };
+

ADD
crates/rome_js_formatter/tests/specs/ts/assignment/assignment_comments.ts.snap
+---
+source: crates/rome_js_formatter/tests/spec_test.rs
+expression: assignment_comments.ts
+---
+# Input
+const a = // test
+ 1;
+
+const b =
+ /* leading */
+ 2;
+
+const c
+ /* leading */
+ = 3;
+
+
+const d: string // 1
+ = // 2
+ 4;
+
+
+const e: string // 1
+ = // 2
+ { object: 5 };
+
+
+=============================
+# Outputs
+## Output 1
+-----
+Indent style: Tab
+Line width: 80
+Quote style: Double Quotes
+Quote properties: As needed
+-----
+const a = 1; // test
+
+const b =
+ /* leading */
+ 2;
+
+const c =
+ /* leading */
+ 3;
+
+const d: string = 4; // 1 // 2
+
+const e: string =
+ // 1
+ // 2
+ { object: 5 };
+

ADD
crates/rome_js_formatter/tests/specs/ts/assignment/property_assignment_comments.ts
+class Test {
+ prop1 = /* leading */ 1;
+
+ prop2 = // test
+ 2;
+
+ prop3 // test
+ = 3;
+
+ prop4 // test
+ = 4;
+
+ prop5 // test
+ = 5 // a
+
+ prop6
+ /* leading */
+ = 6 // c
+
+ prop7 =
+ /* leading */
+ 7 // c
+
+ prop8 /* comment */ = 8;
+
+ prop9: string // 1
+ = // 2
+ 3;
+
+ prop10: any // 1
+ = // 2
+ { object: 3}
+}

ADD
crates/rome_js_formatter/tests/specs/ts/assignment/property_assignment_comments.ts.snap
+---
+source: crates/rome_js_formatter/tests/spec_test.rs
+expression: property_assignment_comments.ts
+---
+# Input
+class Test {
+ prop1 = /* leading */ 1;
+
+ prop2 = // test
+ 2;
+
+ prop3 // test
+ = 3;
+
+ prop4 // test
+ = 4;
+
+ prop5 // test
+ = 5 // a
+
+ prop6
+ /* leading */
+ = 6 // c
+
+ prop7 =
+ /* leading */
+ 7 // c
+
+ prop8 /* comment */ = 8;
+
+ prop9: string // 1
+ = // 2
+ 3;
+
+ prop10: any // 1
+ = // 2
+ { object: 3}
+}
+
+=============================
+# Outputs
+## Output 1
+-----
+Indent style: Tab
+Line width: 80
+Quote style: Double Quotes
+Quote properties: As needed
+-----
+class Test {
+ prop1 = /* leading */ 1;
+
+ prop2 = 2; // test
+
+ prop3 = 3; // test
+
+ prop4 = 4; // test
+
+ prop5 = 5; // test // a
+
+ prop6 =
+ /* leading */
+ 6; // c
+
+ prop7 =
+ /* leading */
+ 7; // c
+
+ prop8 /* comment */ = 8;
+
+ prop9: string = 3; // 1 // 2
+
+ prop10: any = // 1 // 2
+ { object: 3 };
+}
+

fix(rome_js_formatter): Fix dropped initializer comments (#3397)