feat(prettier) check original state for new lines when formatting properties (#1439)

This commit is contained in:
Cameron 2023-11-20 01:36:26 +00:00 committed by GitHub
parent 008eb0d178
commit a53c5e9bab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 9 deletions

View file

@ -1,7 +1,7 @@
use std::{cell::Cell, fmt, hash::Hash};
use oxc_allocator::{Box, Vec};
use oxc_span::{Atom, SourceType, Span};
use oxc_span::{Atom, GetSpan, SourceType, Span};
use oxc_syntax::{
operator::{
AssignmentOperator, BinaryOperator, LogicalOperator, UnaryOperator, UpdateOperator,
@ -919,6 +919,15 @@ pub enum AssignmentTargetProperty<'a> {
AssignmentTargetPropertyProperty(Box<'a, AssignmentTargetPropertyProperty<'a>>),
}
impl<'a> GetSpan for AssignmentTargetProperty<'a> {
fn span(&self) -> Span {
match self {
Self::AssignmentTargetPropertyIdentifier(identifier) => identifier.span,
Self::AssignmentTargetPropertyProperty(literal) => literal.span,
}
}
}
/// Assignment Property - Identifier Reference
#[derive(Debug, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
@ -1447,6 +1456,12 @@ pub struct BindingProperty<'a> {
pub computed: bool,
}
impl<'a> GetSpan for BindingProperty<'a> {
fn span(&self) -> Span {
self.span
}
}
#[derive(Debug, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))]
pub struct ArrayPattern<'a> {

View file

@ -18,3 +18,7 @@ pub(super) fn adjust_clause<'a>(
indent![p, Doc::Line, clause]
}
pub(super) fn has_new_line_in_range(text: &str, start: u32, end: u32) -> bool {
text[(start as usize)..(end as usize)].contains('\n')
}

View file

@ -36,6 +36,7 @@ use crate::{
use self::{
array::Array,
binaryish::{BinaryishLeft, BinaryishOperator},
object::ObjectLike,
template_literal::TemplateLiteralPrinter,
};
@ -1361,7 +1362,7 @@ impl<'a> Format<'a> for ArrayExpression<'a> {
impl<'a> Format<'a> for ObjectExpression<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
object::print_object_properties(p, &self.properties)
object::print_object_properties(p, &ObjectLike::ObjectExpression(self), &self.properties)
}
}
@ -1582,7 +1583,11 @@ 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, &self.properties)
object::print_object_properties(
p,
&ObjectLike::ObjectAssignmentTarget(self),
&self.properties,
)
}
}
@ -1938,7 +1943,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, &self.properties)
object::print_object_properties(p, &ObjectLike::ObjectPattern(self), &self.properties)
}
}

View file

@ -1,14 +1,34 @@
use oxc_allocator::Vec;
use oxc_ast::ast::{ObjectAssignmentTarget, ObjectExpression, ObjectPattern};
use oxc_span::{GetSpan, Span};
use crate::{
doc::{Doc, Group},
group, if_break, line, softline, ss, Prettier,
};
use super::Format;
use super::{misc, Format};
pub(super) fn print_object_properties<'a, F: Format<'a>>(
#[allow(clippy::enum_variant_names)]
pub enum ObjectLike<'a, 'b> {
ObjectExpression(&'b ObjectExpression<'a>),
ObjectAssignmentTarget(&'b ObjectAssignmentTarget<'a>),
ObjectPattern(&'b ObjectPattern<'a>),
}
impl ObjectLike<'_, '_> {
pub fn span(&self) -> Span {
match self {
ObjectLike::ObjectExpression(object) => object.span,
ObjectLike::ObjectAssignmentTarget(object) => object.span,
ObjectLike::ObjectPattern(object) => object.span,
}
}
}
pub(super) fn print_object_properties<'a, F: Format<'a> + GetSpan>(
p: &mut Prettier<'a>,
object: &ObjectLike<'a, '_>,
properties: &Vec<'a, F>,
) -> Doc<'a> {
let left_brace = ss!("{");
@ -29,7 +49,18 @@ pub(super) fn print_object_properties<'a, F: Format<'a>>(
indent_parts.push(Doc::Line);
}
}
parts.push(group!(p, Doc::Indent(indent_parts)));
let should_break = misc::has_new_line_in_range(
p.source_text,
object.span().start,
// SAFETY: we checked above that `properties` is not empty
properties[0].span().start,
);
let mut group = p.vec();
group.push(Doc::Indent(indent_parts));
parts.push(Doc::Group(Group::new(group, should_break)));
parts.push(if_break!(p, ","));
if p.options.bracket_spacing {

View file

@ -1,4 +1,4 @@
Compatibility: 109/601 (18.14%)
Compatibility: 110/601 (18.30%)
# Failed
@ -89,7 +89,6 @@ Compatibility: 109/601 (18.14%)
### async
* async/async-iteration.js
* async/async-shorthand-method.js
* async/await-parse.js
* async/conditional-expression.js
* async/exponentiation.js