Skip to content

Commit 7730a6e

Browse files
authored
fix(es/transforms): Fix bugs (#1795)
swc_ecma_transforms_compat: - `async_to_generator`: Handle await in async generators correctly. (#1752) swc_ecma_transforms_module: - Don't panic on double import from one module. (#1757)
1 parent 03db7ad commit 7730a6e

File tree

14 files changed

+324
-9
lines changed

14 files changed

+324
-9
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
class x87 { constructor(parm: () => Base[] = function named() { return [d1, d2] }) { } }
2+
3+
class x90 { constructor(parm: { (): Base[]; } = function named() { return [d1, d2] }) { } }
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
class x87 {
2+
constructor(parm__2: () => Base[] = function named__3() {
3+
return [d1, d2];
4+
}){
5+
}
6+
}
7+
class x90 {
8+
constructor(parm__4: {
9+
() : Base[];
10+
} = function named__5() {
11+
return [d1, d2];
12+
}){
13+
}
14+
}

ecmascript/transforms/compat/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ edition = "2018"
66
license = "Apache-2.0/MIT"
77
name = "swc_ecma_transforms_compat"
88
repository = "https://github.com/swc-project/swc.git"
9-
version = "0.17.9"
9+
version = "0.17.10"
1010
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1111

1212
[dependencies]

ecmascript/transforms/compat/src/es2017/async_to_generator.rs

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -866,7 +866,9 @@ impl Actual {
866866
///
867867
/// `_asyncToGenerator(function*() {})` from `async function() {}`;
868868
fn make_fn_ref(mut expr: FnExpr, should_not_bind_this: bool) -> Expr {
869-
expr.function.body = expr.function.body.fold_with(&mut AsyncFnBodyHandler);
869+
expr.function.body = expr.function.body.fold_with(&mut AsyncFnBodyHandler {
870+
is_async_generator: expr.function.is_generator,
871+
});
870872

871873
assert!(expr.function.is_async);
872874
expr.function.is_async = false;
@@ -901,7 +903,9 @@ fn make_fn_ref(mut expr: FnExpr, should_not_bind_this: bool) -> Expr {
901903
})
902904
}
903905

904-
struct AsyncFnBodyHandler;
906+
struct AsyncFnBodyHandler {
907+
is_async_generator: bool,
908+
}
905909

906910
macro_rules! noop {
907911
($name:ident, $T:path) => {
@@ -924,11 +928,28 @@ impl Fold for AsyncFnBodyHandler {
924928
let expr = expr.fold_children_with(self);
925929

926930
match expr {
927-
Expr::Await(AwaitExpr { span, arg }) => Expr::Yield(YieldExpr {
928-
span,
929-
delegate: false,
930-
arg: Some(arg),
931-
}),
931+
Expr::Await(AwaitExpr { span, arg }) => {
932+
if self.is_async_generator {
933+
let callee = helper!(await_async_generator, "awaitAsyncGenerator");
934+
let arg = Box::new(Expr::Call(CallExpr {
935+
span,
936+
callee,
937+
args: vec![arg.as_arg()],
938+
type_args: Default::default(),
939+
}));
940+
Expr::Yield(YieldExpr {
941+
span,
942+
delegate: false,
943+
arg: Some(arg),
944+
})
945+
} else {
946+
Expr::Yield(YieldExpr {
947+
span,
948+
delegate: false,
949+
arg: Some(arg),
950+
})
951+
}
952+
}
932953
_ => expr,
933954
}
934955
}

ecmascript/transforms/compat/tests/es2017_async_to_generator.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2612,3 +2612,31 @@ test!(
26122612
}
26132613
"
26142614
);
2615+
2616+
test_exec!(
2617+
syntax(),
2618+
|_| async_to_generator(),
2619+
issue_1752_1,
2620+
"
2621+
async function* generate() {
2622+
const results = await Promise.all([
2623+
Promise.resolve(1),
2624+
Promise.resolve(2),
2625+
Promise.resolve(3),
2626+
])
2627+
for (const result of results) {
2628+
console.log(`yield ${result}`)
2629+
yield result
2630+
}
2631+
}
2632+
2633+
async function printValues() {
2634+
const iterator = generate()
2635+
for await (const value of iterator) {
2636+
console.log(`iterator value: ${value}`)
2637+
}
2638+
}
2639+
2640+
printValues()
2641+
"
2642+
);

ecmascript/transforms/module/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ edition = "2018"
66
license = "Apache-2.0/MIT"
77
name = "swc_ecma_transforms_module"
88
repository = "https://github.com/swc-project/swc.git"
9-
version = "0.17.1"
9+
version = "0.17.2"
1010
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1111

1212
[dependencies]

ecmascript/transforms/module/src/util.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,14 @@ impl Scope {
318318
} else {
319319
self.imports
320320
.entry(import.src.value.clone())
321+
.and_modify(|opt| {
322+
if opt.is_none() {
323+
*opt = Some((
324+
local_name_for_src(&import.src.value),
325+
import.src.span.apply_mark(Mark::fresh(Mark::root())),
326+
));
327+
}
328+
})
321329
.or_insert_with(|| {
322330
Some((
323331
local_name_for_src(&import.src.value),

ecmascript/transforms/module/tests/common_js.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4765,3 +4765,20 @@ test!(
47654765
});
47664766
"
47674767
);
4768+
4769+
test!(
4770+
syntax(),
4771+
|_| tr(Default::default()),
4772+
issue_1757_1,
4773+
"
4774+
import 'testlibrary';
4775+
import { aFunc } from 'testlibrary';
4776+
4777+
console.log('aFunc: ', aFunc(1,2));
4778+
",
4779+
"
4780+
'use strict';
4781+
var _testlibrary = require('testlibrary');
4782+
console.log('aFunc: ', (0, _testlibrary).aFunc(1, 2));
4783+
"
4784+
);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"jsc": {
3+
"parser": {
4+
"syntax": "typescript"
5+
},
6+
"target": "es2017"
7+
}
8+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
async function* generate() {
2+
const results = await Promise.all([
3+
Promise.resolve(1),
4+
Promise.resolve(2),
5+
Promise.resolve(3),
6+
])
7+
for (const result of results) {
8+
console.log(`yield ${result}`)
9+
yield result
10+
}
11+
}
12+
13+
async function printValues() {
14+
const iterator = generate()
15+
for await (const value of iterator) {
16+
console.log(`iterator value: ${value}`)
17+
}
18+
}
19+
20+
printValues()

0 commit comments

Comments
 (0)