mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 20:32:10 +00:00
139 lines
4.3 KiB
Rust
139 lines
4.3 KiB
Rust
use oxc_ast::{ast::*, AstKind};
|
|
|
|
use crate::{
|
|
comments::CommentFlags,
|
|
doc::{Doc, DocBuilder, Group},
|
|
hardline, if_break, indent, line, softline, ss, Format, Prettier,
|
|
};
|
|
|
|
pub(super) fn should_hug_the_only_function_parameter(
|
|
p: &mut Prettier<'_>,
|
|
params: &FormalParameters<'_>,
|
|
) -> bool {
|
|
if params.parameters_count() != 1 {
|
|
return false;
|
|
}
|
|
let Some(parameter) = params.items.first() else { return false };
|
|
|
|
let all_comment_flags = CommentFlags::Trailing
|
|
| CommentFlags::Leading
|
|
| CommentFlags::Dangling
|
|
| CommentFlags::Block
|
|
| CommentFlags::Line
|
|
| CommentFlags::PrettierIgnore
|
|
| CommentFlags::First
|
|
| CommentFlags::Last;
|
|
if p.has_comment(parameter.span, all_comment_flags) {
|
|
return false;
|
|
}
|
|
|
|
match ¶meter.pattern.kind {
|
|
BindingPatternKind::ObjectPattern(_) | BindingPatternKind::ArrayPattern(_) => true,
|
|
BindingPatternKind::BindingIdentifier(_) => {
|
|
let Some(ts_type_annotation) = ¶meter.pattern.type_annotation else { return false };
|
|
matches!(
|
|
ts_type_annotation.type_annotation,
|
|
TSType::TSTypeLiteral(_) | TSType::TSMappedType(_)
|
|
)
|
|
}
|
|
BindingPatternKind::AssignmentPattern(assignment_pattern) => {
|
|
let left = &assignment_pattern.left.kind;
|
|
if matches!(left, BindingPatternKind::ObjectPattern(_)) {
|
|
return true;
|
|
}
|
|
|
|
if !matches!(left, BindingPatternKind::ArrayPattern(_)) {
|
|
return false;
|
|
}
|
|
|
|
let right = &assignment_pattern.right;
|
|
match right {
|
|
Expression::Identifier(_) => true,
|
|
Expression::ObjectExpression(obj_expr) => obj_expr.properties.len() == 0,
|
|
Expression::ArrayExpression(arr_expr) => arr_expr.elements.len() == 0,
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub(super) fn print_function_parameters<'a>(
|
|
p: &mut Prettier<'a>,
|
|
params: &FormalParameters<'a>,
|
|
) -> Doc<'a> {
|
|
let mut parts = p.vec();
|
|
let is_arrow_function = matches!(p.parent_kind(), AstKind::ArrowExpression(_));
|
|
let need_parens =
|
|
!is_arrow_function || p.options.arrow_parens.is_always() || params.items.len() != 1;
|
|
if need_parens {
|
|
parts.push(ss!("("));
|
|
}
|
|
|
|
let mut printed = p.vec();
|
|
for (i, param) in params.items.iter().enumerate() {
|
|
printed.push(param.format(p));
|
|
if i == params.items.len() - 1 {
|
|
break;
|
|
}
|
|
printed.push(ss!(","));
|
|
if should_hug_the_only_function_parameter(p, params) {
|
|
printed.push(ss!(" "));
|
|
} else if p.is_next_line_empty(param.span) {
|
|
printed.extend(hardline!());
|
|
printed.extend(hardline!());
|
|
} else {
|
|
printed.push(line!());
|
|
}
|
|
}
|
|
|
|
if let Some(rest) = ¶ms.rest {
|
|
if !params.items.is_empty() {
|
|
printed.push(ss!(", "));
|
|
}
|
|
printed.push(rest.format(p));
|
|
}
|
|
|
|
let mut indented = p.vec();
|
|
indented.push(softline!());
|
|
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 { "," }));
|
|
parts.push(softline!());
|
|
if need_parens {
|
|
parts.push(ss!(")"));
|
|
}
|
|
|
|
if p.args.expand_first_arg {
|
|
Doc::Group(Group::new(parts, false))
|
|
} else {
|
|
Doc::Array(parts)
|
|
}
|
|
}
|
|
|
|
pub(super) fn should_group_function_parameters(func: &Function) -> bool {
|
|
let Some(return_type) = &func.return_type else {
|
|
return false;
|
|
};
|
|
let type_parameters = func.type_parameters.as_ref().map(|x| &x.params);
|
|
|
|
if let Some(type_parameter) = type_parameters {
|
|
if type_parameter.len() > 1 {
|
|
return false;
|
|
}
|
|
|
|
if let Some(type_parameter) = type_parameter.first() {
|
|
if type_parameter.constraint.is_some() || type_parameter.default.is_some() {
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// TODO: need union `willBreak`
|
|
func.params.parameters_count() == 1
|
|
&& (matches!(
|
|
return_type.type_annotation,
|
|
TSType::TSTypeLiteral(_) | TSType::TSMappedType(_)
|
|
))
|
|
}
|