feat(prettier): print statements with newlines (#1367)

This commit is contained in:
Boshen 2023-11-17 15:13:51 +08:00 committed by GitHub
parent 9b94226531
commit bfdb6eac86
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 56 additions and 23 deletions

View file

@ -76,6 +76,12 @@ impl<'a> GetSpan for Expression<'a> {
}
}
impl GetSpan for Directive {
fn span(&self) -> Span {
self.span
}
}
impl<'a> GetSpan for BindingPatternKind<'a> {
fn span(&self) -> Span {
match self {

View file

@ -17,7 +17,7 @@ pub(super) fn print_block<'a>(
parts.push(ss!("static "));
}
parts.push(ss!("{"));
if let Some(doc) = print_block_body(p, stmts, directives, true) {
if let Some(doc) = print_block_body(p, stmts, directives, true, false) {
parts.push(indent![p, hardline!(), doc]);
parts.push(hardline!());
}
@ -30,6 +30,7 @@ pub(super) fn print_block_body<'a>(
stmts: &Vec<'a, Statement<'a>>,
directives: Option<&Vec<'a, Directive>>,
remove_last_statement_hardline: bool,
is_program: bool,
) -> Option<Doc<'a>> {
let has_directives = directives.is_some_and(|directives| !directives.is_empty());
let has_body = stmts.iter().any(|stmt| !matches!(stmt, Statement::EmptyStatement(_)));
@ -50,5 +51,9 @@ pub(super) fn print_block_body<'a>(
parts.extend(statement::print_statement_sequence(p, stmts, remove_last_statement_hardline));
}
if is_program {
parts.push(hardline!());
}
Some(Doc::Array(parts))
}

View file

@ -1,7 +1,7 @@
#[allow(clippy::wildcard_imports)]
use oxc_ast::ast::*;
use crate::{doc::Doc, group, hardline, if_break, indent, softline, ss, Format, Prettier};
use crate::{doc::Doc, group, if_break, indent, softline, ss, Format, Prettier};
pub(super) fn print_function<'a>(p: &mut Prettier<'a>, func: &Function<'a>) -> Doc<'a> {
let mut parts = p.vec();
@ -35,8 +35,6 @@ pub(super) fn print_function<'a>(p: &mut Prettier<'a>, func: &Function<'a>) -> D
parts.push(p.str(";"));
}
parts.push(hardline!());
Doc::Array(parts)
}
@ -61,7 +59,6 @@ pub(super) fn print_return_or_throw_argument<'a>(
}
parts.push(p.str(";"));
parts.push(hardline!());
Doc::Array(parts)
}

View file

@ -26,9 +26,7 @@ mod ternary;
use crate::{
array,
doc::{Doc, Separator},
format, group, hardline, indent, softline, ss, string,
util::is_next_line_empty,
Prettier,
format, group, hardline, indent, softline, ss, string, Prettier,
};
use self::{
@ -52,7 +50,8 @@ where
impl<'a> Format<'a> for Program<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
block::print_block_body(p, &self.body, Some(&self.directives), false).unwrap_or(ss!(""))
block::print_block_body(p, &self.body, Some(&self.directives), false, true)
.unwrap_or(ss!(""))
}
}
@ -96,7 +95,6 @@ impl<'a> Format<'a> for ExpressionStatement<'a> {
if p.options.semi {
parts.push(ss!(";"));
}
parts.push(Doc::Hardline);
Doc::Array(parts)
}
}
@ -388,12 +386,6 @@ impl<'a> Format<'a> for VariableDeclaration<'a> {
parts.push(ss!(";"));
}
parts.push(Doc::Hardline);
if is_next_line_empty(p.source_text, self.span) {
parts.push(Doc::Hardline);
}
Doc::Group(parts)
}
}
@ -504,7 +496,6 @@ impl<'a> Format<'a> for ImportDeclaration<'a> {
}
parts.push(ss!(" from "));
parts.push(self.source.format(p));
parts.push(hardline!());
Doc::Array(parts)
}
}

View file

@ -25,5 +25,28 @@ pub(super) fn print_export_declaration<'a>(
ModuleDeclaration::TSNamespaceExportDeclaration(decl) => decl.format(p),
});
if let Some(doc) = print_semicolon_after_export_declaration(p, decl) {
parts.push(doc);
}
Doc::Array(parts)
}
fn print_semicolon_after_export_declaration<'a>(
p: &Prettier<'a>,
decl: &ModuleDeclaration<'a>,
) -> Option<Doc<'a>> {
if !p.options.semi {
return None;
}
let ModuleDeclaration::ExportDefaultDeclaration(decl) = decl else { return None };
match decl.declaration {
ExportDefaultDeclarationKind::Expression(_) => Some(ss!(";")),
ExportDefaultDeclarationKind::FunctionDeclaration(_)
| ExportDefaultDeclarationKind::ClassDeclaration(_)
| ExportDefaultDeclarationKind::TSInterfaceDeclaration(_)
| ExportDefaultDeclarationKind::TSEnumDeclaration(_) => None,
}
}

View file

@ -1,19 +1,22 @@
use oxc_allocator::Vec;
use crate::{doc::Doc, Prettier};
use crate::{doc::Doc, hardline, Prettier};
use oxc_span::GetSpan;
use super::Format;
use crate::util::is_next_line_empty;
pub(super) fn print_statement_sequence<'a, F: Format<'a>>(
pub(super) fn print_statement_sequence<'a, F: Format<'a> + GetSpan>(
p: &mut Prettier<'a>,
stmts: &Vec<'a, F>,
remove_last_statement_hardline: bool,
) -> Vec<'a, Doc<'a>> {
let mut parts = p.vec();
for (index, stmt) in stmts.iter().enumerate() {
for (i, stmt) in stmts.iter().enumerate() {
let mut docs = stmt.format(p);
if remove_last_statement_hardline && index == stmts.len() - 1 {
if remove_last_statement_hardline && i == stmts.len() - 1 {
match docs {
Doc::Array(ref mut docs) | Doc::Group(ref mut docs) => {
if matches!(docs.last(), Some(Doc::Hardline)) {
@ -25,6 +28,15 @@ pub(super) fn print_statement_sequence<'a, F: Format<'a>>(
}
parts.push(docs);
if i < stmts.len() - 1 {
parts.push(hardline!());
if is_next_line_empty(p.source_text, stmt.span()) {
parts.push(hardline!());
}
}
}
parts
}

View file

@ -1,4 +1,4 @@
Compatibility: 11/173 (6.36%)
Compatibility: 12/173 (6.94%)
# Failed
@ -85,7 +85,6 @@ Compatibility: 11/173 (6.36%)
* import-meta
* import-reflection
* in
* invalid-code
* label
* last-argument-expansion
* line-suffix-boundary