mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
feat(prettier): improve format of ExportDefaultDeclaration (#1520)
This commit is contained in:
parent
f4c89ce5a6
commit
78c6fcd1d0
3 changed files with 98 additions and 41 deletions
|
|
@ -139,6 +139,7 @@ pub enum AstKind<'a> {
|
|||
TSAsExpression(&'a TSAsExpression<'a>),
|
||||
TSSatisfiesExpression(&'a TSSatisfiesExpression<'a>),
|
||||
TSNonNullExpression(&'a TSNonNullExpression<'a>),
|
||||
TSInstantiationExpression(&'a TSInstantiationExpression<'a>),
|
||||
|
||||
TSEnumDeclaration(&'a TSEnumDeclaration<'a>),
|
||||
TSEnumMember(&'a TSEnumMember<'a>),
|
||||
|
|
@ -256,6 +257,51 @@ impl<'a> AstKind<'a> {
|
|||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_expression(e: &'a Expression<'a>) -> Self {
|
||||
match e {
|
||||
Expression::BooleanLiteral(e) => Self::BooleanLiteral(e),
|
||||
Expression::NullLiteral(e) => Self::NullLiteral(e),
|
||||
Expression::NumberLiteral(e) => Self::NumberLiteral(e),
|
||||
Expression::BigintLiteral(e) => Self::BigintLiteral(e),
|
||||
Expression::RegExpLiteral(e) => Self::RegExpLiteral(e),
|
||||
Expression::StringLiteral(e) => Self::StringLiteral(e),
|
||||
Expression::TemplateLiteral(e) => Self::TemplateLiteral(e),
|
||||
Expression::Identifier(e) => Self::IdentifierReference(e),
|
||||
Expression::MetaProperty(e) => Self::MetaProperty(e),
|
||||
Expression::Super(e) => Self::Super(e),
|
||||
Expression::ArrayExpression(e) => Self::ArrayExpression(e),
|
||||
Expression::ArrowExpression(e) => Self::ArrowExpression(e),
|
||||
Expression::AssignmentExpression(e) => Self::AssignmentExpression(e),
|
||||
Expression::AwaitExpression(e) => Self::AwaitExpression(e),
|
||||
Expression::BinaryExpression(e) => Self::BinaryExpression(e),
|
||||
Expression::CallExpression(e) => Self::CallExpression(e),
|
||||
Expression::ChainExpression(e) => Self::ChainExpression(e),
|
||||
Expression::ClassExpression(e) => Self::Class(e),
|
||||
Expression::ConditionalExpression(e) => Self::ConditionalExpression(e),
|
||||
Expression::FunctionExpression(e) => Self::Function(e),
|
||||
Expression::ImportExpression(e) => Self::ImportExpression(e),
|
||||
Expression::LogicalExpression(e) => Self::LogicalExpression(e),
|
||||
Expression::MemberExpression(e) => Self::MemberExpression(e),
|
||||
Expression::NewExpression(e) => Self::NewExpression(e),
|
||||
Expression::ObjectExpression(e) => Self::ObjectExpression(e),
|
||||
Expression::ParenthesizedExpression(e) => Self::ParenthesizedExpression(e),
|
||||
Expression::SequenceExpression(e) => Self::SequenceExpression(e),
|
||||
Expression::TaggedTemplateExpression(e) => Self::TaggedTemplateExpression(e),
|
||||
Expression::ThisExpression(e) => Self::ThisExpression(e),
|
||||
Expression::UnaryExpression(e) => Self::UnaryExpression(e),
|
||||
Expression::UpdateExpression(e) => Self::UpdateExpression(e),
|
||||
Expression::YieldExpression(e) => Self::YieldExpression(e),
|
||||
Expression::PrivateInExpression(e) => Self::PrivateInExpression(e),
|
||||
Expression::JSXElement(e) => Self::JSXElement(e),
|
||||
Expression::JSXFragment(e) => Self::JSXFragment(e),
|
||||
Expression::TSAsExpression(e) => Self::TSAsExpression(e),
|
||||
Expression::TSSatisfiesExpression(e) => Self::TSSatisfiesExpression(e),
|
||||
Expression::TSTypeAssertion(e) => Self::TSTypeAssertion(e),
|
||||
Expression::TSNonNullExpression(e) => Self::TSNonNullExpression(e),
|
||||
Expression::TSInstantiationExpression(e) => Self::TSInstantiationExpression(e),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> GetSpan for AstKind<'a> {
|
||||
|
|
@ -391,6 +437,7 @@ impl<'a> GetSpan for AstKind<'a> {
|
|||
Self::TSAsExpression(x) => x.span,
|
||||
Self::TSSatisfiesExpression(x) => x.span,
|
||||
Self::TSNonNullExpression(x) => x.span,
|
||||
Self::TSInstantiationExpression(x) => x.span,
|
||||
|
||||
Self::TSEnumDeclaration(x) => x.span,
|
||||
Self::TSEnumMember(x) => x.span,
|
||||
|
|
@ -561,6 +608,7 @@ impl<'a> AstKind<'a> {
|
|||
Self::TSAsExpression(_) => "TSAsExpression".into(),
|
||||
Self::TSSatisfiesExpression(_) => "TSSatisfiesExpression".into(),
|
||||
Self::TSNonNullExpression(_) => "TSNonNullExpression".into(),
|
||||
Self::TSInstantiationExpression(_) => "TSInstantiationExpression".into(),
|
||||
|
||||
Self::TSEnumDeclaration(decl) => format!("TSEnumDeclaration({})", &decl.id.name).into(),
|
||||
Self::TSEnumBody(_) => "TSEnumBody".into(),
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ use oxc_syntax::operator::{BinaryOperator, UnaryOperator, UpdateOperator};
|
|||
use crate::{array, doc::Doc, ss, Prettier};
|
||||
|
||||
impl<'a> Prettier<'a> {
|
||||
pub(crate) fn wrap_parens(&self, doc: Doc<'a>, kind: AstKind<'a>) -> Doc<'a> {
|
||||
pub(crate) fn wrap_parens(&mut self, doc: Doc<'a>, kind: AstKind<'a>) -> Doc<'a> {
|
||||
if self.need_parens(kind) {
|
||||
array![self, ss!("("), doc, ss!(")")]
|
||||
} else {
|
||||
|
|
@ -29,7 +29,7 @@ impl<'a> Prettier<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn need_parens(&self, kind: AstKind<'a>) -> bool {
|
||||
fn need_parens(&mut self, kind: AstKind<'a>) -> bool {
|
||||
if matches!(kind, AstKind::Program(_)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -165,7 +165,7 @@ impl<'a> Prettier<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_parent_kind(&self, kind: AstKind<'a>, parent_kind: AstKind<'a>) -> bool {
|
||||
fn check_parent_kind(&mut self, kind: AstKind<'a>, parent_kind: AstKind<'a>) -> bool {
|
||||
match parent_kind {
|
||||
AstKind::Class(class) => {
|
||||
if let Some(h) = &class.super_class {
|
||||
|
|
@ -198,7 +198,7 @@ impl<'a> Prettier<'a> {
|
|||
AstKind::ModuleDeclaration(ModuleDeclaration::ExportDefaultDeclaration(decl)) => {
|
||||
if let ExportDefaultDeclarationKind::Expression(e) = &decl.declaration {
|
||||
return matches!(e, Expression::SequenceExpression(_))
|
||||
|| Self::should_wrap_function_for_export_default(e);
|
||||
|| self.should_wrap_function_for_export_default();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
|
@ -307,38 +307,51 @@ impl<'a> Prettier<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// This differs from the prettier implementation, which may be wrong.
|
||||
fn should_wrap_function_for_export_default(e: &Expression<'a>) -> bool {
|
||||
match e {
|
||||
Expression::FunctionExpression(_) | Expression::ClassExpression(_) => true,
|
||||
Expression::CallExpression(e) => {
|
||||
Self::should_wrap_function_for_export_default(&e.callee)
|
||||
}
|
||||
Expression::MemberExpression(e) => {
|
||||
Self::should_wrap_function_for_export_default(e.object())
|
||||
}
|
||||
Expression::AssignmentExpression(e) => match &e.left {
|
||||
AssignmentTarget::SimpleAssignmentTarget(t) => match t {
|
||||
SimpleAssignmentTarget::AssignmentTargetIdentifier(_) => false,
|
||||
SimpleAssignmentTarget::MemberAssignmentTarget(e) => {
|
||||
Self::should_wrap_function_for_export_default(e.object())
|
||||
}
|
||||
SimpleAssignmentTarget::TSAsExpression(e) => {
|
||||
Self::should_wrap_function_for_export_default(&e.expression)
|
||||
}
|
||||
SimpleAssignmentTarget::TSSatisfiesExpression(e) => {
|
||||
Self::should_wrap_function_for_export_default(&e.expression)
|
||||
}
|
||||
SimpleAssignmentTarget::TSNonNullExpression(e) => {
|
||||
Self::should_wrap_function_for_export_default(&e.expression)
|
||||
}
|
||||
SimpleAssignmentTarget::TSTypeAssertion(e) => {
|
||||
Self::should_wrap_function_for_export_default(&e.expression)
|
||||
}
|
||||
},
|
||||
AssignmentTarget::AssignmentTargetPattern(_) => false,
|
||||
},
|
||||
_ => false,
|
||||
fn should_wrap_function_for_export_default(&mut self) -> bool {
|
||||
let kind = self.current_kind();
|
||||
let b = matches!(
|
||||
self.parent_kind(),
|
||||
AstKind::ModuleDeclaration(ModuleDeclaration::ExportDefaultDeclaration(_))
|
||||
);
|
||||
if matches!(kind, AstKind::Function(f) if f.is_expression())
|
||||
|| matches!(kind, AstKind::Class(c) if c.is_expression())
|
||||
{
|
||||
return b || !self.need_parens(self.current_kind());
|
||||
}
|
||||
|
||||
if !Self::has_naked_left_side(kind) || (!b && self.need_parens(self.current_kind())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let lhs = Self::get_left_side_path_name(kind);
|
||||
self.nodes.push(lhs);
|
||||
self.should_wrap_function_for_export_default()
|
||||
}
|
||||
|
||||
fn has_naked_left_side(kind: AstKind<'a>) -> bool {
|
||||
matches!(
|
||||
kind,
|
||||
AstKind::AssignmentExpression(_)
|
||||
| AstKind::BinaryExpression(_)
|
||||
| AstKind::LogicalExpression(_)
|
||||
| AstKind::ConditionalExpression(_)
|
||||
| AstKind::CallExpression(_)
|
||||
| AstKind::MemberExpression(_)
|
||||
| AstKind::SequenceExpression(_)
|
||||
| AstKind::TaggedTemplateExpression(_)
|
||||
| AstKind::TSNonNullExpression(_)
|
||||
| AstKind::ChainExpression(_)
|
||||
) || matches!(kind, AstKind::UpdateExpression(e) if !e.prefix)
|
||||
}
|
||||
|
||||
fn get_left_side_path_name(kind: AstKind<'a>) -> AstKind<'a> {
|
||||
match kind {
|
||||
AstKind::CallExpression(e) => AstKind::from_expression(&e.callee),
|
||||
AstKind::ConditionalExpression(e) => AstKind::from_expression(&e.test),
|
||||
AstKind::TaggedTemplateExpression(e) => AstKind::from_expression(&e.tag),
|
||||
AstKind::AssignmentExpression(e) => AstKind::AssignmentTarget(&e.left),
|
||||
AstKind::MemberExpression(e) => AstKind::from_expression(e.object()),
|
||||
_ => panic!("need to handle {}", kind.debug_name()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Compatibility: 150/597 (25.13%)
|
||||
Compatibility: 152/597 (25.46%)
|
||||
|
||||
# Failed
|
||||
|
||||
|
|
@ -311,9 +311,6 @@ Compatibility: 150/597 (25.13%)
|
|||
* export/blank-line-between-specifiers.js
|
||||
* export/same-local-and-exported.js
|
||||
|
||||
### export-default
|
||||
* export-default/iife.js
|
||||
|
||||
### export-default/escaped
|
||||
* export-default/escaped/default-escaped.js
|
||||
|
||||
|
|
@ -331,7 +328,6 @@ Compatibility: 150/597 (25.13%)
|
|||
* for/continue-and-break-comment-without-blocks.js
|
||||
|
||||
### function
|
||||
* function/function_expression.js
|
||||
* function/issue-10277.js
|
||||
|
||||
### function-comments
|
||||
|
|
|
|||
Loading…
Reference in a new issue