Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions crates/oxc_ast/src/ast/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,15 @@ pub enum TSModuleDeclarationBody<'a> {
TSModuleBlock(Box<'a, TSModuleBlock<'a>>) = 1,
}

impl TSModuleDeclarationBody<'_> {
pub fn is_empty(&self) -> bool {
match self {
TSModuleDeclarationBody::TSModuleDeclaration(declaration) => declaration.body.is_none(),
TSModuleDeclarationBody::TSModuleBlock(block) => block.body.len() == 0,
}
}
}

// See serializer in serialize.rs
#[ast(visit)]
#[derive(Debug)]
Expand Down
13 changes: 13 additions & 0 deletions crates/oxc_prettier/src/format/call_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ impl<'a, 'b> CallExpressionLike<'a, 'b> {
CallExpressionLike::NewExpression(new) => &new.arguments,
}
}

pub fn type_parameters(
&self,
) -> &Option<oxc_allocator::Box<'a, TSTypeParameterInstantiation<'a>>> {
match self {
CallExpressionLike::CallExpression(call) => &call.type_parameters,
CallExpressionLike::NewExpression(new) => &new.type_parameters,
}
}
}

impl GetSpan for CallExpressionLike<'_, '_> {
Expand All @@ -61,6 +70,10 @@ pub(super) fn print_call_expression<'a>(

parts.push(expression.callee().format(p));

if let Some(type_parameters) = expression.type_parameters() {
parts.push(type_parameters.format(p));
}

if expression.optional() {
parts.push(ss!("?."));
}
Expand Down
25 changes: 23 additions & 2 deletions crates/oxc_prettier/src/format/function_parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,26 @@ pub(super) fn print_function_parameters<'a>(
let mut printed = p.vec();
let len = params.items.len();
let has_rest = params.rest.is_some();

if let AstKind::Function(function) = p.parent_kind() {
if let Some(this_param) = &function.this_param {
parts.push(this_param.format(p));

if params.items.len() > 0 {
printed.push(ss!(","));

if should_hug_the_only_function_parameter {
printed.push(space!());
} else if p.is_next_line_empty(this_param.span) {
printed.extend(hardline!());
printed.extend(hardline!());
} else {
printed.push(line!());
}
}
}
}

for (i, param) in params.items.iter().enumerate() {
if let Some(accessibility) = &param.accessibility {
printed.push(ss!(accessibility.as_str()));
Expand Down Expand Up @@ -119,8 +139,9 @@ pub(super) fn print_function_parameters<'a>(
indented.extend(printed);
let indented = indent!(p, Doc::Array(indented));
parts.push(indented);
let has_rest_parameter = params.rest.is_some();
parts.push(if_break!(p, if has_rest_parameter { "" } else { "," }));
let skip_dangling_comma = params.rest.is_some()
|| matches!(p.parent_kind(), AstKind::Function(func) if func.this_param.is_some());
parts.push(if_break!(p, if skip_dangling_comma { "" } else { "," }));
parts.push(softline!());
if need_parens {
parts.push(ss!(")"));
Expand Down
169 changes: 139 additions & 30 deletions crates/oxc_prettier/src/format/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -797,7 +797,17 @@ impl<'a> Format<'a> for TSArrayType<'a> {

impl<'a> Format<'a> for TSConditionalType<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
let mut parts = p.vec();

parts.push(self.check_type.format(p));
parts.push(ss!(" extends "));
parts.push(self.extends_type.format(p));
parts.push(ss!(" ? "));
parts.push(self.true_type.format(p));
parts.push(ss!(" : "));
parts.push(self.false_type.format(p));

Doc::Array(parts)
}
}

Expand All @@ -822,11 +832,6 @@ impl<'a> Format<'a> for TSFunctionType<'a> {
parts.push(type_parameters.format(p));
}

if let Some(this_param) = &self.this_param {
parts.push(this_param.format(p));
parts.push(ss!(", "));
}

parts.push(self.params.format(p));

parts.push(ss!(" => "));
Expand All @@ -835,6 +840,7 @@ impl<'a> Format<'a> for TSFunctionType<'a> {
Doc::Array(parts)
}
}

impl<'a> Format<'a> for TSThisParameter<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
let mut parts = p.vec();
Expand All @@ -851,7 +857,27 @@ impl<'a> Format<'a> for TSThisParameter<'a> {

impl<'a> Format<'a> for TSImportType<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
let mut parts = p.vec();

if self.is_type_of {
parts.push(ss!("typeof "));
}

parts.push(ss!("import("));
parts.push(self.parameter.format(p));
// ToDo: attributes
parts.push(ss!(")"));

if let Some(qualifier) = &self.qualifier {
parts.push(ss!("."));
parts.push(qualifier.format(p));
}

if let Some(type_parameters) = &self.type_parameters {
parts.push(type_parameters.format(p));
}

Doc::Array(parts)
}
}

Expand Down Expand Up @@ -1040,7 +1066,28 @@ impl<'a> Format<'a> for TSTypeOperator<'a> {

impl<'a> Format<'a> for TSTypePredicate<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
let mut parts = p.vec();

if self.asserts {
parts.push(ss!("asserts "));
}
parts.push(self.parameter_name.format(p));

if let Some(type_annotation) = &self.type_annotation {
parts.push(ss!(" is "));
parts.push(type_annotation.type_annotation.format(p));
}

Doc::Array(parts)
}
}

impl<'a> Format<'a> for TSTypePredicateName<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
match self {
TSTypePredicateName::Identifier(it) => it.format(p),
TSTypePredicateName::This(it) => it.format(p),
}
}
}

Expand Down Expand Up @@ -1251,14 +1298,17 @@ impl<'a> Format<'a> for TSModuleDeclaration<'a> {
parts.push(ss!(" {"));

if let Some(body) = &self.body {
let mut indent_parts = p.vec();
if !body.is_empty() {
let mut indent_parts = p.vec();

indent_parts.extend(hardline!());
indent_parts.push(body.format(p));
parts.push(Doc::Indent(indent_parts));
indent_parts.extend(hardline!());
indent_parts.push(body.format(p));

parts.push(Doc::Indent(indent_parts));
parts.extend(hardline!());
}
}

parts.extend(hardline!());
parts.push(ss!("}"));

Doc::Array(parts)
Expand Down Expand Up @@ -1288,8 +1338,15 @@ impl<'a> Format<'a> for TSModuleDeclarationBody<'a> {
impl<'a> Format<'a> for TSModuleBlock<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
let mut parts = p.vec();
let mut add_line = false;

for body_part in &self.body {
if add_line {
parts.push(line!());
} else {
add_line = true;
}

parts.push(body_part.format(p));
}

Expand Down Expand Up @@ -1616,7 +1673,7 @@ impl<'a> Format<'a> for TSExportAssignment<'a> {

impl<'a> Format<'a> for TSNamespaceExportDeclaration<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
array!(p, ss!(" as namespace "), self.id.format(p), ss!(";"))
}
}

Expand Down Expand Up @@ -1707,10 +1764,10 @@ impl<'a> Format<'a> for Expression<'a> {
Self::JSXElement(el) => el.format(p),
Self::JSXFragment(fragment) => fragment.format(p),
Self::TSAsExpression(expr) => expr.format(p),
Self::TSSatisfiesExpression(expr) => expr.expression.format(p),
Self::TSTypeAssertion(expr) => expr.expression.format(p),
Self::TSNonNullExpression(expr) => expr.expression.format(p),
Self::TSInstantiationExpression(expr) => expr.expression.format(p),
Self::TSSatisfiesExpression(expr) => expr.format(p),
Self::TSTypeAssertion(expr) => expr.format(p),
Self::TSNonNullExpression(expr) => expr.format(p),
Self::TSInstantiationExpression(expr) => expr.format(p),
}
}
}
Expand Down Expand Up @@ -2222,11 +2279,11 @@ impl<'a> Format<'a> for SimpleAssignmentTarget<'a> {
match self {
Self::AssignmentTargetIdentifier(ident) => ident.format(p),
match_member_expression!(Self) => self.to_member_expression().format(p),
Self::TSAsExpression(expr) => expr.expression.format(p),
Self::TSSatisfiesExpression(expr) => expr.expression.format(p),
Self::TSNonNullExpression(expr) => expr.expression.format(p),
Self::TSTypeAssertion(expr) => expr.expression.format(p),
Self::TSInstantiationExpression(expr) => expr.expression.format(p),
Self::TSAsExpression(expr) => expr.format(p),
Self::TSSatisfiesExpression(expr) => expr.format(p),
Self::TSNonNullExpression(expr) => expr.format(p),
Self::TSTypeAssertion(expr) => expr.format(p),
Self::TSInstantiationExpression(expr) => expr.format(p),
}
}
}
Expand Down Expand Up @@ -2465,25 +2522,25 @@ impl<'a> Format<'a> for TSClassImplements<'a> {

impl<'a> Format<'a> for TSTypeAssertion<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
array!(p, ss!("<"), self.type_annotation.format(p), ss!(">"), self.expression.format(p))
}
}

impl<'a> Format<'a> for TSSatisfiesExpression<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
array!(p, self.expression.format(p), ss!(" satisfies "), self.type_annotation.format(p))
}
}

impl<'a> Format<'a> for TSInstantiationExpression<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
array!(p, self.expression.format(p), self.type_parameters.format(p))
}
}

impl<'a> Format<'a> for TSNonNullExpression<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
array!(p, self.expression.format(p), ss!("!"))
}
}

Expand Down Expand Up @@ -2868,7 +2925,31 @@ impl<'a> Format<'a> for RegExpFlags {

impl<'a> Format<'a> for TSIndexSignature<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
let mut parts = p.vec();

if self.readonly {
parts.push(ss!("readonly "));
}

parts.push(ss!("["));
for param in &self.parameters {
parts.push(param.format(p));
}
parts.push(ss!("]: "));
parts.push(self.type_annotation.type_annotation.format(p));

Doc::Array(parts)
}
}

impl<'a> Format<'a> for TSIndexSignatureName<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
array!(
p,
ss!(self.name.as_str()),
ss!(": "),
self.type_annotation.type_annotation.format(p)
)
}
}

Expand All @@ -2893,13 +2974,41 @@ impl<'a> Format<'a> for TSPropertySignature<'a> {

impl<'a> Format<'a> for TSCallSignatureDeclaration<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
let mut parts = p.vec();

if let Some(type_parameters) = &self.type_parameters {
parts.push(type_parameters.format(p));
}

parts.push(self.params.format(p));

if let Some(return_type) = &self.return_type {
parts.push(ss!(": "));
parts.push(return_type.type_annotation.format(p));
}

Doc::Array(parts)
}
}

impl<'a> Format<'a> for TSConstructSignatureDeclaration<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
let mut parts = p.vec();

parts.push(ss!("new "));

if let Some(type_parameters) = &self.type_parameters {
parts.push(type_parameters.format(p));
}

parts.push(self.params.format(p));

if let Some(return_type) = &self.return_type {
parts.push(ss!(": "));
parts.push(return_type.type_annotation.format(p));
}

Doc::Array(parts)
}
}

Expand Down
7 changes: 4 additions & 3 deletions crates/oxc_prettier/src/format/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ fn print_semicolon_after_export_declaration<'a>(
};

match declaration {
Declaration::TSInterfaceDeclaration(_) | Declaration::VariableDeclaration(_) => {
None
}
Declaration::TSInterfaceDeclaration(_)
| Declaration::VariableDeclaration(_)
| Declaration::ClassDeclaration(_)
| Declaration::TSModuleDeclaration(_) => None,
_ => Some(ss!(";")),
}
}
Expand Down
Loading