diff --git a/crates/biome_grit_formatter/src/grit/auxiliary/like.rs b/crates/biome_grit_formatter/src/grit/auxiliary/like.rs index 83625c5dccbb..bbc628b7cb8b 100644 --- a/crates/biome_grit_formatter/src/grit/auxiliary/like.rs +++ b/crates/biome_grit_formatter/src/grit/auxiliary/like.rs @@ -1,10 +1,27 @@ use crate::prelude::*; -use biome_grit_syntax::GritLike; -use biome_rowan::AstNode; +use biome_formatter::write; +use biome_grit_syntax::{GritLike, GritLikeFields}; #[derive(Debug, Clone, Default)] pub(crate) struct FormatGritLike; impl FormatNodeRule for FormatGritLike { fn fmt_fields(&self, node: &GritLike, f: &mut GritFormatter) -> FormatResult<()> { - format_verbatim_node(node.syntax()).fmt(f) + let GritLikeFields { + like_token, + l_curly_token, + example, + threshold, + r_curly_token, + } = node.as_fields(); + + write!( + f, + [ + like_token.format(), + l_curly_token.format(), + example.format(), + threshold.format(), + r_curly_token.format() + ] + ) } } diff --git a/crates/biome_grit_formatter/src/grit/lists/predicate_list.rs b/crates/biome_grit_formatter/src/grit/lists/predicate_list.rs index bc94f77bd127..6f2773bcc5dd 100644 --- a/crates/biome_grit_formatter/src/grit/lists/predicate_list.rs +++ b/crates/biome_grit_formatter/src/grit/lists/predicate_list.rs @@ -1,17 +1,18 @@ use crate::prelude::*; use biome_grit_syntax::GritPredicateList; + #[derive(Debug, Clone, Default)] pub(crate) struct FormatGritPredicateList; impl FormatRule for FormatGritPredicateList { type Context = GritFormatContext; fn fmt(&self, node: &GritPredicateList, f: &mut GritFormatter) -> FormatResult<()> { - let mut join = f.join_nodes_with_hardline(); + let separator = soft_line_break_or_space(); + let mut joiner = f.join_with(&separator); - for predicate in node { - let predicate = predicate?; - join.entry(predicate.syntax(), &format_or_verbatim(predicate.format())); + for formatted in node.format_separated(",") { + joiner.entry(&group(&indent(&formatted))); } - join.finish() + joiner.finish() } } diff --git a/crates/biome_grit_formatter/src/grit/predicates/predicate_accumulate.rs b/crates/biome_grit_formatter/src/grit/predicates/predicate_accumulate.rs index 3449decbdf50..b52983118618 100644 --- a/crates/biome_grit_formatter/src/grit/predicates/predicate_accumulate.rs +++ b/crates/biome_grit_formatter/src/grit/predicates/predicate_accumulate.rs @@ -1,6 +1,7 @@ use crate::prelude::*; -use biome_grit_syntax::GritPredicateAccumulate; -use biome_rowan::AstNode; +use biome_formatter::write; +use biome_grit_syntax::{GritPredicateAccumulate, GritPredicateAccumulateFields}; + #[derive(Debug, Clone, Default)] pub(crate) struct FormatGritPredicateAccumulate; impl FormatNodeRule for FormatGritPredicateAccumulate { @@ -9,6 +10,21 @@ impl FormatNodeRule for FormatGritPredicateAccumulate { node: &GritPredicateAccumulate, f: &mut GritFormatter, ) -> FormatResult<()> { - format_verbatim_node(node.syntax()).fmt(f) + let GritPredicateAccumulateFields { + left, + add_assign_token, + right, + } = node.as_fields(); + + write!( + f, + [ + left.format(), + space(), + add_assign_token.format(), + space(), + right.format() + ] + ) } } diff --git a/crates/biome_grit_formatter/src/grit/predicates/predicate_match.rs b/crates/biome_grit_formatter/src/grit/predicates/predicate_match.rs index d4fc199209de..f5d77c4cdcef 100644 --- a/crates/biome_grit_formatter/src/grit/predicates/predicate_match.rs +++ b/crates/biome_grit_formatter/src/grit/predicates/predicate_match.rs @@ -1,10 +1,25 @@ use crate::prelude::*; -use biome_grit_syntax::GritPredicateMatch; -use biome_rowan::AstNode; +use biome_formatter::write; +use biome_grit_syntax::{GritPredicateMatch, GritPredicateMatchFields}; #[derive(Debug, Clone, Default)] pub(crate) struct FormatGritPredicateMatch; impl FormatNodeRule for FormatGritPredicateMatch { fn fmt_fields(&self, node: &GritPredicateMatch, f: &mut GritFormatter) -> FormatResult<()> { - format_verbatim_node(node.syntax()).fmt(f) + let GritPredicateMatchFields { + left, + match_token, + right, + } = node.as_fields(); + + write!( + f, + [ + left.format(), + space(), + match_token.format(), + space(), + right.format() + ] + ) } } diff --git a/crates/biome_grit_formatter/src/grit/predicates/predicate_rewrite.rs b/crates/biome_grit_formatter/src/grit/predicates/predicate_rewrite.rs index b4c682600b99..6641ee7780b9 100644 --- a/crates/biome_grit_formatter/src/grit/predicates/predicate_rewrite.rs +++ b/crates/biome_grit_formatter/src/grit/predicates/predicate_rewrite.rs @@ -1,10 +1,29 @@ use crate::prelude::*; -use biome_grit_syntax::GritPredicateRewrite; -use biome_rowan::AstNode; +use biome_formatter::write; +use biome_grit_syntax::{GritPredicateRewrite, GritPredicateRewriteFields}; + #[derive(Debug, Clone, Default)] pub(crate) struct FormatGritPredicateRewrite; impl FormatNodeRule for FormatGritPredicateRewrite { fn fmt_fields(&self, node: &GritPredicateRewrite, f: &mut GritFormatter) -> FormatResult<()> { - format_verbatim_node(node.syntax()).fmt(f) + let GritPredicateRewriteFields { + annotation, + left, + fat_arrow_token, + right, + } = node.as_fields(); + + write!( + f, + [ + annotation.format(), + space(), + left.format(), + space(), + fat_arrow_token.format(), + space(), + right.format() + ] + ) } } diff --git a/crates/biome_grit_formatter/src/lib.rs b/crates/biome_grit_formatter/src/lib.rs index 4e04079ee536..74e5c55a8935 100644 --- a/crates/biome_grit_formatter/src/lib.rs +++ b/crates/biome_grit_formatter/src/lib.rs @@ -4,6 +4,7 @@ mod cst; mod generated; mod grit; mod prelude; +pub(crate) mod separated; use biome_formatter::{ comments::Comments, diff --git a/crates/biome_grit_formatter/src/prelude.rs b/crates/biome_grit_formatter/src/prelude.rs index 3dc661422125..0d15758a8fd8 100644 --- a/crates/biome_grit_formatter/src/prelude.rs +++ b/crates/biome_grit_formatter/src/prelude.rs @@ -3,10 +3,10 @@ #[allow(unused_imports)] pub(crate) use crate::{ - AsFormat, FormatNodeRule, FormattedIterExt as _, GritFormatContext, GritFormatter, IntoFormat, + AsFormat, FormatNodeRule, FormattedIterExt as _, FormattedIterExt, GritFormatContext, + GritFormatter, IntoFormat, }; pub(crate) use biome_formatter::prelude::*; -#[allow(unused_imports)] -pub(crate) use biome_rowan::{ - AstNode as _, AstNodeList as _, AstNodeSlotMap as _, AstSeparatedList as _, -}; +pub(crate) use biome_rowan::{AstNode as _, AstSeparatedList}; + +pub(crate) use crate::separated::FormatAstSeparatedListExtension; diff --git a/crates/biome_grit_formatter/src/separated.rs b/crates/biome_grit_formatter/src/separated.rs new file mode 100644 index 000000000000..82eebdf2fd14 --- /dev/null +++ b/crates/biome_grit_formatter/src/separated.rs @@ -0,0 +1,63 @@ +use biome_formatter::{ + separated::{FormatSeparatedElementRule, FormatSeparatedIter}, + FormatRefWithRule, +}; + +use crate::prelude::*; +use biome_grit_syntax::{GritLanguage, GritSyntaxToken}; +use biome_rowan::{AstNode, AstSeparatedListElementsIterator}; +use std::marker::PhantomData; + +use crate::{cst::FormatGritSyntaxToken, AsFormat, GritFormatContext}; + +#[derive(Clone)] +pub(crate) struct GritFormatSeparatedElementRule +where + N: AstNode, +{ + node: PhantomData, +} + +impl FormatSeparatedElementRule for GritFormatSeparatedElementRule +where + N: AstNode + AsFormat + 'static, +{ + type Context = GritFormatContext; + type FormatNode<'a> = N::Format<'a>; + type FormatSeparator<'a> = FormatRefWithRule<'a, GritSyntaxToken, FormatGritSyntaxToken>; + + fn format_node<'a>(&self, node: &'a N) -> Self::FormatNode<'a> { + node.format() + } + + fn format_separator<'a>(&self, separator: &'a GritSyntaxToken) -> Self::FormatSeparator<'a> { + separator.format() + } +} + +type GritFormatSeparatedIter = FormatSeparatedIter< + AstSeparatedListElementsIterator, + Node, + GritFormatSeparatedElementRule, +>; + +/// AST Separated list formatting extension methods +pub(crate) trait FormatAstSeparatedListExtension: + AstSeparatedList +{ + /// Prints a separated list of nodes + /// + /// Trailing separators will be reused from the original list or + /// created by calling the `separator_factory` function. + /// The last trailing separator in the list will only be printed + /// if the outer group breaks. + fn format_separated(&self, separator: &'static str) -> GritFormatSeparatedIter { + GritFormatSeparatedIter::new( + self.elements(), + separator, + GritFormatSeparatedElementRule { node: PhantomData }, + ) + } +} + +impl FormatAstSeparatedListExtension for T where T: AstSeparatedList {} diff --git a/crates/biome_grit_formatter/tests/specs/grit/patterns/create_new_files.grit b/crates/biome_grit_formatter/tests/specs/grit/patterns/create_new_files.grit new file mode 100644 index 000000000000..ecc38c6053f6 --- /dev/null +++ b/crates/biome_grit_formatter/tests/specs/grit/patterns/create_new_files.grit @@ -0,0 +1 @@ +`function $functionName($_) {$_}` as $f where{ $functionName<:r"test.*",$f=>.,$new_file_name=`$functionName.test.js`,$new_files+=file(name = $new_file_name, body = $f)} \ No newline at end of file diff --git a/crates/biome_grit_formatter/tests/specs/grit/patterns/create_new_files.grit.snap b/crates/biome_grit_formatter/tests/specs/grit/patterns/create_new_files.grit.snap new file mode 100644 index 000000000000..c77607c91516 --- /dev/null +++ b/crates/biome_grit_formatter/tests/specs/grit/patterns/create_new_files.grit.snap @@ -0,0 +1,47 @@ +--- +source: crates/biome_formatter_test/src/snapshot_builder.rs +info: grit/patterns/create_new_files.grit +--- +# Input + +```grit +`function $functionName($_) {$_}` as $f where{ $functionName<:r"test.*",$f=>.,$new_file_name=`$functionName.test.js`,$new_files+=file(name = $new_file_name, body = $f)} +``` + + +============================= + +# Outputs + +## Output 1 + +----- +Indent style: Tab +Indent width: 2 +Line ending: LF +Line width: 80 +Attribute Position: Auto +----- + +```grit +`function $functionName($_) {$_}` as $f where { + $functionName <: r"test.*", + $f => ., + $new_file_name = `$functionName.test.js`, + $new_files += file(name = $new_file_name, body = $f) +} +``` + + + +## Unimplemented nodes/tokens + +"`function $functionName($_) {$_}` as $f " => 0..40 +"\t$functionNam" => 48..61 +" r\"test.*" => 65..74 +"\t$" => 77..79 +" " => 83..84 +"\t$new_file_nam" => 87..101 +" `$functionName.test.js" => 104..127 +"\t$new_file" => 130..140 +" file(name = $new_file_name, body = $f" => 144..182