mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
[rust] swc->estree for optional chaining
Handles conversion of optional chains from swc -> estree.
This commit is contained in:
@@ -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<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
impl Serialize for OptionalMemberExpression {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
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<ExpressionOrSpread>,
|
||||
#[serde(rename = "optional")]
|
||||
#[serde(default)]
|
||||
pub is_optional: bool,
|
||||
#[serde(default)]
|
||||
pub loc: Option<SourceLocation>,
|
||||
#[serde(default)]
|
||||
pub range: Option<SourceRange>,
|
||||
}
|
||||
impl Serialize for OptionalCallExpression {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
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<MetaProperty>),
|
||||
NewExpression(Box<NewExpression>),
|
||||
ObjectExpression(Box<ObjectExpression>),
|
||||
OptionalCallExpression(Box<OptionalCallExpression>),
|
||||
OptionalMemberExpression(Box<OptionalMemberExpression>),
|
||||
SequenceExpression(Box<SequenceExpression>),
|
||||
TaggedTemplateExpression(Box<TaggedTemplateExpression>),
|
||||
TemplateLiteral(Box<TemplateLiteral>),
|
||||
@@ -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<OptionalCallExpression> = <Box<
|
||||
OptionalCallExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(Expression::OptionalCallExpression(node))
|
||||
}
|
||||
__ExpressionTag::OptionalMemberExpression => {
|
||||
let node: Box<OptionalMemberExpression> = <Box<
|
||||
OptionalMemberExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(Expression::OptionalMemberExpression(node))
|
||||
}
|
||||
__ExpressionTag::SequenceExpression => {
|
||||
let node: Box<SequenceExpression> = <Box<
|
||||
SequenceExpression,
|
||||
@@ -3000,6 +3077,8 @@ enum __ExpressionOrSuperTag {
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
@@ -3181,6 +3260,30 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSuper {
|
||||
)?;
|
||||
Ok(ExpressionOrSuper::Expression(Expression::ObjectExpression(node)))
|
||||
}
|
||||
__ExpressionOrSuperTag::OptionalCallExpression => {
|
||||
let node: Box<OptionalCallExpression> = <Box<
|
||||
OptionalCallExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(
|
||||
ExpressionOrSuper::Expression(
|
||||
Expression::OptionalCallExpression(node),
|
||||
),
|
||||
)
|
||||
}
|
||||
__ExpressionOrSuperTag::OptionalMemberExpression => {
|
||||
let node: Box<OptionalMemberExpression> = <Box<
|
||||
OptionalMemberExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(
|
||||
ExpressionOrSuper::Expression(
|
||||
Expression::OptionalMemberExpression(node),
|
||||
),
|
||||
)
|
||||
}
|
||||
__ExpressionOrSuperTag::SequenceExpression => {
|
||||
let node: Box<SequenceExpression> = <Box<
|
||||
SequenceExpression,
|
||||
@@ -3279,6 +3382,8 @@ enum __ExpressionOrSpreadTag {
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
@@ -3464,6 +3569,30 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSpread {
|
||||
)?;
|
||||
Ok(ExpressionOrSpread::Expression(Expression::ObjectExpression(node)))
|
||||
}
|
||||
__ExpressionOrSpreadTag::OptionalCallExpression => {
|
||||
let node: Box<OptionalCallExpression> = <Box<
|
||||
OptionalCallExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(
|
||||
ExpressionOrSpread::Expression(
|
||||
Expression::OptionalCallExpression(node),
|
||||
),
|
||||
)
|
||||
}
|
||||
__ExpressionOrSpreadTag::OptionalMemberExpression => {
|
||||
let node: Box<OptionalMemberExpression> = <Box<
|
||||
OptionalMemberExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(
|
||||
ExpressionOrSpread::Expression(
|
||||
Expression::OptionalMemberExpression(node),
|
||||
),
|
||||
)
|
||||
}
|
||||
__ExpressionOrSpreadTag::SequenceExpression => {
|
||||
let node: Box<SequenceExpression> = <Box<
|
||||
SequenceExpression,
|
||||
@@ -3563,6 +3692,8 @@ enum __FunctionBodyTag {
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
@@ -3743,6 +3874,22 @@ impl<'de> serde::Deserialize<'de> for FunctionBody {
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::ObjectExpression(node)))
|
||||
}
|
||||
__FunctionBodyTag::OptionalCallExpression => {
|
||||
let node: Box<OptionalCallExpression> = <Box<
|
||||
OptionalCallExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::OptionalCallExpression(node)))
|
||||
}
|
||||
__FunctionBodyTag::OptionalMemberExpression => {
|
||||
let node: Box<OptionalMemberExpression> = <Box<
|
||||
OptionalMemberExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(FunctionBody::Expression(Expression::OptionalMemberExpression(node)))
|
||||
}
|
||||
__FunctionBodyTag::SequenceExpression => {
|
||||
let node: Box<SequenceExpression> = <Box<
|
||||
SequenceExpression,
|
||||
@@ -3901,6 +4048,8 @@ enum __ForInitTag {
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
@@ -4074,6 +4223,22 @@ impl<'de> serde::Deserialize<'de> for ForInit {
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::ObjectExpression(node)))
|
||||
}
|
||||
__ForInitTag::OptionalCallExpression => {
|
||||
let node: Box<OptionalCallExpression> = <Box<
|
||||
OptionalCallExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::OptionalCallExpression(node)))
|
||||
}
|
||||
__ForInitTag::OptionalMemberExpression => {
|
||||
let node: Box<OptionalMemberExpression> = <Box<
|
||||
OptionalMemberExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(ForInit::Expression(Expression::OptionalMemberExpression(node)))
|
||||
}
|
||||
__ForInitTag::SequenceExpression => {
|
||||
let node: Box<SequenceExpression> = <Box<
|
||||
SequenceExpression,
|
||||
@@ -4372,6 +4537,8 @@ enum __AssignmentTargetTag {
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
@@ -4552,6 +4719,30 @@ impl<'de> serde::Deserialize<'de> for AssignmentTarget {
|
||||
)?;
|
||||
Ok(AssignmentTarget::Expression(Expression::ObjectExpression(node)))
|
||||
}
|
||||
__AssignmentTargetTag::OptionalCallExpression => {
|
||||
let node: Box<OptionalCallExpression> = <Box<
|
||||
OptionalCallExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(
|
||||
AssignmentTarget::Expression(
|
||||
Expression::OptionalCallExpression(node),
|
||||
),
|
||||
)
|
||||
}
|
||||
__AssignmentTargetTag::OptionalMemberExpression => {
|
||||
let node: Box<OptionalMemberExpression> = <Box<
|
||||
OptionalMemberExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(
|
||||
AssignmentTarget::Expression(
|
||||
Expression::OptionalMemberExpression(node),
|
||||
),
|
||||
)
|
||||
}
|
||||
__AssignmentTargetTag::SequenceExpression => {
|
||||
let node: Box<SequenceExpression> = <Box<
|
||||
SequenceExpression,
|
||||
@@ -4758,6 +4949,8 @@ enum __JSXExpressionOrEmptyTag {
|
||||
MetaProperty,
|
||||
NewExpression,
|
||||
ObjectExpression,
|
||||
OptionalCallExpression,
|
||||
OptionalMemberExpression,
|
||||
SequenceExpression,
|
||||
TaggedTemplateExpression,
|
||||
TemplateLiteral,
|
||||
@@ -4947,6 +5140,30 @@ impl<'de> serde::Deserialize<'de> for JSXExpressionOrEmpty {
|
||||
)?;
|
||||
Ok(JSXExpressionOrEmpty::Expression(Expression::ObjectExpression(node)))
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::OptionalCallExpression => {
|
||||
let node: Box<OptionalCallExpression> = <Box<
|
||||
OptionalCallExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(
|
||||
JSXExpressionOrEmpty::Expression(
|
||||
Expression::OptionalCallExpression(node),
|
||||
),
|
||||
)
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::OptionalMemberExpression => {
|
||||
let node: Box<OptionalMemberExpression> = <Box<
|
||||
OptionalMemberExpression,
|
||||
> as Deserialize>::deserialize(
|
||||
serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
|
||||
)?;
|
||||
Ok(
|
||||
JSXExpressionOrEmpty::Expression(
|
||||
Expression::OptionalMemberExpression(node),
|
||||
),
|
||||
)
|
||||
}
|
||||
__JSXExpressionOrEmptyTag::SequenceExpression => {
|
||||
let node: Box<SequenceExpression> = <Box<
|
||||
SequenceExpression,
|
||||
|
||||
@@ -903,6 +903,40 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"OptionalMemberExpression": {
|
||||
"fields": {
|
||||
"object": {
|
||||
"type": "Expression"
|
||||
},
|
||||
"property": {
|
||||
"type": "Identifier"
|
||||
},
|
||||
"is_computed": {
|
||||
"type": "bool",
|
||||
"rename": "computed"
|
||||
},
|
||||
"is_optional": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"rename": "optional"
|
||||
}
|
||||
}
|
||||
},
|
||||
"OptionalCallExpression": {
|
||||
"fields": {
|
||||
"callee": {
|
||||
"type": "ExpressionOrSuper"
|
||||
},
|
||||
"arguments": {
|
||||
"type": "Vec<ExpressionOrSpread>"
|
||||
},
|
||||
"is_optional": {
|
||||
"type": "bool",
|
||||
"optional": true,
|
||||
"rename": "optional"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ImportExpression": {
|
||||
"fields": {
|
||||
"source": {
|
||||
@@ -955,6 +989,8 @@
|
||||
"MetaProperty",
|
||||
"NewExpression",
|
||||
"ObjectExpression",
|
||||
"OptionalCallExpression",
|
||||
"OptionalMemberExpression",
|
||||
"SequenceExpression",
|
||||
"TaggedTemplateExpression",
|
||||
"TemplateLiteral",
|
||||
|
||||
@@ -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<forget_estree::ExpressionOrSpread> {
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user