diff --git a/crates/oxc_ast/src/ast/ts.rs b/crates/oxc_ast/src/ast/ts.rs index c26dc3dfe3b62..4b7d182e16edd 100644 --- a/crates/oxc_ast/src/ast/ts.rs +++ b/crates/oxc_ast/src/ast/ts.rs @@ -1081,6 +1081,14 @@ impl TSModuleDeclarationKind { pub fn is_global(self) -> bool { matches!(self, TSModuleDeclarationKind::Global) } + + pub fn to_str(self) -> &'static str { + match self { + TSModuleDeclarationKind::Global => "global", + TSModuleDeclarationKind::Namespace => "namespace", + TSModuleDeclarationKind::Module => "module", + } + } } #[ast(visit)] diff --git a/crates/oxc_prettier/src/format/mod.rs b/crates/oxc_prettier/src/format/mod.rs index 39aabab2a7448..1f79de72f621b 100644 --- a/crates/oxc_prettier/src/format/mod.rs +++ b/crates/oxc_prettier/src/format/mod.rs @@ -893,7 +893,27 @@ impl<'a> Format<'a> for TSTupleType<'a> { impl<'a> Format<'a> for TSTypeLiteral<'a> { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { - line!() + let mut parts = p.vec(); + + parts.push(ss!("{")); + if self.members.len() > 0 { + let mut indent_parts = p.vec(); + + for member in &self.members { + indent_parts.extend(hardline!()); + indent_parts.push(member.format(p)); + + if let Some(semi) = p.semi() { + indent_parts.push(semi); + } + } + + parts.push(Doc::Indent(indent_parts)); + parts.extend(hardline!()); + } + parts.push(ss!("}")); + + Doc::Array(parts) } } @@ -981,6 +1001,10 @@ impl<'a> Format<'a> for TSInterfaceDeclaration<'a> { for sig in &self.body.body { indent_parts.extend(hardline!()); indent_parts.push(format!(p, sig)); + + if let Some(semi) = p.semi() { + indent_parts.push(semi); + } } parts.push(Doc::Indent(indent_parts)); parts.extend(hardline!()); @@ -1046,7 +1070,61 @@ impl<'a> Format<'a> for TSEnumMemberName<'a> { impl<'a> Format<'a> for TSModuleDeclaration<'a> { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { - line!() + let mut parts = p.vec(); + + if self.declare { + parts.push(ss!("declare ")); + } + + parts.push(ss!(self.kind.to_str())); + parts.push(space!()); + parts.push(self.id.format(p)); + parts.push(ss!(" {")); + + if let Some(body) = &self.body { + let mut indent_parts = p.vec(); + + indent_parts.extend(hardline!()); + indent_parts.push(body.format(p)); + parts.push(Doc::Indent(indent_parts)); + } + + parts.extend(hardline!()); + parts.push(ss!("}")); + + Doc::Array(parts) + } +} + +impl<'a> Format<'a> for TSModuleDeclarationName<'a> { + fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { + match self { + TSModuleDeclarationName::Identifier(identifier) => identifier.format(p), + TSModuleDeclarationName::StringLiteral(string_literal) => string_literal.format(p), + } + } +} + +impl<'a> Format<'a> for TSModuleDeclarationBody<'a> { + fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { + match self { + TSModuleDeclarationBody::TSModuleBlock(module_block) => module_block.format(p), + TSModuleDeclarationBody::TSModuleDeclaration(module_declaration) => { + module_declaration.format(p) + } + } + } +} + +impl<'a> Format<'a> for TSModuleBlock<'a> { + fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { + let mut parts = p.vec(); + + for body_part in &self.body { + parts.push(body_part.format(p)); + } + + Doc::Array(parts) } } @@ -1110,7 +1188,21 @@ impl<'a> Format<'a> for TSTypeParameterDeclaration<'a> { impl<'a> Format<'a> for TSTypeParameterInstantiation<'a> { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { - line!() + let mut parts = p.vec(); + + if self.params.len() == 0 { + return Doc::Array(parts); + } + + parts.push(ss!("<")); + + for param in &self.params { + parts.push(param.format(p)); + } + + parts.push(ss!(">")); + + Doc::Array(parts) } } @@ -2402,7 +2494,34 @@ impl<'a> Format<'a> for TSConstructSignatureDeclaration<'a> { impl<'a> Format<'a> for TSMethodSignature<'a> { fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> { - line!() + let mut parts = p.vec(); + + if self.computed { + parts.push(ss!("[")); + } + + parts.push(self.key.format(p)); + + if self.computed { + parts.push(ss!("]")); + } + + if self.optional { + parts.push(ss!("?")); + } + + 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) } } diff --git a/crates/oxc_prettier/src/format/module.rs b/crates/oxc_prettier/src/format/module.rs index aae5362c12a5a..01fd52bb8ee38 100644 --- a/crates/oxc_prettier/src/format/module.rs +++ b/crates/oxc_prettier/src/format/module.rs @@ -58,13 +58,23 @@ fn print_semicolon_after_export_declaration<'a>( match decl { ModuleDeclaration::ExportDefaultDeclaration(decl) => match decl.declaration { match_expression!(ExportDefaultDeclarationKind) => Some(ss!(";")), - ExportDefaultDeclarationKind::FunctionDeclaration(_) - | ExportDefaultDeclarationKind::ClassDeclaration(_) - | ExportDefaultDeclarationKind::TSInterfaceDeclaration(_) => None, + _ => None, }, - ModuleDeclaration::ExportAllDeclaration(_) - | ModuleDeclaration::ExportNamedDeclaration(_) - | ModuleDeclaration::TSExportAssignment(_) => Some(ss!(";")), + ModuleDeclaration::ExportNamedDeclaration(decl) => { + let Some(declaration) = &decl.declaration else { + return Some(ss!(";")); + }; + + match declaration { + Declaration::TSInterfaceDeclaration(_) | Declaration::VariableDeclaration(_) => { + None + } + _ => Some(ss!(";")), + } + } + ModuleDeclaration::ExportAllDeclaration(_) | ModuleDeclaration::TSExportAssignment(_) => { + Some(ss!(";")) + } _ => None, } } diff --git a/tasks/prettier_conformance/prettier.js.snap.md b/tasks/prettier_conformance/prettier.js.snap.md index 3f4f16090bc4f..4a639444a824f 100644 --- a/tasks/prettier_conformance/prettier.js.snap.md +++ b/tasks/prettier_conformance/prettier.js.snap.md @@ -1,4 +1,4 @@ -js compatibility: 266/593 (44.86%) +js compatibility: 267/593 (45.03%) # Failed @@ -292,7 +292,6 @@ js compatibility: 266/593 (44.86%) * last-argument-expansion/issue-7518.js * last-argument-expansion/jsx.js * last-argument-expansion/number-only-array.js -* last-argument-expansion/object.js * last-argument-expansion/overflow.js ### line-suffix-boundary diff --git a/tasks/prettier_conformance/prettier.ts.snap.md b/tasks/prettier_conformance/prettier.ts.snap.md index 8c025818f03e3..c95b4ceccfc69 100644 --- a/tasks/prettier_conformance/prettier.ts.snap.md +++ b/tasks/prettier_conformance/prettier.ts.snap.md @@ -1,4 +1,4 @@ -ts compatibility: 68/526 (12.93%) +ts compatibility: 89/526 (16.92%) # Failed @@ -32,7 +32,6 @@ ts compatibility: 68/526 (12.93%) * as/array-pattern.ts * as/as-const-embedded.ts * as/as.ts -* as/assignment.ts * as/assignment2.ts * as/export_default_as.ts * as/expression-statement.ts @@ -49,9 +48,7 @@ ts compatibility: 68/526 (12.93%) * assignment/issue-10848.tsx * assignment/issue-10850.ts * assignment/issue-12413.ts -* assignment/issue-2322.ts * assignment/issue-2482.ts -* assignment/issue-2485.ts * assignment/issue-3122.ts * assignment/issue-5370.ts * assignment/issue-6783.ts @@ -172,7 +169,6 @@ ts compatibility: 68/526 (12.93%) * conformance/classes/classDeclarations/classAbstractKeyword/classAbstractWithInterface.ts ### conformance/classes/classDeclarations/classHeritageSpecification -* conformance/classes/classDeclarations/classHeritageSpecification/classAppearsToHaveMembersOfObject.ts * conformance/classes/classDeclarations/classHeritageSpecification/classExtendingClass.ts * conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts * conformance/classes/classDeclarations/classHeritageSpecification/classIsSubtypeOfBaseType.ts @@ -214,9 +210,7 @@ ts compatibility: 68/526 (12.93%) ### conformance/internalModules/importDeclarations * conformance/internalModules/importDeclarations/circularImportAlias.ts * conformance/internalModules/importDeclarations/exportImportAlias.ts -* conformance/internalModules/importDeclarations/exportInterface.ts * conformance/internalModules/importDeclarations/importAliasIdentifiers.ts -* conformance/internalModules/importDeclarations/invalidImportAliasIdentifiers.ts * conformance/internalModules/importDeclarations/shadowedInternalModule.ts ### conformance/parser/ecmascript5/Statements @@ -244,9 +238,6 @@ ts compatibility: 68/526 (12.93%) * conformance/types/functions/functionOverloadErrorsSyntax.ts * conformance/types/functions/functionTypeTypeParameters.ts -### conformance/types/interfaceDeclaration -* conformance/types/interfaceDeclaration/interfaceDeclaration.ts - ### conformance/types/intersectionType * conformance/types/intersectionType/intersectionType.ts @@ -256,9 +247,6 @@ ts compatibility: 68/526 (12.93%) ### conformance/types/mappedType * conformance/types/mappedType/mappedType.ts -### conformance/types/methodSignature -* conformance/types/methodSignature/methodSignature.ts - ### conformance/types/moduleDeclaration * conformance/types/moduleDeclaration/kind-detection.ts * conformance/types/moduleDeclaration/moduleDeclaration.ts @@ -336,7 +324,6 @@ ts compatibility: 68/526 (12.93%) * custom/call/callSignature.ts ### custom/computedProperties -* custom/computedProperties/string.ts * custom/computedProperties/symbol.ts ### custom/declare @@ -369,8 +356,6 @@ ts compatibility: 68/526 (12.93%) * declare/declare_class_fields.ts * declare/declare_function.ts * declare/declare_interface.ts -* declare/declare_module.ts -* declare/declare_namespace.ts * declare/declare_var.ts * declare/object-type-in-declare-function.ts @@ -423,11 +408,9 @@ ts compatibility: 68/526 (12.93%) ### export * export/comment.ts -* export/default.ts * export/export-class.ts * export/export-type-star-from-2.ts * export/export-type-star-from.ts -* export/export.ts ### export-default * export-default/function_as.ts @@ -477,12 +460,10 @@ ts compatibility: 68/526 (12.93%) ### interface * interface/comments-generic.ts -* interface/comments.ts * interface/generic.ts * interface/ignore.ts * interface/long-extends.ts * interface/pattern-parameters.ts -* interface/separator.ts ### interface/long-type-parameters * interface/long-type-parameters/long-type-parameters.ts @@ -517,7 +498,6 @@ ts compatibility: 68/526 (12.93%) ### keywords * keywords/keywords-2.ts -* keywords/keywords.ts * keywords/module.ts ### last-argument-expansion @@ -555,9 +535,6 @@ ts compatibility: 68/526 (12.93%) ### multiparser-css * multiparser-css/issue-6259.ts -### namespace -* namespace/invalid-await.ts - ### never * never/type-argument.src.ts @@ -608,9 +585,6 @@ ts compatibility: 68/526 (12.93%) ### private-fields-in-in * private-fields-in-in/basic.ts -### quote-props -* quote-props/types.ts - ### range * range/export-assignment.ts * range/issue-4926.ts @@ -724,11 +698,8 @@ ts compatibility: 68/526 (12.93%) * typeparams/tagged-template-expression.ts ### typeparams/consistent -* typeparams/consistent/flow-only.ts * typeparams/consistent/issue-9501.ts -* typeparams/consistent/simple-types.ts * typeparams/consistent/template-literal-types.ts -* typeparams/consistent/typescript-only.ts ### typeparams/empty-parameters-with-arrow-function * typeparams/empty-parameters-with-arrow-function/issue-13817.ts