Skip to content

Commit

Permalink
refactor(prettier): clean up object::print_object_properties (oxc-pro…
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen authored Nov 29, 2023
1 parent 72dd72b commit c5b138f
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 48 deletions.
18 changes: 18 additions & 0 deletions crates/oxc_ast/src/ast/js.rs
Original file line number Diff line number Diff line change
Expand Up @@ -885,6 +885,16 @@ pub struct ObjectAssignmentTarget<'a> {
pub rest: Option<AssignmentTarget<'a>>,
}

impl<'a> ObjectAssignmentTarget<'a> {
pub fn is_empty(&self) -> bool {
self.properties.is_empty() && self.rest.is_none()
}

pub fn len(&self) -> usize {
self.properties.len() + usize::from(self.rest.is_some())
}
}

#[derive(Debug, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize), serde(untagged))]
pub enum AssignmentTargetMaybeDefault<'a> {
Expand Down Expand Up @@ -1441,6 +1451,10 @@ impl<'a> ObjectPattern<'a> {
pub fn is_empty(&self) -> bool {
self.properties.is_empty() && self.rest.is_none()
}

pub fn len(&self) -> usize {
self.properties.len() + usize::from(self.rest.is_some())
}
}

#[derive(Debug, Hash)]
Expand All @@ -1467,6 +1481,10 @@ impl<'a> ArrayPattern<'a> {
pub fn is_empty(&self) -> bool {
self.elements.is_empty() && self.rest.is_none()
}

pub fn len(&self) -> usize {
self.elements.len() + usize::from(self.rest.is_some())
}
}

#[derive(Debug, Hash)]
Expand Down
1 change: 1 addition & 0 deletions crates/oxc_prettier/src/format/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ fn print_elements<'a>(p: &mut Prettier<'a>, array: &Array<'a, '_>) -> Doc<'a> {
if let Some(rest) = &array_pat.rest {
parts.push(ss!(","));
parts.push(line!());
parts.push(ss!("..."));
parts.push(rest.format(p));
}
}
Expand Down
4 changes: 3 additions & 1 deletion crates/oxc_prettier/src/format/function_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ pub(super) fn print_function_parameters<'a>(
}

if let Some(rest) = &params.rest {
parts.push(ss!(", "));
if !params.items.is_empty() {
parts.push(ss!(", "));
}
parts.push(rest.format(p));
}

Expand Down
14 changes: 3 additions & 11 deletions crates/oxc_prettier/src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1455,11 +1455,7 @@ impl<'a> Format<'a> for ArrayExpression<'a> {
impl<'a> Format<'a> for ObjectExpression<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
wrap!(p, self, ObjectExpression, {
object::print_object_properties(
p,
&ObjectLike::ObjectExpression(self),
&self.properties,
)
object::print_object_properties(p, ObjectLike::Expression(self))
})
}
}
Expand Down Expand Up @@ -1698,11 +1694,7 @@ impl<'a> Format<'a> for AssignmentTargetMaybeDefault<'a> {

impl<'a> Format<'a> for ObjectAssignmentTarget<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
object::print_object_properties(
p,
&ObjectLike::ObjectAssignmentTarget(self),
&self.properties,
)
object::print_object_properties(p, ObjectLike::AssignmentTarget(self))
}
}

Expand Down Expand Up @@ -2074,7 +2066,7 @@ impl<'a> Format<'a> for BindingPattern<'a> {

impl<'a> Format<'a> for ObjectPattern<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
object::print_object_properties(p, &ObjectLike::ObjectPattern(self), &self.properties)
object::print_object_properties(p, ObjectLike::Pattern(self))
}
}

Expand Down
109 changes: 73 additions & 36 deletions crates/oxc_prettier/src/format/object.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use oxc_allocator::Vec;
use oxc_ast::ast::{ObjectAssignmentTarget, ObjectExpression, ObjectPattern};
use oxc_span::{GetSpan, Span};
use oxc_span::Span;

use crate::{
doc::{Doc, DocBuilder, Group},
Expand All @@ -9,62 +8,100 @@ use crate::{

use super::{misc, Format};

#[allow(clippy::enum_variant_names)]
#[derive(Debug, Clone, Copy)]
pub enum ObjectLike<'a, 'b> {
ObjectExpression(&'b ObjectExpression<'a>),
ObjectAssignmentTarget(&'b ObjectAssignmentTarget<'a>),
ObjectPattern(&'b ObjectPattern<'a>),
Expression(&'b ObjectExpression<'a>),
AssignmentTarget(&'b ObjectAssignmentTarget<'a>),
Pattern(&'b ObjectPattern<'a>),
}

impl ObjectLike<'_, '_> {
impl<'a, 'b> ObjectLike<'a, 'b> {
fn len(&self) -> usize {
match self {
ObjectLike::Expression(object) => object.properties.len(),
ObjectLike::AssignmentTarget(object) => object.properties.len(),
ObjectLike::Pattern(object) => object.properties.len(),
}
}

fn is_empty(&self) -> bool {
match self {
ObjectLike::Expression(object) => object.properties.is_empty(),
ObjectLike::AssignmentTarget(object) => object.is_empty(),
ObjectLike::Pattern(object) => object.is_empty(),
}
}

fn is_object_pattern(&self) -> bool {
matches!(self, ObjectLike::ObjectPattern(_))
matches!(self, ObjectLike::Pattern(_))
}

fn span(&self) -> Span {
match self {
ObjectLike::Expression(object) => object.span,
ObjectLike::AssignmentTarget(object) => object.span,
ObjectLike::Pattern(object) => object.span,
}
}
}

impl ObjectLike<'_, '_> {
pub fn span(&self) -> Span {
fn iter(&'b self, p: &'b mut Prettier<'a>) -> Box<dyn Iterator<Item = Doc<'a>> + 'b> {
match self {
ObjectLike::ObjectExpression(object) => object.span,
ObjectLike::ObjectAssignmentTarget(object) => object.span,
ObjectLike::ObjectPattern(object) => object.span,
ObjectLike::Expression(object) => {
Box::new(object.properties.iter().map(|prop| prop.format(p)))
}
ObjectLike::AssignmentTarget(object) => {
Box::new(object.properties.iter().map(|prop| prop.format(p)))
}
ObjectLike::Pattern(object) => {
Box::new(object.properties.iter().map(|prop| prop.format(p)))
}
}
}
}

pub(super) fn print_object_properties<'a, F: Format<'a> + GetSpan>(
pub(super) fn print_object_properties<'a>(
p: &mut Prettier<'a>,
object: &ObjectLike<'a, '_>,
properties: &Vec<'a, F>,
object: ObjectLike<'a, '_>,
) -> Doc<'a> {
let left_brace = ss!("{");
let right_brace = ss!("}");

let content = if properties.is_empty() {
let content = if object.is_empty() {
group![p, left_brace, softline!(), right_brace]
} else {
let mut parts = p.vec();
parts.push(ss!("{"));

let mut indent_parts = p.vec();
indent_parts.push(if p.options.bracket_spacing { line!() } else { softline!() });
for (i, prop) in properties.iter().enumerate() {
indent_parts.push(prop.format(p));
if i < properties.len() - 1 {
indent_parts.push(Doc::Str(","));
indent_parts.push(line!());
parts.push(Doc::Indent({
let len = object.len();
let mut indent_parts = p.vec();
indent_parts.push(if p.options.bracket_spacing { line!() } else { softline!() });
for (i, doc) in object.iter(p).enumerate() {
indent_parts.push(doc);
if i < len - 1 {
indent_parts.push(ss!(","));
indent_parts.push(line!());
}
}
}

parts.push(Doc::Indent(indent_parts));
match object {
ObjectLike::Expression(object) => {}
ObjectLike::AssignmentTarget(object) => {
if let Some(rest) = &object.rest {
indent_parts.push(ss!("..."));
indent_parts.push(rest.format(p));
}
}
ObjectLike::Pattern(object) => {
if let Some(rest) = &object.rest {
indent_parts.push(ss!(","));
indent_parts.push(line!());
indent_parts.push(rest.format(p));
}
}
}
indent_parts
}));
parts.push(if_break!(p, ",", "", None));

if p.options.bracket_spacing {
parts.push(line!());
} else {
parts.push(softline!());
}

parts.push(if p.options.bracket_spacing { line!() } else { softline!() });
parts.push(ss!("}"));

if object.is_object_pattern() {
Expand Down

0 comments on commit c5b138f

Please sign in to comment.