From ca77ccc9514b868465cdd6c60ea1c9c9686546ae Mon Sep 17 00:00:00 2001 From: Boshen Date: Fri, 9 Feb 2024 12:11:42 +0800 Subject: [PATCH] refactor(prettier): add a `space!()` macro (#2348) --- crates/oxc_prettier/src/binaryish.rs | 4 -- crates/oxc_prettier/src/comments/print.rs | 8 ++-- crates/oxc_prettier/src/format/assignment.rs | 8 ++-- crates/oxc_prettier/src/format/binaryish.rs | 38 ++++++++++++------- crates/oxc_prettier/src/format/class.rs | 6 +-- crates/oxc_prettier/src/format/function.rs | 8 ++-- .../src/format/function_parameters.rs | 4 +- crates/oxc_prettier/src/format/misc.rs | 4 +- crates/oxc_prettier/src/format/mod.rs | 22 +++++------ crates/oxc_prettier/src/format/module.rs | 8 ++-- crates/oxc_prettier/src/macros.rs | 7 ++++ 11 files changed, 65 insertions(+), 52 deletions(-) diff --git a/crates/oxc_prettier/src/binaryish.rs b/crates/oxc_prettier/src/binaryish.rs index f3213ee31287e..8f91378fb7ef6 100644 --- a/crates/oxc_prettier/src/binaryish.rs +++ b/crates/oxc_prettier/src/binaryish.rs @@ -82,10 +82,6 @@ impl GetPrecedence for BinaryishOperator { } impl BinaryishOperator { - pub fn is_binary(self) -> bool { - matches!(self, Self::BinaryOperator(_)) - } - pub fn should_flatten(self, parent_op: Self) -> bool { if self.precedence() != parent_op.precedence() { return false; diff --git a/crates/oxc_prettier/src/comments/print.rs b/crates/oxc_prettier/src/comments/print.rs index 1c674e6451f3f..3bd59350567f7 100644 --- a/crates/oxc_prettier/src/comments/print.rs +++ b/crates/oxc_prettier/src/comments/print.rs @@ -4,7 +4,7 @@ use oxc_span::Span; use crate::{ array, doc::{Doc, DocBuilder, Separator}, - hardline, line, ss, Prettier, + hardline, line, space, Prettier, }; use super::{Comment, CommentFlags, DanglingCommentsPrintOptions}; @@ -97,7 +97,7 @@ impl<'a> Prettier<'a> { parts.push(line!()); } } else { - parts.push(ss!(" ")); + parts.push(space!()); }; } else { parts.extend(hardline!()); @@ -164,7 +164,7 @@ impl<'a> Prettier<'a> { if !comment.is_block || previous.is_some_and(|c| c.has_line_suffix) { let suffix = { let mut parts = self.vec(); - parts.push(ss!(" ")); + parts.push(space!()); parts.push(printed); parts }; @@ -173,7 +173,7 @@ impl<'a> Prettier<'a> { return comment.with_line_suffix(true); } - let doc = array![self, ss!(" "), printed]; + let doc = array![self, space!(), printed]; parts.push(doc); comment.with_line_suffix(false) } diff --git a/crates/oxc_prettier/src/format/assignment.rs b/crates/oxc_prettier/src/format/assignment.rs index 76a56096e41c0..d3d8a7989ea28 100644 --- a/crates/oxc_prettier/src/format/assignment.rs +++ b/crates/oxc_prettier/src/format/assignment.rs @@ -11,7 +11,7 @@ use oxc_ast::{ use crate::{ array, doc::{Doc, DocBuilder, Group, IndentIfBreak}, - group, indent, line, ss, Format, Prettier, + group, indent, line, space, Format, Prettier, }; use super::{binaryish::should_inline_logical_expression, class::ClassMemberish}; @@ -25,7 +25,7 @@ pub(super) fn print_assignment_expression<'a>( p, AssignmentLikeNode::AssignmentExpression(assignment_expr), left_doc, - array![p, ss!(" "), Doc::Str(assignment_expr.operator.as_str())], + array![p, space!(), Doc::Str(assignment_expr.operator.as_str())], Some(&assignment_expr.right), ) } @@ -83,7 +83,7 @@ pub(super) fn print_assignment<'a>( group!(p, group!(p, left_doc), op, group!(p, indent!(p, line!(), right_doc))) } Layout::NeverBreakAfterOperator => { - group!(p, group!(p, left_doc), op, ss!(" "), group!(p, right_doc)) + group!(p, group!(p, left_doc), op, space!(), group!(p, right_doc)) } // First break right-hand side, then after operator Layout::Fluid => { @@ -104,7 +104,7 @@ pub(super) fn print_assignment<'a>( group!(p, group!(p, left_doc), op, after_op, right_doc) } Layout::BreakLhs => { - group!(p, left_doc, op, ss!(" "), group!(p, right_doc)) + group!(p, left_doc, op, space!(), group!(p, right_doc)) } // Parts of assignment chains aren't wrapped in groups. // Once one of them breaks, the chain breaks too. diff --git a/crates/oxc_prettier/src/format/binaryish.rs b/crates/oxc_prettier/src/format/binaryish.rs index 460fec7add21d..27238a71e94eb 100644 --- a/crates/oxc_prettier/src/format/binaryish.rs +++ b/crates/oxc_prettier/src/format/binaryish.rs @@ -4,7 +4,7 @@ use crate::{ binaryish::{BinaryishLeft, BinaryishOperator}, comments::CommentFlags, doc::{Doc, DocBuilder, Group}, - group, line, ss, Format, Prettier, + group, line, space, ss, Format, Prettier, }; pub(super) fn print_binaryish_expression<'a>( @@ -38,26 +38,36 @@ fn print_binaryish_expressions<'a>( parts.push(group!(p, left.format(p))); } let should_inline = should_inline_logical_expression(right); - let mut right_parts = p.vec(); - right_parts.push(ss!(operator.as_str())); - right_parts.push(if should_inline { ss!(" ") } else { line!() }); - right_parts.push(right.format(p)); + let line_before_operator = false; + + let right = if should_inline { + p.vec() + } else { + let mut parts = p.vec(); + if line_before_operator { + parts.push(line!()); + } + parts.push(ss!(operator.as_str())); + parts.push(if line_before_operator { space!() } else { line!() }); + parts.push(right.format(p)); + parts + }; let should_break = p.has_comment(left.span(), CommentFlags::Trailing | CommentFlags::Line); + let should_group = false; - parts.push(ss!(" ")); - if should_break { - let group = Doc::Group(Group::new(right_parts, should_break)); - parts.push(group); - } else { - parts.push(Doc::Array(right_parts)); + if !line_before_operator { + parts.push(space!()); } - if operator.is_binary() { - Doc::Group(Group::new(parts, false)) + if should_group { + let group = Doc::Group(Group::new(right, should_break)); + parts.push(group); } else { - Doc::Array(parts) + parts.push(Doc::Array(right)); } + + Doc::Array(parts) } pub(super) fn should_inline_logical_expression(expr: &Expression) -> bool { diff --git a/crates/oxc_prettier/src/format/class.rs b/crates/oxc_prettier/src/format/class.rs index 50cf93866f556..4fc066116d3de 100644 --- a/crates/oxc_prettier/src/format/class.rs +++ b/crates/oxc_prettier/src/format/class.rs @@ -5,7 +5,7 @@ use crate::{ array, doc::{Doc, DocBuilder}, format::assignment, - hardline, ss, Format, Prettier, + hardline, space, ss, Format, Prettier, }; use super::assignment::AssignmentLikeNode; @@ -15,13 +15,13 @@ pub(super) fn print_class<'a>(p: &mut Prettier<'a>, class: &Class<'a>) -> Doc<'a parts.push(ss!("class ")); if let Some(id) = &class.id { parts.push(id.format(p)); - parts.push(ss!(" ")); + parts.push(space!()); } if let Some(super_class) = &class.super_class { parts.push(ss!("extends ")); parts.push(super_class.format(p)); - parts.push(ss!(" ")); + parts.push(space!()); } parts.push(class.body.format(p)); diff --git a/crates/oxc_prettier/src/format/function.rs b/crates/oxc_prettier/src/format/function.rs index b1a1b1df64821..8edd5befa7037 100644 --- a/crates/oxc_prettier/src/format/function.rs +++ b/crates/oxc_prettier/src/format/function.rs @@ -3,7 +3,7 @@ use oxc_ast::ast::*; use crate::{ doc::{Doc, DocBuilder}, format::function_parameters::should_group_function_parameters, - group, if_break, indent, softline, ss, Format, Prettier, + group, if_break, indent, softline, space, ss, Format, Prettier, }; pub(super) fn print_function<'a>( @@ -41,7 +41,7 @@ pub(super) fn print_function<'a>( // Prettier has `returnTypeDoc` to group together, write this for keep same with prettier. parts.push(group!(p, params_doc)); if let Some(body) = &func.body { - parts.push(ss!(" ")); + parts.push(space!()); parts.push(body.format(p)); } if func.is_ts_declare_function() || func.body.is_none() { @@ -94,7 +94,7 @@ fn print_method_value<'a>(p: &mut Prettier<'a>, function: &Function<'a>) -> Doc< parts.push(group!(p, parameters_doc)); if let Some(body) = &function.body { - parts.push(ss!(" ")); + parts.push(space!()); parts.push(body.format(p)); } Doc::Array(parts) @@ -110,7 +110,7 @@ pub(super) fn print_return_or_throw_argument<'a>( parts.push(ss!(if is_return { "return" } else { "throw" })); if let Some(argument) = argument { - parts.push(ss!(" ")); + parts.push(space!()); parts.push( if argument.is_binaryish() || matches!(argument, Expression::SequenceExpression(_)) { group![ diff --git a/crates/oxc_prettier/src/format/function_parameters.rs b/crates/oxc_prettier/src/format/function_parameters.rs index 3a3dc90bff53e..28a4bdad4496e 100644 --- a/crates/oxc_prettier/src/format/function_parameters.rs +++ b/crates/oxc_prettier/src/format/function_parameters.rs @@ -3,7 +3,7 @@ use oxc_ast::{ast::*, AstKind}; use crate::{ comments::CommentFlags, doc::{Doc, DocBuilder, Group}, - hardline, if_break, indent, line, softline, ss, Format, Prettier, + hardline, if_break, indent, line, softline, space, ss, Format, Prettier, }; pub(super) fn should_hug_the_only_function_parameter( @@ -77,7 +77,7 @@ pub(super) fn print_function_parameters<'a>( } printed.push(ss!(",")); if should_hug_the_only_function_parameter(p, params) { - printed.push(ss!(" ")); + printed.push(space!()); } else if p.is_next_line_empty(param.span) { printed.extend(hardline!()); printed.extend(hardline!()); diff --git a/crates/oxc_prettier/src/format/misc.rs b/crates/oxc_prettier/src/format/misc.rs index ac08f77a3b35f..4ff2402ca3b04 100644 --- a/crates/oxc_prettier/src/format/misc.rs +++ b/crates/oxc_prettier/src/format/misc.rs @@ -1,7 +1,7 @@ use oxc_ast::{ast::*, AstKind}; use oxc_span::Span; -use crate::{array, doc::Doc, indent, line, ss, Prettier}; +use crate::{array, doc::Doc, indent, line, space, ss, Prettier}; pub(super) fn adjust_clause<'a>( p: &Prettier<'a>, @@ -14,7 +14,7 @@ pub(super) fn adjust_clause<'a>( } if matches!(node, Statement::BlockStatement(_)) || force_space { - return array![p, ss!(" "), clause]; + return array![p, space!(), clause]; } indent![p, line!(), clause] diff --git a/crates/oxc_prettier/src/format/mod.rs b/crates/oxc_prettier/src/format/mod.rs index 2712aad363596..24d6975f93668 100644 --- a/crates/oxc_prettier/src/format/mod.rs +++ b/crates/oxc_prettier/src/format/mod.rs @@ -33,7 +33,7 @@ use oxc_syntax::identifier::is_identifier_name; use crate::{ array, doc::{Doc, DocBuilder, Group, Separator}, - format, group, hardline, indent, line, softline, ss, string, wrap, Prettier, + format, group, hardline, indent, line, softline, space, ss, string, wrap, Prettier, }; use self::{array::Array, object::ObjectLike, template_literal::TemplateLiteralPrinter}; @@ -165,7 +165,7 @@ impl<'a> Format<'a> for IfStatement<'a> { if let Some(alternate) = &self.alternate { let else_on_same_line = matches!(alternate, Statement::BlockStatement(_)); if else_on_same_line { - parts.push(ss!(" ")); + parts.push(space!()); } else { parts.extend(hardline!()); } @@ -312,7 +312,7 @@ impl<'a> Format<'a> for DoWhileStatement<'a> { parts.push(do_body); if matches!(self.body, Statement::BlockStatement(_)) { - parts.push(ss!(" ")); + parts.push(space!()); } else { parts.extend(hardline!()); } @@ -335,7 +335,7 @@ impl<'a> Format<'a> for ContinueStatement { parts.push(ss!("continue")); if let Some(label) = &self.label { - parts.push(ss!(" ")); + parts.push(space!()); parts.push(format!(p, label)); } @@ -349,7 +349,7 @@ impl<'a> Format<'a> for BreakStatement { parts.push(ss!("break")); if let Some(label) = &self.label { - parts.push(ss!(" ")); + parts.push(space!()); parts.push(format!(p, label)); } @@ -434,7 +434,7 @@ impl<'a> Format<'a> for SwitchCase<'a> { } if is_only_one_block_statement { - consequent_parts.push(ss!(" ")); + consequent_parts.push(space!()); } else { consequent_parts.extend(hardline!()); } @@ -478,7 +478,7 @@ impl<'a> Format<'a> for TryStatement<'a> { parts.push(ss!("try ")); parts.push(format!(p, self.block)); if let Some(handler) = &self.handler { - parts.push(ss!(" ")); + parts.push(space!()); parts.push(format!(p, handler)); } if let Some(finalizer) = &self.finalizer { @@ -584,7 +584,7 @@ impl<'a> Format<'a> for VariableDeclaration<'a> { let mut parts = p.vec(); parts.push(ss!(kind)); - parts.push(ss!(" ")); + parts.push(space!()); let is_hardline = !p.parent_kind().is_iteration_statement() && self.declarations.iter().all(|decl| decl.init.is_some()); @@ -1103,7 +1103,7 @@ impl<'a> Format<'a> for ExportNamedDeclaration<'a> { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { let mut parts = p.vec(); if let Some(decl) = &self.declaration { - parts.push(ss!(" ")); + parts.push(space!()); parts.push(decl.format(p)); } else { parts.push(module::print_module_specifiers( @@ -1628,7 +1628,7 @@ impl<'a> Format<'a> for YieldExpression<'a> { parts.push(ss!("*")); } if let Some(argument) = &self.argument { - parts.push(ss!(" ")); + parts.push(space!()); parts.push(format!(p, argument)); } Doc::Array(parts) @@ -1654,7 +1654,7 @@ impl<'a> Format<'a> for UnaryExpression<'a> { let mut parts = p.vec(); parts.push(string!(p, self.operator.as_str())); if self.operator.is_keyword() { - parts.push(ss!(" ")); + parts.push(space!()); } parts.push(format!(p, self.argument)); Doc::Array(parts) diff --git a/crates/oxc_prettier/src/format/module.rs b/crates/oxc_prettier/src/format/module.rs index b7de88d563bf3..6d035eac7e489 100644 --- a/crates/oxc_prettier/src/format/module.rs +++ b/crates/oxc_prettier/src/format/module.rs @@ -5,7 +5,7 @@ use oxc_ast::ast::*; use crate::{ doc::{Doc, DocBuilder, Separator}, - group, if_break, indent, line, softline, ss, Format, Prettier, + group, if_break, indent, line, softline, space, ss, Format, Prettier, }; pub(super) fn print_export_declaration<'a>( @@ -75,7 +75,7 @@ pub fn print_module_specifiers<'a, T: Format<'a>>( if specifiers.is_empty() { parts.push(ss!(" {}")); } else { - parts.push(ss!(" ")); + parts.push(space!()); let mut specifiers_iter: VecDeque<_> = specifiers.iter().collect(); if include_default { @@ -113,11 +113,11 @@ pub fn print_module_specifiers<'a, T: Format<'a>>( } else { parts.push(ss!("{")); if p.options.bracket_spacing { - parts.push(ss!(" ")); + parts.push(space!()); } parts.extend(specifiers_iter.iter().map(|s| s.format(p))); if p.options.bracket_spacing { - parts.push(ss!(" ")); + parts.push(space!()); } parts.push(ss!("}")); } diff --git a/crates/oxc_prettier/src/macros.rs b/crates/oxc_prettier/src/macros.rs index 3196ecc7c472d..ae2ef977b55a3 100644 --- a/crates/oxc_prettier/src/macros.rs +++ b/crates/oxc_prettier/src/macros.rs @@ -15,6 +15,13 @@ macro_rules! ss { }}; } +#[macro_export] +macro_rules! space { + () => {{ + Doc::Str(" ") + }}; +} + #[macro_export] macro_rules! string { ($p:ident, $s:expr) => {{