diff --git a/crates/oxc_prettier/src/printer/mod.rs b/crates/oxc_prettier/src/printer/mod.rs index a285dbb4d..cf34c8824 100644 --- a/crates/oxc_prettier/src/printer/mod.rs +++ b/crates/oxc_prettier/src/printer/mod.rs @@ -5,7 +5,7 @@ mod command; -use std::collections::VecDeque; +use std::{collections::VecDeque, vec}; use crate::{ doc::{Doc, Group}, @@ -97,14 +97,8 @@ impl<'a> Printer<'a> { #[allow(clippy::cast_possible_wrap)] let remaining_width = (self.options.print_width as isize) - (self.pos as isize); - if !group.should_break && self.fits(&group.contents, indent, remaining_width) { - self.cmds.extend( - group - .contents - .into_iter() - .rev() - .map(|doc| Command::new(indent, Mode::Flat, doc)), - ); + if !group.should_break && self.fits(&group.contents, remaining_width) { + self.cmds.push(Command::new(indent, Mode::Flat, Doc::Group(group))); } else { self.cmds.extend( group @@ -166,51 +160,61 @@ impl<'a> Printer<'a> { } #[allow(clippy::cast_possible_wrap)] - fn fits( - &self, - doc: &oxc_allocator::Vec<'a, Doc<'a>>, - indent: Indent, - remaining_width: isize, - ) -> bool { + fn fits(&self, docs: &oxc_allocator::Vec<'a, Doc<'a>>, remaining_width: isize) -> bool { let mut remaining_width = remaining_width; // TODO: these should be commands - let mut queue: VecDeque<&Doc<'a>> = doc.iter().collect(); + let mut queue: VecDeque<(Mode, &Doc)> = docs.iter().map(|doc| (Mode::Flat, doc)).collect(); + let mut cmds = self.cmds.iter().rev(); - while let Some(next) = queue.pop_front() { - match next { + while let Some((mode, doc)) = queue.pop_front() { + let is_break = matches!(mode, Mode::Break); + match doc { Doc::Str(string) => { remaining_width -= string.len() as isize; } - Doc::IndentIfBreak(docs) | Doc::Array(docs) | Doc::Indent(docs) => { + Doc::IndentIfBreak(docs) | Doc::Indent(docs) | Doc::Array(docs) => { // Prepend docs to the queue for d in docs.iter().rev() { - queue.push_front(d); - } - - if matches!(next, Doc::Indent(_)) { - remaining_width -= (self.options.tab_width * indent.length) as isize; + queue.push_front((mode, d)); } } Doc::Group(group) => { - if group.should_break { - return false; - } + let mode = if group.should_break { Mode::Break } else { mode }; for d in group.contents.iter().rev() { - queue.push_front(d); + queue.push_front((mode, d)); + } + } + Doc::IfBreak(doc) => { + if is_break { + queue.push_front((mode, doc)); + } + } + Doc::Line => { + if is_break { + return true; + } + remaining_width -= 1_isize; + } + Doc::Softline => { + if is_break { + return true; } } - // 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::Hardline => { - return false; + return true; } } if remaining_width < 0 { return false; } + + if queue.is_empty() { + if let Some(cmd) = cmds.next() { + queue.push_back((cmd.mode, &cmd.doc)); + } + } } true diff --git a/tasks/prettier_conformance/prettier.snap.md b/tasks/prettier_conformance/prettier.snap.md index ba841326a..a9be5a2da 100644 --- a/tasks/prettier_conformance/prettier.snap.md +++ b/tasks/prettier_conformance/prettier.snap.md @@ -1,4 +1,4 @@ -Compatibility: 114/601 (18.97%) +Compatibility: 113/601 (18.80%) # Failed @@ -89,6 +89,7 @@ Compatibility: 114/601 (18.97%) ### async * async/async-iteration.js +* async/async-shorthand-method.js * async/await-parse.js * async/conditional-expression.js * async/exponentiation.js @@ -131,8 +132,8 @@ Compatibility: 114/601 (18.97%) ### call/first-argument-expansion * call/first-argument-expansion/expression-2nd-arg.js +* call/first-argument-expansion/issue-12892.js * call/first-argument-expansion/issue-13237.js -* call/first-argument-expansion/issue-14454.js * call/first-argument-expansion/issue-2456.js * call/first-argument-expansion/issue-4401.js * call/first-argument-expansion/issue-5172.js @@ -407,7 +408,6 @@ Compatibility: 114/601 (18.97%) ### import * import/comments.js -* import/inline.js * import/same-local-and-imported.js ### label @@ -499,8 +499,12 @@ Compatibility: 114/601 (18.97%) ### nullish-coalescing * nullish-coalescing/nullish_coalesing_operator.js +### object-colon-bug +* object-colon-bug/bug.js + ### object-prop-break-in * object-prop-break-in/comment.js +* object-prop-break-in/long-value.js * object-prop-break-in/short-keys.js * object-prop-break-in/test.js @@ -515,6 +519,7 @@ Compatibility: 114/601 (18.97%) * objects/escape-sequence-key.js * objects/expand.js * objects/expression.js +* objects/getter-setter.js * objects/range.js * objects/right-break.js @@ -612,10 +617,6 @@ Compatibility: 114/601 (18.97%) * switch/empty_switch.js * switch/switch.js -### tab-width -* tab-width/class.js -* tab-width/nested-functions.spec.js - ### template * template/arrow.js * template/call.js