oxc/crates/oxc_prettier/src/format/call_expression.rs

102 lines
3 KiB
Rust

use oxc_allocator::Vec;
use oxc_ast::ast::*;
use oxc_span::{GetSpan, Span};
use super::call_arguments::print_call_arguments;
use crate::{
doc::{Doc, DocBuilder, Group},
ss, Format, Prettier,
};
pub(super) enum CallExpressionLike<'a, 'b> {
CallExpression(&'b CallExpression<'a>),
NewExpression(&'b NewExpression<'a>),
}
impl<'a, 'b> CallExpressionLike<'a, 'b> {
pub fn is_new(&self) -> bool {
matches!(self, CallExpressionLike::NewExpression(_))
}
pub fn callee(&self) -> &Expression<'a> {
match self {
CallExpressionLike::CallExpression(call) => &call.callee,
CallExpressionLike::NewExpression(new) => &new.callee,
}
}
pub fn optional(&self) -> bool {
match self {
CallExpressionLike::CallExpression(call) => call.optional,
CallExpressionLike::NewExpression(new) => false,
}
}
pub fn arguments(&self) -> &Vec<'a, Argument<'a>> {
match self {
CallExpressionLike::CallExpression(call) => &call.arguments,
CallExpressionLike::NewExpression(new) => &new.arguments,
}
}
}
impl GetSpan for CallExpressionLike<'_, '_> {
fn span(&self) -> Span {
match self {
CallExpressionLike::CallExpression(call) => call.span,
CallExpressionLike::NewExpression(new) => new.span,
}
}
}
pub(super) fn print_call_expression<'a>(
p: &mut Prettier<'a>,
expression: &CallExpressionLike<'a, '_>,
) -> Doc<'a> {
let mut parts = p.vec();
if expression.is_new() {
parts.push(ss!("new "));
};
parts.push(expression.callee().format(p));
if expression.optional() {
parts.push(ss!("?."));
}
parts.push(print_call_arguments(p, expression));
Doc::Group(Group::new(parts))
}
/// https://github.com/prettier/prettier/blob/7aecca5d6473d73f562ca3af874831315f8f2581/src/language-js/print/call-expression.js#L93-L116
pub fn is_commons_js_or_amd_call<'a>(
callee: &Expression<'a>,
arguments: &Vec<'a, Argument<'a>>,
) -> bool {
if let Expression::Identifier(callee) = callee {
if callee.name == "require" {
return arguments.len() == 1
&& matches!(arguments[0], Argument::Expression(Expression::StringLiteral(_)))
|| arguments.len() > 1;
}
if callee.name == "define" {
// TODO: the parent node is ExpressionStatement
return arguments.len() == 1
|| (arguments.len() == 2
&& matches!(
arguments[1],
Argument::Expression(Expression::ArrayExpression(_))
))
|| (arguments.len() == 3
&& matches!(arguments[0], Argument::Expression(Expression::StringLiteral(_)))
&& matches!(
arguments[1],
Argument::Expression(Expression::ArrayExpression(_))
));
}
}
false
}