fix(es/module): Fix handling of this for systemjs (#6857)

**Related issue:**

 - Closes https://github.com/swc-project/swc/issues/6784.
This commit is contained in:
Alex Vasilev 2023-01-27 15:58:22 +03:00 committed by GitHub
parent 5a5a7d70e4
commit 39c75fdcce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 100 additions and 16 deletions

View File

@ -13,7 +13,7 @@ System.register([
execute: function() {
_export("C", C = function C() {
"use strict";
_class_call_check(void 0, C);
_class_call_check(this, C);
});
__ = {
writable: true,

View File

@ -13,7 +13,7 @@ System.register([
execute: function() {
_export("C", C = function C() {
"use strict";
_class_call_check(void 0, C);
_class_call_check(this, C);
}), C.x = 1;
}
};

View File

@ -13,7 +13,7 @@ System.register([
execute: function() {
_export("Object", Object = function Object() {
"use strict";
_class_call_check(void 0, Object);
_class_call_check(this, Object);
});
}
};

View File

@ -13,7 +13,7 @@ System.register([
execute: function() {
_export("Object", function Object() {
"use strict";
_class_call_check(void 0, Object);
_class_call_check(this, Object);
});
}
};

View File

@ -91,8 +91,8 @@ System.register([
});
_export("cl2", cl2 = function cl2() {
"use strict";
_class_call_check(void 0, cl2);
(void 0).p = {
_class_call_check(this, cl2);
this.p = {
m: /*#__PURE__*/ _async_to_generator(function() {
var req;
return _ts_generator(this, function(_state) {

View File

@ -91,8 +91,8 @@ System.register([
});
_export("cl2", cl2 = function cl2() {
"use strict";
_class_call_check(void 0, cl2);
(void 0).p = {
_class_call_check(this, cl2);
this.p = {
m: /*#__PURE__*/ _async_to_generator(function() {
var req;
return _ts_generator(this, function(_state) {

View File

@ -42,7 +42,7 @@ System.register([
});
_export("cl2", cl2 = class cl2 {
constructor(){
(void 0).p = {
this.p = {
m: /*#__PURE__*/ _async_to_generator(function*() {
const req = yield import('./test') // FOUR
;

View File

@ -30,7 +30,7 @@ struct SystemJs {
export_values: Vec<Box<Expr>>,
tla: bool,
enter_async_fn: u32,
enter_fn: u32,
is_global_this: bool,
root_fn_decl_idents: Vec<Ident>,
module_item_meta_list: Vec<ModuleItemMeta>,
import_idents: Vec<Id>,
@ -48,9 +48,9 @@ pub fn system_js(unresolved_mark: Mark, config: Config) -> impl Fold {
export_map: Default::default(),
export_names: vec![],
export_values: vec![],
is_global_this: true,
tla: false,
enter_async_fn: 0,
enter_fn: 0,
root_fn_decl_idents: vec![],
module_item_meta_list: vec![],
import_idents: vec![],
@ -69,14 +69,13 @@ pub fn system_js_with_resolver(
unresolved_mark,
resolver: Resolver::Real { base, resolver },
config,
is_global_this: true,
declare_var_idents: vec![],
export_map: Default::default(),
export_names: vec![],
export_values: vec![],
tla: false,
enter_async_fn: 0,
enter_fn: 0,
root_fn_decl_idents: vec![],
module_item_meta_list: vec![],
import_idents: vec![],
@ -94,6 +93,19 @@ struct ModuleItemMeta {
}
impl SystemJs {
fn fold_children_with_non_global_this<T>(&mut self, n: T) -> T
where
T: FoldWith<Self>,
{
let is_global_this = self.is_global_this;
self.is_global_this = false;
let node = n.fold_children_with(self);
self.is_global_this = is_global_this;
node
}
fn export_call(&self, name: JsWord, span: Span, expr: Expr) -> CallExpr {
CallExpr {
span,
@ -568,7 +580,7 @@ impl Fold for SystemJs {
Expr::Await(await_expr)
}
Expr::This(this_expr) => {
if !self.config.allow_top_level_this && self.enter_fn == 0 {
if !self.config.allow_top_level_this && self.is_global_this {
return *undefined(DUMMY_SP);
}
Expr::This(this_expr)
@ -582,15 +594,21 @@ impl Fold for SystemJs {
if is_async {
self.enter_async_fn += 1;
}
self.enter_fn += 1;
let fold_fn_expr = fn_decl.fold_children_with(self);
if is_async {
self.enter_async_fn -= 1;
}
self.enter_fn -= 1;
fold_fn_expr
}
fn fold_class_expr(&mut self, n: ClassExpr) -> ClassExpr {
self.fold_children_with_non_global_this(n)
}
fn fold_function(&mut self, n: Function) -> Function {
self.fold_children_with_non_global_this(n)
}
fn fold_prop(&mut self, prop: Prop) -> Prop {
match prop {
Prop::Shorthand(shorthand) => Prop::KeyValue(KeyValueProp {

View File

@ -46,6 +46,72 @@ test!(
});"#
);
test!(
syntax(),
|tester| tr(
tester,
Config {
allow_top_level_this: false
}
),
iife,
r#"
(function(a) {
this.foo = a;
})(this);
"#,
r#"System.register([], function(_export, _context) {
"use strict";
return {
setters: [],
execute: function() {
(function(a) {
this.foo = a;
})(void 0);
}
};
});"#
);
test!(
syntax(),
|tester| tr(
tester,
Config {
allow_top_level_this: false
}
),
top_level_this_false_class,
r#"
const a = this;
class A {
constructor() {
this.a = 1;
}
test() {
this.a = 2;
}
}"#,
r#"System.register([], function(_export, _context) {
"use strict";
var A, a;
return {
setters: [],
execute: function() {
a = void 0;
A = class A {
constructor(){
this.a = 1;
}
test() {
this.a = 2;
}
};
}
};
});"#
);
test!(
syntax(),
|tester| tr(