feat(prettier): improve ts compatibility (#5900)

This commit is contained in:
Alexander S. 2024-09-20 04:40:31 +02:00 committed by GitHub
parent 9192e5ad03
commit 65c337a071
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 189 additions and 103 deletions

View file

@ -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)]

View file

@ -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<'_, '_> {
@ -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!("?."));
}

View file

@ -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()));
@ -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!(")"));

View file

@ -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)
}
}
@ -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!(" => "));
@ -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();
@ -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)
}
}
@ -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),
}
}
}
@ -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)
@ -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));
}
@ -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!(";"))
}
}
@ -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),
}
}
}
@ -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),
}
}
}
@ -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!("!"))
}
}
@ -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)
)
}
}
@ -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)
}
}

View file

@ -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!(";")),
}
}

View file

@ -1,4 +1,4 @@
ts compatibility: 173/526 (32.89%)
ts compatibility: 214/526 (40.68%)
# Failed
@ -28,7 +28,6 @@ ts compatibility: 173/526 (32.89%)
* arrows/type_params.ts
### as
* as/array-pattern.ts
* as/as-const-embedded.ts
* as/as.ts
* as/assignment2.ts
@ -40,22 +39,15 @@ ts compatibility: 173/526 (32.89%)
### assert
* assert/comment.ts
* assert/index.ts
### assignment
* assignment/issue-10846.ts
* assignment/issue-10848.tsx
* assignment/issue-10850.ts
* assignment/issue-12413.ts
* assignment/issue-2482.ts
* assignment/issue-3122.ts
* assignment/issue-6783.ts
* assignment/lone-arg.ts
* assignment/parenthesized.ts
### break-calls
* break-calls/type_args.ts
### call-signature
* call-signature/call-signature.ts
@ -69,14 +61,12 @@ ts compatibility: 173/526 (32.89%)
### chain-expression
* chain-expression/test.ts
* chain-expression/test2.ts
### class
* class/constructor.ts
* class/empty-method-body.ts
* class/extends_implements.ts
* class/generics.ts
* class/methods.ts
* class/parameter-properties.ts
* class/quoted-property.ts
@ -116,17 +106,14 @@ ts compatibility: 173/526 (32.89%)
### compiler
* compiler/castOfAwait.ts
* compiler/castParentheses.ts
* compiler/castTest.ts
* compiler/checkInfiniteExpansionTermination.ts
* compiler/commentInNamespaceDeclarationWithIdentifierPathName.ts
* compiler/contextualSignatureInstantiation2.ts
* compiler/declareDottedModuleName.ts
* compiler/es5ExportDefaultClassDeclaration4.ts
* compiler/functionOverloadsOnGenericArity1.ts
* compiler/globalIsContextualKeyword.ts
* compiler/indexSignatureWithInitializer.ts
* compiler/mappedTypeWithCombinedTypeMappers.ts
* compiler/modifiersOnInterfaceIndexSignature1.ts
* compiler/privacyGloImport.ts
### conditional-types
@ -143,8 +130,6 @@ ts compatibility: 173/526 (32.89%)
* conformance/classes/mixinClassesAnonymous.ts
### conformance/classes/classDeclarations/classAbstractKeyword
* conformance/classes/classDeclarations/classAbstractKeyword/classAbstractImportInstantiation.ts
* conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInAModule.ts
* conformance/classes/classDeclarations/classAbstractKeyword/classAbstractWithInterface.ts
### conformance/classes/constructorDeclarations/constructorParameters
@ -154,9 +139,6 @@ ts compatibility: 173/526 (32.89%)
### conformance/comments
* conformance/comments/comments.ts
### conformance/declarationEmit/typePredicates
* conformance/declarationEmit/typePredicates/declarationEmitThisPredicatesWithPrivateName01.ts
### conformance/es6/Symbols
* conformance/es6/Symbols/symbolProperty15.ts
@ -183,13 +165,6 @@ ts compatibility: 173/526 (32.89%)
* conformance/parser/ecmascript5/Statements/parserES5ForOfStatement21.ts
* conformance/parser/ecmascript5/Statements/parserForInStatement2.ts
### conformance/types/ambient
* conformance/types/ambient/ambientDeclarations.ts
### conformance/types/any
* conformance/types/any/anyAsConstructor.ts
* conformance/types/any/anyAsGenericFunctionCall.ts
### conformance/types/firstTypeNode
* conformance/types/firstTypeNode/firstTypeNode.ts
@ -205,13 +180,6 @@ ts compatibility: 173/526 (32.89%)
### conformance/types/moduleDeclaration
* conformance/types/moduleDeclaration/kind-detection.ts
* conformance/types/moduleDeclaration/moduleDeclaration.ts
### conformance/types/namespaceExportDeclaration
* conformance/types/namespaceExportDeclaration/exportAsNamespace.d.ts
### conformance/types/nonNullExpression
* conformance/types/nonNullExpression/nonNullExpression.ts
### conformance/types/parameterProperty
* conformance/types/parameterProperty/parameterProperty.ts
@ -255,12 +223,6 @@ ts compatibility: 173/526 (32.89%)
* cursor/property-signature.ts
* cursor/rest.ts
### custom/abstract
* custom/abstract/abstractNewlineHandling.ts
### custom/call
* custom/call/callSignature.ts
### custom/computedProperties
* custom/computedProperties/symbol.ts
@ -271,7 +233,6 @@ ts compatibility: 173/526 (32.89%)
### custom/module
* custom/module/global.ts
* custom/module/moduleNamespace.ts
* custom/module/nestedNamespace.ts
### custom/new
@ -288,8 +249,6 @@ ts compatibility: 173/526 (32.89%)
* custom/typeParameters/variables.ts
### declare
* declare/declare_function.ts
* declare/declare_interface.ts
* declare/object-type-in-declare-function.ts
### decorator-auto-accessors
@ -328,13 +287,11 @@ ts compatibility: 173/526 (32.89%)
* enum/enum.ts
### error-recovery
* error-recovery/generic.ts
* error-recovery/index-signature.ts
* error-recovery/jsdoc_only_types.ts
### export
* export/comment.ts
* export/export-class.ts
* export/export-type-star-from-2.ts
* export/export-type-star-from.ts
@ -360,9 +317,6 @@ ts compatibility: 173/526 (32.89%)
### import-require
* import-require/type-imports.ts
### import-type
* import-type/import-type.ts
### index-signature
* index-signature/index-signature.ts
* index-signature/static.ts
@ -371,11 +325,7 @@ ts compatibility: 173/526 (32.89%)
* infer-extends/basic.ts
### instantiation-expression
* instantiation-expression/basic.ts
* instantiation-expression/binary-expr.ts
* instantiation-expression/inferface-asi.ts
* instantiation-expression/logical-expr.ts
* instantiation-expression/new.ts
* instantiation-expression/property-access.ts
### interface
@ -447,9 +397,6 @@ ts compatibility: 173/526 (32.89%)
### multiparser-css
* multiparser-css/issue-6259.ts
### never
* never/type-argument.src.ts
### new
* new/new-signature.ts
@ -459,17 +406,12 @@ ts compatibility: 173/526 (32.89%)
### non-null
* non-null/braces.ts
* non-null/member-chain.ts
* non-null/optional-chain.ts
* non-null/parens.ts
### nosemi
* nosemi/index-signature.ts
* nosemi/type.ts
### optional-call
* optional-call/type-parameters.ts
### optional-type
* optional-type/complex.ts
@ -477,9 +419,6 @@ ts compatibility: 173/526 (32.89%)
* optional-variance/basic.ts
* optional-variance/with-jsx.tsx
### predicate-types
* predicate-types/predicate-types.ts
### prettier-ignore
* prettier-ignore/issue-14238.ts
* prettier-ignore/mapped-types.ts
@ -502,7 +441,6 @@ ts compatibility: 173/526 (32.89%)
* satisfies-operators/argument-expansion.ts
* satisfies-operators/assignment.ts
* satisfies-operators/basic.ts
* satisfies-operators/comments-unstable.ts
* satisfies-operators/comments.ts
* satisfies-operators/export-default-as.ts
* satisfies-operators/expression-statement.ts
@ -516,9 +454,6 @@ ts compatibility: 173/526 (32.89%)
* satisfies-operators/ternary.ts
* satisfies-operators/types-comments.ts
### semi
* semi/no-semi.ts
### static-blocks
* static-blocks/nested.ts
@ -559,11 +494,9 @@ ts compatibility: 173/526 (32.89%)
### type-arguments-bit-shift-left-like
* type-arguments-bit-shift-left-like/1.ts
* type-arguments-bit-shift-left-like/2.ts
* type-arguments-bit-shift-left-like/3.ts
* type-arguments-bit-shift-left-like/4.ts
* type-arguments-bit-shift-left-like/5.tsx
* type-arguments-bit-shift-left-like/6.ts
### type-member-get-set
* type-member-get-set/type-member-get-set.ts