Skip to content

Commit

Permalink
feat(prettier): add ConditionalGroup command (#1635)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dunqing authored Dec 7, 2023
1 parent 86fe7e3 commit 6e5aad2
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 16 deletions.
24 changes: 23 additions & 1 deletion crates/oxc_prettier/src/doc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,19 @@ impl Line {
pub struct Group<'a> {
pub contents: Vec<'a, Doc<'a>>,
pub should_break: bool,
pub expanded_states: Option<Vec<'a, Doc<'a>>>,
pub id: Option<GroupId>,
}

impl<'a> Group<'a> {
pub fn new(contents: Vec<'a, Doc<'a>>, should_break: bool) -> Self {
Self { contents, should_break, id: None }
Self { contents, should_break, id: None, expanded_states: None }
}
pub fn new_conditional_group(
contents: Vec<'a, Doc<'a>>,
expanded_states: Vec<'a, Doc<'a>>,
) -> Self {
Self { contents, should_break: false, id: None, expanded_states: Some(expanded_states) }
}
pub fn with_id(mut self, id: GroupId) -> Self {
self.id = Some(id);
Expand Down Expand Up @@ -244,6 +251,10 @@ fn print_doc_to_debug(doc: &Doc<'_>) -> std::string::String {
string.push_str("])");
}
Doc::Group(group) => {
if group.expanded_states.is_some() {
string.push_str("conditionalGroup([\n");
}

string.push_str("group([\n");
for (idx, doc) in group.contents.iter().enumerate() {
string.push_str(&print_doc_to_debug(doc));
Expand All @@ -257,6 +268,17 @@ fn print_doc_to_debug(doc: &Doc<'_>) -> std::string::String {
string.push_str(&format!(", id: {id}"));
}
string.push_str(" })");

if let Some(expanded_states) = &group.expanded_states {
string.push_str(",\n");
for (idx, doc) in expanded_states.iter().enumerate() {
string.push_str(&print_doc_to_debug(doc));
if idx != expanded_states.len() - 1 {
string.push_str(", ");
}
}
string.push(']');
}
}
Doc::Line(Line { soft, hard, .. }) => {
if *soft {
Expand Down
29 changes: 29 additions & 0 deletions crates/oxc_prettier/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,35 @@ macro_rules! group {
};
}

#[macro_export]
macro_rules! conditional_group {
($p:ident, $c: expr, $( $x:expr ),* $(,)?) => {
{
use $crate::doc::DocBuilder;
let mut temp_vec = $p.vec();
$(
temp_vec.push($x);
)*
let contents = $p.vec_single($c);
Doc::Group($crate::doc::Group::new_conditional_group(contents, temp_vec))
}
};
}

#[macro_export]
macro_rules! group_break {
($p:ident, $( $x:expr ),* $(,)?) => {
{
use $crate::doc::DocBuilder;
let mut temp_vec = $p.vec();
$(
temp_vec.push($x);
)*
Doc::Group($crate::doc::Group::new(temp_vec, true))
}
};
}

#[macro_export]
macro_rules! if_break {
($p:ident, $s:expr, $flat:expr, $group_id:expr) => {{
Expand Down
59 changes: 44 additions & 15 deletions crates/oxc_prettier/src/printer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,28 @@ impl<'a> Printer<'a> {
self.cmds.push(Command::new(indent, Mode::Flat, cmd.doc));
} else {
let Doc::Group(group) = cmd.doc else { unreachable!() };
self.cmds.extend(
group
.contents
.into_iter()
.rev()
.map(|doc| Command::new(indent, Mode::Break, doc)),
);

if let Some(mut expanded_states) = group.expanded_states {
let most_expanded = expanded_states.pop().unwrap();
if group.should_break {
self.cmds.push(Command::new(indent, Mode::Break, most_expanded));
return;
}
for state in expanded_states {
let cmd = Command::new(indent, Mode::Flat, state);
if self.fits(&cmd, remaining_width) {
self.cmds.push(cmd);
return;
}
}
self.cmds.push(Command::new(indent, Mode::Break, most_expanded));
} else {
self.cmds.push(Command::new(
indent,
Mode::Break,
Doc::Array(group.contents),
));
}
}
self.set_group_mode_from_last_cmd(group_id);
}
Expand Down Expand Up @@ -360,9 +375,16 @@ impl<'a> Printer<'a> {
}
Doc::Group(group) => {
let mode = if group.should_break { Mode::Break } else { mode };
for d in group.contents.iter().rev() {
queue.push_front((mode, d));
}
if group.expanded_states.is_some() && mode.is_break() {
queue.push_front((
mode,
group.expanded_states.as_ref().unwrap().last().unwrap(),
));
} else {
for d in group.contents.iter().rev() {
queue.push_front((mode, d));
}
};
}
Doc::IfBreak(if_break_doc) => {
let group_mode = if_break_doc
Expand Down Expand Up @@ -413,11 +435,20 @@ impl<'a> Printer<'a> {
/// Reference:
/// * https://github.com/prettier/prettier/blob/main/src/document/utils.js#L156-L185
pub fn propagate_breaks(doc: &mut Doc<'_>) -> bool {
let check_array = |arr: &mut oxc_allocator::Vec<'_, Doc<'_>>| {
arr.iter_mut().rev().any(|doc| Self::propagate_breaks(doc))
};

match doc {
Doc::BreakParent => true,
Doc::Group(group) => {
let should_break =
group.contents.iter_mut().rev().any(|doc| Self::propagate_breaks(doc));
let mut should_break = false;
if let Some(expanded_states) = &mut group.expanded_states {
should_break = expanded_states.iter_mut().rev().any(Self::propagate_breaks);
}
if !should_break {
should_break = check_array(&mut group.contents);
}
if should_break {
group.should_break = should_break;
}
Expand All @@ -426,9 +457,7 @@ impl<'a> Printer<'a> {
Doc::IfBreak(d) => Self::propagate_breaks(&mut d.break_contents),
Doc::Array(arr)
| Doc::Indent(arr)
| Doc::IndentIfBreak(IndentIfBreak { contents: arr, .. }) => {
arr.iter_mut().any(|doc| Self::propagate_breaks(doc))
}
| Doc::IndentIfBreak(IndentIfBreak { contents: arr, .. }) => check_array(arr),
_ => false,
}
}
Expand Down

0 comments on commit 6e5aad2

Please sign in to comment.