diff --git a/crates/swc_ecma_ast/src/expr.rs b/crates/swc_ecma_ast/src/expr.rs index 428691c2a682..ce17cd8e5343 100644 --- a/crates/swc_ecma_ast/src/expr.rs +++ b/crates/swc_ecma_ast/src/expr.rs @@ -170,6 +170,9 @@ pub enum Expr { Invalid(Invalid), } +#[cfg(target_pointer_width = "64")] +assert_eq_size!(Expr, [u8; 80]); + impl Expr { /// Normalize parenthesized expressions. /// @@ -862,7 +865,8 @@ pub struct ArrowExpr { pub params: Vec, - pub body: BlockStmtOrExpr, + /// This is boxed to reduce the type size of [Expr]. + pub body: Box, #[serde(default, rename = "async")] pub is_async: bool, @@ -978,8 +982,9 @@ pub struct TaggedTpl { #[serde(default, rename = "typeParameters")] pub type_params: Option>, + /// This is boxed to reduce the type size of [Expr]. #[serde(rename = "template")] - pub tpl: Tpl, + pub tpl: Box, } impl Take for TaggedTpl { @@ -1366,7 +1371,8 @@ impl Take for PatOrExpr { pub struct OptChainExpr { pub span: Span, pub question_dot_token: Span, - pub base: OptChainBase, + /// This is boxed to reduce the type size of [Expr]. + pub base: Box, } #[ast_node] diff --git a/crates/swc_ecma_ast/src/macros.rs b/crates/swc_ecma_ast/src/macros.rs index fe40e9dbb399..e356bceb466f 100644 --- a/crates/swc_ecma_ast/src/macros.rs +++ b/crates/swc_ecma_ast/src/macros.rs @@ -234,3 +234,12 @@ macro_rules! bridge_decl_from { bridge_from!(crate::ModuleItem, crate::Stmt, $src); }; } + +/// Copied from static_assertions +macro_rules! assert_eq_size { + ($x:ty, $($xs:ty),+ $(,)?) => { + const _: fn() = || { + $(let _ = std::mem::transmute::<$x, $xs>;)+ + }; + }; +} diff --git a/crates/swc_ecma_ast/src/stmt.rs b/crates/swc_ecma_ast/src/stmt.rs index f6bbcc6b629e..99c016874f91 100644 --- a/crates/swc_ecma_ast/src/stmt.rs +++ b/crates/swc_ecma_ast/src/stmt.rs @@ -104,6 +104,9 @@ pub enum Stmt { Expr(ExprStmt), } +#[cfg(target_pointer_width = "64")] +assert_eq_size!(Stmt, [u8; 64]); + // Implement Clone without inline to avoid multiple copies of the // implementation. impl Clone for Stmt { diff --git a/crates/swc_ecma_codegen/src/lib.rs b/crates/swc_ecma_codegen/src/lib.rs index 60bf1935ed95..326e6819326e 100644 --- a/crates/swc_ecma_codegen/src/lib.rs +++ b/crates/swc_ecma_codegen/src/lib.rs @@ -813,7 +813,7 @@ where fn emit_opt_chain(&mut self, n: &OptChainExpr) -> Result { self.emit_leading_comments_of_span(n.span(), false)?; - match n.base { + match &*n.base { OptChainBase::Member(ref e) => { if let Expr::New(new) = &*e.obj { self.emit_new(new, false)?; diff --git a/crates/swc_ecma_codegen/src/util.rs b/crates/swc_ecma_codegen/src/util.rs index c052b7460c74..e765f8a80d6a 100644 --- a/crates/swc_ecma_codegen/src/util.rs +++ b/crates/swc_ecma_codegen/src/util.rs @@ -144,15 +144,10 @@ impl StartsWithAlphaNum for Expr { | Expr::TsInstantiation(TsInstantiation { ref expr, .. }) | Expr::TsSatisfies(TsSatisfiesExpr { ref expr, .. }) => expr.starts_with_alpha_num(), - Expr::OptChain(OptChainExpr { - base: OptChainBase::Member(MemberExpr { obj: expr, .. }), - .. - }) => expr.starts_with_alpha_num(), - - Expr::OptChain(OptChainExpr { - base: OptChainBase::Call(OptCall { callee, .. }), - .. - }) => callee.starts_with_alpha_num(), + Expr::OptChain(OptChainExpr { base, .. }) => match &**base { + OptChainBase::Member(base) => base.obj.starts_with_alpha_num(), + OptChainBase::Call(base) => base.callee.starts_with_alpha_num(), + }, Expr::Invalid(..) => true, } diff --git a/crates/swc_ecma_lints/src/lib.rs b/crates/swc_ecma_lints/src/lib.rs index af91c07f279c..d06a038506b8 100644 --- a/crates/swc_ecma_lints/src/lib.rs +++ b/crates/swc_ecma_lints/src/lib.rs @@ -1,5 +1,6 @@ #![cfg_attr(feature = "non_critical_lints", deny(unused))] #![cfg_attr(feature = "non_critical_lints", deny(clippy::all))] +#![feature(box_patterns)] pub mod config; pub mod rule; diff --git a/crates/swc_ecma_lints/src/rules/duplicate_bindings.rs b/crates/swc_ecma_lints/src/rules/duplicate_bindings.rs index 7c3a9df5e430..51ad36a98189 100644 --- a/crates/swc_ecma_lints/src/rules/duplicate_bindings.rs +++ b/crates/swc_ecma_lints/src/rules/duplicate_bindings.rs @@ -168,7 +168,7 @@ impl Visit for DuplicateBindings { return_type: _, } = a; params.visit_with(self); - if let BlockStmtOrExpr::BlockStmt(b) = body { + if let BlockStmtOrExpr::BlockStmt(b) = &**body { self.visit_with_stmts(&b.stmts, false) } } diff --git a/crates/swc_ecma_lints/src/rules/no_alert.rs b/crates/swc_ecma_lints/src/rules/no_alert.rs index 882f5daed3a9..4f859e72909a 100644 --- a/crates/swc_ecma_lints/src/rules/no_alert.rs +++ b/crates/swc_ecma_lints/src/rules/no_alert.rs @@ -138,7 +138,7 @@ impl NoAlert { } Expr::Member(member_expr) | Expr::OptChain(OptChainExpr { - base: OptChainBase::Member(member_expr), + base: box OptChainBase::Member(member_expr), .. }) => { let MemberExpr { obj, prop, .. } = member_expr; diff --git a/crates/swc_ecma_lints/src/rules/no_empty_function.rs b/crates/swc_ecma_lints/src/rules/no_empty_function.rs index cf593d75483c..92d3a2ddef35 100644 --- a/crates/swc_ecma_lints/src/rules/no_empty_function.rs +++ b/crates/swc_ecma_lints/src/rules/no_empty_function.rs @@ -290,7 +290,7 @@ impl Visit for NoEmptyFunction { } fn visit_arrow_expr(&mut self, function: &ArrowExpr) { - if let BlockStmtOrExpr::BlockStmt(BlockStmt { stmts, span }) = &function.body { + if let BlockStmtOrExpr::BlockStmt(BlockStmt { stmts, span }) = &*function.body { if self.consider_comments && self.has_comment_in_body(span) { return; } diff --git a/crates/swc_ecma_lints/src/rules/radix.rs b/crates/swc_ecma_lints/src/rules/radix.rs index f6f800f6f003..2b4ae2619b07 100644 --- a/crates/swc_ecma_lints/src/rules/radix.rs +++ b/crates/swc_ecma_lints/src/rules/radix.rs @@ -244,7 +244,7 @@ impl Radix { return self.extract_obj_and_prop_member_case(member_expr); } Expr::OptChain(OptChainExpr { - base: OptChainBase::Member(member_expr), + base: box OptChainBase::Member(member_expr), .. }) => { return self.extract_obj_and_prop_member_case(member_expr); diff --git a/crates/swc_ecma_lints/src/rules/utils.rs b/crates/swc_ecma_lints/src/rules/utils.rs index 8bb25ddfecde..b1925387e8d1 100644 --- a/crates/swc_ecma_lints/src/rules/utils.rs +++ b/crates/swc_ecma_lints/src/rules/utils.rs @@ -67,12 +67,8 @@ pub fn extract_arg_val(unresolved_ctxt: SyntaxContext, expr: &Expr) -> ArgValue ArgValue::Other } } - Expr::TaggedTpl(TaggedTpl { - tag, - tpl: Tpl { exprs, quasis, .. }, - .. - }) => { - if exprs.is_empty() { + Expr::TaggedTpl(TaggedTpl { tag, tpl, .. }) => { + if tpl.exprs.is_empty() { if let Expr::Member(MemberExpr { obj, prop, .. }) = tag.as_ref() { if let (Expr::Ident(obj), MemberProp::Ident(prop)) = (obj.as_ref(), prop) { if &*obj.sym != "String" { @@ -87,7 +83,7 @@ pub fn extract_arg_val(unresolved_ctxt: SyntaxContext, expr: &Expr) -> ArgValue return ArgValue::Other; } - return ArgValue::Str(quasis.first().unwrap().raw.clone()); + return ArgValue::Str(tpl.quasis.first().unwrap().raw.clone()); } } } diff --git a/crates/swc_ecma_minifier/src/compress/optimize/iife.rs b/crates/swc_ecma_minifier/src/compress/optimize/iife.rs index dfd9084fa808..7e8535e27f17 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/iife.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/iife.rs @@ -472,7 +472,7 @@ where } if self.ctx.in_top_level() && !self.ctx.in_call_arg && self.options.negate_iife { - match &f.body { + match &*f.body { BlockStmtOrExpr::BlockStmt(body) => { let has_decl = body.stmts.iter().any(|stmt| matches!(stmt, Stmt::Decl(..))); @@ -494,7 +494,7 @@ where .map(|p| p.clone().ident().unwrap().id) .collect::>(); - match &mut f.body { + match &mut *f.body { BlockStmtOrExpr::BlockStmt(body) => { let new = self.inline_fn_like(¶m_ids, body, &mut call.args); if let Some(new) = new { @@ -1080,7 +1080,7 @@ where Expr::Arrow(ArrowExpr { params, - body: BlockStmtOrExpr::Expr(body), + body: box BlockStmtOrExpr::Expr(body), is_async: false, is_generator: false, .. @@ -1107,7 +1107,7 @@ fn find_params(callee: &mut Expr) -> Option> { } fn find_body(callee: &mut Expr) -> Option> { match callee { - Expr::Arrow(e) => match &mut e.body { + Expr::Arrow(e) => match &mut *e.body { BlockStmtOrExpr::BlockStmt(b) => Some(Either::Left(b)), BlockStmtOrExpr::Expr(b) => Some(Either::Right(&mut **b)), }, diff --git a/crates/swc_ecma_minifier/src/compress/optimize/inline.rs b/crates/swc_ecma_minifier/src/compress/optimize/inline.rs index 08a18e50e786..cb2a3fa546c0 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/inline.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/inline.rs @@ -785,7 +785,7 @@ fn is_arrow_simple_enough_for_copy(e: &ArrowExpr) -> bool { return false; } - match &e.body { + match &*e.body { BlockStmtOrExpr::BlockStmt(s) => is_block_stmt_of_fn_simple_enough_for_copy(s), BlockStmtOrExpr::Expr(e) => is_arrow_body_simple_enough_for_copy(e), } diff --git a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs index 7aecefac5e95..25637280782c 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/mod.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/mod.rs @@ -750,7 +750,7 @@ where .as_ref() .map(|body| body.stmts.is_empty()) .unwrap_or(false), - Expr::Arrow(f) => match &f.body { + Expr::Arrow(f) => match &*f.body { BlockStmtOrExpr::BlockStmt(body) => body.stmts.is_empty(), BlockStmtOrExpr::Expr(_) => false, }, @@ -1407,7 +1407,7 @@ where if !self.prepend_stmts.is_empty() { let mut stmts = self.prepend_stmts.take().take_stmts(); - match &mut n.body { + match &mut *n.body { BlockStmtOrExpr::BlockStmt(v) => { prepend_stmts(&mut v.stmts, stmts.into_iter()); } @@ -1419,17 +1419,17 @@ where span: DUMMY_SP, arg: Some(v.take()), })); - n.body = BlockStmtOrExpr::BlockStmt(BlockStmt { + n.body = Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt { span: DUMMY_SP, stmts, - }); + })); } } } self.prepend_stmts = prepend; - if let BlockStmtOrExpr::BlockStmt(body) = &mut n.body { + if let BlockStmtOrExpr::BlockStmt(body) = &mut *n.body { drop_invalid_stmts(&mut body.stmts); } } diff --git a/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs b/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs index 685a5ec96e77..2b38c6cd4740 100644 --- a/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs +++ b/crates/swc_ecma_minifier/src/compress/optimize/sequences.rs @@ -1408,7 +1408,7 @@ where Expr::Paren(e) => self.is_skippable_for_seq(a, &e.expr), Expr::Unary(e) => self.is_skippable_for_seq(a, &e.arg), - Expr::OptChain(OptChainExpr { base, .. }) => match base { + Expr::OptChain(OptChainExpr { base, .. }) => match &**base { OptChainBase::Member(e) => { if !self.should_preserve_property_access( &e.obj, diff --git a/crates/swc_ecma_minifier/src/compress/pure/arrows.rs b/crates/swc_ecma_minifier/src/compress/pure/arrows.rs index 73631488ae8f..7ada4cb26bb4 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/arrows.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/arrows.rs @@ -31,7 +31,7 @@ impl Pure<'_> { *e = Expr::Arrow(ArrowExpr { span: function.span, params: function.params.take().into_iter().map(|p| p.pat).collect(), - body: BlockStmtOrExpr::BlockStmt(function.body.take().unwrap()), + body: Box::new(BlockStmtOrExpr::BlockStmt(function.body.take().unwrap())), is_async: function.is_async, is_generator: function.is_generator, type_params: Default::default(), @@ -104,7 +104,7 @@ impl Pure<'_> { .into_iter() .map(|v| v.pat) .collect(), - body: BlockStmtOrExpr::Expr(arg), + body: Box::new(BlockStmtOrExpr::Expr(arg)), is_async: m.function.is_async, is_generator: m.function.is_generator, type_params: Default::default(), @@ -133,7 +133,7 @@ impl Pure<'_> { if let Expr::Arrow( m @ ArrowExpr { - body: BlockStmtOrExpr::BlockStmt(..), + body: box BlockStmtOrExpr::BlockStmt(..), .. }, ) = &mut *kv.value diff --git a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs index 96f5d7c3d1ce..7dd796ea96a9 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/evaluate.rs @@ -537,7 +537,7 @@ impl Pure<'_> { _ => return, }; - match &mut opt.base { + match &mut *opt.base { OptChainBase::Member(MemberExpr { span, obj, .. }) => { // if is_pure_undefined_or_null(&self.expr_ctx, obj) { diff --git a/crates/swc_ecma_minifier/src/compress/pure/misc.rs b/crates/swc_ecma_minifier/src/compress/pure/misc.rs index f2b3eb9da481..7c37d081034d 100644 --- a/crates/swc_ecma_minifier/src/compress/pure/misc.rs +++ b/crates/swc_ecma_minifier/src/compress/pure/misc.rs @@ -373,7 +373,7 @@ impl Pure<'_> { _ => return, }; - if let OptChainBase::Member(base) = &mut opt.base { + if let OptChainBase::Member(base) = &mut *opt.base { if match &*base.obj { Expr::Lit(Lit::Null(..)) => false, Expr::Lit(..) | Expr::Object(..) | Expr::Array(..) => true, @@ -866,15 +866,11 @@ impl Pure<'_> { return; } - Expr::TaggedTpl(TaggedTpl { - span, - tpl: Tpl { exprs, .. }, - .. - }) if span.has_mark(self.marks.pure) => { + Expr::TaggedTpl(TaggedTpl { span, tpl, .. }) if span.has_mark(self.marks.pure) => { report_change!("ignore_return_value: Dropping a pure call"); self.changed = true; - let new = self.make_ignored_expr(exprs.take().into_iter()); + let new = self.make_ignored_expr(tpl.exprs.take().into_iter()); *e = new.unwrap_or(Expr::Invalid(Invalid { span: DUMMY_SP })); return; @@ -1228,7 +1224,7 @@ impl Pure<'_> { } } } - Expr::Arrow(callee) => match &mut callee.body { + Expr::Arrow(callee) => match &mut *callee.body { BlockStmtOrExpr::BlockStmt(body) => { for stmt in &mut body.stmts { self.ignore_return_value_of_return_stmt(stmt, opts); diff --git a/crates/swc_ecma_minifier/src/lib.rs b/crates/swc_ecma_minifier/src/lib.rs index 7dff7819c391..39071532b6d3 100644 --- a/crates/swc_ecma_minifier/src/lib.rs +++ b/crates/swc_ecma_minifier/src/lib.rs @@ -36,6 +36,7 @@ #![allow(clippy::only_used_in_recursion)] #![allow(unstable_name_collisions)] #![allow(clippy::match_like_matches_macro)] +#![feature(box_patterns)] use once_cell::sync::Lazy; use swc_common::{comments::Comments, pass::Repeated, sync::Lrc, SourceMap, SyntaxContext}; diff --git a/crates/swc_ecma_minifier/src/pass/global_defs.rs b/crates/swc_ecma_minifier/src/pass/global_defs.rs index 062ab4a8dda9..33ceb6b5bc40 100644 --- a/crates/swc_ecma_minifier/src/pass/global_defs.rs +++ b/crates/swc_ecma_minifier/src/pass/global_defs.rs @@ -116,7 +116,7 @@ fn should_replace(pred: &Expr, node: &Expr) -> bool { }) | Expr::OptChain(OptChainExpr { base: - OptChainBase::Member(MemberExpr { + box OptChainBase::Member(MemberExpr { obj: node_obj, prop: nodes, .. diff --git a/crates/swc_ecma_minifier/src/util/size.rs b/crates/swc_ecma_minifier/src/util/size.rs index d33386eb51f2..386b1d1040c2 100644 --- a/crates/swc_ecma_minifier/src/util/size.rs +++ b/crates/swc_ecma_minifier/src/util/size.rs @@ -153,7 +153,7 @@ impl SizeWithCtxt for Expr { body, is_async, .. - }) => match body { + }) => match &**body { BlockStmtOrExpr::BlockStmt(_) => TODO, BlockStmtOrExpr::Expr(e) => { let p = match ¶ms[..] { @@ -178,7 +178,7 @@ impl SizeWithCtxt for Expr { MetaPropKind::ImportMeta => 11, }, Expr::PrivateName(p) => p.size(), - Expr::OptChain(p) => match &p.base { + Expr::OptChain(p) => match &*p.base { OptChainBase::Member(m) => 1 + m.obj.size(unresolved) + m.prop.size(unresolved), OptChainBase::Call(c) => { 1 + c.callee.size(unresolved) + c.args.size(unresolved) + 2 diff --git a/crates/swc_ecma_minifier/tests/eval.rs b/crates/swc_ecma_minifier/tests/eval.rs index 3596279d4629..f5749f6359bc 100644 --- a/crates/swc_ecma_minifier/tests/eval.rs +++ b/crates/swc_ecma_minifier/tests/eval.rs @@ -194,11 +194,11 @@ impl VisitMut for PartialInliner { raw: Atom::new(&*s.value), cooked: Some(Atom::new(&*s.value)), }; - tt.tpl = Tpl { + tt.tpl = Box::new(Tpl { span: el.span, exprs: Default::default(), quasis: vec![el], - }; + }); } _ => { unreachable!() diff --git a/crates/swc_ecma_parser/src/parser/class_and_fn.rs b/crates/swc_ecma_parser/src/parser/class_and_fn.rs index de27be8f1442..f46bdbc441a3 100644 --- a/crates/swc_ecma_parser/src/parser/class_and_fn.rs +++ b/crates/swc_ecma_parser/src/parser/class_and_fn.rs @@ -1584,19 +1584,26 @@ fn has_use_strict(block: &BlockStmt) -> Option { _ => None, } } -impl FnBodyParser for Parser { - fn parse_fn_body_inner(&mut self, is_simple_parameter_list: bool) -> PResult { +impl FnBodyParser> for Parser { + fn parse_fn_body_inner( + &mut self, + is_simple_parameter_list: bool, + ) -> PResult> { if is!(self, '{') { - self.parse_block(false).map(|block_stmt| { - if !is_simple_parameter_list { - if let Some(span) = has_use_strict(&block_stmt) { - self.emit_err(span, SyntaxError::IllegalLanguageModeDirective); + self.parse_block(false) + .map(|block_stmt| { + if !is_simple_parameter_list { + if let Some(span) = has_use_strict(&block_stmt) { + self.emit_err(span, SyntaxError::IllegalLanguageModeDirective); + } } - } - BlockStmtOrExpr::BlockStmt(block_stmt) - }) + BlockStmtOrExpr::BlockStmt(block_stmt) + }) + .map(Box::new) } else { - self.parse_assignment_expr().map(BlockStmtOrExpr::Expr) + self.parse_assignment_expr() + .map(BlockStmtOrExpr::Expr) + .map(Box::new) } } } diff --git a/crates/swc_ecma_parser/src/parser/expr.rs b/crates/swc_ecma_parser/src/parser/expr.rs index 59da3d960e5a..0728f870f61e 100644 --- a/crates/swc_ecma_parser/src/parser/expr.rs +++ b/crates/swc_ecma_parser/src/parser/expr.rs @@ -819,7 +819,7 @@ impl Parser { .into_iter() .collect(); - let body: BlockStmtOrExpr = p.parse_fn_body( + let body: Box = p.parse_fn_body( async_span.is_some(), false, true, @@ -882,7 +882,7 @@ impl Parser { .into_iter() .collect(); - let body: BlockStmtOrExpr = self.parse_fn_body( + let body: Box = self.parse_fn_body( async_span.is_some(), false, true, @@ -897,7 +897,7 @@ impl Parser { return_type, type_params: None, }; - if let BlockStmtOrExpr::BlockStmt(..) = arrow_expr.body { + if let BlockStmtOrExpr::BlockStmt(..) = &*arrow_expr.body { if let Ok(&Token::BinOp(..)) = cur!(self, false) { // ) is required self.emit_err(self.input.cur_span(), SyntaxError::TS1005); @@ -1042,7 +1042,7 @@ impl Parser { let tagged_tpl_start = tag.span_lo(); trace_cur!(self, parse_tagged_tpl); - let tpl = self.parse_tpl(true)?; + let tpl = Box::new(self.parse_tpl(true)?); let span = span!(self, tagged_tpl_start); Ok(TaggedTpl { @@ -1302,7 +1302,7 @@ impl Parser { Expr::OptChain(OptChainExpr { span, question_dot_token, - base: OptChainBase::Member(expr), + base: Box::new(OptChainBase::Member(expr)), }) } else { Expr::Member(expr) @@ -1345,12 +1345,12 @@ impl Parser { Box::new(Expr::OptChain(OptChainExpr { span, question_dot_token, - base: OptChainBase::Call(OptCall { + base: Box::new(OptChainBase::Call(OptCall { span: span!(self, start), callee, args, type_args, - }), + })), })), true, )), @@ -1442,7 +1442,7 @@ impl Parser { Expr::OptChain(OptChainExpr { span: span!(self, start), question_dot_token, - base: OptChainBase::Member(expr), + base: Box::new(OptChainBase::Member(expr)), }) } else { Expr::Member(expr) @@ -1856,7 +1856,7 @@ impl Parser { .into_iter() .collect(); - let body: BlockStmtOrExpr = + let body: Box = self.parse_fn_body(false, false, true, params.is_simple_parameter_list())?; let span = span!(self, start); diff --git a/crates/swc_ecma_parser/src/parser/expr/ops.rs b/crates/swc_ecma_parser/src/parser/expr/ops.rs index 4a407991b106..3ae6a3007b16 100644 --- a/crates/swc_ecma_parser/src/parser/expr/ops.rs +++ b/crates/swc_ecma_parser/src/parser/expr/ops.rs @@ -312,11 +312,10 @@ impl Parser { if self.input.syntax().typescript() && op == op!("delete") { match arg.unwrap_parens() { - Expr::Member(..) - | Expr::OptChain(OptChainExpr { - base: OptChainBase::Member(..), - .. - }) => {} + Expr::Member(..) => {} + Expr::OptChain(OptChainExpr { base, .. }) + if matches!(&**base, OptChainBase::Member(..)) => {} + expr => { self.emit_err(expr.span(), SyntaxError::TS2703); } diff --git a/crates/swc_ecma_parser/src/parser/expr/tests.rs b/crates/swc_ecma_parser/src/parser/expr/tests.rs index f98f473ed637..61dbc2103d32 100644 --- a/crates/swc_ecma_parser/src/parser/expr/tests.rs +++ b/crates/swc_ecma_parser/src/parser/expr/tests.rs @@ -112,7 +112,7 @@ fn async_arrow() { is_async: true, is_generator: false, params: vec![], - body: BlockStmtOrExpr::Expr(expr("foo")), + body: Box::new(BlockStmtOrExpr::Expr(expr("foo"))), return_type: None, type_params: None, })) @@ -138,10 +138,10 @@ fn object_rest_pat() { })], type_ann: None })], - body: BlockStmtOrExpr::BlockStmt(BlockStmt { + body: Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt { span, stmts: vec![] - }), + })), return_type: None, type_params: None, })) @@ -217,7 +217,7 @@ fn arrow_fn_no_args() { is_async: false, is_generator: false, params: vec![], - body: BlockStmtOrExpr::Expr(expr("1")), + body: Box::new(BlockStmtOrExpr::Expr(expr("1"))), return_type: None, type_params: None, })) @@ -232,7 +232,7 @@ fn arrow_fn() { is_async: false, is_generator: false, params: vec![Pat::Ident(Ident::new("a".into(), span).into())], - body: BlockStmtOrExpr::Expr(expr("1")), + body: Box::new(BlockStmtOrExpr::Expr(expr("1"))), return_type: None, type_params: None, })) @@ -252,7 +252,7 @@ fn arrow_fn_rest() { arg: Box::new(Pat::Ident(Ident::new("a".into(), span).into())), type_ann: None })], - body: BlockStmtOrExpr::Expr(expr("1")), + body: Box::new(BlockStmtOrExpr::Expr(expr("1"))), return_type: None, type_params: None, })) @@ -267,7 +267,7 @@ fn arrow_fn_no_paren() { is_async: false, is_generator: false, params: vec![Pat::Ident(Ident::new("a".into(), span).into())], - body: BlockStmtOrExpr::Expr(expr("1")), + body: Box::new(BlockStmtOrExpr::Expr(expr("1"))), type_params: None, return_type: None, })) diff --git a/crates/swc_ecma_transforms_base/src/fixer.rs b/crates/swc_ecma_transforms_base/src/fixer.rs index 324ef76948d2..3410df93c194 100644 --- a/crates/swc_ecma_transforms_base/src/fixer.rs +++ b/crates/swc_ecma_transforms_base/src/fixer.rs @@ -127,7 +127,7 @@ impl VisitMut for Fixer<'_> { let old = self.ctx; self.ctx = Context::Default; node.visit_mut_children_with(self); - match &mut node.body { + match &mut *node.body { BlockStmtOrExpr::Expr(e) if e.is_seq() => { self.wrap(e); } @@ -909,7 +909,7 @@ impl Fixer<'_> { .. }) | Expr::OptChain(OptChainExpr { - base: OptChainBase::Call(OptCall { callee, .. }), + base: box OptChainBase::Call(OptCall { callee, .. }), .. }) if callee.is_seq() => { *callee = Box::new(Expr::Paren(ParenExpr { @@ -923,7 +923,7 @@ impl Fixer<'_> { .. }) | Expr::OptChain(OptChainExpr { - base: OptChainBase::Call(OptCall { callee, .. }), + base: box OptChainBase::Call(OptCall { callee, .. }), .. }) if callee.is_arrow() || callee.is_await_expr() || callee.is_assign() => { self.wrap(callee); @@ -935,7 +935,7 @@ impl Fixer<'_> { .. }) | Expr::OptChain(OptChainExpr { - base: OptChainBase::Call(OptCall { callee, .. }), + base: box OptChainBase::Call(OptCall { callee, .. }), .. }) if callee.is_fn_expr() => match self.ctx { Context::ForcedExpr | Context::FreeExpr => {} diff --git a/crates/swc_ecma_transforms_base/src/lib.rs b/crates/swc_ecma_transforms_base/src/lib.rs index 402ce8b87674..a6daad150987 100644 --- a/crates/swc_ecma_transforms_base/src/lib.rs +++ b/crates/swc_ecma_transforms_base/src/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(test, deny(warnings))] +#![feature(box_patterns)] pub use self::resolver::resolver; diff --git a/crates/swc_ecma_transforms_base/src/resolver/mod.rs b/crates/swc_ecma_transforms_base/src/resolver/mod.rs index 32ef4b4d3351..c66b60fbc7ed 100644 --- a/crates/swc_ecma_transforms_base/src/resolver/mod.rs +++ b/crates/swc_ecma_transforms_base/src/resolver/mod.rs @@ -543,7 +543,7 @@ impl<'a> VisitMut for Resolver<'a> { child.ident_type = old; { - match &mut e.body { + match &mut *e.body { BlockStmtOrExpr::BlockStmt(s) => { let old_strict_mode = child.strict_mode; child.strict_mode = s diff --git a/crates/swc_ecma_transforms_compat/src/bugfixes/template_literal_caching.rs b/crates/swc_ecma_transforms_compat/src/bugfixes/template_literal_caching.rs index 1addbb7b8020..1058261326e2 100644 --- a/crates/swc_ecma_transforms_compat/src/bugfixes/template_literal_caching.rs +++ b/crates/swc_ecma_transforms_compat/src/bugfixes/template_literal_caching.rs @@ -73,7 +73,7 @@ impl Fold for TemplateLiteralCaching { Some(Expr::Arrow(ArrowExpr { span: DUMMY_SP, params: vec![t.clone().into()], - body: BlockStmtOrExpr::Expr(Box::new(Expr::Ident(t))), + body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Ident(t)))), is_async: false, is_generator: false, type_params: None, @@ -90,11 +90,11 @@ impl Fold for TemplateLiteralCaching { let template = TaggedTpl { span: DUMMY_SP, tag: Box::new(Expr::Ident(helper_ident.clone())), - tpl: Tpl { + tpl: Box::new(Tpl { span: DUMMY_SP, quasis: n.tpl.quasis, exprs: n.tpl.exprs.iter().map(|_| 0.0.into()).collect(), - }, + }), type_params: None, }; diff --git a/crates/swc_ecma_transforms_compat/src/es2015/arrow.rs b/crates/swc_ecma_transforms_compat/src/es2015/arrow.rs index 65ff7cc69983..85a5a8682477 100644 --- a/crates/swc_ecma_transforms_compat/src/es2015/arrow.rs +++ b/crates/swc_ecma_transforms_compat/src/es2015/arrow.rs @@ -144,7 +144,7 @@ impl VisitMut for Arrow { params, is_async: *is_async, is_generator: *is_generator, - body: Some(match body { + body: Some(match &mut **body { BlockStmtOrExpr::BlockStmt(block) => block.take(), BlockStmtOrExpr::Expr(expr) => BlockStmt { span: DUMMY_SP, diff --git a/crates/swc_ecma_transforms_compat/src/es2015/block_scoping/vars.rs b/crates/swc_ecma_transforms_compat/src/es2015/block_scoping/vars.rs index 23362a29891e..54c4f81d1b21 100644 --- a/crates/swc_ecma_transforms_compat/src/es2015/block_scoping/vars.rs +++ b/crates/swc_ecma_transforms_compat/src/es2015/block_scoping/vars.rs @@ -244,7 +244,7 @@ impl VisitMut for BlockScopedVars { n.params.visit_mut_with(v); v.is_param = old; - match &mut n.body { + match &mut *n.body { BlockStmtOrExpr::BlockStmt(b) => { b.visit_mut_children_with(v); } diff --git a/crates/swc_ecma_transforms_compat/src/es2015/parameters.rs b/crates/swc_ecma_transforms_compat/src/es2015/parameters.rs index ce43b4e1c592..5b2157c83b99 100644 --- a/crates/swc_ecma_transforms_compat/src/es2015/parameters.rs +++ b/crates/swc_ecma_transforms_compat/src/es2015/parameters.rs @@ -569,7 +569,7 @@ impl VisitMut for Params { }) .collect(); - let mut body = match f.body.take() { + let mut body = match *f.body.take() { BlockStmtOrExpr::BlockStmt(block) => block, BlockStmtOrExpr::Expr(expr) => BlockStmt { span: body_span, @@ -600,7 +600,7 @@ impl VisitMut for Params { params: Vec::new(), is_async: false, is_generator: false, - body: BlockStmtOrExpr::BlockStmt(BlockStmt { + body: Box::new(BlockStmtOrExpr::BlockStmt(BlockStmt { span: f.span, stmts: vec![ var_decl, @@ -609,7 +609,7 @@ impl VisitMut for Params { arg: Some(Box::new(func)), }), ], - }), + })), type_params: Default::default(), return_type: Default::default(), }) @@ -628,12 +628,12 @@ impl VisitMut for Params { ) { match body.stmts.pop().unwrap() { Stmt::Return(ReturnStmt { arg: Some(arg), .. }) => { - BlockStmtOrExpr::Expr(arg) + Box::new(BlockStmtOrExpr::Expr(arg)) } _ => unreachable!(), } } else { - BlockStmtOrExpr::BlockStmt(body) + Box::new(BlockStmtOrExpr::BlockStmt(body)) }; *e = Expr::Arrow(ArrowExpr { diff --git a/crates/swc_ecma_transforms_compat/src/es2015/template_literal.rs b/crates/swc_ecma_transforms_compat/src/es2015/template_literal.rs index 5744eb14be9b..3805de9177d6 100644 --- a/crates/swc_ecma_transforms_compat/src/es2015/template_literal.rs +++ b/crates/swc_ecma_transforms_compat/src/es2015/template_literal.rs @@ -237,12 +237,8 @@ impl VisitMut for TemplateLiteral { *e = *obj } - Expr::TaggedTpl(TaggedTpl { - tag, - tpl: Tpl { exprs, quasis, .. }, - .. - }) => { - assert_eq!(quasis.len(), exprs.len() + 1); + Expr::TaggedTpl(TaggedTpl { tag, tpl, .. }) => { + assert_eq!(tpl.quasis.len(), tpl.exprs.len() + 1); let fn_ident = private_ident!("_templateObject"); @@ -273,13 +269,14 @@ impl VisitMut for TemplateLiteral { }, args: { let has_escape = - quasis.iter().any(|s| s.raw.contains('\\')); + tpl.quasis.iter().any(|s| s.raw.contains('\\')); let raw = if has_escape { Some( ArrayLit { span: DUMMY_SP, - elems: quasis + elems: tpl + .quasis .iter() .cloned() .map(|elem| elem.raw.as_arg()) @@ -295,7 +292,8 @@ impl VisitMut for TemplateLiteral { iter::once( ArrayLit { span: DUMMY_SP, - elems: quasis + elems: tpl + .quasis .take() .into_iter() .map(|elem| match elem.cooked { @@ -378,7 +376,7 @@ impl VisitMut for TemplateLiteral { } .as_arg(), ) - .chain(exprs.take().into_iter().map(|e| e.as_arg())) + .chain(tpl.exprs.take().into_iter().map(|e| e.as_arg())) .collect(), type_args: Default::default(), }) diff --git a/crates/swc_ecma_transforms_compat/src/es2020/opt_chaining.rs b/crates/swc_ecma_transforms_compat/src/es2020/opt_chaining.rs index ea57774d1b66..59a60ce0ac3f 100644 --- a/crates/swc_ecma_transforms_compat/src/es2020/opt_chaining.rs +++ b/crates/swc_ecma_transforms_compat/src/es2020/opt_chaining.rs @@ -323,7 +323,7 @@ impl OptChaining { let span = e.span; let cons = undefined(span); - match &mut e.base { + match &mut *e.base { OptChainBase::Member(MemberExpr { obj, prop, @@ -335,11 +335,11 @@ impl OptChaining { let obj_span = obj.span; let obj = self.unwrap(&mut obj); - let alt = OptChainBase::Member(MemberExpr { + let alt = Box::new(OptChainBase::Member(MemberExpr { span: *m_span, obj: obj.alt, prop: prop.take(), - }); + })); let alt = Box::new(Expr::OptChain(OptChainExpr { span: obj_span, question_dot_token, @@ -359,12 +359,12 @@ impl OptChaining { let obj = self.unwrap(&mut callee); - let alt = OptChainBase::Call(OptCall { + let alt = Box::new(OptChainBase::Call(OptCall { span: *span, callee: obj.alt, args: args.take(), type_args: type_args.take(), - }); + })); let alt = Box::new(Expr::OptChain(OptChainExpr { span: *span, question_dot_token, @@ -380,12 +380,14 @@ impl OptChaining { _ => {} } - let mut base = match &mut e.base { + let mut base = match &mut *e.base { OptChainBase::Member(MemberExpr { obj, prop, .. }) => { let obj_span = obj.span(); let (left, right, alt) = match &mut **obj { - Expr::Ident(..) => (obj.clone(), obj.clone(), Box::new(e.base.take().into())), + Expr::Ident(..) => { + (obj.clone(), obj.clone(), Box::new((*e.base.take()).into())) + } _ => { let i = alias_ident_for(obj, "ref"); self.vars_without_init.push(VarDeclarator { diff --git a/crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs b/crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs index b25cbefa21ef..608ebfaa5ceb 100644 --- a/crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs +++ b/crates/swc_ecma_transforms_compat/src/es2022/class_properties/private_field.rs @@ -439,7 +439,7 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> { } Expr::OptChain(OptChainExpr { - base: OptChainBase::Call(call), + base: box OptChainBase::Call(call), question_dot_token, span, }) if call.callee.is_member() => { @@ -455,11 +455,11 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> { callee: OptChainExpr { span: *span, question_dot_token: *question_dot_token, - base: OptChainBase::Member(MemberExpr { + base: Box::new(OptChainBase::Member(MemberExpr { span: call.span, obj: Box::new(expr), prop: MemberProp::Ident(quote_ident!("call")), - }), + })), } .as_callee(), args, @@ -476,7 +476,7 @@ impl<'a> VisitMut for PrivateAccessVisitor<'a> { } Expr::OptChain(OptChainExpr { base: - OptChainBase::Member( + box OptChainBase::Member( member @ MemberExpr { prop: MemberProp::PrivateName(..), .. diff --git a/crates/swc_ecma_transforms_compat/src/es2022/private_in_object.rs b/crates/swc_ecma_transforms_compat/src/es2022/private_in_object.rs index cd45d7ee3a52..472532f4697c 100644 --- a/crates/swc_ecma_transforms_compat/src/es2022/private_in_object.rs +++ b/crates/swc_ecma_transforms_compat/src/es2022/private_in_object.rs @@ -266,7 +266,7 @@ impl VisitMut for PrivateInObject { callee: ArrowExpr { span: DUMMY_SP, params: Default::default(), - body: BlockStmtOrExpr::BlockStmt(bs), + body: Box::new(BlockStmtOrExpr::BlockStmt(bs)), is_async: false, is_generator: false, type_params: Default::default(), diff --git a/crates/swc_ecma_transforms_compat/src/es2022/static_blocks.rs b/crates/swc_ecma_transforms_compat/src/es2022/static_blocks.rs index 302ba36dbaa7..14df20250ecf 100644 --- a/crates/swc_ecma_transforms_compat/src/es2022/static_blocks.rs +++ b/crates/swc_ecma_transforms_compat/src/es2022/static_blocks.rs @@ -45,7 +45,7 @@ impl ClassStaticBlock { is_generator: false, type_params: None, return_type: None, - body: BlockStmtOrExpr::BlockStmt(static_block.body), + body: Box::new(BlockStmtOrExpr::BlockStmt(static_block.body)), } .as_callee(), args: Vec::new(), diff --git a/crates/swc_ecma_transforms_compat/src/lib.rs b/crates/swc_ecma_transforms_compat/src/lib.rs index 0eb2f13e3809..1459886ef436 100644 --- a/crates/swc_ecma_transforms_compat/src/lib.rs +++ b/crates/swc_ecma_transforms_compat/src/lib.rs @@ -3,6 +3,7 @@ #![allow(clippy::vec_box)] #![allow(clippy::boxed_local)] #![allow(clippy::match_like_matches_macro)] +#![feature(box_patterns)] pub use self::{ bugfixes::bugfixes, es2015::es2015, es2016::es2016, es2017::es2017, es2018::es2018, diff --git a/crates/swc_ecma_transforms_compat/src/macros.rs b/crates/swc_ecma_transforms_compat/src/macros.rs index cc6ba60e0d65..332be2e0d446 100644 --- a/crates/swc_ecma_transforms_compat/src/macros.rs +++ b/crates/swc_ecma_transforms_compat/src/macros.rs @@ -18,7 +18,7 @@ macro_rules! impl_visit_mut_fn { f.visit_mut_children_with(self); - let was_expr = match f.body { + let was_expr = match *f.body { BlockStmtOrExpr::Expr(..) => true, _ => false, }; @@ -34,7 +34,7 @@ macro_rules! impl_visit_mut_fn { pat, }) .collect(), - &mut match &mut f.body { + &mut match &mut *f.body { BlockStmtOrExpr::BlockStmt(block) => block.take(), BlockStmtOrExpr::Expr(expr) => BlockStmt { span: body_span, @@ -53,11 +53,13 @@ macro_rules! impl_visit_mut_fn { _ => false, } { match body.stmts.pop().unwrap() { - Stmt::Return(ReturnStmt { arg: Some(arg), .. }) => BlockStmtOrExpr::Expr(arg), + Stmt::Return(ReturnStmt { arg: Some(arg), .. }) => { + Box::new(BlockStmtOrExpr::Expr(arg)) + } _ => unreachable!(), } } else { - BlockStmtOrExpr::BlockStmt(body) + Box::new(BlockStmtOrExpr::BlockStmt(body)) }; f.params = params.into_iter().map(|param| param.pat).collect(); diff --git a/crates/swc_ecma_transforms_optimization/src/simplify/branch/mod.rs b/crates/swc_ecma_transforms_optimization/src/simplify/branch/mod.rs index 8ac291253b8c..f6f76c0a3bd4 100644 --- a/crates/swc_ecma_transforms_optimization/src/simplify/branch/mod.rs +++ b/crates/swc_ecma_transforms_optimization/src/simplify/branch/mod.rs @@ -1687,16 +1687,13 @@ fn ignore_result(e: Expr, drop_str_lit: bool, ctx: &ExprCtx) -> Option { ctx, ), - Expr::TaggedTpl(TaggedTpl { - span, - tag, - tpl: Tpl { exprs, .. }, - .. - }) if tag.is_pure_callee(ctx) => ignore_result( - ctx.preserve_effects(span, *undefined(span), exprs), - true, - ctx, - ), + Expr::TaggedTpl(TaggedTpl { span, tag, tpl, .. }) if tag.is_pure_callee(ctx) => { + ignore_result( + ctx.preserve_effects(span, *undefined(span), tpl.exprs), + true, + ctx, + ) + } // // Function expressions are useless if they are not used. diff --git a/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs b/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs index 40161acfe891..57234580ce5b 100644 --- a/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs +++ b/crates/swc_ecma_usage_analyzer/src/analyzer/mod.rs @@ -196,7 +196,7 @@ where n.params.visit_with(&mut *child.with_ctx(ctx)); } - match &n.body { + match &*n.body { BlockStmtOrExpr::BlockStmt(body) => { body.visit_with(child); } diff --git a/crates/swc_ecma_utils/src/factory.rs b/crates/swc_ecma_utils/src/factory.rs index 1dd606769d18..eb175d646a85 100644 --- a/crates/swc_ecma_utils/src/factory.rs +++ b/crates/swc_ecma_utils/src/factory.rs @@ -88,7 +88,7 @@ pub trait ExprFactory: Into { ArrowExpr { span: DUMMY_SP, params, - body: BlockStmtOrExpr::from(self), + body: Box::new(BlockStmtOrExpr::from(self)), is_async: false, is_generator: false, type_params: None, diff --git a/crates/swc_ecma_utils/src/function/fn_env_hoister.rs b/crates/swc_ecma_utils/src/function/fn_env_hoister.rs index 9762bf0b910f..be55b298b221 100644 --- a/crates/swc_ecma_utils/src/function/fn_env_hoister.rs +++ b/crates/swc_ecma_utils/src/function/fn_env_hoister.rs @@ -696,7 +696,7 @@ fn extend_super( init: Some(Box::new(Expr::Arrow(ArrowExpr { span: DUMMY_SP, params: vec![prop.clone().into()], - body: BlockStmtOrExpr::Expr(Box::new(Expr::Object(ObjectLit { + body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Object(ObjectLit { span: DUMMY_SP, props: vec![ Prop::Getter(GetterProp { @@ -738,7 +738,7 @@ fn extend_super( .map(Box::new) .map(From::from) .collect(), - }))), + })))), is_async: false, is_generator: false, return_type: None, @@ -753,11 +753,13 @@ fn extend_super( init: Some(Box::new(Expr::Arrow(ArrowExpr { span: DUMMY_SP, params: Vec::new(), - body: BlockStmtOrExpr::Expr(Box::new(Expr::SuperProp(SuperPropExpr { - obj: Super { span: DUMMY_SP }, - prop: SuperProp::Ident(quote_ident!(key)), - span: DUMMY_SP, - }))), + body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::SuperProp( + SuperPropExpr { + obj: Super { span: DUMMY_SP }, + prop: SuperProp::Ident(quote_ident!(key)), + span: DUMMY_SP, + }, + )))), is_async: false, is_generator: false, return_type: None, @@ -773,14 +775,16 @@ fn extend_super( init: Some(Box::new(Expr::Arrow(ArrowExpr { span: DUMMY_SP, params: vec![param.clone().into()], - body: BlockStmtOrExpr::Expr(Box::new(Expr::SuperProp(SuperPropExpr { - obj: Super { span: DUMMY_SP }, - prop: SuperProp::Computed(ComputedPropName { + body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::SuperProp( + SuperPropExpr { + obj: Super { span: DUMMY_SP }, + prop: SuperProp::Computed(ComputedPropName { + span: DUMMY_SP, + expr: Box::new(Expr::Ident(param)), + }), span: DUMMY_SP, - expr: Box::new(Expr::Ident(param)), - }), - span: DUMMY_SP, - }))), + }, + )))), is_async: false, is_generator: false, return_type: None, @@ -797,7 +801,7 @@ fn extend_super( init: Some(Box::new(Expr::Arrow(ArrowExpr { span: DUMMY_SP, params: vec![value.clone().into()], - body: BlockStmtOrExpr::Expr(Box::new(Expr::Assign(AssignExpr { + body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Assign(AssignExpr { span: DUMMY_SP, left: PatOrExpr::Expr(Box::new(Expr::SuperProp(SuperPropExpr { obj: Super { span: DUMMY_SP }, @@ -806,7 +810,7 @@ fn extend_super( }))), op: op!("="), right: Box::new(Expr::Ident(value)), - }))), + })))), is_async: false, is_generator: false, return_type: None, @@ -824,7 +828,7 @@ fn extend_super( init: Some(Box::new(Expr::Arrow(ArrowExpr { span: DUMMY_SP, params: vec![prop.clone().into(), value.clone().into()], - body: BlockStmtOrExpr::Expr(Box::new(Expr::Assign(AssignExpr { + body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Assign(AssignExpr { span: DUMMY_SP, left: PatOrExpr::Expr(Box::new(Expr::SuperProp(SuperPropExpr { obj: Super { span: DUMMY_SP }, @@ -836,7 +840,7 @@ fn extend_super( }))), op: op!("="), right: Box::new(Expr::Ident(value)), - }))), + })))), is_async: false, is_generator: false, return_type: None, diff --git a/crates/swc_ecma_utils/src/function/function_wrapper.rs b/crates/swc_ecma_utils/src/function/function_wrapper.rs index 5479e25e663c..e2e1f847b166 100644 --- a/crates/swc_ecma_utils/src/function/function_wrapper.rs +++ b/crates/swc_ecma_utils/src/function/function_wrapper.rs @@ -295,7 +295,7 @@ impl From for FunctionWrapper { .. }: ArrowExpr, ) -> Self { - let body = Some(match body { + let body = Some(match *body { BlockStmtOrExpr::BlockStmt(block) => block, BlockStmtOrExpr::Expr(expr) => BlockStmt { span: DUMMY_SP, diff --git a/crates/swc_ecma_utils/src/lib.rs b/crates/swc_ecma_utils/src/lib.rs index 23945184d1e8..dd9b35680c7d 100644 --- a/crates/swc_ecma_utils/src/lib.rs +++ b/crates/swc_ecma_utils/src/lib.rs @@ -1427,13 +1427,15 @@ pub trait ExprExt { | Expr::Yield(_) | Expr::Member(_) | Expr::SuperProp(_) - | Expr::OptChain(OptChainExpr { - base: OptChainBase::Member(_), - .. - }) | Expr::Update(_) | Expr::Assign(_) => true, + Expr::OptChain(OptChainExpr { base, .. }) + if matches!(&**base, OptChainBase::Member(_)) => + { + true + } + // TODO Expr::New(_) => true, @@ -1441,24 +1443,24 @@ pub trait ExprExt { callee: Callee::Expr(ref callee), ref args, .. - }) - | Expr::OptChain(OptChainExpr { - base: - OptChainBase::Call(OptCall { - ref callee, - ref args, - .. - }), - .. }) if callee.is_pure_callee(ctx) => { args.iter().any(|arg| arg.expr.may_have_side_effects(ctx)) } + Expr::OptChain(OptChainExpr { base, .. }) + if matches!(&**base, OptChainBase::Call(..)) + && OptChainBase::as_call(base) + .unwrap() + .callee + .is_pure_callee(ctx) => + { + OptChainBase::as_call(base) + .unwrap() + .args + .iter() + .any(|arg| arg.expr.may_have_side_effects(ctx)) + } - Expr::Call(_) - | Expr::OptChain(OptChainExpr { - base: OptChainBase::Call(_), - .. - }) => true, + Expr::Call(_) | Expr::OptChain(..) => true, Expr::Seq(SeqExpr { ref exprs, .. }) => { exprs.iter().any(|e| e.may_have_side_effects(ctx)) @@ -1961,11 +1963,26 @@ pub fn alias_ident_for(expr: &Expr, default: &str) -> Ident { ident: Some(ident), .. }) => Some(ident.sym.to_string()), - Expr::OptChain(OptChainExpr { - base: OptChainBase::Call(OptCall { callee: expr, .. }), - .. - }) - | Expr::Call(CallExpr { + Expr::OptChain(OptChainExpr { base, .. }) => match &**base { + OptChainBase::Call(OptCall { callee: expr, .. }) => sym(expr), + OptChainBase::Member(MemberExpr { + prop: MemberProp::Ident(ident), + obj, + .. + }) => Some(format!("{}_{}", sym(obj).unwrap_or_default(), ident.sym)), + + OptChainBase::Member(MemberExpr { + prop: MemberProp::Computed(ComputedPropName { expr, .. }), + obj, + .. + }) => Some(format!( + "{}_{}", + sym(obj).unwrap_or_default(), + sym(expr).unwrap_or_default() + )), + _ => None, + }, + Expr::Call(CallExpr { callee: Callee::Expr(expr), .. }) => sym(expr), @@ -1980,31 +1997,13 @@ pub fn alias_ident_for(expr: &Expr, default: &str) -> Ident { .. }) => Some(format!("super_{}", sym(expr).unwrap_or_default())), - Expr::OptChain(OptChainExpr { - base: - OptChainBase::Member(MemberExpr { - prop: MemberProp::Ident(ident), - obj, - .. - }), - .. - }) - | Expr::Member(MemberExpr { + Expr::Member(MemberExpr { prop: MemberProp::Ident(ident), obj, .. }) => Some(format!("{}_{}", sym(obj).unwrap_or_default(), ident.sym)), - Expr::OptChain(OptChainExpr { - base: - OptChainBase::Member(MemberExpr { - prop: MemberProp::Computed(ComputedPropName { expr, .. }), - obj, - .. - }), - .. - }) - | Expr::Member(MemberExpr { + Expr::Member(MemberExpr { prop: MemberProp::Computed(ComputedPropName { expr, .. }), obj, .. @@ -2421,12 +2420,12 @@ impl ExprCtx { to.push(Box::new(Expr::New(e))) } - Expr::Member(_) - | Expr::SuperProp(_) - | Expr::OptChain(OptChainExpr { - base: OptChainBase::Member(_), - .. - }) => to.push(Box::new(expr)), + Expr::Member(_) | Expr::SuperProp(_) => to.push(Box::new(expr)), + Expr::OptChain(OptChainExpr { ref base, .. }) + if matches!(&**base, OptChainBase::Member(_)) => + { + to.push(Box::new(expr)) + } // We are at here because we could not determine value of test. //TODO: Drop values if it does not have side effects. @@ -2522,14 +2521,10 @@ impl ExprCtx { }); } - Expr::TaggedTpl(TaggedTpl { - tag, - tpl: Tpl { exprs, .. }, - .. - }) => { + Expr::TaggedTpl(TaggedTpl { tag, tpl, .. }) => { self.extract_side_effects_to(to, *tag); - exprs + tpl.exprs .into_iter() .for_each(|e| self.extract_side_effects_to(to, *e)); } @@ -2555,7 +2550,7 @@ impl ExprCtx { self.extract_side_effects_to(to, *expr) } Expr::OptChain(OptChainExpr { base: child, .. }) => { - self.extract_side_effects_to(to, child.into()) + self.extract_side_effects_to(to, (*child).into()) } Expr::Invalid(..) => unreachable!(), diff --git a/crates/swc_ecma_visit/src/lib.rs b/crates/swc_ecma_visit/src/lib.rs index d25a2a169d0d..d86045946b3b 100644 --- a/crates/swc_ecma_visit/src/lib.rs +++ b/crates/swc_ecma_visit/src/lib.rs @@ -761,7 +761,7 @@ define!({ pub struct ArrowExpr { pub span: Span, pub params: Vec, - pub body: BlockStmtOrExpr, + pub body: Box, pub is_async: bool, pub is_generator: bool, pub type_params: Option>, @@ -793,7 +793,7 @@ define!({ pub span: Span, pub tag: Box, pub type_params: Option>, - pub tpl: Tpl, + pub tpl: Box, } pub struct TplElement { pub span: Span, @@ -831,7 +831,7 @@ define!({ pub struct OptChainExpr { pub span: Span, pub question_dot_token: Span, - pub base: OptChainBase, + pub base: Box, } pub enum OptChainBase { Member(MemberExpr), diff --git a/crates/swc_estree_compat/src/swcify/expr.rs b/crates/swc_estree_compat/src/swcify/expr.rs index a9bfa0ddc5af..e4c37f8861f0 100644 --- a/crates/swc_estree_compat/src/swcify/expr.rs +++ b/crates/swc_estree_compat/src/swcify/expr.rs @@ -622,7 +622,7 @@ impl Swcify for ArrowFunctionExpression { ArrowExpr { span: ctx.span(&self.base), params: self.params.into_iter().map(|v| v.swcify(ctx).pat).collect(), - body: self.body.swcify(ctx), + body: Box::new(self.body.swcify(ctx)), is_async: self.is_async, is_generator: self.generator, type_params: self.type_parameters.swcify(ctx).flatten().map(Box::new), @@ -718,7 +718,7 @@ impl Swcify for TaggedTemplateExpression { span: ctx.span(&self.base), tag: self.tag.swcify(ctx), type_params: self.type_parameters.swcify(ctx).map(From::from), - tpl: self.quasi.swcify(ctx), + tpl: Box::new(self.quasi.swcify(ctx)), } } } @@ -775,7 +775,7 @@ impl Swcify for OptionalMemberExpression { span: ctx.span(&self.base), // TODO: Use correct span. question_dot_token: DUMMY_SP, - base: OptChainBase::Member(MemberExpr { + base: Box::new(OptChainBase::Member(MemberExpr { span: ctx.span(&self.base), obj: self.object.swcify(ctx), prop: match (self.property, self.computed) { @@ -789,7 +789,7 @@ impl Swcify for OptionalMemberExpression { } _ => unreachable!(), }, - }), + })), } } } @@ -813,12 +813,12 @@ impl Swcify for OptionalCallExpression { span: ctx.span(&self.base), // TODO: Use correct span. question_dot_token: DUMMY_SP, - base: OptChainBase::Call(OptCall { + base: Box::new(OptChainBase::Call(OptCall { span: ctx.span(&self.base), callee: self.callee.swcify(ctx), args: self.arguments.swcify(ctx).into_iter().flatten().collect(), type_args: self.type_parameters.swcify(ctx).map(From::from), - }), + })), } } }