Skip to content

Commit

Permalink
fix(js_formatter): only parenthesize default-export function cast exp…
Browse files Browse the repository at this point in the history
…ressions (#1023)
  • Loading branch information
faultyserver authored and yossydev committed Dec 3, 2023
1 parent 117c714 commit 818a9e7
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 17 deletions.
23 changes: 23 additions & 0 deletions crates/biome_js_formatter/src/ts/expressions/as_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,20 @@ impl NeedsParentheses for TsAsOrSatisfiesExpression {
match parent.kind() {
JsSyntaxKind::JS_CONDITIONAL_EXPRESSION => true,

// `export default (function foo() {} as bar)` needs to be special
// cased. All other default-exported as expressions can be written
// without parentheses, but function expressions _without_ the
// parentheses because `JsExportDefaultFunctionDeclaration`s and
// the cast becomes invalid.
JsSyntaxKind::JS_EXPORT_DEFAULT_EXPRESSION_CLAUSE => {
self.expression().map_or(false, |expression| {
matches!(
expression.syntax().kind(),
JsSyntaxKind::JS_FUNCTION_EXPRESSION
)
})
}

_ => {
type_cast_like_needs_parens(self.syntax(), parent)
|| is_binary_like_left_or_right(self.syntax(), parent)
Expand Down Expand Up @@ -152,5 +166,14 @@ mod tests {
assert_needs_parentheses!("(x as any) instanceof (y as any)", TsAsExpression[1]);

assert_not_needs_parentheses!("x as number as string", TsAsExpression[1]);

// default-exported function expressions require parentheses, otherwise
// the end of the function ends the export declaration, and the `as`
// gets treated as a new statement.
assert_needs_parentheses!(
"export default (function foo(){} as typeof console.log)",
TsAsExpression
);
assert_not_needs_parentheses!("export default foo as bar", TsAsExpression);
}
}
22 changes: 5 additions & 17 deletions crates/biome_js_formatter/tests/quick_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,20 @@ mod language {
include!("language.rs");
}

#[ignore]
#[test]
// use this test check if your snippet prints as you wish, without using a snapshot
fn quick_test() {
let src = r#"
const makeSomeFunction =
(services = {logger:null}) =>
(a, b, c) =>
services.logger(a,b,c)
const makeSomeFunction2 =
(services = {
logger: null
}) =>
(a, b, c) =>
services.logger(a, b, c)
export default foo as bar;
"#;
let syntax = JsFileSource::tsx();
let source_type = JsFileSource::tsx();
let tree = parse(
src,
syntax,
source_type,
JsParserOptions::default().with_parse_class_parameter_decorators(),
);
let options = JsFormatOptions::new(syntax)
let options = JsFormatOptions::new(source_type)
.with_indent_style(IndentStyle::Space)
.with_semicolons(Semicolons::Always)
.with_quote_style(QuoteStyle::Double)
Expand All @@ -42,7 +31,6 @@ const makeSomeFunction2 =

let doc = format_node(options.clone(), &tree.syntax()).unwrap();
let result = doc.print().unwrap();
let source_type = JsFileSource::js_module();

println!("{}", doc.into_document());
eprintln!("{}", result.as_code());
Expand Down

0 comments on commit 818a9e7

Please sign in to comment.