Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(prettier/ts): better conformance #2721

Merged
merged 6 commits into from Mar 20, 2024
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions crates/oxc_prettier/src/format/class.rs
Expand Up @@ -12,6 +12,9 @@ use super::assignment::AssignmentLikeNode;

pub(super) fn print_class<'a>(p: &mut Prettier<'a>, class: &Class<'a>) -> Doc<'a> {
let mut parts = p.vec();
if class.modifiers.contains(ModifierKind::Abstract) {
parts.push(ss!("abstract "));
}
parts.push(ss!("class "));
if let Some(id) = &class.id {
parts.push(id.format(p));
Expand Down
12 changes: 12 additions & 0 deletions crates/oxc_prettier/src/format/function.rs
@@ -1,6 +1,7 @@
use oxc_ast::ast::*;

use crate::{
array,
doc::{Doc, DocBuilder},
format::function_parameters::should_group_function_parameters,
group, if_break, indent, softline, space, ss, Format, Prettier,
Expand Down Expand Up @@ -57,6 +58,10 @@ pub(super) fn print_function<'a>(
pub(super) fn print_method<'a>(p: &mut Prettier<'a>, method: &MethodDefinition<'a>) -> Doc<'a> {
let mut parts = p.vec();

if matches!(method.r#type, MethodDefinitionType::TSAbstractMethodDefinition) {
parts.push(ss!("abstract "));
}

if method.r#static {
parts.push(ss!("static "));
}
Expand Down Expand Up @@ -94,10 +99,17 @@ fn print_method_value<'a>(p: &mut Prettier<'a>, function: &Function<'a>) -> Doc<
if should_group_parameters { group!(p, parameters_doc) } else { parameters_doc };
parts.push(group!(p, parameters_doc));

if let Some(ret_typ) = &function.return_type {
parts.push(array![p, ss!(": "), ret_typ.type_annotation.format(p)]);
}

if let Some(body) = &function.body {
parts.push(space!());
parts.push(body.format(p));
} else if p.options.semi {
parts.push(ss!(";"));
}

Doc::Array(parts)
}

Expand Down
104 changes: 97 additions & 7 deletions crates/oxc_prettier/src/format/mod.rs
Expand Up @@ -772,7 +772,7 @@ impl<'a> Format<'a> for TSVoidKeyword {

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

Expand All @@ -784,7 +784,14 @@ impl<'a> Format<'a> for TSConditionalType<'a> {

impl<'a> Format<'a> for TSConstructorType<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
let mut parts = p.vec();
if self.r#abstract {
parts.push(ss!("abstract "));
}
parts.push(ss!("new "));
parts.push(self.params.format(p));
parts.push(array![p, ss!(" => "), self.return_type.type_annotation.format(p)]);
Doc::Array(parts)
}
}

Expand Down Expand Up @@ -897,7 +904,12 @@ impl<'a> Format<'a> for TSTypeQuery<'a> {

impl<'a> Format<'a> for TSTypeReference<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
let mut parts = p.vec();
parts.push(format!(p, self.type_name));
if let Some(params) = &self.type_parameters {
parts.push(format!(p, params));
}
Doc::Array(parts)
}
}

Expand All @@ -921,7 +933,22 @@ impl<'a> Format<'a> for JSDocUnknownType {

impl<'a> Format<'a> for TSInterfaceDeclaration<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
let mut parts = p.vec();
parts.push(ss!("interface "));
parts.push(format!(p, self.id));
parts.push(space!());
parts.push(ss!("{"));
if self.body.body.len() > 0 {
let mut indent_parts = p.vec();
for sig in &self.body.body {
indent_parts.extend(hardline!());
indent_parts.push(format!(p, sig));
}
parts.push(Doc::Indent(indent_parts));
parts.extend(hardline!());
}
parts.push(ss!("}"));
Doc::Array(parts)
}
}

Expand Down Expand Up @@ -969,7 +996,10 @@ impl<'a> Format<'a> for TSModuleReference<'a> {

impl<'a> Format<'a> for TSTypeName<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
line!()
match self {
TSTypeName::IdentifierReference(it) => format!(p, it),
TSTypeName::QualifiedName(it) => format!(p, it),
}
}
}

Expand Down Expand Up @@ -1245,7 +1275,7 @@ impl<'a> Format<'a> for Expression<'a> {
Self::ClassExpression(expr) => expr.format(p),
Self::JSXElement(el) => el.format(p),
Self::JSXFragment(fragment) => fragment.format(p),
Self::TSAsExpression(expr) => expr.expression.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),
Expand Down Expand Up @@ -2175,12 +2205,17 @@ impl<'a> Format<'a> for PrivateIdentifier<'a> {

impl<'a> Format<'a> for BindingPattern<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
match self.kind {
let mut parts = p.vec();
parts.push(match self.kind {
BindingPatternKind::BindingIdentifier(ref ident) => ident.format(p),
BindingPatternKind::ObjectPattern(ref pattern) => pattern.format(p),
BindingPatternKind::ArrayPattern(ref pattern) => pattern.format(p),
BindingPatternKind::AssignmentPattern(ref pattern) => pattern.format(p),
});
if let Some(typ) = &self.type_annotation {
parts.push(array![p, ss!(": "), typ.type_annotation.format(p)]);
}
Doc::Array(parts)
}
}

Expand Down Expand Up @@ -2258,3 +2293,58 @@ impl<'a> Format<'a> for TSIndexSignature<'a> {
line!()
}
}

impl<'a> Format<'a> for TSPropertySignature<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
let mut parts = p.vec();
if self.readonly {
parts.push(ss!("readonly "));
}
parts.push(format!(p, self.key));
if let Some(ty) = &self.type_annotation {
if self.optional {
parts.push(ss!("?"));
}
parts.push(ss!(":"));
parts.push(space!());
parts.push(format!(p, ty.type_annotation));
}
Doc::Array(parts)
}
}

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

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

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

impl<'a> Format<'a> for TSSignature<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
match self {
TSSignature::TSIndexSignature(it) => it.format(p),
TSSignature::TSPropertySignature(it) => it.format(p),
TSSignature::TSCallSignatureDeclaration(it) => it.format(p),
TSSignature::TSConstructSignatureDeclaration(it) => it.format(p),
TSSignature::TSMethodSignature(it) => it.format(p),
}
}
}

impl<'a> Format<'a> for TSAsExpression<'a> {
fn format(&self, p: &mut Prettier<'a>) -> Doc<'a> {
array![p, format!(p, self.expression), ss!(" as "), format!(p, self.type_annotation)]
}
}
75 changes: 46 additions & 29 deletions tasks/coverage/prettier_babel.snap
@@ -1,6 +1,6 @@
prettier_babel Summary:
AST Parsed : 2096/2096 (100.00%)
Positive Passed: 1908/2096 (91.03%)
Positive Passed: 1891/2096 (90.22%)
Expect to Parse: "comments/attachComment-false/array-expression-trailing-comma/input.js"
Expect to Parse: "comments/basic/array-expression-trailing-comma/input.js"
Expect to Parse: "comments/basic/object-expression-trailing-comma/input.js"
Expand All @@ -24,12 +24,21 @@ Expect to Parse: "esprima/es2015-destructuring-assignment-array-pattern/elision/
Expect to Parse: "esprima/es2015-generator/generator-method-with-computed-name/input.js"
Expect to Parse: "esprima/es2015-generator/generator-method-with-yield-delegate/input.js"
Expect to Parse: "esprima/expression-primary-object/migrated_0036/input.js"
Expect to Parse: "typescript/assert-predicate/asserts-this/input.ts"
Expect to Parse: "typescript/assert-predicate/asserts-this-with-predicate/input.ts"
Expect to Parse: "typescript/assert-predicate/asserts-var-with-predicate/input.ts"
Expect to Parse: "typescript/cast/as-const/input.ts"
Expect to Parse: "typescript/cast/multiple-assert-and-assign/input.ts"
Expect to Parse: "typescript/cast/need-parentheses/input.ts"
Expect to Parse: "typescript/cast/nested-parenthesized-assert-and-assign/input.ts"
Expect to Parse: "typescript/catch-clause/unknown/input.ts"
Expect to Parse: "typescript/class/async-optional-method/input.js"
Expect to Parse: "typescript/class/declare/input.ts"
Expect to Parse: "typescript/class/index-signature/input.ts"
Expect to Parse: "typescript/class/predicate-types/input.ts"
Expect to Parse: "typescript/class/private-method-overload/input.ts"
Expect to Parse: "typescript/const/initializer-ambient-context/input.ts"
Expect to Parse: "typescript/declare/interface/input.ts"
Expect to Parse: "typescript/declare/interface-new-line/input.ts"
Expect to Parse: "typescript/declare/destructure/input.ts"
Expect to Parse: "typescript/declare/pattern-parameters/input.ts"
Expect to Parse: "typescript/declare/pattern-parameters-babel-7/input.ts"
Expect to Parse: "typescript/enum/const/input.ts"
Expand All @@ -47,7 +56,6 @@ Expect to Parse: "typescript/enum/members-trailing-comma-with-initializer/input.
Expect to Parse: "typescript/estree-compat/shorthand-ambient-module/input.ts"
Expect to Parse: "typescript/export/as-namespace/input.ts"
Expect to Parse: "typescript/export/declare/input.ts"
Expect to Parse: "typescript/export/export-type-declaration/input.ts"
Expect to Parse: "typescript/export/export-value-declaration/input.ts"
Expect to Parse: "typescript/export/nested-same-name/input.ts"
Expect to Parse: "typescript/function/annotated/input.ts"
Expand All @@ -66,15 +74,10 @@ Expect to Parse: "typescript/interface/call-signature/input.ts"
Expect to Parse: "typescript/interface/call-signature-babel-7/input.ts"
Expect to Parse: "typescript/interface/construct-signature/input.ts"
Expect to Parse: "typescript/interface/construct-signature-babel-7/input.ts"
Expect to Parse: "typescript/interface/export/input.ts"
Expect to Parse: "typescript/interface/extends/input.ts"
Expect to Parse: "typescript/interface/function-like-node-1/input.ts"
Expect to Parse: "typescript/interface/function-like-node-2/input.ts"
Expect to Parse: "typescript/interface/function-like-node-3/input.ts"
Expect to Parse: "typescript/interface/function-like-node-4/input.ts"
Expect to Parse: "typescript/interface/function-like-node-5/input.ts"
Expect to Parse: "typescript/interface/generic/input.ts"
Expect to Parse: "typescript/interface/generic-babel-7/input.ts"
Expect to Parse: "typescript/interface/get-set/input.ts"
Expect to Parse: "typescript/interface/get-set-ambiguous/input.ts"
Expect to Parse: "typescript/interface/get-set-ambiguous-babel-7/input.ts"
Expand All @@ -90,15 +93,11 @@ Expect to Parse: "typescript/interface/method-optional/input.ts"
Expect to Parse: "typescript/interface/method-optional-babel-7/input.ts"
Expect to Parse: "typescript/interface/method-plain/input.ts"
Expect to Parse: "typescript/interface/method-plain-babel-7/input.ts"
Expect to Parse: "typescript/interface/modifiers/input.ts"
Expect to Parse: "typescript/interface/pattern-parameters/input.ts"
Expect to Parse: "typescript/interface/pattern-parameters-babel-7/input.ts"
Expect to Parse: "typescript/interface/properties/input.ts"
Expect to Parse: "typescript/interface/property-computed/input.ts"
Expect to Parse: "typescript/interface/property-named-public/input.ts"
Expect to Parse: "typescript/interface/reserved-method-name/input.ts"
Expect to Parse: "typescript/interface/reserved-method-name-babel-7/input.ts"
Expect to Parse: "typescript/interface/separators/input.ts"
Expect to Parse: "typescript/module-namespace/body/input.ts"
Expect to Parse: "typescript/module-namespace/body-declare/input.ts"
Expect to Parse: "typescript/module-namespace/body-nested/input.ts"
Expand All @@ -122,70 +121,88 @@ Expect to Parse: "typescript/scope/export-enum-after/input.ts"
Expect to Parse: "typescript/scope/export-enum-before/input.ts"
Expect to Parse: "typescript/scope/export-func-in-declare-module/input.ts"
Expect to Parse: "typescript/scope/export-import-in-declare-module/input.ts"
Expect to Parse: "typescript/scope/export-interface-after/input.ts"
Expect to Parse: "typescript/scope/export-interface-before/input.ts"
Expect to Parse: "typescript/scope/export-namespace/input.ts"
Expect to Parse: "typescript/scope/module-declaration-var/input.js"
Expect to Parse: "typescript/scope/module-declaration-var-2/input.js"
Expect to Parse: "typescript/scope/redeclaration-class-interface/input.ts"
Expect to Parse: "typescript/scope/redeclaration-constenum-constenum/input.ts"
Expect to Parse: "typescript/scope/redeclaration-enum-enum/input.ts"
Expect to Parse: "typescript/scope/redeclaration-function-interface/input.ts"
Expect to Parse: "typescript/scope/redeclaration-import-equals-var/input.ts"
Expect to Parse: "typescript/scope/redeclaration-import-let/input.ts"
Expect to Parse: "typescript/scope/redeclaration-import-type-let/input.ts"
Expect to Parse: "typescript/scope/redeclaration-import-type-type/input.ts"
Expect to Parse: "typescript/scope/redeclaration-import-type-var/input.ts"
Expect to Parse: "typescript/scope/redeclaration-import-var/input.ts"
Expect to Parse: "typescript/scope/redeclaration-in-different-module/input.ts"
Expect to Parse: "typescript/scope/redeclaration-in-different-module-and-top-level/input.ts"
Expect to Parse: "typescript/scope/redeclaration-in-nested-module/input.ts"
Expect to Parse: "typescript/scope/redeclaration-interface-class/input.ts"
Expect to Parse: "typescript/scope/redeclaration-interface-function/input.ts"
Expect to Parse: "typescript/scope/redeclaration-interface-interface/input.ts"
Expect to Parse: "typescript/scope/redeclaration-interface-let/input.ts"
Expect to Parse: "typescript/scope/redeclaration-interface-var/input.ts"
Expect to Parse: "typescript/scope/redeclaration-let-interface/input.ts"
Expect to Parse: "typescript/scope/redeclaration-var-interface/input.ts"
Expect to Parse: "typescript/tsx/anonymous-function-generator/input.ts"
Expect to Parse: "typescript/tsx/anonymous-function-generator-babel-7/input.ts"
Expect to Parse: "typescript/tsx/assignment-in-conditional-expression/input.ts"
Expect to Parse: "typescript/tsx/brace-is-block/input.tsx"
Expect to Parse: "typescript/tsx/type-arguments/input.ts"
Expect to Parse: "typescript/type-alias/generic/input.ts"
Expect to Parse: "typescript/type-alias/generic-babel-7/input.ts"
Expect to Parse: "typescript/type-alias/generic-complex-tokens-true/input.ts"
Expect to Parse: "typescript/type-alias/generic-complex-tokens-true-babel-7/input.ts"
Expect to Parse: "typescript/type-arguments/instantiation-expression-asi/input.ts"
Expect to Parse: "typescript/type-arguments/tsx/input.ts"
Expect to Parse: "typescript/type-arguments/whitespace/input.ts"
Expect to Parse: "typescript/type-arguments/whitespace-babel-7/input.ts"
Expect to Parse: "typescript/type-arguments-bit-shift-left-like/jsx-opening-element/input.tsx"
Expect to Parse: "typescript/type-arguments-bit-shift-left-like/type-arguments-like/input.ts"
Expect to Parse: "typescript/type-arguments-bit-shift-left-like-babel-7/jsx-opening-element/input.tsx"
Expect to Parse: "typescript/type-arguments-bit-shift-left-like-babel-7/type-arguments-like/input.ts"
Expect to Parse: "typescript/types/conditional/input.ts"
Expect to Parse: "typescript/types/conditional-infer/input.ts"
Expect to Parse: "typescript/types/conditional-infer-babel-7/input.ts"
Expect to Parse: "typescript/types/function/input.ts"
Expect to Parse: "typescript/types/function-babel-7/input.ts"
Expect to Parse: "typescript/types/function-generic/input.ts"
Expect to Parse: "typescript/types/function-generic-babel-7/input.ts"
Expect to Parse: "typescript/types/function-in-generic/input.ts"
Expect to Parse: "typescript/types/function-in-generic-babel-7/input.ts"
Expect to Parse: "typescript/types/function-with-this/input.ts"
Expect to Parse: "typescript/types/function-with-this-babel-7/input.ts"
Expect to Parse: "typescript/types/import-type-dynamic/input.ts"
Expect to Parse: "typescript/types/infer-with-constraints/input.ts"
Expect to Parse: "typescript/types/infer-with-constraints-and-conditional-types/input.ts"
Expect to Parse: "typescript/types/infer-with-constraints-and-conditional-types-babel-7/input.ts"
Expect to Parse: "typescript/types/infer-with-constraints-babel-7/input.ts"
Expect to Parse: "typescript/types/intrinsic-identifier/input.ts"
Expect to Parse: "typescript/types/intrinsic-keyword/input.ts"
Expect to Parse: "typescript/types/intrinsic-keyword-babel-7/input.ts"
Expect to Parse: "typescript/types/literal-string-4/input.ts"
Expect to Parse: "typescript/types/literal-string-4-babel-7/input.ts"
Expect to Parse: "typescript/types/mapped/input.ts"
Expect to Parse: "typescript/types/mapped-as/input.ts"
Expect to Parse: "typescript/types/mapped-as-babel-7/input.ts"
Expect to Parse: "typescript/types/mapped-babel-7/input.ts"
Expect to Parse: "typescript/types/object-shorthand/input.ts"
Expect to Parse: "typescript/types/object-shorthand-babel-7/input.ts"
Expect to Parse: "typescript/types/parenthesized/input.ts"
Expect to Parse: "typescript/types/parenthesized-object/input.ts"
Expect to Parse: "typescript/types/pattern-parameters/input.ts"
Expect to Parse: "typescript/types/pattern-parameters-babel-7/input.ts"
Expect to Parse: "typescript/types/reference-generic/input.ts"
Expect to Parse: "typescript/types/reference-generic-nested/input.ts"
Expect to Parse: "typescript/types/tuple/input.ts"
Expect to Parse: "typescript/types/tuple-keyword-labeled/input.ts"
Expect to Parse: "typescript/types/tuple-keyword-labeled-babel-7/input.ts"
Expect to Parse: "typescript/types/tuple-labeled/input.ts"
Expect to Parse: "typescript/types/tuple-labeled-after-unlabeled/input.ts"
Expect to Parse: "typescript/types/tuple-labeled-before-unlabeled/input.ts"
Expect to Parse: "typescript/types/tuple-labeled-spread/input.ts"
Expect to Parse: "typescript/types/tuple-optional/input.ts"
Expect to Parse: "typescript/types/tuple-optional-babel-7/input.ts"
Expect to Parse: "typescript/types/tuple-rest/input.ts"
Expect to Parse: "typescript/types/tuple-rest-after-optional/input.ts"
Expect to Parse: "typescript/types/tuple-rest-not-last/input.ts"
Expect to Parse: "typescript/types/tuple-rest-trailing-comma/input.ts"
Expect to Parse: "typescript/types/tuple-unlabeled-spread-after-labeled/input.ts"
Expect to Parse: "typescript/types/tuple-unlabeled-spread-before-labeled/input.ts"
Expect to Parse: "typescript/types/type-literal/input.ts"
Expect to Parse: "typescript/types/type-literal-get-set/input.ts"
Expect to Parse: "typescript/types/type-literal-get-set-babel-7/input.ts"
Expect to Parse: "typescript/types/type-operator/input.ts"
Expect to Parse: "typescript/types/typeof/input.ts"
Expect to Parse: "typescript/types/typeof-type-asi-false-parameters/input.ts"
Expect to Parse: "typescript/types/typeof-type-asi-false-parameters-babel-7/input.ts"
Expect to Parse: "typescript/types/typeof-type-parameters/input.ts"
Expect to Parse: "typescript/types/union-intersection/input.ts"
Expect to Parse: "typescript/types-arrow-function/object-pattern-with-template/input.ts"
Expect to Parse: "typescript/types-arrow-function-babel-7/object-pattern-with-template/input.ts"