Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(es/transforms): Fix bugs #2249

Merged
merged 27 commits into from
Sep 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ecmascript/transforms/compat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms_compat"
repository = "https://github.com/swc-project/swc.git"
version = "0.34.2"
version = "0.34.3"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Expand Down
67 changes: 63 additions & 4 deletions ecmascript/transforms/compat/src/es2015/classes/constructor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::iter;
use swc_atoms::JsWord;
use swc_atoms::{js_word, JsWord};
use swc_common::{Mark, DUMMY_SP};
use swc_ecma_ast::*;
use swc_ecma_transforms_base::helper;
Expand Down Expand Up @@ -44,6 +44,10 @@ impl SuperCallFinder {
macro_rules! ignore_return {
($name:ident, $T:ty) => {
fn $name(&mut self, n: $T) -> $T {
if self.in_injected_define_property_call {
return n;
}

let old = self.ignore_return;
self.ignore_return = true;
let n = n.fold_children_with(self);
Expand Down Expand Up @@ -164,6 +168,7 @@ pub(super) struct ConstructorFolder<'a> {
pub is_constructor_default: bool,
/// True when recursing into other function or class.
pub ignore_return: bool,
pub in_injected_define_property_call: bool,
}

/// `None`: `return _possibleConstructorReturn`
Expand All @@ -190,6 +195,28 @@ impl Fold for ConstructorFolder<'_> {
_ => return expr,
}

// We pretend method folding mode for while folding injected `_defineProperty`
// calls.
match expr {
Expr::Call(CallExpr {
callee: ExprOrSuper::Expr(ref callee),
..
}) => match &**callee {
Expr::Ident(Ident {
sym: js_word!("_defineProperty"),
..
}) => {
let old = self.in_injected_define_property_call;
self.in_injected_define_property_call = true;
let n = expr.fold_children_with(self);
self.in_injected_define_property_call = old;
return n;
}
_ => {}
},
_ => {}
}

let expr = expr.fold_children_with(self);

match expr {
Expand Down Expand Up @@ -395,6 +422,7 @@ pub(super) fn replace_this_in_constructor(mark: Mark, c: Constructor) -> (Constr
mark: Mark,
found: bool,
wrap_with_assertion: bool,
in_injected_define_property_call: bool,
}

impl Fold for Replacer {
Expand All @@ -404,8 +432,30 @@ pub(super) fn replace_this_in_constructor(mark: Mark, c: Constructor) -> (Constr
n
}

fn fold_expr(&mut self, expr: Expr) -> Expr {
match expr {
fn fold_expr(&mut self, n: Expr) -> Expr {
// We pretend method folding mode for while folding injected `_defineProperty`
// calls.
match n {
Expr::Call(CallExpr {
callee: ExprOrSuper::Expr(ref callee),
..
}) => match &**callee {
Expr::Ident(Ident {
sym: js_word!("_defineProperty"),
..
}) => {
let old = self.in_injected_define_property_call;
self.in_injected_define_property_call = true;
let n = n.fold_children_with(self);
self.in_injected_define_property_call = old;
return n;
}
_ => {}
},
_ => {}
}

match n {
Expr::This(..) => {
self.found = true;
let this = quote_ident!(DUMMY_SP.apply_mark(self.mark), "_this");
Expand All @@ -421,8 +471,16 @@ pub(super) fn replace_this_in_constructor(mark: Mark, c: Constructor) -> (Constr
Expr::Ident(this)
}
}
_ => expr.fold_children_with(self),

_ => n.fold_children_with(self),
}
}

fn fold_function(&mut self, n: Function) -> Function {
if self.in_injected_define_property_call {
return n;
}
n.fold_children_with(self)
}

fn fold_member_expr(
Expand Down Expand Up @@ -454,6 +512,7 @@ pub(super) fn replace_this_in_constructor(mark: Mark, c: Constructor) -> (Constr
found: false,
mark,
wrap_with_assertion: true,
in_injected_define_property_call: false,
};
let c = c.fold_with(&mut v);

Expand Down
1 change: 1 addition & 0 deletions ecmascript/transforms/compat/src/es2015/classes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ where
},
mark: this_mark,
ignore_return: false,
in_injected_define_property_call: false,
});

insert_this |= (mode == None && !is_always_initialized)
Expand Down
4 changes: 2 additions & 2 deletions ecmascript/transforms/compat/src/es2015/regenerator/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ mod case;
mod hoist;
mod leap;

pub fn regenerator(global_mark: Mark) -> impl Fold {
pub fn regenerator(top_level_mark: Mark) -> impl Fold {
Regenerator {
global_mark,
global_mark: top_level_mark,
regenerator_runtime: Default::default(),
top_level_vars: Default::default(),
}
Expand Down
2 changes: 1 addition & 1 deletion ecmascript/transforms/compat/tests/es2015_classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6539,7 +6539,7 @@ fn exec(input: PathBuf) {
let src = read_to_string(&input).unwrap();
compare_stdout(
Default::default(),
|t| classes(Some(t.comments.clone())),
|t| chain!(class_properties(), classes(Some(t.comments.clone()))),
&src,
);
}
23 changes: 22 additions & 1 deletion ecmascript/transforms/compat/tests/es2017_async_to_generator.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::es2015::regenerator;
use std::{fs::read_to_string, path::PathBuf};
use swc_common::{chain, Mark, Spanned};
use swc_ecma_ast::*;
use swc_ecma_parser::Syntax;
Expand All @@ -9,7 +10,7 @@ use swc_ecma_transforms_compat::{
es2017::async_to_generator,
es2020::class_properties,
};
use swc_ecma_transforms_testing::{test, test_exec};
use swc_ecma_transforms_testing::{compare_stdout, test, test_exec};
use swc_ecma_visit::{Fold, FoldWith};

struct ParenRemover;
Expand Down Expand Up @@ -2684,3 +2685,23 @@ test_exec!(
await res;
"
);

#[testing::fixture("tests/fixture/async-to-generator/**/exec.js")]
fn exec(input: PathBuf) {
let input = read_to_string(&input).unwrap();
compare_stdout(Default::default(), |_| async_to_generator(), &input);
}

#[testing::fixture("tests/fixture/async-to-generator/**/exec.js")]
fn exec_regenerator(input: PathBuf) {
let input = read_to_string(&input).unwrap();
compare_stdout(
Default::default(),
|_| {
let top_level_mark = Mark::fresh(Mark::root());

chain!(async_to_generator(), regenerator(top_level_mark))
},
&input,
);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![allow(deprecated)]

use std::{fs::read_to_string, path::PathBuf};
use swc_common::chain;
use swc_ecma_parser::{EsConfig, Syntax, TsConfig};
use swc_ecma_transforms_base::resolver::resolver;
Expand All @@ -10,7 +11,7 @@ use swc_ecma_transforms_compat::{
es2020::{class_properties, typescript_class_properties},
es3::reserved_words,
};
use swc_ecma_transforms_testing::{test, test_exec, Tester};
use swc_ecma_transforms_testing::{compare_stdout, test, test_exec, Tester};
use swc_ecma_visit::Fold;

fn ts() -> Syntax {
Expand Down Expand Up @@ -5568,3 +5569,9 @@ test!(
}
"
);

#[testing::fixture("tests/fixture/classes/**/exec.js")]
fn exec(input: PathBuf) {
let src = read_to_string(&input).unwrap();
compare_stdout(Default::default(), |_| class_properties(), &src);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const foo = async () => {
try {
console.log(1)
} catch (err) {
console.log(err.message)
}
}

foo()
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
class Foo { }

class Bar extends Foo {
events = {
"abc: click": function abcClick() {
this.data = 123;
console.log(this);
}
}

setData() {
this.data = 456
}
}

const bar = new Bar();
console.log(bar.data);
console.log(bar.events)
console.log(bar.events["abc: click"]());
console.log(bar.data);
bar.setData();
console.log(bar.data);
2 changes: 1 addition & 1 deletion ecmascript/transforms/typescript/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2018"
license = "Apache-2.0/MIT"
name = "swc_ecma_transforms_typescript"
repository = "https://github.com/swc-project/swc.git"
version = "0.40.2"
version = "0.40.3"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Expand Down
23 changes: 14 additions & 9 deletions ecmascript/transforms/typescript/src/strip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1887,13 +1887,8 @@ impl VisitMut for Strip {
}

ModuleItem::ModuleDecl(ModuleDecl::TsImportEquals(import)) => {
if !import.is_export {
continue;
}

stmts.push(ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
span: DUMMY_SP,
decl: Decl::Var(VarDecl {
if !import.is_type_only {
let var = Decl::Var(VarDecl {
span: DUMMY_SP,
kind: VarDeclKind::Var,
decls: vec![VarDeclarator {
Expand All @@ -1903,8 +1898,18 @@ impl VisitMut for Strip {
definite: false,
}],
declare: false,
}),
})));
});
if import.is_export {
stmts.push(ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(
ExportDecl {
span: DUMMY_SP,
decl: var,
},
)));
} else {
stmts.push(ModuleItem::Stmt(Stmt::Decl(var)));
}
}
}

ModuleItem::ModuleDecl(ModuleDecl::TsExportAssignment(export)) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export function Colors(member: Colors.KeyType): Colors {
return Colors.ValueFor(member);
}

export module Colors {
export type KeyType = keyof typeof ValueMap;

export const ValueMap = {
Red: { value: 0.0, label: 'Red' },
Blue: { value: 1.0, label: 'Blue' },
Green: { value: 2.0, label: 'Green' },
} as const;

export const Values: Colors[] = [0.0, 1.0, 2.0];

export function ValueFor(member: KeyType): Colors {
return ValueMap[member]?.value;
}

export function LabelFor(
member: KeyType
): Promise<string | undefined> {
return ValueMap[member]?.label;
}
}
11 changes: 11 additions & 0 deletions ecmascript/transforms/typescript/tests/fixture/issue-1653/input.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace X {
export namespace Z {
export const foo = 0
}
}

namespace Y {
export namespace Z {
export const bar = 1
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
var X;
(function(X) {
var Z;
(function(Z) {
Z.foo = 0;
})(Z || (Z = {
}));
X.Z = Z;
})(X || (X = {
}));
var Y;
(function(Y) {
(function(Z) {
Z.bar = 1;
})(Z || (Z = {
}));
})(Y || (Y = {
}));
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace Shapes {
export namespace Polygons {
export class Triangle { }
export class Square { }
}
}
import polygons = Shapes.Polygons;
let sq = new polygons.Square();
Loading