diff --git a/crates/swc/tests/tsc-references/classStaticBlock5_es5.1.normal.js b/crates/swc/tests/tsc-references/classStaticBlock5_es5.1.normal.js index aae8c079a7f..190a659b99c 100644 --- a/crates/swc/tests/tsc-references/classStaticBlock5_es5.1.normal.js +++ b/crates/swc/tests/tsc-references/classStaticBlock5_es5.1.normal.js @@ -1,7 +1,9 @@ import * as swcHelpers from "@swc/helpers"; -var _superprop_get_b = ()=>super.b -, _superprop_get_a = ()=>super.a -; +var _superprop_get_b = function() { + return super.b; +}, _superprop_get_a = function() { + return super.a; +}; // @target: esnext, es2022, es2015, es5 var B = function B() { "use strict"; diff --git a/crates/swc/tests/tsc-references/superInStaticMembers1_es5.1.normal.js b/crates/swc/tests/tsc-references/superInStaticMembers1_es5.1.normal.js index 31b4678943a..f013b27a4cf 100644 --- a/crates/swc/tests/tsc-references/superInStaticMembers1_es5.1.normal.js +++ b/crates/swc/tests/tsc-references/superInStaticMembers1_es5.1.normal.js @@ -1,6 +1,7 @@ import * as swcHelpers from "@swc/helpers"; -var _this = this, _superprop_get_w = ()=>super.w -; +var _this = this, _superprop_get_w = function() { + return super.w; +}; // @target: es5, es2015, es2021, es2022, esnext // @noTypesAndSymbols: true // @filename: external.ts @@ -773,8 +774,9 @@ _$_Reflect = function Reflect() { }, _$__ = { writable: true, value: function() { - var _this1 = _this, _superprop_get_w1 = ()=>_superprop_get_w() - ; + var _this1 = _this, _superprop_get_w1 = function() { + return super.w; + }; var _$_Reflect, _$__; var C = /*#__PURE__*/ function(B) { "use strict"; @@ -838,8 +840,9 @@ var _$__21 = { C._ = swcHelpers.get(swcHelpers.getPrototypeOf(C), "w", C).call(C); }); (function Reflect() { - var _this2 = this, _superprop_get_w2 = ()=>super.w - ; + var _this2 = this, _superprop_get_w2 = function() { + return super.w; + }; var C = /*#__PURE__*/ function(B) { "use strict"; swcHelpers.inherits(C, B); diff --git a/crates/swc/tests/tsc-references/superInStaticMembers1_es5.2.minified.js b/crates/swc/tests/tsc-references/superInStaticMembers1_es5.2.minified.js index 978e0982777..e0d74aace98 100644 --- a/crates/swc/tests/tsc-references/superInStaticMembers1_es5.2.minified.js +++ b/crates/swc/tests/tsc-references/superInStaticMembers1_es5.2.minified.js @@ -1,6 +1,7 @@ import * as swcHelpers from "@swc/helpers"; -var _this = this, _superprop_get_w = ()=>super.w -; +var _this = this, _superprop_get_w = function() { + return super.w; +}; export var Reflect = function() { "use strict"; swcHelpers.classCallCheck(this, Reflect); @@ -483,7 +484,7 @@ _superprop_get_w().call(_this), _$_Reflect = function Reflect3() { } return C; }(B); - _superprop_get_w().call(_this); + super.w.call(_this); }() }; var C = function(B) { diff --git a/crates/swc_ecma_transforms_compat/src/es2015/arrow.rs b/crates/swc_ecma_transforms_compat/src/es2015/arrow.rs index 06bc7e93b1f..879a175c629 100644 --- a/crates/swc_ecma_transforms_compat/src/es2015/arrow.rs +++ b/crates/swc_ecma_transforms_compat/src/es2015/arrow.rs @@ -65,6 +65,7 @@ pub fn arrow() -> impl Fold + VisitMut + InjectVars { #[derive(Default)] struct Arrow { in_subclass: bool, + disable_fn_env_hoister: bool, hoister: FnEnvHoister, } @@ -119,7 +120,9 @@ impl VisitMut for Arrow { .. }) => { params.visit_mut_with(self); - params.visit_mut_with(&mut self.hoister); + if !self.disable_fn_env_hoister { + params.visit_mut_with(&mut self.hoister); + } let params: Vec = params .take() @@ -133,7 +136,9 @@ impl VisitMut for Arrow { body.visit_mut_with(self); - body.visit_mut_with(&mut self.hoister); + if !self.disable_fn_env_hoister { + body.visit_mut_with(&mut self.hoister); + } let fn_expr = Expr::Fn(FnExpr { ident: None, @@ -178,8 +183,15 @@ impl VisitMut for Arrow { let decl = self.hoister.take().to_stmt(); - if let Some(stmt) = decl { + if let Some(mut stmt) = decl { + let old_disable = self.disable_fn_env_hoister; + self.disable_fn_env_hoister = true; + + stmt.visit_mut_with(self); + prepend(stmts, ModuleItem::Stmt(stmt)); + + self.disable_fn_env_hoister = old_disable; } } @@ -188,11 +200,20 @@ impl VisitMut for Arrow { stmts.visit_mut_children_with(self); - let decl = mem::replace(&mut self.hoister, old_rep).to_stmt(); + let decl = self.hoister.take().to_stmt(); + + if let Some(mut stmt) = decl { + let old_disable = self.disable_fn_env_hoister; + self.disable_fn_env_hoister = true; + + stmt.visit_mut_with(self); - if let Some(stmt) = decl { prepend(stmts, stmt); + + self.disable_fn_env_hoister = old_disable; } + + self.hoister = old_rep; } } diff --git a/crates/swc_ecma_transforms_compat/tests/arrows/issue-4088/1/input.js b/crates/swc_ecma_transforms_compat/tests/arrows/issue-4088/1/input.js new file mode 100644 index 00000000000..78a42aa2f75 --- /dev/null +++ b/crates/swc_ecma_transforms_compat/tests/arrows/issue-4088/1/input.js @@ -0,0 +1,15 @@ +function f0() { +} +f0.prototype = { + name: 'Nicholas', + age: 29, + job: 'Software Engineer', + sayName() { + + v0[args](1, { + v9: v7 => super.v3(v27), + foo: a, + done: 'a' + }); + } +}; \ No newline at end of file diff --git a/crates/swc_ecma_transforms_compat/tests/arrows/issue-4088/1/output.js b/crates/swc_ecma_transforms_compat/tests/arrows/issue-4088/1/output.js new file mode 100644 index 00000000000..50dbb384f6b --- /dev/null +++ b/crates/swc_ecma_transforms_compat/tests/arrows/issue-4088/1/output.js @@ -0,0 +1,18 @@ +function f0() {} +f0.prototype = { + name: "Nicholas", + age: 29, + job: "Software Engineer", + sayName () { + var _this = this, _superprop_get_v3 = function() { + return super.v3; + }; + v0[args](1, { + v9: function(v7) { + return _superprop_get_v3().call(_this, v27); + }, + foo: a, + done: "a" + }); + } +}; diff --git a/crates/swc_ecma_transforms_compat/tests/es2015_arrow.rs b/crates/swc_ecma_transforms_compat/tests/es2015_arrow.rs index 30455f851f7..11f536db1f6 100644 --- a/crates/swc_ecma_transforms_compat/tests/es2015_arrow.rs +++ b/crates/swc_ecma_transforms_compat/tests/es2015_arrow.rs @@ -1,5 +1,8 @@ +use std::path::PathBuf; + +use swc_ecma_parser::EsConfig; use swc_ecma_transforms_compat::es2015::arrow; -use swc_ecma_transforms_testing::{compare_stdout, test}; +use swc_ecma_transforms_testing::{compare_stdout, test, test_fixture}; test!( ::swc_ecma_parser::Syntax::default(), @@ -523,3 +526,18 @@ test!( }; }" ); + +#[testing::fixture("tests/arrows/**/input.js")] +fn fixture(input: PathBuf) { + let output = input.with_file_name("output.js"); + + test_fixture( + swc_ecma_parser::Syntax::Es(EsConfig { + allow_super_outside_method: true, + ..Default::default() + }), + &|_| arrow(), + &input, + &output, + ); +} diff --git a/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs b/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs index 977002a8e07..0160498b3d6 100644 --- a/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs +++ b/crates/swc_ecma_transforms_compat/tests/es2017_async_to_generator.rs @@ -2,7 +2,7 @@ use std::{fs::read_to_string, path::PathBuf}; use swc_common::{chain, Mark, Spanned}; use swc_ecma_ast::*; -use swc_ecma_parser::Syntax; +use swc_ecma_parser::{EsConfig, Syntax}; use swc_ecma_transforms_base::{fixer::fixer, resolver::resolver}; use swc_ecma_transforms_compat::{ es2015, @@ -35,7 +35,10 @@ impl Fold for ParenRemover { } fn syntax() -> Syntax { - Syntax::default() + Syntax::Es(EsConfig { + allow_super_outside_method: true, + ..Default::default() + }) } fn tr() -> impl Fold { @@ -423,12 +426,14 @@ test!( class Foo extends class{ }{ method() { - var _this = this, _superprop_get_method = ()=>super.method; + var _this = this, _superprop_get_method1 = ()=>super.method; return _asyncToGenerator(function*() { - var _this1 = _this, _superprop_get_method1 = ()=>_superprop_get_method(); - _superprop_get_method().call(_this); + var _this1 = _this, _superprop_get_method = function _superprop_get_method() { + return super.method; + }; + _superprop_get_method1().call(_this); var arrow = function arrow() { - return _superprop_get_method1().call(_this1); + return _superprop_get_method().call(_this1); }; })(); }