Skip to content

Commit

Permalink
feat(format/grit): add logic for formatting with separators and other…
Browse files Browse the repository at this point in the history
… predicates (#4327)
  • Loading branch information
branberry authored Oct 19, 2024
1 parent 8081745 commit e9d3b6e
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 22 deletions.
23 changes: 20 additions & 3 deletions crates/biome_grit_formatter/src/grit/auxiliary/like.rs
Original file line number Diff line number Diff line change
@@ -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<GritLike> 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()
]
)
}
}
11 changes: 6 additions & 5 deletions crates/biome_grit_formatter/src/grit/lists/predicate_list.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
use crate::prelude::*;
use biome_grit_syntax::GritPredicateList;

#[derive(Debug, Clone, Default)]
pub(crate) struct FormatGritPredicateList;
impl FormatRule<GritPredicateList> 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()
}
}
Original file line number Diff line number Diff line change
@@ -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<GritPredicateAccumulate> for FormatGritPredicateAccumulate {
Expand All @@ -9,6 +10,21 @@ impl FormatNodeRule<GritPredicateAccumulate> 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()
]
)
}
}
21 changes: 18 additions & 3 deletions crates/biome_grit_formatter/src/grit/predicates/predicate_match.rs
Original file line number Diff line number Diff line change
@@ -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<GritPredicateMatch> 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()
]
)
}
}
Original file line number Diff line number Diff line change
@@ -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<GritPredicateRewrite> 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()
]
)
}
}
1 change: 1 addition & 0 deletions crates/biome_grit_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod cst;
mod generated;
mod grit;
mod prelude;
pub(crate) mod separated;

use biome_formatter::{
comments::Comments,
Expand Down
10 changes: 5 additions & 5 deletions crates/biome_grit_formatter/src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
63 changes: 63 additions & 0 deletions crates/biome_grit_formatter/src/separated.rs
Original file line number Diff line number Diff line change
@@ -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<N>
where
N: AstNode<Language = GritLanguage>,
{
node: PhantomData<N>,
}

impl<N> FormatSeparatedElementRule<N> for GritFormatSeparatedElementRule<N>
where
N: AstNode<Language = GritLanguage> + AsFormat<GritFormatContext> + '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<Node> = FormatSeparatedIter<
AstSeparatedListElementsIterator<GritLanguage, Node>,
Node,
GritFormatSeparatedElementRule<Node>,
>;

/// AST Separated list formatting extension methods
pub(crate) trait FormatAstSeparatedListExtension:
AstSeparatedList<Language = GritLanguage>
{
/// 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<Self::Node> {
GritFormatSeparatedIter::new(
self.elements(),
separator,
GritFormatSeparatedElementRule { node: PhantomData },
)
}
}

impl<T> FormatAstSeparatedListExtension for T where T: AstSeparatedList<Language = GritLanguage> {}
Original file line number Diff line number Diff line change
@@ -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)}
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit e9d3b6e

Please sign in to comment.