Skip to content

Commit

Permalink
challenge(formatter): edge case wit hexpression statement and type cast
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Nov 20, 2023
1 parent e60c49b commit bb5f62b
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 79 deletions.
30 changes: 27 additions & 3 deletions crates/biome_js_formatter/src/ts/expressions/as_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::ts::expressions::type_assertion_expression::type_cast_like_needs_pare
use biome_formatter::{format_args, write};
use biome_js_syntax::{AnyJsExpression, JsSyntaxKind, JsSyntaxNode, JsSyntaxToken, TsAsExpression};
use biome_js_syntax::{AnyTsType, TsSatisfiesExpression};
use biome_rowan::{declare_node_union, SyntaxResult};
use biome_rowan::{declare_node_union, SyntaxNodeOptionExt, SyntaxResult};

#[derive(Debug, Clone, Default)]
pub struct FormatTsAsExpression;
Expand Down Expand Up @@ -62,9 +62,33 @@ impl Format<JsFormatContext> for TsAsOrSatisfiesExpression {
let expression = self.expression();
let operation_token = self.operation_token()?;
let ty = self.ty()?;

// edge case: `(type) as T;`
// This check could be implemented in `JsIdentifierExpression::needs_parentheses_with_parent`,
// however this could incurs a perf penality.
let expression_needs_parens = self.syntax().parent().kind()
== Some(JsSyntaxKind::JS_EXPRESSION_STATEMENT)
&& expression
.as_ref()
.ok()
.and_then(|expr| expr.as_js_reference_identifier()?.value_token().ok())
.map_or(false, |name| {
// These keywords are contextually reserved by TypeSCript in strict and sloppy modes.
matches!(
name.text_trimmed(),
"await" | "interface" | "let" | "module" | "type" | "yield" | "using"
)
});
let format_inner = format_with(|f| {
write!(f, [expression.format(), space(), operation_token.format()])?;
write!(
f,
[
expression_needs_parens.then_some(text("(")),
expression.format(),
expression_needs_parens.then_some(text(")")),
space(),
operation_token.format()
]
)?;

if f.comments().has_leading_own_line_comment(ty.syntax()) {
write!(f, [indent(&format_args![hard_line_break(), &ty.format()])])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
// expression statemnt of "as" expression hardly ever makes sense, but it's still valid.
const [type, x] = [0, 0];
// FIXME
// TODO: parse issue
// (type) as unknown;
(type) as unknown;
x as unknown;

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,6 @@ satisfies satisfies satisfies satisfies satisfies;
```diff
--- Prettier
+++ Biome
@@ -9,7 +9,7 @@
return 2;
default:
// exhaustiveness check idiom
- (type) satisfies never;
+ type satisfies never;
throw new Error("unreachable");
}
};
@@ -17,8 +17,8 @@
function needParens() {
(let) satisfies unknown;
(interface) satisfies unknown;
- (module) satisfies unknown;
- (using) satisfies unknown;
+ module satisfies unknown;
+ using satisfies unknown;
(yield) satisfies unknown;
(await) satisfies unknown;
}
@@ -33,5 +33,5 @@

function satisfiesChain() {
Expand All @@ -96,16 +76,16 @@ const _ = () => {
return 2;
default:
// exhaustiveness check idiom
type satisfies never;
(type) satisfies never;
throw new Error("unreachable");
}
};

function needParens() {
(let) satisfies unknown;
(interface) satisfies unknown;
module satisfies unknown;
using satisfies unknown;
(module) satisfies unknown;
(using) satisfies unknown;
(yield) satisfies unknown;
(await) satisfies unknown;
}
Expand Down

0 comments on commit bb5f62b

Please sign in to comment.