Changelog: swc v1.1.4

loose mode#

swc now has a loose mode, just like babel 2015 transform. See doc for more detail.

Lots of bug fix (#489)#

I copied almost all tests from babel, and fixed lots of bugs.

resolver pass#

Resolver pass, along with hygiene and fixer, is core of the swc.

Handle object literals correctly#

Previously, key of an object literal may interfere with outer identifiers. It means,

let a = {
b: "c"
};
use(b);

Second usage of b could be interfered by b in a. swc now hanldes it correctly.

hygiene pass#

Renaming of computed property name#

Previously,

class A {
[key#1]: "foo";
[key#2]: "bar";
}

(where #n is hygiene number)

was compiled to

class A {
[key]: "foo";
[key]: "bar";
}

which results in a bug. It is now compiled as

class A {
[key]: "foo";
[key1]: "bar";
}

fixer pass#

export default expression#

The arrow expression lke

export default arrow => foo;

and sequence expression like

export default a, b, c;

is now wrapped with a parenthesis.

sequence expression in an arrow expression#

Previously

() => (a, b, c);

was compiled as

() => a, b, c;

which is wrong.

swc now compiles it as

() => (a, b, c);

classes pass#

Handle super accesses correctly#

swc now handles all valid super accesses. It includes something strange like

class Parent {}
class Outer extends Parent {
constructor() {
class Inner {
[super()] = 1;
}
}
}

computed_properties pass#

Better codegen#

let foo = { a, [b]: c };

is now compiled as

let((_ref = { a }), defineProperty(_ref, b, c), _ref);

instead of

let((_ref = {}), defineProperty(_ref, a, a), defineProperty(_ref, b, c), _ref);

destructuring pass#

for-of, for-in loop support#

From now, for-of loop and for-in are supported.

loose mode is here#

If you want smaller output, you can turn on loose mode.

for_of pass#

assume_array mode is here#

If you want smaller output, you can turn on assume_array by enabling loose mode.

labelled for loop is handled correctly#

Previously, label was stripped out without any error message, and it resulted in a runtime error. swc now handles labaelled loops correctly.

spread pass#

loose mode is here#

If you don't want _toConsumableArray in output, you can turn on loose mode.

template_literal pass#

Performance#

template_literal pass become much more performant by removing redundant .clone()s.

Literal#

The pass try it's best to reduce template literals into constant.

let a = `${"foo"}bar`;

is compiled as

let a = "foobar";

Caching#

Functions generated for tagged template literals are cached. This behavior is same as it of babel.

class_properties pass#

Handle this inside static properties#

swc can now handle

class A {
static f = 1;
}
class B extends A {
static c = super.f;
}

Handle private field in complex assignment#

swc can now handle

class A {
#f = 0;
#g = 0;
constructor() {
([#f, #g = 3] = [1, 2])
}
}

Handle super access in properties#

swc now can handle

class A {
f = 1;
}
class B extends A {
c = super.f;
}

Handle complex super initialization#

swc now can handle

class A extends Parent {
constructor() {
class B extends (super(), Parent) {}
}
}

object rest spread pass#

Computed key with side effect#

swc can now handle complex object pattern like

const { a, [key++]: b, ...c } = foo;

Destructuring null#

const {} = null;

now throws an error, instead of being silent.

async_to_generator pass#

Efficient handling of simple async functions#

swc now emits minimal output for

async () => await promise;
async () => {
await promise;
};

Correct number of parameters#

swc now convert async functions in a way that preserves function.length.