diff --git a/crates/oxc_formatter/src/parentheses/expression.rs b/crates/oxc_formatter/src/parentheses/expression.rs index a3bc6c73b5ba5..e6b558f0e0c17 100644 --- a/crates/oxc_formatter/src/parentheses/expression.rs +++ b/crates/oxc_formatter/src/parentheses/expression.rs @@ -626,13 +626,13 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, JSXEmptyExpression> { impl<'a> NeedsParentheses<'a> for AstNode<'a, TSAsExpression<'a>> { fn needs_parentheses(&self, f: &Formatter<'_, 'a>) -> bool { - ts_as_or_satisfies_needs_parens(self.parent) + ts_as_or_satisfies_needs_parens(self.span(), &self.expression, self.parent) } } impl<'a> NeedsParentheses<'a> for AstNode<'a, TSSatisfiesExpression<'a>> { fn needs_parentheses(&self, f: &Formatter<'_, 'a>) -> bool { - ts_as_or_satisfies_needs_parens(self.parent) + ts_as_or_satisfies_needs_parens(self.span(), &self.expression, self.parent) } } @@ -649,7 +649,7 @@ impl<'a> NeedsParentheses<'a> for AstNode<'a, TSTypeAssertion<'a>> { } fn type_cast_like_needs_parens(span: Span, parent: &AstNodes<'_>) -> bool { - #[expect(clippy::match_same_arms)] + #[expect(clippy::match_same_arms)] // for better readability match parent { AstNodes::ExportDefaultDeclaration(_) | AstNodes::TSTypeAssertion(_) @@ -942,16 +942,23 @@ fn await_or_yield_needs_parens(span: Span, node: &AstNodes<'_>) -> bool { } } -fn ts_as_or_satisfies_needs_parens(parent: &AstNodes<'_>) -> bool { - matches!( - parent, - AstNodes::ComputedMemberExpression(_) - | AstNodes::StaticMemberExpression(_) - | AstNodes::PrivateFieldExpression(_) - | AstNodes::AssignmentExpression(_) - | AstNodes::AssignmentTargetWithDefault(_) - | AstNodes::UpdateExpression(_) - ) +fn ts_as_or_satisfies_needs_parens( + span: Span, + inner: &Expression<'_>, + parent: &AstNodes<'_>, +) -> bool { + match parent { + AstNodes::ConditionalExpression(_) + // Binary-like + | AstNodes::LogicalExpression(_) + | AstNodes::BinaryExpression(_) => true, + // `export default (function foo() {} as bar)` and `export default (class {} as bar)` + AstNodes::ExportDefaultDeclaration(_) => + matches!(inner, Expression::FunctionExpression(_) | Expression::ClassExpression(_)), + _ => { + type_cast_like_needs_parens(span, parent) + } + } } fn is_class_extends(span: Span, parent: &AstNodes<'_>) -> bool { diff --git a/tasks/coverage/snapshots/formatter_misc.snap b/tasks/coverage/snapshots/formatter_misc.snap index cb23e752f2e8e..43440ae400813 100644 --- a/tasks/coverage/snapshots/formatter_misc.snap +++ b/tasks/coverage/snapshots/formatter_misc.snap @@ -1,10 +1,8 @@ formatter_misc Summary: AST Parsed : 49/49 (100.00%) -Positive Passed: 45/49 (91.84%) +Positive Passed: 46/49 (93.88%) Expect to Parse: tasks/coverage/misc/pass/oxc-11487.cjs Cannot use `await` as an identifier in an async context -Mismatch: tasks/coverage/misc/pass/oxc-12612.ts - Mismatch: tasks/coverage/misc/pass/oxc-2592.ts Expect to Parse: tasks/coverage/misc/pass/oxc-4449.ts diff --git a/tasks/coverage/snapshots/formatter_typescript.snap b/tasks/coverage/snapshots/formatter_typescript.snap index 32ab0f1165eed..0eb719daaf9f9 100644 --- a/tasks/coverage/snapshots/formatter_typescript.snap +++ b/tasks/coverage/snapshots/formatter_typescript.snap @@ -2,41 +2,31 @@ commit: 261630d6 formatter_typescript Summary: AST Parsed : 8816/8816 (100.00%) -Positive Passed: 8775/8816 (99.53%) +Positive Passed: 8785/8816 (99.65%) Mismatch: tasks/coverage/typescript/tests/cases/compiler/amdLikeInputDeclarationEmit.ts Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/arrayFromAsync.ts `await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules`await` is only allowed within async functions and at the top levels of modules Mismatch: tasks/coverage/typescript/tests/cases/compiler/callOfConditionalTypeWithConcreteBranches.ts -Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/castFunctionExpressionShouldBeParenthesized.ts -Expected a semicolon or an implicit semicolon after a statement, but found none Mismatch: tasks/coverage/typescript/tests/cases/compiler/coAndContraVariantInferences3.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/complexNarrowingWithAny.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/declarationEmitCastReusesTypeNode4.ts -Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/declarationEmitPromise.ts -Expected a semicolon or an implicit semicolon after a statement, but found none Mismatch: tasks/coverage/typescript/tests/cases/compiler/declarationEmitRecursiveConditionalAliasPreserved.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/declarationEmitShadowingInferNotRenamed.ts -Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/exportDefaultParenthesizeES6.ts -Expected a semicolon or an implicit semicolon after a statement, but found none Mismatch: tasks/coverage/typescript/tests/cases/compiler/jsxNamespaceGlobalReexport.tsx Mismatch: tasks/coverage/typescript/tests/cases/compiler/jsxNamespaceGlobalReexportMissingAliasTarget.tsx Mismatch: tasks/coverage/typescript/tests/cases/compiler/jsxNamespaceImplicitImportJSXNamespace.tsx -Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/narrowingByTypeofInSwitch.ts -Expected a semicolon or an implicit semicolon after a statement, but found none Mismatch: tasks/coverage/typescript/tests/cases/compiler/propertyAccessExpressionInnerComments.ts -Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts -Expected `{` but found `as` Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/reverseMappedTypeInferenceSameSource1.ts An implementation cannot be declared in ambient contexts. Mismatch: tasks/coverage/typescript/tests/cases/compiler/sourceMapValidationClasses.ts @@ -45,8 +35,6 @@ Mismatch: tasks/coverage/typescript/tests/cases/compiler/styledComponentsInstant Mismatch: tasks/coverage/typescript/tests/cases/compiler/substitutionTypeForIndexedAccessType2.ts -Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/superAccessCastedCall.ts -Expected a semicolon or an implicit semicolon after a statement, but found none Mismatch: tasks/coverage/typescript/tests/cases/compiler/tryStatementInternalComments.ts Mismatch: tasks/coverage/typescript/tests/cases/compiler/unionSignaturesWithThisParameter.ts @@ -57,31 +45,23 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/classes/prope Classes may not have a static property named prototypeClasses may not have a static property named prototypeClasses may not have a static property named prototypeClasses may not have a static property named prototypeClasses may not have a static property named prototypeClasses may not have a static property named prototype Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/controlFlow/controlFlowAssignmentPatternOrder.ts An implementation cannot be declared in ambient contexts. -Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/esDecorators/classDeclaration/classSuper/esDecorators-classDeclaration-classSuper.2.ts -Expected `{` but found `as` -Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/esDecorators/classExpression/classSuper/esDecorators-classExpression-classSuper.2.ts -Expected `{` but found `as` Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/esDecorators/classExpression/esDecorators-classExpression-missingEmitHelpers-classDecorator.3.ts Decorators are not valid here.Unexpected token Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/esDecorators/classExpression/namedEvaluation/esDecorators-classExpression-namedEvaluation.8.ts Decorators are not valid here.Unexpected token -Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/expressions/asOperator/asOpEmitParens.ts -Expected a semicolon or an implicit semicolon after a statement, but found none Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/expressions/elementAccess/letIdentifierInElementAccess01.ts Unexpected token -Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/expressions/optionalChaining/optionalChainingInTypeAssertions.ts -Expected a semicolon or an implicit semicolon after a statement, but found none Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfAndAndOperator.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/expressions/typeGuards/typeGuardsInRightOperandOfOrOrOperator.ts -Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/generators/yieldStatementNoAsiAfterTransform.ts -Expected a semicolon or an implicit semicolon after a statement, but found none +Mismatch: tasks/coverage/typescript/tests/cases/conformance/generators/yieldStatementNoAsiAfterTransform.ts + Mismatch: tasks/coverage/typescript/tests/cases/conformance/interfaces/interfacesExtendingClasses/interfaceExtendingClassWithPrivates2.ts Mismatch: tasks/coverage/typescript/tests/cases/conformance/interfaces/interfacesExtendingClasses/interfaceExtendingClassWithProtecteds2.ts -Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/returnStatements/returnStatementNoAsiAfterTransform.ts -Expected `,` but found `(` +Mismatch: tasks/coverage/typescript/tests/cases/conformance/statements/returnStatements/returnStatementNoAsiAfterTransform.ts + Mismatch: tasks/coverage/typescript/tests/cases/conformance/types/tuple/named/namedTupleMembers.ts diff --git a/tasks/prettier_conformance/snapshots/prettier.ts.snap.md b/tasks/prettier_conformance/snapshots/prettier.ts.snap.md index 486daa7e81ad3..f7fe7c31c0761 100644 --- a/tasks/prettier_conformance/snapshots/prettier.ts.snap.md +++ b/tasks/prettier_conformance/snapshots/prettier.ts.snap.md @@ -1,4 +1,4 @@ -ts compatibility: 389/573 (67.89%) +ts compatibility: 401/573 (69.98%) # Failed @@ -16,18 +16,13 @@ ts compatibility: 389/573 (67.89%) | typescript/argument-expansion/arrow-with-return-type.ts | 💥 | 89.47% | | typescript/arrow/16067.ts | 💥💥 | 95.92% | | typescript/arrow/comments.ts | 💥✨ | 44.44% | -| typescript/as/as.ts | 💥 | 74.02% | -| typescript/as/assignment.ts | 💥 | 86.67% | +| typescript/as/as.ts | 💥 | 85.04% | | typescript/as/assignment2.ts | 💥 | 94.12% | -| typescript/as/export_default_as.ts | 💥 | 0.00% | | typescript/as/expression-statement.ts | 💥 | 75.00% | -| typescript/as/long-identifiers.ts | 💥 | 92.86% | | typescript/as/nested-await-and-as.ts | 💥 | 42.86% | -| typescript/as/ternary.ts | 💥 | 82.00% | | typescript/assignment/issue-10846.ts | 💥 | 63.16% | | typescript/assignment/issue-10848.tsx | 💥 | 52.12% | | typescript/assignment/issue-10850.ts | 💥 | 50.00% | -| typescript/cast/as-const.ts | 💥 | 60.00% | | typescript/cast/generic-cast.ts | 💥 | 39.60% | | typescript/cast/tuple-and-record.ts | 💥 | 0.00% | | typescript/chain-expression/call-expression.ts | 💥 | 68.75% | @@ -102,7 +97,6 @@ ts compatibility: 389/573 (67.89%) | typescript/enum/computed-members.ts | 💥 | 0.00% | | typescript/export/comment.ts | 💥 | 50.00% | | typescript/export/export.ts | 💥 | 85.71% | -| typescript/export-default/function_as.ts | 💥 | 0.00% | | typescript/function-type/consistent.ts | 💥 | 70.83% | | typescript/function-type/type-annotation.ts | 💥 | 0.00% | | typescript/generic/arrow-return-type.ts | 💥 | 80.77% | @@ -134,7 +128,6 @@ ts compatibility: 389/573 (67.89%) | typescript/module/namespace_function.ts | 💥 | 66.67% | | typescript/multiparser-css/issue-6259.ts | 💥 | 57.14% | | typescript/new/new-signature.ts | 💥 | 93.85% | -| typescript/no-semi/non-null.ts | 💥💥 | 66.67% | | typescript/non-null/optional-chain.ts | 💥 | 72.22% | | typescript/non-null/parens.ts | 💥 | 96.00% | | typescript/nosemi/index-signature.ts | 💥 | 75.00% | @@ -148,15 +141,10 @@ ts compatibility: 389/573 (67.89%) | typescript/prettier-ignore/prettier-ignore-parenthesized-type.ts | 💥 | 0.00% | | typescript/rest-type/complex.ts | 💥 | 0.00% | | typescript/rest-type/infer-type.ts | 💥 | 80.00% | -| typescript/satisfies-operators/assignment.ts | 💥💥 | 72.73% | -| typescript/satisfies-operators/export-default-as.ts | 💥💥 | 0.00% | +| typescript/satisfies-operators/assignment.ts | 💥💥 | 90.91% | | typescript/satisfies-operators/expression-statement.ts | 💥💥 | 78.38% | -| typescript/satisfies-operators/gt-lt.ts | 💥💥 | 0.00% | | typescript/satisfies-operators/lhs.ts | 💥✨ | 35.00% | | typescript/satisfies-operators/nested-await-and-satisfies.ts | 💥💥 | 42.86% | -| typescript/satisfies-operators/non-null.ts | 💥💥 | 66.67% | -| typescript/satisfies-operators/satisfies.ts | 💥💥 | 81.82% | -| typescript/satisfies-operators/ternary.ts | 💥💥 | 82.00% | | typescript/template-literal-types/template-literal-types.ts | 💥 | 80.00% | | typescript/test-declarations/test_declarations.ts | 💥💥 | 66.67% | | typescript/trailing-comma/arrow-functions.tsx | 💥💥💥 | 25.00% |