[rust] swc->estree for optional chaining
Handles conversion of optional chains from swc -> estree.
Joe Savona committed
Jul 25, 2023 at 16:56 UTC
d4a1356ecaef6745145edc256dbf0390e16325e5
3 files changed
+301
-27
compiler/forget/crates/forget_estree/src/generated.rs
+217
@@ -2008,6 +2008,63 @@ impl Serialize for ChainExpression {
2008
}
2009
}
2010
#[derive(Deserialize, Clone, Debug)]
2011
+pub struct OptionalMemberExpression {
2012
+ pub object: Expression,
2013
+ pub property: Identifier,
2014
+ #[serde(rename = "computed")]
2015
+ pub is_computed: bool,
2016
+ #[serde(rename = "optional")]
2017
+ #[serde(default)]
2018
+ pub is_optional: bool,
2019
+ #[serde(default)]
2020
+ pub loc: Option<SourceLocation>,
2021
+ #[serde(default)]
2022
+ pub range: Option<SourceRange>,
2023
+}
2024
+impl Serialize for OptionalMemberExpression {
2025
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2026
+ where
2027
+ S: Serializer,
2028
+ {
2029
+ let mut state = serializer.serialize_map(None)?;
2030
+ state.serialize_entry("type", "OptionalMemberExpression")?;
2031
+ state.serialize_entry("object", &self.object)?;
2032
+ state.serialize_entry("property", &self.property)?;
2033
+ state.serialize_entry("computed", &self.is_computed)?;
2034
+ state.serialize_entry("optional", &self.is_optional)?;
2035
+ state.serialize_entry("loc", &self.loc)?;
2036
+ state.serialize_entry("range", &self.range)?;
2037
+ state.end()
2038
+ }
2039
+}
2040
+#[derive(Deserialize, Clone, Debug)]
2041
+pub struct OptionalCallExpression {
2042
+ pub callee: ExpressionOrSuper,
2043
+ pub arguments: Vec<ExpressionOrSpread>,
2044
+ #[serde(rename = "optional")]
2045
+ #[serde(default)]
2046
+ pub is_optional: bool,
2047
+ #[serde(default)]
2048
+ pub loc: Option<SourceLocation>,
2049
+ #[serde(default)]
2050
+ pub range: Option<SourceRange>,
2051
+}
2052
+impl Serialize for OptionalCallExpression {
2053
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
2054
+ where
2055
+ S: Serializer,
2056
+ {
2057
+ let mut state = serializer.serialize_map(None)?;
2058
+ state.serialize_entry("type", "OptionalCallExpression")?;
2059
+ state.serialize_entry("callee", &self.callee)?;
2060
+ state.serialize_entry("arguments", &self.arguments)?;
2061
+ state.serialize_entry("optional", &self.is_optional)?;
2062
+ state.serialize_entry("loc", &self.loc)?;
2063
+ state.serialize_entry("range", &self.range)?;
2064
+ state.end()
2065
+ }
2066
+}
2067
+#[derive(Deserialize, Clone, Debug)]
2068
pub struct ImportExpression {
2069
pub source: Expression,
2070
#[serde(default)]
@@ -2282,6 +2339,8 @@ pub enum Expression {
2339
MetaProperty(Box<MetaProperty>),
2340
NewExpression(Box<NewExpression>),
2341
ObjectExpression(Box<ObjectExpression>),
2342
+ OptionalCallExpression(Box<OptionalCallExpression>),
2343
+ OptionalMemberExpression(Box<OptionalMemberExpression>),
2344
SequenceExpression(Box<SequenceExpression>),
2345
TaggedTemplateExpression(Box<TaggedTemplateExpression>),
2346
TemplateLiteral(Box<TemplateLiteral>),
@@ -2311,6 +2370,8 @@ enum __ExpressionTag {
2370
MetaProperty,
2371
NewExpression,
2372
ObjectExpression,
2373
+ OptionalCallExpression,
2374
+ OptionalMemberExpression,
2375
SequenceExpression,
2376
TaggedTemplateExpression,
2377
TemplateLiteral,
@@ -2483,6 +2544,22 @@ impl<'de> serde::Deserialize<'de> for Expression {
2544
)?;
2545
Ok(Expression::ObjectExpression(node))
2546
}
2547
+ __ExpressionTag::OptionalCallExpression => {
2548
+ let node: Box<OptionalCallExpression> = <Box<
2549
+ OptionalCallExpression,
2550
+ > as Deserialize>::deserialize(
2551
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
2552
+ )?;
2553
+ Ok(Expression::OptionalCallExpression(node))
2554
+ }
2555
+ __ExpressionTag::OptionalMemberExpression => {
2556
+ let node: Box<OptionalMemberExpression> = <Box<
2557
+ OptionalMemberExpression,
2558
+ > as Deserialize>::deserialize(
2559
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
2560
+ )?;
2561
+ Ok(Expression::OptionalMemberExpression(node))
2562
+ }
2563
__ExpressionTag::SequenceExpression => {
2564
let node: Box<SequenceExpression> = <Box<
2565
SequenceExpression,
@@ -3000,6 +3077,8 @@ enum __ExpressionOrSuperTag {
3077
MetaProperty,
3078
NewExpression,
3079
ObjectExpression,
3080
+ OptionalCallExpression,
3081
+ OptionalMemberExpression,
3082
SequenceExpression,
3083
TaggedTemplateExpression,
3084
TemplateLiteral,
@@ -3181,6 +3260,30 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSuper {
3260
)?;
3261
Ok(ExpressionOrSuper::Expression(Expression::ObjectExpression(node)))
3262
}
3263
+ __ExpressionOrSuperTag::OptionalCallExpression => {
3264
+ let node: Box<OptionalCallExpression> = <Box<
3265
+ OptionalCallExpression,
3266
+ > as Deserialize>::deserialize(
3267
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
3268
+ )?;
3269
+ Ok(
3270
+ ExpressionOrSuper::Expression(
3271
+ Expression::OptionalCallExpression(node),
3272
+ ),
3273
+ )
3274
+ }
3275
+ __ExpressionOrSuperTag::OptionalMemberExpression => {
3276
+ let node: Box<OptionalMemberExpression> = <Box<
3277
+ OptionalMemberExpression,
3278
+ > as Deserialize>::deserialize(
3279
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
3280
+ )?;
3281
+ Ok(
3282
+ ExpressionOrSuper::Expression(
3283
+ Expression::OptionalMemberExpression(node),
3284
+ ),
3285
+ )
3286
+ }
3287
__ExpressionOrSuperTag::SequenceExpression => {
3288
let node: Box<SequenceExpression> = <Box<
3289
SequenceExpression,
@@ -3279,6 +3382,8 @@ enum __ExpressionOrSpreadTag {
3382
MetaProperty,
3383
NewExpression,
3384
ObjectExpression,
3385
+ OptionalCallExpression,
3386
+ OptionalMemberExpression,
3387
SequenceExpression,
3388
TaggedTemplateExpression,
3389
TemplateLiteral,
@@ -3464,6 +3569,30 @@ impl<'de> serde::Deserialize<'de> for ExpressionOrSpread {
3569
)?;
3570
Ok(ExpressionOrSpread::Expression(Expression::ObjectExpression(node)))
3571
}
3572
+ __ExpressionOrSpreadTag::OptionalCallExpression => {
3573
+ let node: Box<OptionalCallExpression> = <Box<
3574
+ OptionalCallExpression,
3575
+ > as Deserialize>::deserialize(
3576
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
3577
+ )?;
3578
+ Ok(
3579
+ ExpressionOrSpread::Expression(
3580
+ Expression::OptionalCallExpression(node),
3581
+ ),
3582
+ )
3583
+ }
3584
+ __ExpressionOrSpreadTag::OptionalMemberExpression => {
3585
+ let node: Box<OptionalMemberExpression> = <Box<
3586
+ OptionalMemberExpression,
3587
+ > as Deserialize>::deserialize(
3588
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
3589
+ )?;
3590
+ Ok(
3591
+ ExpressionOrSpread::Expression(
3592
+ Expression::OptionalMemberExpression(node),
3593
+ ),
3594
+ )
3595
+ }
3596
__ExpressionOrSpreadTag::SequenceExpression => {
3597
let node: Box<SequenceExpression> = <Box<
3598
SequenceExpression,
@@ -3563,6 +3692,8 @@ enum __FunctionBodyTag {
3692
MetaProperty,
3693
NewExpression,
3694
ObjectExpression,
3695
+ OptionalCallExpression,
3696
+ OptionalMemberExpression,
3697
SequenceExpression,
3698
TaggedTemplateExpression,
3699
TemplateLiteral,
@@ -3743,6 +3874,22 @@ impl<'de> serde::Deserialize<'de> for FunctionBody {
3874
)?;
3875
Ok(FunctionBody::Expression(Expression::ObjectExpression(node)))
3876
}
3877
+ __FunctionBodyTag::OptionalCallExpression => {
3878
+ let node: Box<OptionalCallExpression> = <Box<
3879
+ OptionalCallExpression,
3880
+ > as Deserialize>::deserialize(
3881
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
3882
+ )?;
3883
+ Ok(FunctionBody::Expression(Expression::OptionalCallExpression(node)))
3884
+ }
3885
+ __FunctionBodyTag::OptionalMemberExpression => {
3886
+ let node: Box<OptionalMemberExpression> = <Box<
3887
+ OptionalMemberExpression,
3888
+ > as Deserialize>::deserialize(
3889
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
3890
+ )?;
3891
+ Ok(FunctionBody::Expression(Expression::OptionalMemberExpression(node)))
3892
+ }
3893
__FunctionBodyTag::SequenceExpression => {
3894
let node: Box<SequenceExpression> = <Box<
3895
SequenceExpression,
@@ -3901,6 +4048,8 @@ enum __ForInitTag {
4048
MetaProperty,
4049
NewExpression,
4050
ObjectExpression,
4051
+ OptionalCallExpression,
4052
+ OptionalMemberExpression,
4053
SequenceExpression,
4054
TaggedTemplateExpression,
4055
TemplateLiteral,
@@ -4074,6 +4223,22 @@ impl<'de> serde::Deserialize<'de> for ForInit {
4223
)?;
4224
Ok(ForInit::Expression(Expression::ObjectExpression(node)))
4225
}
4226
+ __ForInitTag::OptionalCallExpression => {
4227
+ let node: Box<OptionalCallExpression> = <Box<
4228
+ OptionalCallExpression,
4229
+ > as Deserialize>::deserialize(
4230
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
4231
+ )?;
4232
+ Ok(ForInit::Expression(Expression::OptionalCallExpression(node)))
4233
+ }
4234
+ __ForInitTag::OptionalMemberExpression => {
4235
+ let node: Box<OptionalMemberExpression> = <Box<
4236
+ OptionalMemberExpression,
4237
+ > as Deserialize>::deserialize(
4238
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
4239
+ )?;
4240
+ Ok(ForInit::Expression(Expression::OptionalMemberExpression(node)))
4241
+ }
4242
__ForInitTag::SequenceExpression => {
4243
let node: Box<SequenceExpression> = <Box<
4244
SequenceExpression,
@@ -4372,6 +4537,8 @@ enum __AssignmentTargetTag {
4537
MetaProperty,
4538
NewExpression,
4539
ObjectExpression,
4540
+ OptionalCallExpression,
4541
+ OptionalMemberExpression,
4542
SequenceExpression,
4543
TaggedTemplateExpression,
4544
TemplateLiteral,
@@ -4552,6 +4719,30 @@ impl<'de> serde::Deserialize<'de> for AssignmentTarget {
4719
)?;
4720
Ok(AssignmentTarget::Expression(Expression::ObjectExpression(node)))
4721
}
4722
+ __AssignmentTargetTag::OptionalCallExpression => {
4723
+ let node: Box<OptionalCallExpression> = <Box<
4724
+ OptionalCallExpression,
4725
+ > as Deserialize>::deserialize(
4726
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
4727
+ )?;
4728
+ Ok(
4729
+ AssignmentTarget::Expression(
4730
+ Expression::OptionalCallExpression(node),
4731
+ ),
4732
+ )
4733
+ }
4734
+ __AssignmentTargetTag::OptionalMemberExpression => {
4735
+ let node: Box<OptionalMemberExpression> = <Box<
4736
+ OptionalMemberExpression,
4737
+ > as Deserialize>::deserialize(
4738
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
4739
+ )?;
4740
+ Ok(
4741
+ AssignmentTarget::Expression(
4742
+ Expression::OptionalMemberExpression(node),
4743
+ ),
4744
+ )
4745
+ }
4746
__AssignmentTargetTag::SequenceExpression => {
4747
let node: Box<SequenceExpression> = <Box<
4748
SequenceExpression,
@@ -4758,6 +4949,8 @@ enum __JSXExpressionOrEmptyTag {
4949
MetaProperty,
4950
NewExpression,
4951
ObjectExpression,
4952
+ OptionalCallExpression,
4953
+ OptionalMemberExpression,
4954
SequenceExpression,
4955
TaggedTemplateExpression,
4956
TemplateLiteral,
@@ -4947,6 +5140,30 @@ impl<'de> serde::Deserialize<'de> for JSXExpressionOrEmpty {
5140
)?;
5141
Ok(JSXExpressionOrEmpty::Expression(Expression::ObjectExpression(node)))
5142
}
5143
+ __JSXExpressionOrEmptyTag::OptionalCallExpression => {
5144
+ let node: Box<OptionalCallExpression> = <Box<
5145
+ OptionalCallExpression,
5146
+ > as Deserialize>::deserialize(
5147
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
5148
+ )?;
5149
+ Ok(
5150
+ JSXExpressionOrEmpty::Expression(
5151
+ Expression::OptionalCallExpression(node),
5152
+ ),
5153
+ )
5154
+ }
5155
+ __JSXExpressionOrEmptyTag::OptionalMemberExpression => {
5156
+ let node: Box<OptionalMemberExpression> = <Box<
5157
+ OptionalMemberExpression,
5158
+ > as Deserialize>::deserialize(
5159
+ serde::__private::de::ContentDeserializer::<D::Error>::new(tagged.1),
5160
+ )?;
5161
+ Ok(
5162
+ JSXExpressionOrEmpty::Expression(
5163
+ Expression::OptionalMemberExpression(node),
5164
+ ),
5165
+ )
5166
+ }
5167
__JSXExpressionOrEmptyTag::SequenceExpression => {
5168
let node: Box<SequenceExpression> = <Box<
5169
SequenceExpression,
compiler/forget/crates/forget_estree_codegen/src/ecmascript.json
+36
@@ -903,6 +903,40 @@
903
}
904
}
905
},
906
+ "OptionalMemberExpression": {
907
+ "fields": {
908
+ "object": {
909
+ "type": "Expression"
910
+ },
911
+ "property": {
912
+ "type": "Identifier"
913
+ },
914
+ "is_computed": {
915
+ "type": "bool",
916
+ "rename": "computed"
917
+ },
918
+ "is_optional": {
919
+ "type": "bool",
920
+ "optional": true,
921
+ "rename": "optional"
922
+ }
923
+ }
924
+ },
925
+ "OptionalCallExpression": {
926
+ "fields": {
927
+ "callee": {
928
+ "type": "ExpressionOrSuper"
929
+ },
930
+ "arguments": {
931
+ "type": "Vec<ExpressionOrSpread>"
932
+ },
933
+ "is_optional": {
934
+ "type": "bool",
935
+ "optional": true,
936
+ "rename": "optional"
937
+ }
938
+ }
939
+ },
940
"ImportExpression": {
941
"fields": {
942
"source": {
@@ -955,6 +989,8 @@
989
"MetaProperty",
990
"NewExpression",
991
"ObjectExpression",
992
+ "OptionalCallExpression",
993
+ "OptionalMemberExpression",
994
"SequenceExpression",
995
"TaggedTemplateExpression",
996
"TemplateLiteral",
compiler/forget/crates/forget_estree_swc/src/lib.rs
+48
-27
@@ -8,9 +8,9 @@ use swc_core::common::errors::Handler;
8
use swc_core::common::source_map::Pos;
9
use swc_core::common::{FileName, FilePathMapping, Mark, SourceMap, Span, SyntaxContext, GLOBALS};
10
use swc_core::ecma::ast::{
11
- AssignOp, BinaryOp, BlockStmt, BlockStmtOrExpr, Callee, Decl, EsVersion, Expr, ExprOrSpread,
12
- Function, Ident, Lit, MemberExpr, MemberProp, ModuleItem, Pat, PatOrExpr, Program, Stmt,
13
- UnaryOp, VarDecl, VarDeclKind, VarDeclOrExpr,
11
+ AssignOp, BinaryOp, BlockStmt, BlockStmtOrExpr, CallExpr, Callee, Decl, EsVersion, Expr,
12
+ ExprOrSpread, Function, Ident, Lit, MemberExpr, MemberProp, ModuleItem, OptChainBase, Pat,
13
+ PatOrExpr, Program, Stmt, UnaryOp, VarDecl, VarDeclKind, VarDeclOrExpr,
14
};
15
use swc_core::ecma::parser::Syntax;
16
use swc_core::ecma::transforms::base::resolver;
@@ -334,27 +334,7 @@ fn convert_expression(cx: &Context, expr: &Expr) -> forget_estree::Expression {
334
}
335
_ => todo!(),
336
},
337
- arguments: expr
338
- .args
339
- .iter()
340
- .map(|arg| match arg {
341
- ExprOrSpread {
342
- spread: Some(spread),
343
- expr,
344
- } => forget_estree::ExpressionOrSpread::SpreadElement(Box::new(
345
- forget_estree::SpreadElement {
346
- argument: convert_expression(cx, expr),
347
- loc: None,
348
- range: convert_span(&spread),
349
- },
350
- )),
351
- ExprOrSpread { spread: None, expr } => {
352
- forget_estree::ExpressionOrSpread::Expression(convert_expression(
353
- cx, expr,
354
- ))
355
- }
356
- })
357
- .collect(),
337
+ arguments: convert_arguments(cx, &expr.args),
338
is_optional: false,
339
loc: None,
340
range: convert_span(&expr.span),
@@ -471,10 +451,53 @@ fn convert_expression(cx: &Context, expr: &Expr) -> forget_estree::Expression {
451
range: convert_span(&expr.span),
452
},
453
)),
454
+ Expr::OptChain(expr) => match expr.base.as_ref() {
455
+ OptChainBase::Call(base) => forget_estree::Expression::OptionalCallExpression(
456
+ Box::new(forget_estree::OptionalCallExpression {
457
+ callee: forget_estree::ExpressionOrSuper::Expression(convert_expression(
458
+ cx,
459
+ &base.callee,
460
+ )),
461
+ arguments: convert_arguments(cx, &base.args),
462
+ is_optional: expr.optional,
463
+ loc: None,
464
+ range: convert_span(&expr.span),
465
+ }),
466
+ ),
467
+ OptChainBase::Member(base) => {
468
+ let mut member = convert_member_expression(cx, base);
469
+ member.is_optional = expr.optional;
470
+ forget_estree::Expression::MemberExpression(Box::new(member))
471
+ }
472
+ },
473
_ => todo!("translate expression {:#?}", expr),
474
}
475
}
476
477
+fn convert_arguments(
478
+ cx: &Context,
479
+ arguments: &[ExprOrSpread],
480
+) -> Vec<forget_estree::ExpressionOrSpread> {
481
+ arguments
482
+ .iter()
483
+ .map(|arg| match arg {
484
+ ExprOrSpread {
485
+ spread: Some(spread),
486
+ expr,
487
+ } => forget_estree::ExpressionOrSpread::SpreadElement(Box::new(
488
+ forget_estree::SpreadElement {
489
+ argument: convert_expression(cx, expr),
490
+ loc: None,
491
+ range: convert_span(&spread),
492
+ },
493
+ )),
494
+ ExprOrSpread { spread: None, expr } => {
495
+ forget_estree::ExpressionOrSpread::Expression(convert_expression(cx, expr))
496
+ }
497
+ })
498
+ .collect()
499
+}
500
+
501
fn convert_assignment_target(cx: &Context, target: &PatOrExpr) -> forget_estree::AssignmentTarget {
502
match target {
503
PatOrExpr::Pat(target) => {
@@ -554,7 +577,7 @@ fn convert_binary_operator(op: BinaryOp) -> Operator {
577
BinaryOp::Div => Operator::Binary(forget_estree::BinaryOperator::Divide),
578
BinaryOp::EqEq => Operator::Binary(forget_estree::BinaryOperator::Equals),
579
BinaryOp::EqEqEq => Operator::Binary(forget_estree::BinaryOperator::StrictEquals),
557
- // BinaryOp::Exp => Operator::Binary(forget_estree::BinaryOperator::AsteriskAsterisk),
580
+ BinaryOp::Exp => Operator::Binary(forget_estree::BinaryOperator::Exponent),
581
BinaryOp::Gt => Operator::Binary(forget_estree::BinaryOperator::GreaterThan),
582
BinaryOp::GtEq => Operator::Binary(forget_estree::BinaryOperator::GreaterThanOrEqual),
583
BinaryOp::In => Operator::Binary(forget_estree::BinaryOperator::In),
@@ -577,8 +600,6 @@ fn convert_binary_operator(op: BinaryOp) -> Operator {
600
BinaryOp::NullishCoalescing => {
601
Operator::Logical(forget_estree::LogicalOperator::NullCoalescing)
602
}
580
-
581
- _ => panic!("Unsupported binary operator `{}`", op),
603
}
604
}
605