Skip to content

Commit

Permalink
challenge(formatter): predictable order of type parameter modifiers (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Conaclos committed Nov 14, 2023
1 parent 9dba0f0 commit fc877aa
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 20 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/biome_js_formatter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ biome_text_size = { workspace = true }
cfg-if = "1.0.0"
schemars = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"], optional = true }
smallvec = { workspace = true }
tracing = { workspace = true }
unicode-width = "0.1.9"

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
use crate::prelude::*;
use biome_js_syntax::TsTypeParameterModifierList;
use biome_js_syntax::{
AnyTsTypeParameterModifier, TsTypeParameterModifierList, TypeParameterModifiers,
};
use biome_rowan::AstNodeList;
use smallvec::SmallVec;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatTsTypeParameterModifierList;

impl FormatRule<TsTypeParameterModifierList> for FormatTsTypeParameterModifierList {
type Context = JsFormatContext;
fn fmt(&self, node: &TsTypeParameterModifierList, f: &mut JsFormatter) -> FormatResult<()> {
let modifiers = sort_modifiers_by_precedence(node);
f.join_with(&space())
.entries(node.iter().formatted())
.entries(modifiers.into_iter().formatted())
.finish()
}
}

/// This function consumes a list of modifiers and applies a predictable sorting.
fn sort_modifiers_by_precedence(
list: &TsTypeParameterModifierList,
) -> SmallVec<[AnyTsTypeParameterModifier; 3]> {
let mut result = list.iter().collect::<SmallVec<_>>();
result.sort_unstable_by_key(|node| TypeParameterModifiers::from(node));
result
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,7 @@ class _ {
<const T extends U>() => {};
(function <const T>() {});
(function <const T extends U>() {});
@@ -11,18 +11,18 @@
class A<const T> {}
class B<const T extends U> {}
class C<T, const U> {}
-class D<const in T> {}
+class D<in const T> {}
class E<const in T> {}
(class<const T> {});
(class<const T extends U> {});
(class<T, const U> {});
-(class<const in T> {});
+(class<in const T> {});
(class<const in T> {});

@@ -22,7 +22,7 @@
interface I<const T> {}
interface J<const T extends U> {}
interface K<T, const U> {}
Expand All @@ -96,12 +83,12 @@ declare function d<const T>();
class A<const T> {}
class B<const T extends U> {}
class C<T, const U> {}
class D<in const T> {}
class D<const in T> {}
class E<const in T> {}
(class<const T> {});
(class<const T extends U> {});
(class<T, const U> {});
(class<in const T> {});
(class<const in T> {});
(class<const in T> {});

interface I<const T> {}
Expand Down
22 changes: 20 additions & 2 deletions crates/biome_js_syntax/src/modifier_ext.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use crate::{
AnyJsMethodModifier, AnyJsPropertyModifier, AnyTsIndexSignatureModifier,
AnyTsMethodSignatureModifier, AnyTsPropertyParameterModifier, AnyTsPropertySignatureModifier,
JsSyntaxKind, TsAccessibilityModifier,
AnyTsTypeParameterModifier, JsSyntaxKind, TsAccessibilityModifier,
};

/// Helpful data structure to make the order modifiers predictable inside the formatter
/// Helpful data structure to make the order of modifiers predictable inside the formatter
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
pub enum Modifiers {
// modifiers must be sorted by precedence.
Expand Down Expand Up @@ -88,6 +88,24 @@ impl From<&AnyTsPropertySignatureModifier> for Modifiers {
}
}

/// Helpful data structure to make the order of type parameter modifiers predictable inside the formatter
#[derive(Debug, Ord, PartialOrd, Eq, PartialEq)]
pub enum TypeParameterModifiers {
Const,
In,
Out,
}

impl From<&AnyTsTypeParameterModifier> for TypeParameterModifiers {
fn from(modifier: &AnyTsTypeParameterModifier) -> Self {
match modifier {
AnyTsTypeParameterModifier::TsConstModifier(_) => Self::Const,
AnyTsTypeParameterModifier::TsInModifier(_) => Self::In,
AnyTsTypeParameterModifier::TsOutModifier(_) => Self::Out,
}
}
}

impl TsAccessibilityModifier {
/// Is `self` the `private` accessibility modifier?
///
Expand Down

0 comments on commit fc877aa

Please sign in to comment.