Fix(rome_js_formatter): keep parenthesis around string literal expression statements
MODIFY
crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs
crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs
@@ -2,8 +2,8 @@ use crate::prelude::*;
use crate::utils::{is_simple_expression, FormatPrecedence};
use rome_js_syntax::{
- JsAnyExpression, JsParenthesizedExpression, JsParenthesizedExpressionFields,
- JsStringLiteralExpression, JsSyntaxKind, JsSyntaxNode,
+ JsAnyExpression, JsAnyLiteralExpression, JsParenthesizedExpression,
+ JsParenthesizedExpressionFields, JsStringLiteralExpression, JsSyntaxKind, JsSyntaxNode,
};
use rome_rowan::{AstNode, SyntaxResult};
@@ -100,13 +100,37 @@ fn is_simple_parenthesized_expression(node: &JsParenthesizedExpression) -> Synta
fn parenthesis_can_be_omitted(node: &JsParenthesizedExpression) -> SyntaxResult<bool> {
let expression = node.expression()?;
let parent = node.syntax().parent();
+
+ // if expression is a StringLiteralExpression, we need to check it before precedence comparison, here is an example:
+ // ```js
+ // a[("test")]
+ // ```
+ // if we use precedence comparison, we will get:
+ // parent_precedence should be `High` due to the parenthesized_expression's parent is ComputedMemberExpression,
+ // and node_precedence should be `Low` due to expression is StringLiteralExpression. `parent_precedence > node_precedence` will return false,
+ // the parenthesis will not be omitted.
+ // But the expected behavior is that the parenthesis will be omitted. The code above should be formatted as:
+ // ```js
+ // a["test"]
+ // ```
+ // So we need to add extra branch to handle this case.
+ if matches!(
+ expression,
+ JsAnyExpression::JsAnyLiteralExpression(JsAnyLiteralExpression::JsStringLiteralExpression(
+ _
+ ))
+ ) {
+ return Ok(!matches!(
+ parent.map(|p| p.kind()),
+ Some(JsSyntaxKind::JS_EXPRESSION_STATEMENT)
+ ));
+ }
let parent_precedence = FormatPrecedence::with_precedence_for_parenthesis(parent.as_ref());
let node_precedence = FormatPrecedence::with_precedence_for_parenthesis(Some(node.syntax()));
if parent_precedence > node_precedence {
return Ok(false);
}
-
// Here we handle cases where we have binary/logical expressions.
// We want to remove the parenthesis only in cases where `left` and `right` are not other
// binary/logical expressions.

MODIFY
crates/rome_js_formatter/tests/specs/js/module/expression/member-chain/computed.js
crates/rome_js_formatter/tests/specs/js/module/expression/member-chain/computed.js
@@ -4,5 +4,3 @@ nock(/test/)
.reply(200, {
foo: 'bar',
});
\ No newline at end of file
-
-a[("test")]
\ No newline at end of file

MODIFY
crates/rome_js_formatter/tests/specs/js/module/expression/member-chain/computed.js.snap
crates/rome_js_formatter/tests/specs/js/module/expression/member-chain/computed.js.snap
@@ -10,8 +10,6 @@ nock(/test/)
.reply(200, {
foo: 'bar',
});
-
-a[("test")]
=============================
# Outputs
## Output 1
@@ -24,5 +22,3 @@ nock(/test/)
.matchHeader("Accept", "application/json")[httpMethodNock(method)]("/foo")
.reply(200, { foo: "bar" });
-a[("test")];
-

MODIFY
crates/rome_js_formatter/tests/specs/js/module/object/computed_member.js
crates/rome_js_formatter/tests/specs/js/module/object/computed_member.js
@@ -14,3 +14,6 @@ x.very.long.chain.of.static.members.that.goes.on.for.ever.I.mean.it.for.ever["an
x.very.long.chain.of.static.members.that.goes.on.for.ever.I.mean.it.for.ever[and()].even.longer.than.that.and["rofefefeefefme"].doesnt.supportit
x[b["test"]]
+
+
+a[("test")]

MODIFY
crates/rome_js_formatter/tests/specs/js/module/object/computed_member.js.snap
crates/rome_js_formatter/tests/specs/js/module/object/computed_member.js.snap
---
source: crates/rome_js_formatter/tests/spec_test.rs
+assertion_line: 242
expression: computed_member.js
---
# Input
@@ -20,6 +21,9 @@ x.very.long.chain.of.static.members.that.goes.on.for.ever.I.mean.it.for.ever[and
x[b["test"]]
+
+a[("test")]
+
=============================
# Outputs
## Output 1
@@ -53,3 +57,5 @@ x.very.long.chain.of.static.members.that.goes.on.for.ever.I.mean.it.for.ever[
x[b["test"]];
+a["test"];
+

Fix(rome_js_formatter): keep parenthesis around string literal expression statements