Skip to content

Commit

Permalink
feat(prettier/ts): better conformance (#2721)
Browse files Browse the repository at this point in the history
I know 5% isn't much, but it's small steps like this that move us toward
our goal.
  • Loading branch information
LIMPIX31 committed Mar 20, 2024
1 parent 451162e commit 1721fee
Show file tree
Hide file tree
Showing 6 changed files with 667 additions and 144 deletions.
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"

0 comments on commit 1721fee

Please sign in to comment.