fix(rome_js_formatter): wrap string literal expression statements in parentheses
Wraps string literal expressions that are direct children of an expression statement in parentheses.
MODIFY
crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs
crates/rome_js_formatter/src/js/expressions/parenthesized_expression.rs
@@ -5,8 +5,8 @@ use crate::{
};
use rome_formatter::FormatResult;
use rome_js_syntax::{
- JsAnyExpression, JsParenthesizedExpression, JsParenthesizedExpressionFields, JsSyntaxKind,
- JsSyntaxNode,
+ JsAnyExpression, JsParenthesizedExpression, JsParenthesizedExpressionFields,
+ JsStringLiteralExpression, JsSyntaxKind, JsSyntaxNode,
};
use rome_rowan::{AstNode, SyntaxResult};
@@ -20,6 +20,8 @@ impl FormatNode for JsParenthesizedExpression {
let parenthesis_can_be_omitted = parenthesis_can_be_omitted(self)?;
+ let expression = expression?;
+
if is_simple_parenthesized_expression(self)? {
Ok(hard_group_elements(format_elements![
if parenthesis_can_be_omitted {
@@ -41,6 +43,31 @@ impl FormatNode for JsParenthesizedExpression {
group_elements(expression.format(formatter)?),
formatter.format_replaced(&r_paren_token?, empty_element()),
])
+ // if the expression inside the parenthesis is a stringLiteralExpression, we should leave it as is rather than
+ // add extra soft_block_indent, for example:
+ // ```js
+ // ("escaped carriage return \
+ // ");
+ // ```
+ // if we add soft_block_indent, we will get:
+ // ```js
+ // (
+ // "escaped carriage return \
+ // "
+ // );
+ // ```
+ // which will not match prettier's formatting behavior, if we add this extra branch to handle this case, it become:
+ // ```js
+ // ("escaped carriage return \
+ // ");
+ // ```
+ // this is what we want
+ } else if JsStringLiteralExpression::can_cast(expression.syntax().kind()) {
+ Ok(format_elements![
+ l_paren_token.format(formatter)?,
+ expression.format(formatter)?,
+ r_paren_token.format(formatter)?,
+ ])
} else {
formatter.format_delimited_soft_block_indent(
&l_paren_token?,

MODIFY
crates/rome_js_formatter/src/js/expressions/string_literal_expression.rs
crates/rome_js_formatter/src/js/expressions/string_literal_expression.rs
use crate::{FormatElement, FormatNode, Formatter};
-use rome_formatter::FormatResult;
+use rome_formatter::{format_elements, token, FormatResult};
+use rome_js_syntax::JsExpressionStatement;
+use rome_rowan::AstNode;
use crate::utils::format_string_literal_token;
use rome_js_syntax::JsStringLiteralExpression;
@@ -10,7 +12,21 @@ impl FormatNode for JsStringLiteralExpression {
let JsStringLiteralExpressionFields { value_token } = self.as_fields();
let value_token = value_token?;
+ let syntax_node = self.syntax();
+ let parent = syntax_node.parent();
- Ok(format_string_literal_token(value_token, formatter))
+ let needs_parenthesis = parent.and_then(JsExpressionStatement::cast).is_some();
+
+ let formatted_element = format_string_literal_token(value_token, formatter);
+ if needs_parenthesis {
+ let (leading_trivia, content, trailing_trivia) = formatted_element.split_trivia();
+ Ok(format_elements![
+ leading_trivia,
+ format_elements![token("("), content, token(")"),],
+ trailing_trivia,
+ ])
+ } else {
+ Ok(formatted_element)
+ }
}
}

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,3 +4,5 @@ nock(/test/)
.reply(200, {
foo: 'bar',
});
+
+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
source: crates/rome_js_formatter/tests/spec_test.rs
assertion_line: 242
expression: computed.js
-
---
# Input
nock(/test/)
@@ -12,6 +11,7 @@ nock(/test/)
foo: 'bar',
});
+a[("test")]
=============================
# Outputs
## Output 1
@@ -24,3 +24,5 @@ nock(/test/)
.matchHeader("Accept", "application/json")[httpMethodNock(method)]("/foo")
.reply(200, { foo: "bar" });
+a[("test")];
+

MODIFY
crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/export-default-from.js.snap
crates/rome_js_formatter/tests/specs/prettier/js/babel-plugins/export-default-from.js.snap
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
-assertion_line: 83
+assertion_line: 175
expression: export-default-from.js
-
---
# Input
```js
@@ -21,7 +20,7 @@ export v from 'mod';
export
v;
from;
-"mod";
+("mod");
```

MODIFY
crates/rome_js_formatter/tests/specs/prettier/js/decorators/multiple.js.snap
crates/rome_js_formatter/tests/specs/prettier/js/decorators/multiple.js.snap
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
+assertion_line: 175
expression: multiple.js
---
# Input
@@ -38,7 +39,7 @@ eyes: 2;
}
const foo = {
-@multipleDecorators @inline @theyWontAllFitInOneline aVeryLongPropName: "A very long string as value";
+@multipleDecorators @inline @theyWontAllFitInOneline aVeryLongPropName: ("A very long string as value");
}
```
@@ -80,6 +81,6 @@ error[SyntaxError]: expected a statement but instead found '}'
# Lines exceeding max width of 80 characters
```
- 15: @multipleDecorators @inline @theyWontAllFitInOneline aVeryLongPropName: "A very long string as value";
+ 15: @multipleDecorators @inline @theyWontAllFitInOneline aVeryLongPropName: ("A very long string as value");
```

MODIFY
crates/rome_js_formatter/tests/specs/prettier/js/directives/issue-7346.js.snap
crates/rome_js_formatter/tests/specs/prettier/js/directives/issue-7346.js.snap
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
+assertion_line: 175
expression: issue-7346.js
---
# Input
@@ -15,13 +16,13 @@ expression: issue-7346.js
```js
("bar"); // parens should not be removed to avoid becoming a directive
`foo`;
-"bar"; // parens should be added, see https://github.com/prettier/prettier/issues/7346#issuecomment-574823604
-'"';
+("bar"); // parens should be added, see https://github.com/prettier/prettier/issues/7346#issuecomment-574823604
+('"');
```
# Lines exceeding max width of 80 characters
```
- 3: "bar"; // parens should be added, see https://github.com/prettier/prettier/issues/7346#issuecomment-574823604
+ 3: ("bar"); // parens should be added, see https://github.com/prettier/prettier/issues/7346#issuecomment-574823604
```

MODIFY
crates/rome_js_formatter/tests/specs/prettier/js/do/do.js.snap
crates/rome_js_formatter/tests/specs/prettier/js/do/do.js.snap
@@ -70,7 +70,7 @@ const envSpecific = {
if(env === 'production') 'https://abc.mno.com/';
else
if (env === "development") {
- "http://localhost:4000";
+ ("http://localhost:4000");
}
}
}

MODIFY
crates/rome_js_formatter/tests/specs/prettier/js/export-default/escaped/default-escaped.js.snap
crates/rome_js_formatter/tests/specs/prettier/js/export-default/escaped/default-escaped.js.snap
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
-assertion_line: 83
+assertion_line: 175
expression: default-escaped.js
-
---
# Input
```js
@@ -16,7 +15,7 @@ export n\u{63} from "async";
export
n\u{63};
from;
-"async";
+("async");
```

MODIFY
crates/rome_js_formatter/tests/specs/prettier/js/export-extension/export.js.snap
crates/rome_js_formatter/tests/specs/prettier/js/export-extension/export.js.snap
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
+assertion_line: 175
expression: export.js
---
# Input
@@ -21,28 +22,28 @@ export * as ns from "mod";
export
v;
from;
-"mod";
+("mod");
export
a, * as
b;
from;
-"mod";
+("mod");
export
c, { foo };
from;
-"mod";
+("mod");
export * as d
,
{
bar;
}
from;
-"mod";
+("mod");
export { fooooooooooooooooooooooooooooooooooooooooooooooooo } from "fooooooooooooooooooooooooooooo";
export
Bar, { barrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr };
from;
-"barrrrrrrrrrrrrrrrrrrrrrrrrrrr";
+("barrrrrrrrrrrrrrrrrrrrrrrrrrrr");
export {
foooooooooooooooooooooooooooooooooooooooooooooo,
fooooooooooooooooooooooooooooooooooooooooooooooo,

MODIFY
crates/rome_js_formatter/tests/specs/prettier/js/exports/test.js.snap
crates/rome_js_formatter/tests/specs/prettier/js/exports/test.js.snap
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
-assertion_line: 144
+assertion_line: 175
expression: test.js
-
---
# Input
```js
@@ -31,7 +30,7 @@ export {
export
a, { b };
from;
-"./baz";
+("./baz");
export * as ns from "mod";
@@ -41,7 +40,7 @@ export * as foo
bar;
}
from;
-"./baz";
+("./baz");
export { undefinedExport };

MODIFY
crates/rome_js_formatter/tests/specs/prettier/js/record/spread.js.snap
crates/rome_js_formatter/tests/specs/prettier/js/record/spread.js.snap
---
source: crates/rome_js_formatter/tests/prettier_tests.rs
+assertion_line: 175
expression: spread.js
---
# Input
@@ -17,7 +18,7 @@ assert(taskLater === #{ status: "DONE", title: formData.title, id: 42 })
```js
const formData = #
{
- title: "Implement all the things";
+ title: ("Implement all the things");
}
const taskNow = #
{

fix(rome_js_formatter): wrap string literal expression statements in parentheses

Wraps string literal expressions that are direct children of an expression statement in parentheses.