From 40be405a577af8830c101c0f9a9a8803a5ccb993 Mon Sep 17 00:00:00 2001 From: Dunqing Date: Thu, 16 Nov 2023 20:48:27 +0800 Subject: [PATCH] feat(prettier): support for printing objects with longer properties (#1353) --- crates/oxc_prettier/src/format/mod.rs | 9 +++++++-- crates/oxc_prettier/src/format/object.rs | 20 +++++++++++++------- crates/oxc_prettier/src/format/ternary.rs | 17 +++++++++++------ crates/oxc_prettier/src/printer/command.rs | 2 +- crates/oxc_prettier/src/printer/mod.rs | 20 ++++++++++++-------- tasks/prettier_conformance/prettier.snap.md | 1 - 6 files changed, 44 insertions(+), 25 deletions(-) diff --git a/crates/oxc_prettier/src/format/mod.rs b/crates/oxc_prettier/src/format/mod.rs index c0902766f..51753ab91 100644 --- a/crates/oxc_prettier/src/format/mod.rs +++ b/crates/oxc_prettier/src/format/mod.rs @@ -778,7 +778,12 @@ impl<'a> Format<'a> for ObjectPropertyKind<'a> { impl<'a> Format<'a> for ObjectProperty<'a> { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { - array!(p, format!(p, self.key), ss!(": "), format!(p, self.value)) + // Perf: Use same print function with BindingProperty + if self.shorthand { + self.key.format(p) + } else { + group!(p, format!(p, self.key), ss!(": "), format!(p, self.value)) + } } } @@ -1252,7 +1257,7 @@ impl<'a> Format<'a> for BindingProperty<'a> { if self.shorthand { self.key.format(p) } else { - array![p, format!(p, self.key), ss!(": "), format!(p, self.value)] + group!(p, format!(p, self.key), ss!(": "), format!(p, self.value)) } } } diff --git a/crates/oxc_prettier/src/format/object.rs b/crates/oxc_prettier/src/format/object.rs index 774016f33..ac8998bfe 100644 --- a/crates/oxc_prettier/src/format/object.rs +++ b/crates/oxc_prettier/src/format/object.rs @@ -1,6 +1,6 @@ use oxc_allocator::Vec; -use crate::{doc::Doc, ss, Prettier}; +use crate::{doc::Doc, group, if_break, ss, Prettier}; use super::Format; @@ -10,28 +10,34 @@ impl<'a> Prettier<'a> { properties: &Vec<'a, F>, ) -> Doc<'a> { let mut parts = self.vec(); - parts.push(ss!("{")); + + let mut indent_parts = self.vec(); + if self.options.bracket_spacing { - parts.push(Doc::Line); + indent_parts.push(Doc::Line); } else { - parts.push(Doc::Softline); + indent_parts.push(Doc::Softline); }; let len = properties.len(); properties.iter().map(|prop| prop.format(self)).enumerate().for_each(|(i, prop)| { - parts.push(prop); + indent_parts.push(prop); if i < len - 1 { - parts.push(Doc::Str(",")); - parts.push(Doc::Line); + indent_parts.push(Doc::Str(",")); + indent_parts.push(Doc::Line); } }); + parts.push(group!(self, Doc::Indent(indent_parts))); + parts.push(if_break!(self, ",")); + if self.options.bracket_spacing { parts.push(Doc::Line); } else { parts.push(Doc::Softline); } + parts.push(ss!("}")); Doc::Group(parts) diff --git a/crates/oxc_prettier/src/format/ternary.rs b/crates/oxc_prettier/src/format/ternary.rs index 08e1acdb8..e454af661 100644 --- a/crates/oxc_prettier/src/format/ternary.rs +++ b/crates/oxc_prettier/src/format/ternary.rs @@ -1,17 +1,22 @@ #[allow(clippy::wildcard_imports)] use oxc_ast::ast::*; -use crate::{array, doc::Doc, ss, Format, Prettier}; +use crate::{doc::Doc, group, indent, ss, Format, Prettier}; impl<'a> Prettier<'a> { pub(super) fn print_ternary(&mut self, expr: &ConditionalExpression<'a>) -> Doc<'a> { - array![ + group![ self, expr.test.format(self), - ss!(" ? "), - expr.consequent.format(self), - ss!(" : "), - expr.alternate.format(self) + indent!( + self, + Doc::Line, + ss!("? "), + expr.consequent.format(self), + Doc::Line, + ss!(": "), + expr.alternate.format(self) + ) ] } } diff --git a/crates/oxc_prettier/src/printer/command.rs b/crates/oxc_prettier/src/printer/command.rs index e26c2c29f..0d13dc976 100644 --- a/crates/oxc_prettier/src/printer/command.rs +++ b/crates/oxc_prettier/src/printer/command.rs @@ -12,7 +12,7 @@ impl<'a> Command<'a> { } } -#[derive(Clone, Copy, Eq, PartialEq)] +#[derive(Clone, Debug, Copy, Eq, PartialEq)] pub enum Mode { Break, Flat, diff --git a/crates/oxc_prettier/src/printer/mod.rs b/crates/oxc_prettier/src/printer/mod.rs index 7d0f584dd..135aaec90 100644 --- a/crates/oxc_prettier/src/printer/mod.rs +++ b/crates/oxc_prettier/src/printer/mod.rs @@ -86,7 +86,7 @@ impl<'a> Printer<'a> { #[allow(clippy::cast_possible_wrap)] let remaining_width = (self.options.print_width as isize) - (self.pos as isize); - if Self::fits(&docs, remaining_width) { + if self.fits(&docs, indent, remaining_width) { self.cmds.extend( docs.into_iter().rev().map(|doc| Command::new(indent, Mode::Flat, doc)), ); @@ -127,7 +127,12 @@ impl<'a> Printer<'a> { } #[allow(clippy::cast_possible_wrap)] - fn fits(doc: &oxc_allocator::Vec<'a, Doc<'a>>, remaining_width: isize) -> bool { + fn fits( + &self, + doc: &oxc_allocator::Vec<'a, Doc<'a>>, + indent: Indent, + remaining_width: isize, + ) -> bool { let mut remaining_width = remaining_width; // TODO: these should be commands @@ -138,20 +143,19 @@ impl<'a> Printer<'a> { Doc::Str(string) => { remaining_width -= string.len() as isize; } - Doc::Array(docs) | Doc::Indent(docs) => { + Doc::Array(docs) | Doc::Indent(docs) | Doc::Group(docs) => { // Prepend docs to the queue for d in docs.iter().rev() { queue.push_front(d); } - } - Doc::Group(doc) => { - for d in doc.iter().rev() { - queue.push_front(d); + + if matches!(next, Doc::Indent(_)) { + remaining_width -= (self.options.tab_width * indent.length) as isize; } } // trying to fit on a single line, so we don't need to consider line breaks Doc::IfBreak { .. } | Doc::Softline => {} - Doc::Line => remaining_width += 1, + Doc::Line => remaining_width -= 1, Doc::Hardline => { return false; } diff --git a/tasks/prettier_conformance/prettier.snap.md b/tasks/prettier_conformance/prettier.snap.md index 2d239d538..57c3abf25 100644 --- a/tasks/prettier_conformance/prettier.snap.md +++ b/tasks/prettier_conformance/prettier.snap.md @@ -113,7 +113,6 @@ Compatibility: 9/173 (5.20%) * non-strict * nullish-coalescing * numeric-separators -* object-colon-bug * object-prop-break-in * object-property-comment * object-property-ignore