diff --git a/compiler/forget/crates/forget_estree/src/generated.rs b/compiler/forget/crates/forget_estree/src/generated.rs index 4f60f49438..b5b2e8fa97 100644 --- a/compiler/forget/crates/forget_estree/src/generated.rs +++ b/compiler/forget/crates/forget_estree/src/generated.rs @@ -2008,6 +2008,63 @@ impl Serialize for ChainExpression { } } #[derive(Deserialize, Clone, Debug)] +pub struct OptionalMemberExpression { + pub object: Expression, + pub property: Identifier, + #[serde(rename = "computed")] + pub is_computed: bool, + #[serde(rename = "optional")] + #[serde(default)] + pub is_optional: bool, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for OptionalMemberExpression { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "OptionalMemberExpression")?; + state.serialize_entry("object", &self.object)?; + state.serialize_entry("property", &self.property)?; + state.serialize_entry("computed", &self.is_computed)?; + state.serialize_entry("optional", &self.is_optional)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] +pub struct OptionalCallExpression { + pub callee: ExpressionOrSuper, + pub arguments: Vec, + #[serde(rename = "optional")] + #[serde(default)] + pub is_optional: bool, + #[serde(default)] + pub loc: Option, + #[serde(default)] + pub range: Option, +} +impl Serialize for OptionalCallExpression { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let mut state = serializer.serialize_map(None)?; + state.serialize_entry("type", "OptionalCallExpression")?; + state.serialize_entry("callee", &self.callee)?; + state.serialize_entry("arguments", &self.arguments)?; + state.serialize_entry("optional", &self.is_optional)?; + state.serialize_entry("loc", &self.loc)?; + state.serialize_entry("range", &self.range)?; + state.end() + } +} +#[derive(Deserialize, Clone, Debug)] pub struct ImportExpression { pub source: Expression, #[serde(default)] @@ -2282,6 +2339,8 @@ pub enum Expression { MetaProperty(Box), NewExpression(Box), ObjectExpression(Box), + OptionalCallExpression(Box), + OptionalMemberExpression(Box), SequenceExpression(Box), TaggedTemplateExpression(Box), TemplateLiteral(Box), @@ -2311,6 +2370,8 @@ enum __ExpressionTag { MetaProperty, NewExpression, ObjectExpression, + OptionalCallExpression, + OptionalMemberExpression, SequenceExpression, TaggedTemplateExpression, TemplateLiteral, @@ -2483,6 +2544,22 @@ impl<'de> serde::Deserialize<'de> for Expression { )?; Ok(Expression::ObjectExpression(node)) } + __ExpressionTag::OptionalCallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Expression::OptionalCallExpression(node)) + } + __ExpressionTag::OptionalMemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(Expression::OptionalMemberExpression(node)) + } __ExpressionTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for ExpressionOrSuper { )?; Ok(ExpressionOrSuper::Expression(Expression::ObjectExpression(node))) } + __ExpressionOrSuperTag::OptionalCallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrSuper::Expression( + Expression::OptionalCallExpression(node), + ), + ) + } + __ExpressionOrSuperTag::OptionalMemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrSuper::Expression( + Expression::OptionalMemberExpression(node), + ), + ) + } __ExpressionOrSuperTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for ExpressionOrSpread { )?; Ok(ExpressionOrSpread::Expression(Expression::ObjectExpression(node))) } + __ExpressionOrSpreadTag::OptionalCallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrSpread::Expression( + Expression::OptionalCallExpression(node), + ), + ) + } + __ExpressionOrSpreadTag::OptionalMemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + ExpressionOrSpread::Expression( + Expression::OptionalMemberExpression(node), + ), + ) + } __ExpressionOrSpreadTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for FunctionBody { )?; Ok(FunctionBody::Expression(Expression::ObjectExpression(node))) } + __FunctionBodyTag::OptionalCallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(FunctionBody::Expression(Expression::OptionalCallExpression(node))) + } + __FunctionBodyTag::OptionalMemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(FunctionBody::Expression(Expression::OptionalMemberExpression(node))) + } __FunctionBodyTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for ForInit { )?; Ok(ForInit::Expression(Expression::ObjectExpression(node))) } + __ForInitTag::OptionalCallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInit::Expression(Expression::OptionalCallExpression(node))) + } + __ForInitTag::OptionalMemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok(ForInit::Expression(Expression::OptionalMemberExpression(node))) + } __ForInitTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for AssignmentTarget { )?; Ok(AssignmentTarget::Expression(Expression::ObjectExpression(node))) } + __AssignmentTargetTag::OptionalCallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + AssignmentTarget::Expression( + Expression::OptionalCallExpression(node), + ), + ) + } + __AssignmentTargetTag::OptionalMemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + AssignmentTarget::Expression( + Expression::OptionalMemberExpression(node), + ), + ) + } __AssignmentTargetTag::SequenceExpression => { let node: Box = serde::Deserialize<'de> for JSXExpressionOrEmpty { )?; Ok(JSXExpressionOrEmpty::Expression(Expression::ObjectExpression(node))) } + __JSXExpressionOrEmptyTag::OptionalCallExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + JSXExpressionOrEmpty::Expression( + Expression::OptionalCallExpression(node), + ), + ) + } + __JSXExpressionOrEmptyTag::OptionalMemberExpression => { + let node: Box = as Deserialize>::deserialize( + serde::__private::de::ContentDeserializer::::new(tagged.1), + )?; + Ok( + JSXExpressionOrEmpty::Expression( + Expression::OptionalMemberExpression(node), + ), + ) + } __JSXExpressionOrEmptyTag::SequenceExpression => { let node: Box = " + }, + "is_optional": { + "type": "bool", + "optional": true, + "rename": "optional" + } + } + }, "ImportExpression": { "fields": { "source": { @@ -955,6 +989,8 @@ "MetaProperty", "NewExpression", "ObjectExpression", + "OptionalCallExpression", + "OptionalMemberExpression", "SequenceExpression", "TaggedTemplateExpression", "TemplateLiteral", diff --git a/compiler/forget/crates/forget_estree_swc/src/lib.rs b/compiler/forget/crates/forget_estree_swc/src/lib.rs index 8017eb6f7d..8bd1e5a191 100644 --- a/compiler/forget/crates/forget_estree_swc/src/lib.rs +++ b/compiler/forget/crates/forget_estree_swc/src/lib.rs @@ -8,9 +8,9 @@ use swc_core::common::errors::Handler; use swc_core::common::source_map::Pos; use swc_core::common::{FileName, FilePathMapping, Mark, SourceMap, Span, SyntaxContext, GLOBALS}; use swc_core::ecma::ast::{ - AssignOp, BinaryOp, BlockStmt, BlockStmtOrExpr, Callee, Decl, EsVersion, Expr, ExprOrSpread, - Function, Ident, Lit, MemberExpr, MemberProp, ModuleItem, Pat, PatOrExpr, Program, Stmt, - UnaryOp, VarDecl, VarDeclKind, VarDeclOrExpr, + AssignOp, BinaryOp, BlockStmt, BlockStmtOrExpr, CallExpr, Callee, Decl, EsVersion, Expr, + ExprOrSpread, Function, Ident, Lit, MemberExpr, MemberProp, ModuleItem, OptChainBase, Pat, + PatOrExpr, Program, Stmt, UnaryOp, VarDecl, VarDeclKind, VarDeclOrExpr, }; use swc_core::ecma::parser::Syntax; use swc_core::ecma::transforms::base::resolver; @@ -334,27 +334,7 @@ fn convert_expression(cx: &Context, expr: &Expr) -> forget_estree::Expression { } _ => todo!(), }, - arguments: expr - .args - .iter() - .map(|arg| match arg { - ExprOrSpread { - spread: Some(spread), - expr, - } => forget_estree::ExpressionOrSpread::SpreadElement(Box::new( - forget_estree::SpreadElement { - argument: convert_expression(cx, expr), - loc: None, - range: convert_span(&spread), - }, - )), - ExprOrSpread { spread: None, expr } => { - forget_estree::ExpressionOrSpread::Expression(convert_expression( - cx, expr, - )) - } - }) - .collect(), + arguments: convert_arguments(cx, &expr.args), is_optional: false, loc: None, range: convert_span(&expr.span), @@ -471,10 +451,53 @@ fn convert_expression(cx: &Context, expr: &Expr) -> forget_estree::Expression { range: convert_span(&expr.span), }, )), + Expr::OptChain(expr) => match expr.base.as_ref() { + OptChainBase::Call(base) => forget_estree::Expression::OptionalCallExpression( + Box::new(forget_estree::OptionalCallExpression { + callee: forget_estree::ExpressionOrSuper::Expression(convert_expression( + cx, + &base.callee, + )), + arguments: convert_arguments(cx, &base.args), + is_optional: expr.optional, + loc: None, + range: convert_span(&expr.span), + }), + ), + OptChainBase::Member(base) => { + let mut member = convert_member_expression(cx, base); + member.is_optional = expr.optional; + forget_estree::Expression::MemberExpression(Box::new(member)) + } + }, _ => todo!("translate expression {:#?}", expr), } } +fn convert_arguments( + cx: &Context, + arguments: &[ExprOrSpread], +) -> Vec { + arguments + .iter() + .map(|arg| match arg { + ExprOrSpread { + spread: Some(spread), + expr, + } => forget_estree::ExpressionOrSpread::SpreadElement(Box::new( + forget_estree::SpreadElement { + argument: convert_expression(cx, expr), + loc: None, + range: convert_span(&spread), + }, + )), + ExprOrSpread { spread: None, expr } => { + forget_estree::ExpressionOrSpread::Expression(convert_expression(cx, expr)) + } + }) + .collect() +} + fn convert_assignment_target(cx: &Context, target: &PatOrExpr) -> forget_estree::AssignmentTarget { match target { PatOrExpr::Pat(target) => { @@ -554,7 +577,7 @@ fn convert_binary_operator(op: BinaryOp) -> Operator { BinaryOp::Div => Operator::Binary(forget_estree::BinaryOperator::Divide), BinaryOp::EqEq => Operator::Binary(forget_estree::BinaryOperator::Equals), BinaryOp::EqEqEq => Operator::Binary(forget_estree::BinaryOperator::StrictEquals), - // BinaryOp::Exp => Operator::Binary(forget_estree::BinaryOperator::AsteriskAsterisk), + BinaryOp::Exp => Operator::Binary(forget_estree::BinaryOperator::Exponent), BinaryOp::Gt => Operator::Binary(forget_estree::BinaryOperator::GreaterThan), BinaryOp::GtEq => Operator::Binary(forget_estree::BinaryOperator::GreaterThanOrEqual), BinaryOp::In => Operator::Binary(forget_estree::BinaryOperator::In), @@ -577,8 +600,6 @@ fn convert_binary_operator(op: BinaryOp) -> Operator { BinaryOp::NullishCoalescing => { Operator::Logical(forget_estree::LogicalOperator::NullCoalescing) } - - _ => panic!("Unsupported binary operator `{}`", op), } }