mirror of
https://github.com/swc-project/swc.git
synced 2024-12-24 22:22:34 +03:00
f8995848b8
swc_ecma_transforms_proposal: - Try the type of the LHS of an assignment pattern. (#2428)
6014 lines
125 KiB
Rust
6014 lines
125 KiB
Rust
#![cfg(all(
|
|
feature = "swc_ecma_transforms_compat",
|
|
feature = "swc_ecma_transforms_module",
|
|
feature = "swc_ecma_transforms_optimization",
|
|
feature = "swc_ecma_transforms_proposal",
|
|
))]
|
|
|
|
use swc_common::{chain, Mark};
|
|
use swc_ecma_parser::{EsConfig, Syntax, TsConfig};
|
|
use swc_ecma_transforms_base::resolver::resolver;
|
|
use swc_ecma_transforms_compat::{
|
|
es2015::{classes, function_name},
|
|
es2020::class_properties,
|
|
};
|
|
use swc_ecma_transforms_module::common_js;
|
|
use swc_ecma_transforms_optimization::simplify::inlining;
|
|
use swc_ecma_transforms_proposal::{decorators, decorators::Config};
|
|
use swc_ecma_transforms_testing::{test, test_exec};
|
|
use swc_ecma_transforms_typescript::strip;
|
|
use swc_ecma_visit::Fold;
|
|
|
|
fn ts() -> Syntax {
|
|
Syntax::Typescript(TsConfig {
|
|
decorators: true,
|
|
..Default::default()
|
|
})
|
|
}
|
|
|
|
fn syntax(decorators_before_export: bool) -> Syntax {
|
|
Syntax::Es(EsConfig {
|
|
decorators_before_export,
|
|
decorators: true,
|
|
class_props: true,
|
|
..Default::default()
|
|
})
|
|
}
|
|
|
|
fn tr() -> impl Fold {
|
|
chain!(
|
|
decorators(Default::default()),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
)
|
|
}
|
|
|
|
fn ts_transform() -> impl Fold {
|
|
chain!(
|
|
decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
simple_strip(),
|
|
)
|
|
}
|
|
|
|
fn simple_strip() -> impl Fold {
|
|
strip::strip_with_config(strip::Config {
|
|
no_empty_export: true,
|
|
..Default::default()
|
|
})
|
|
}
|
|
|
|
/// Folder for `transformation_*` tests
|
|
fn transformation() -> impl Fold {
|
|
chain!(decorators(Default::default()), simple_strip(),)
|
|
}
|
|
|
|
// transformation_declaration
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_declaration,
|
|
r#"
|
|
@dec()
|
|
class A {}
|
|
"#,
|
|
r#"
|
|
let A = _decorate([dec()], function (_initialize) {
|
|
|
|
|
|
class A {
|
|
constructor() {
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: A,
|
|
d: []
|
|
};
|
|
});
|
|
|
|
"#
|
|
);
|
|
// transformation_initialize_after_super_multiple
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_initialize_after_super_multiple,
|
|
r#"
|
|
@dec
|
|
class B extends A {
|
|
constructor() {
|
|
const foo = () => { super(); };
|
|
|
|
if (a) { super(); }
|
|
else { foo(); }
|
|
|
|
while (0) { super(); }
|
|
|
|
super();
|
|
}
|
|
}
|
|
|
|
|
|
"#,
|
|
r#"
|
|
let B = _decorate([dec], function (_initialize, _A) {
|
|
|
|
|
|
class B extends _A {
|
|
constructor() {
|
|
const foo = () => {
|
|
super();
|
|
|
|
_initialize(this);
|
|
};
|
|
|
|
if (a) {
|
|
super();
|
|
|
|
_initialize(this);
|
|
} else {
|
|
foo();
|
|
}
|
|
|
|
while (0) {
|
|
super();
|
|
|
|
_initialize(this);
|
|
}
|
|
|
|
super();
|
|
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: B,
|
|
d: []
|
|
};
|
|
}, A);
|
|
|
|
"#
|
|
);
|
|
// transformation_export_default_anonymous
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_export_default_anonymous,
|
|
r#"
|
|
export default @dec() class {}
|
|
|
|
"#,
|
|
r#"
|
|
export default _decorate([dec()], function (_initialize) {
|
|
class _class {
|
|
constructor() {
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: _class,
|
|
d: []
|
|
};
|
|
});
|
|
|
|
"#
|
|
);
|
|
// transformation_initialize_after_super_statement
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_initialize_after_super_statement,
|
|
r#"
|
|
@dec
|
|
class B extends A {
|
|
constructor() {
|
|
super();
|
|
}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
let B = _decorate([dec], function (_initialize, _A) {
|
|
|
|
|
|
class B extends _A {
|
|
constructor() {
|
|
super();
|
|
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: B,
|
|
d: []
|
|
};
|
|
}, A);
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_created_own_method_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_created_own_method_exec,
|
|
r#"
|
|
function pushElement(e) {
|
|
return function (c) { c.elements.push(e); return c };
|
|
}
|
|
|
|
function method() {}
|
|
|
|
@pushElement({
|
|
kind: "method",
|
|
placement: "own",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: method,
|
|
}
|
|
})
|
|
class A {}
|
|
|
|
expect(A).not.toHaveProperty("foo");
|
|
expect(A.prototype).not.toHaveProperty("foo");
|
|
|
|
expect(Object.getOwnPropertyDescriptor(new A(), "foo")).toEqual({
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: method,
|
|
});
|
|
|
|
"#
|
|
);
|
|
// finishers_return_class_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
finishers_return_class_exec,
|
|
r#"
|
|
class C {}
|
|
|
|
function decorator(el) {
|
|
return Object.assign(el, {
|
|
finisher() {
|
|
return C;
|
|
},
|
|
});
|
|
}
|
|
|
|
class A {
|
|
@decorator
|
|
foo() {}
|
|
}
|
|
|
|
expect(A).toBe(C);
|
|
|
|
"#
|
|
);
|
|
// misc_method_name_not_shadow
|
|
test!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
misc_method_name_not_shadow,
|
|
r#"
|
|
var method = 1;
|
|
|
|
@decorator
|
|
class Foo {
|
|
method() {
|
|
return method;
|
|
}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
var method = 1;
|
|
let Foo = _decorate([decorator], function (_initialize) {
|
|
|
|
|
|
class Foo {
|
|
constructor() {
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: Foo,
|
|
d: [{
|
|
kind: "method",
|
|
key: "method",
|
|
value: function method1() {
|
|
return method;
|
|
}
|
|
}]
|
|
};
|
|
});
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_original_class_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_original_class_exec,
|
|
r#"
|
|
var el = null;
|
|
|
|
@(_ => el = _)
|
|
class A {}
|
|
|
|
expect(el).toEqual(Object.defineProperty({
|
|
kind: "class",
|
|
elements: []
|
|
}, Symbol.toStringTag, { value: "Descriptor" }));
|
|
|
|
@(_ => el = _)
|
|
class B {
|
|
foo = 2;
|
|
static bar() {}
|
|
get baz() {}
|
|
set baz(x) {}
|
|
}
|
|
|
|
expect(el.elements).toHaveLength(3);
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_create_existing_element_with_extras_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_create_existing_element_with_extras_exec,
|
|
r#"
|
|
function decorate(el) {
|
|
el.extras = [{
|
|
kind: "method",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: function() {},
|
|
}
|
|
}];
|
|
|
|
return el;
|
|
}
|
|
|
|
expect(() => {
|
|
class A {
|
|
@decorate
|
|
bar() {}
|
|
|
|
foo() {}
|
|
}
|
|
}).toThrow(TypeError);
|
|
|
|
|
|
|
|
"#
|
|
);
|
|
// finishers_no_in_extras_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
finishers_no_in_extras_exec,
|
|
r#"
|
|
class C {}
|
|
|
|
function decorator(el) {
|
|
return Object.assign(el, {
|
|
extras: [
|
|
Object.assign({}, el, {
|
|
key: "bar",
|
|
finisher() {
|
|
return C;
|
|
}
|
|
})
|
|
]
|
|
});
|
|
}
|
|
|
|
expect(() => {
|
|
class A {
|
|
@decorator
|
|
foo() {}
|
|
}
|
|
}).toThrow();
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_computed_keys_same_value
|
|
test!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_computed_keys_same_value,
|
|
r#"
|
|
@(_ => desc = _)
|
|
class Foo {
|
|
[getKeyI()]() {
|
|
return 1;
|
|
}
|
|
|
|
[getKeyJ()]() {
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
let Foo = _decorate([_ => desc = _], function (_initialize) {
|
|
|
|
|
|
class Foo {
|
|
constructor() {
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: Foo,
|
|
d: [{
|
|
kind: "method",
|
|
key: getKeyI(),
|
|
value: function () {
|
|
return 1;
|
|
}
|
|
}, {
|
|
kind: "method",
|
|
key: getKeyJ(),
|
|
value: function () {
|
|
return 2;
|
|
}
|
|
}]
|
|
};
|
|
});
|
|
|
|
"#
|
|
);
|
|
// transformation_only_decorated
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_only_decorated,
|
|
r#"
|
|
class B {
|
|
foo = 2;
|
|
bar() {}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
class B {
|
|
bar() {}
|
|
constructor() {
|
|
this.foo = 2;
|
|
}
|
|
|
|
}
|
|
|
|
"#
|
|
);
|
|
// ordering_finishers_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
ordering_finishers_exec,
|
|
r#"
|
|
var log = [];
|
|
|
|
function push(x) { log.push(x); return x; }
|
|
|
|
function logFinisher(x) {
|
|
return function (el) {
|
|
return Object.assign(el, {
|
|
finisher() { push(x); }
|
|
});
|
|
};
|
|
}
|
|
|
|
@logFinisher(9)
|
|
@logFinisher(8)
|
|
class A {
|
|
@logFinisher(1)
|
|
@logFinisher(0)
|
|
foo;
|
|
|
|
@logFinisher(3)
|
|
@logFinisher(2)
|
|
static bar() {}
|
|
|
|
@logFinisher(5)
|
|
@logFinisher(4)
|
|
static baz;
|
|
|
|
@logFinisher(7)
|
|
@logFinisher(6)
|
|
asd() {}
|
|
}
|
|
|
|
var numsFrom0to9 = Array.from({ length: 10 }, (_, i) => i);
|
|
expect(log).toEqual(numsFrom0to9);
|
|
|
|
"#
|
|
);
|
|
// transformation_initiailzer_after_super_bug_8808
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_initiailzer_after_super_bug_8808,
|
|
r#"
|
|
@decorator(parameter)
|
|
class Sub extends Super {
|
|
constructor() {
|
|
super().method();
|
|
}
|
|
}
|
|
"#,
|
|
r#"
|
|
let Sub = _decorate([decorator(parameter)], function (_initialize, _Super) {
|
|
|
|
|
|
class Sub extends _Super {
|
|
constructor() {
|
|
var _temp;
|
|
|
|
(_temp = super(), _initialize(this), _temp).method();
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: Sub,
|
|
d: []
|
|
};
|
|
}, Super);
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_original_method_overwritten_no_decorators_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_original_method_overwritten_no_decorators_exec,
|
|
r#"
|
|
var el;
|
|
|
|
@(_ => el = _)
|
|
class A {
|
|
method() {
|
|
return 1;
|
|
}
|
|
|
|
method() {
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
expect(el.elements).toHaveLength(1);
|
|
|
|
expect(A.prototype.method()).toBe(2);
|
|
|
|
"#
|
|
);
|
|
// transformation_arguments
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_arguments,
|
|
r#"
|
|
@dec(a, b, ...c)
|
|
class A {
|
|
@dec(a, b, ...c) method() {}
|
|
}
|
|
"#,
|
|
r#"
|
|
let A = _decorate([dec(a, b, ...c)], function (_initialize) {
|
|
|
|
|
|
class A {
|
|
constructor() {
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: A,
|
|
d: [{
|
|
kind: "method",
|
|
decorators: [dec(a, b, ...c)],
|
|
key: "method",
|
|
value: function method() {}
|
|
}]
|
|
};
|
|
});
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_original_method_overwritten_both_decorated_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_original_method_overwritten_both_decorated_exec,
|
|
r#"
|
|
expect(() => {
|
|
class A {
|
|
@(el => el)
|
|
method() {
|
|
return 1;
|
|
}
|
|
|
|
@(el => el)
|
|
method() {
|
|
return 2;
|
|
}
|
|
}
|
|
}).toThrow(ReferenceError);
|
|
|
|
"#
|
|
);
|
|
// ordering_field_initializers_after_methods_exec
|
|
test_exec!(
|
|
// Babel 7.3.0 fails
|
|
ignore,
|
|
syntax(false),
|
|
|_| tr(),
|
|
ordering_field_initializers_after_methods_exec,
|
|
r#"
|
|
var counter = 0;
|
|
|
|
@(x => x)
|
|
class A {
|
|
foo = (() => {
|
|
counter++;
|
|
expect(typeof this.method).toBe("function");
|
|
expect(this.foo).toBeUndefined();
|
|
expect(this.bar).toBeUndefined();
|
|
return "foo";
|
|
})();
|
|
|
|
method() {}
|
|
|
|
bar = (() => {
|
|
counter++;
|
|
expect(typeof this.method).toBe("function");
|
|
expect(this.foo).toBe("foo");
|
|
expect(this.bar).toBeUndefined();
|
|
})();
|
|
}
|
|
|
|
expect(counter).toBe(0);
|
|
|
|
new A();
|
|
|
|
expect(counter).toBe(2);
|
|
|
|
"#
|
|
);
|
|
// misc_to_primitive_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
misc_to_primitive_exec,
|
|
r#"
|
|
let calls = 0;
|
|
const baz = {
|
|
[Symbol.toPrimitive]() {
|
|
calls++;
|
|
return "baz";
|
|
}
|
|
}
|
|
|
|
function dec() {}
|
|
|
|
@dec
|
|
class A {
|
|
[baz]() {}
|
|
}
|
|
|
|
expect(calls).toBe(1);
|
|
|
|
"#
|
|
);
|
|
// ordering
|
|
// transformation_initialize_after_super_expression
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_initialize_after_super_expression,
|
|
r#"
|
|
@dec
|
|
class B extends A {
|
|
constructor() {
|
|
(0, super());
|
|
}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
let B = _decorate([dec], function (_initialize, _A) {
|
|
|
|
|
|
class B extends _A {
|
|
constructor() {
|
|
var _temp;
|
|
|
|
_temp = super(), _initialize(this), _temp;
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: B,
|
|
d: []
|
|
};
|
|
}, A);
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_not_reused_field_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_not_reused_field_exec,
|
|
r#"
|
|
var dec1, dec2;
|
|
|
|
class A {
|
|
@(_ => dec1 = _)
|
|
@(_ => dec2 = _)
|
|
field = {}
|
|
}
|
|
|
|
expect(dec1).toEqual(dec2);
|
|
expect(dec1).not.toBe(dec2);
|
|
expect(dec1.descriptor).toEqual(dec2.descriptor);
|
|
expect(dec1.descriptor).not.toBe(dec2.descriptor);
|
|
expect(dec1.initializer).toBe(dec2.initializer);
|
|
|
|
"#
|
|
);
|
|
// transformation_export_default_named
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_export_default_named,
|
|
r#"
|
|
export default @dec() class Foo {}
|
|
|
|
"#,
|
|
r#"
|
|
let Foo = _decorate([dec()], function (_initialize) {
|
|
class Foo {
|
|
constructor() {
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: Foo,
|
|
d: []
|
|
};
|
|
});
|
|
export { Foo as default };
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_original_own_field_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_original_own_field_exec,
|
|
r#"
|
|
var el = null;
|
|
var val = {};
|
|
|
|
class A {
|
|
@(_ => el = _)
|
|
foo = val;
|
|
}
|
|
|
|
expect(el).toEqual(Object.defineProperty({
|
|
kind: "field",
|
|
key: "foo",
|
|
placement: "own",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
},
|
|
initializer: expect.any(Function),
|
|
}, Symbol.toStringTag, { value: "Descriptor" }));
|
|
|
|
expect(el.initializer()).toBe(val);
|
|
|
|
"#
|
|
);
|
|
// transformation
|
|
// ordering_decorators_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
ordering_decorators_exec,
|
|
r#"
|
|
var log = [];
|
|
|
|
function push(x) { log.push(x); return x; }
|
|
|
|
function logDecoratorRun(a, b) {
|
|
push(a);
|
|
return function (el) { push(b); return el; };
|
|
}
|
|
|
|
@logDecoratorRun(0, 23)
|
|
@logDecoratorRun(1, 22)
|
|
class A {
|
|
@logDecoratorRun(2, 15)
|
|
@logDecoratorRun(3, 14)
|
|
[push(4)] = "4";
|
|
|
|
@logDecoratorRun(5, 17)
|
|
@logDecoratorRun(6, 16)
|
|
static [push(7)]() {}
|
|
|
|
@logDecoratorRun(8, 19)
|
|
@logDecoratorRun(9, 18)
|
|
static [push(10)] = "10";
|
|
|
|
@logDecoratorRun(11, 21)
|
|
@logDecoratorRun(12, 20)
|
|
[push(13)]() {}
|
|
}
|
|
|
|
var numsFrom0to23 = Array.from({ length: 24 }, (_, i) => i);
|
|
expect(log).toEqual(numsFrom0to23);
|
|
|
|
"#
|
|
);
|
|
// transformation_async_generator_method
|
|
// element_descriptors_default_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_default_exec,
|
|
r#"
|
|
function decorate(el) {
|
|
el.descriptor.value = 2;
|
|
}
|
|
|
|
var Foo;
|
|
|
|
expect(() => {
|
|
Foo = @(() => void 0) class Foo {
|
|
@decorate
|
|
bar() {}
|
|
}
|
|
}).not.toThrow();
|
|
|
|
expect(Foo.prototype.bar).toBe(2);
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_original_prototype_method_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_original_prototype_method_exec,
|
|
r#"
|
|
var el = null;
|
|
|
|
class A {
|
|
@(_ => el = _)
|
|
foo() {}
|
|
}
|
|
|
|
expect(el).toEqual(Object.defineProperty({
|
|
kind: "method",
|
|
key: "foo",
|
|
placement: "prototype",
|
|
descriptor: {
|
|
enumerable: false,
|
|
configurable: true,
|
|
writable: true,
|
|
value: A.prototype.foo,
|
|
},
|
|
}, Symbol.toStringTag, { value: "Descriptor" }));
|
|
|
|
"#
|
|
);
|
|
// misc_method_name_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
misc_method_name_exec,
|
|
r#"
|
|
function decorator() {}
|
|
|
|
@decorator
|
|
class Foo {
|
|
method() {}
|
|
}
|
|
|
|
expect(Foo.prototype.method.name).toBe("method");
|
|
|
|
"#
|
|
);
|
|
// transformation_strict_directive
|
|
test!(
|
|
ignore,
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_strict_directive,
|
|
r#"
|
|
(() => {
|
|
|
|
|
|
@dec
|
|
class Foo {
|
|
method() {}
|
|
}
|
|
});
|
|
|
|
(() => {
|
|
@dec
|
|
class Foo {
|
|
method() {}
|
|
}
|
|
});
|
|
|
|
"#,
|
|
r#"
|
|
() => {
|
|
|
|
|
|
let Foo = _decorate([dec], function (_initialize) {
|
|
class Foo {
|
|
constructor() {
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: Foo,
|
|
d: [{
|
|
kind: "method",
|
|
key: "method",
|
|
value: function method() {}
|
|
}]
|
|
};
|
|
});
|
|
};
|
|
|
|
() => {
|
|
let Foo = _decorate([dec], function (_initialize2) {
|
|
|
|
|
|
class Foo {
|
|
constructor() {
|
|
_initialize2(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: Foo,
|
|
d: [{
|
|
kind: "method",
|
|
key: "method",
|
|
value: function method() {}
|
|
}]
|
|
};
|
|
});
|
|
};
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_created_static_method_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_created_static_method_exec,
|
|
r#"
|
|
function pushElement(e) {
|
|
return function (c) { c.elements.push(e); return c };
|
|
}
|
|
|
|
function method() {}
|
|
|
|
@pushElement({
|
|
kind: "method",
|
|
placement: "static",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: method,
|
|
}
|
|
})
|
|
class A {}
|
|
|
|
expect(A.prototype).not.toHaveProperty("foo");
|
|
expect(new A()).not.toHaveProperty("foo");
|
|
|
|
expect(Object.getOwnPropertyDescriptor(A, "foo")).toEqual({
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: method,
|
|
});
|
|
|
|
"#
|
|
);
|
|
// misc_method_name_not_shadow_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
misc_method_name_not_shadow_exec,
|
|
r#"
|
|
function decorator() {}
|
|
|
|
var method = 1;
|
|
|
|
@decorator
|
|
class Foo {
|
|
method() {
|
|
return method;
|
|
}
|
|
}
|
|
|
|
expect(new Foo().method()).toBe(1);
|
|
expect(Foo.prototype.method.name).toBe("method");
|
|
|
|
"#
|
|
);
|
|
// transformation_class_decorators_yield_await
|
|
// duplicated_keys_original_method_overwritten_second_decorated_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_original_method_overwritten_second_decorated_exec,
|
|
r#"
|
|
expect(() => {
|
|
class A {
|
|
@(el => el)
|
|
method() {
|
|
return 1;
|
|
}
|
|
|
|
method() {
|
|
return 2;
|
|
}
|
|
}
|
|
}).toThrow(ReferenceError);
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_get_set_both_decorated_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_get_set_both_decorated_exec,
|
|
r#"
|
|
function dec(el) { return el }
|
|
|
|
expect(() => {
|
|
class A {
|
|
@dec
|
|
get foo() {}
|
|
|
|
@dec
|
|
set foo(x) {}
|
|
}
|
|
}).toThrow(ReferenceError);
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_original_method_overwritten_first_decorated_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_original_method_overwritten_first_decorated_exec,
|
|
r#"
|
|
expect(() => {
|
|
class A {
|
|
method() {
|
|
return 1;
|
|
}
|
|
|
|
@(el => el)
|
|
method() {
|
|
return 2;
|
|
}
|
|
}
|
|
}).toThrow(ReferenceError);
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_created_prototype_field_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_created_prototype_field_exec,
|
|
r#"
|
|
function pushElement(e) {
|
|
return function (c) { c.elements.push(e); return c };
|
|
}
|
|
|
|
var value = {};
|
|
|
|
@pushElement({
|
|
kind: "field",
|
|
placement: "prototype",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
},
|
|
initializer() {
|
|
return value;
|
|
}
|
|
})
|
|
class A {}
|
|
|
|
expect(A).not.toHaveProperty("foo");
|
|
|
|
expect(Object.getOwnPropertyDescriptor(A.prototype, "foo")).toEqual({
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: value,
|
|
});
|
|
|
|
"#
|
|
);
|
|
// transformation_extends
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_extends,
|
|
r#"
|
|
@dec class A extends B {}
|
|
|
|
"#,
|
|
r#"
|
|
let A = _decorate([dec], function (_initialize, _B) {
|
|
|
|
|
|
class A extends _B {
|
|
constructor(...args) {
|
|
super(...args);
|
|
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: A,
|
|
d: []
|
|
};
|
|
}, B);
|
|
|
|
"#
|
|
);
|
|
// finishers
|
|
// transformation_extends_await
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_extends_await,
|
|
r#"
|
|
async function g() {
|
|
@dec class A extends (await B) {}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
async function g() {
|
|
let A = _decorate([dec], function (_initialize, _super) {
|
|
|
|
|
|
class A extends _super {
|
|
constructor(...args) {
|
|
super(...args);
|
|
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: A,
|
|
d: []
|
|
};
|
|
}, await B);
|
|
}
|
|
|
|
"#
|
|
);
|
|
// transformation_extends_yield
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_extends_yield,
|
|
r#"
|
|
function* g() {
|
|
@dec class A extends (yield B) {}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
function* g() {
|
|
let A = _decorate([dec], function (_initialize, _super) {
|
|
|
|
|
|
class A extends _super {
|
|
constructor(...args) {
|
|
super(...args);
|
|
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: A,
|
|
d: []
|
|
};
|
|
}, (yield B));
|
|
}
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_created_static_field_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_created_static_field_exec,
|
|
r#"
|
|
function pushElement(e) {
|
|
return function (c) { c.elements.push(e); return c };
|
|
}
|
|
|
|
var value = {};
|
|
|
|
@pushElement({
|
|
kind: "field",
|
|
placement: "static",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
},
|
|
initializer() {
|
|
return value;
|
|
}
|
|
})
|
|
class A {}
|
|
|
|
expect(A.prototype).not.toHaveProperty("foo");
|
|
expect(new A()).not.toHaveProperty("foo");
|
|
|
|
expect(Object.getOwnPropertyDescriptor(A, "foo")).toEqual({
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: value,
|
|
});
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_created_own_field_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_created_own_field_exec,
|
|
r#"
|
|
function pushElement(e) {
|
|
return function (c) { c.elements.push(e); return c };
|
|
}
|
|
|
|
var value = {};
|
|
|
|
@pushElement({
|
|
kind: "field",
|
|
placement: "own",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
},
|
|
initializer() {
|
|
return value;
|
|
}
|
|
})
|
|
class A {}
|
|
|
|
expect(A).not.toHaveProperty("foo");
|
|
expect(A.prototype).not.toHaveProperty("foo");
|
|
|
|
expect(Object.getOwnPropertyDescriptor(new A(), "foo")).toEqual({
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: value,
|
|
});
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_not_reused_method_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_not_reused_method_exec,
|
|
r#"
|
|
var dec1, dec2;
|
|
|
|
class A {
|
|
@(_ => dec1 = _)
|
|
@(_ => dec2 = _)
|
|
fn() {}
|
|
}
|
|
|
|
expect(dec1).toEqual(dec2);
|
|
expect(dec1).not.toBe(dec2);
|
|
expect(dec1.descriptor).toEqual(dec2.descriptor);
|
|
expect(dec1.descriptor).not.toBe(dec2.descriptor);
|
|
expect(dec1.descriptor.value).toBe(dec2.descriptor.value);
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_not_reused_class_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_not_reused_class_exec,
|
|
r#"
|
|
var dec1, dec2;
|
|
|
|
@(_ => dec1 = _)
|
|
@(_ => dec2 = _)
|
|
class A {}
|
|
|
|
expect(dec1).toEqual(dec2);
|
|
expect(dec1).not.toBe(dec2);
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_computed_keys_same_ast_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_computed_keys_same_ast_exec,
|
|
r#"
|
|
var i = 0;
|
|
|
|
function getKey() {
|
|
return (i++).toString();
|
|
}
|
|
|
|
var desc;
|
|
|
|
@(_ => desc = _)
|
|
class Foo {
|
|
[getKey()]() {
|
|
return 1;
|
|
}
|
|
|
|
[getKey()]() {
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
expect(desc.elements).toHaveLength(2);
|
|
|
|
expect(desc.elements[0].key).toBe("0");
|
|
expect(desc.elements[0].descriptor.value()).toBe(1);
|
|
|
|
expect(desc.elements[1].key).toBe("1");
|
|
expect(desc.elements[1].descriptor.value()).toBe(2);
|
|
|
|
expect(i).toBe(2);
|
|
|
|
"#
|
|
);
|
|
// transformation_initialize_after_super_bug_8931
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_initialize_after_super_bug_8931,
|
|
r#"
|
|
@dec
|
|
class B extends A {
|
|
constructor() {
|
|
super();
|
|
[];
|
|
}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
let B = _decorate([dec], function (_initialize, _A) {
|
|
|
|
|
|
class B extends _A {
|
|
constructor() {
|
|
super();
|
|
|
|
_initialize(this);
|
|
|
|
[];
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: B,
|
|
d: []
|
|
};
|
|
}, A);
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys
|
|
// ordering_static_field_initializers_after_methods_exec
|
|
test_exec!(
|
|
// Babel 7.3.0 fails
|
|
ignore,
|
|
syntax(false),
|
|
|_| tr(),
|
|
ordering_static_field_initializers_after_methods_exec,
|
|
r#"
|
|
var counter = 0;
|
|
|
|
@(x => x)
|
|
class A {
|
|
static foo = (() => {
|
|
counter++;
|
|
expect(typeof this.method).toBe("function");
|
|
expect(this.foo).toBeUndefined();
|
|
expect(this.bar).toBeUndefined();
|
|
return "foo";
|
|
})();
|
|
|
|
static method() {}
|
|
|
|
static bar = (() => {
|
|
counter++;
|
|
expect(typeof this.method).toBe("function");
|
|
expect(this.foo).toBe("foo");
|
|
expect(this.bar).toBeUndefined();
|
|
})();
|
|
}
|
|
|
|
expect(counter).toBe(2);
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_original_static_method_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_original_static_method_exec,
|
|
r#"
|
|
var el = null;
|
|
|
|
class A {
|
|
@(_ => el = _)
|
|
static foo() {}
|
|
}
|
|
|
|
expect(el).toEqual(Object.defineProperty({
|
|
kind: "method",
|
|
key: "foo",
|
|
placement: "static",
|
|
descriptor: {
|
|
enumerable: false,
|
|
configurable: true,
|
|
writable: true,
|
|
value: A.foo,
|
|
},
|
|
}, Symbol.toStringTag, { value: "Descriptor" }));
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_extras_duplicated_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_extras_duplicated_exec,
|
|
r#"
|
|
function decorate(el) {
|
|
el.extras = [{
|
|
kind: "method",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: function() {},
|
|
}
|
|
}, {
|
|
kind: "method",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: function() {},
|
|
}
|
|
}];
|
|
|
|
return el;
|
|
}
|
|
|
|
expect(() => {
|
|
class A {
|
|
@decorate
|
|
method() {}
|
|
}
|
|
}).toThrow(TypeError);
|
|
|
|
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_extras_same_as_return_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_extras_same_as_return_exec,
|
|
r#"
|
|
function decorate(el) {
|
|
return {
|
|
kind: "method",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: function() {},
|
|
},
|
|
extras: [{
|
|
kind: "method",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: function() {},
|
|
}
|
|
}]
|
|
};
|
|
}
|
|
|
|
expect(() => {
|
|
class A {
|
|
@decorate
|
|
method() {}
|
|
}
|
|
}).toThrow(TypeError);
|
|
|
|
|
|
|
|
"#
|
|
);
|
|
// finishers_class_as_parameter_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
finishers_class_as_parameter_exec,
|
|
r#"
|
|
var C;
|
|
|
|
function decorator(el) {
|
|
return Object.assign(el, {
|
|
finisher(Class) {
|
|
C = Class;
|
|
},
|
|
});
|
|
}
|
|
|
|
class A {
|
|
@decorator
|
|
foo() {}
|
|
}
|
|
|
|
expect(C).toBe(A);
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_moved_and_created_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_moved_and_created_exec,
|
|
r#"
|
|
var value1, value2 = {};
|
|
|
|
function makeStatic(el) {
|
|
el.placement = "static";
|
|
return el;
|
|
}
|
|
|
|
function defineBar(el) {
|
|
el.extras = [{
|
|
key: "bar",
|
|
kind: "method",
|
|
placement: "prototype",
|
|
descriptor: {
|
|
value: value2,
|
|
},
|
|
}];
|
|
return el;
|
|
}
|
|
|
|
function storeValue(el) {
|
|
value1 = el.descriptor.value;
|
|
return el;
|
|
}
|
|
|
|
class Foo {
|
|
@defineBar
|
|
@makeStatic
|
|
@storeValue
|
|
bar() {}
|
|
}
|
|
|
|
expect(Foo.bar).toBe(value1);
|
|
expect(Foo.prototype.bar).toBe(value2);
|
|
|
|
"#
|
|
);
|
|
// transformation_expression
|
|
test!(
|
|
syntax(false),
|
|
|_| transformation(),
|
|
transformation_expression,
|
|
r#"
|
|
(@dec() class {});
|
|
"#,
|
|
r#"
|
|
_decorate([dec()], function (_initialize) {
|
|
|
|
|
|
class _class {
|
|
constructor() {
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: _class,
|
|
d: []
|
|
};
|
|
});
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_original_method_prototype_and_static_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_original_method_prototype_and_static_exec,
|
|
r#"
|
|
var el;
|
|
|
|
@(_ => el = _)
|
|
class A {
|
|
method() {
|
|
return 1;
|
|
}
|
|
|
|
static method() {
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
expect(el.elements).toHaveLength(2);
|
|
|
|
expect(A.prototype.method()).toBe(1);
|
|
expect(A.method()).toBe(2);
|
|
|
|
"#
|
|
);
|
|
// element_descriptors
|
|
// duplicated_keys_computed_keys_same_ast
|
|
test!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_computed_keys_same_ast,
|
|
r#"
|
|
@(_ => desc = _)
|
|
class Foo {
|
|
[getKey()]() {
|
|
return 1;
|
|
}
|
|
|
|
[getKey()]() {
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
let Foo = _decorate([_ => desc = _], function (_initialize) {
|
|
|
|
|
|
class Foo {
|
|
constructor() {
|
|
_initialize(this);
|
|
}
|
|
|
|
}
|
|
|
|
return {
|
|
F: Foo,
|
|
d: [{
|
|
kind: "method",
|
|
key: getKey(),
|
|
value: function () {
|
|
return 1;
|
|
}
|
|
}, {
|
|
kind: "method",
|
|
key: getKey(),
|
|
value: function () {
|
|
return 2;
|
|
}
|
|
}]
|
|
};
|
|
});
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_created_prototype_method_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_created_prototype_method_exec,
|
|
r#"
|
|
function pushElement(e) {
|
|
return function (c) { c.elements.push(e); return c };
|
|
}
|
|
|
|
function method() {}
|
|
|
|
@pushElement({
|
|
kind: "method",
|
|
placement: "prototype",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: method,
|
|
}
|
|
})
|
|
class A {}
|
|
|
|
expect(A).not.toHaveProperty("foo");
|
|
|
|
expect(Object.getOwnPropertyDescriptor(A.prototype, "foo")).toEqual({
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: method,
|
|
});
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_create_existing_element_from_method_decorator_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_create_existing_element_from_method_decorator_exec,
|
|
r#"
|
|
function decorate() {
|
|
return {
|
|
kind: "method",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: function() {},
|
|
}
|
|
};
|
|
}
|
|
|
|
expect(() => {
|
|
class A {
|
|
@decorate
|
|
bar() {}
|
|
|
|
foo() {}
|
|
}
|
|
}).toThrow(TypeError);
|
|
|
|
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_original_static_field_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_original_static_field_exec,
|
|
r#"
|
|
var el = null;
|
|
var val = { foo: 2 };
|
|
|
|
class A {
|
|
@(_ => el = _)
|
|
static foo = val;
|
|
}
|
|
|
|
expect(el).toEqual(Object.defineProperty({
|
|
kind: "field",
|
|
key: "foo",
|
|
placement: "static",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
},
|
|
initializer: expect.any(Function),
|
|
}, Symbol.toStringTag, { value: "Descriptor" }));
|
|
|
|
expect(el.initializer()).toBe(val);
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_coalesce_get_set_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_coalesce_get_set_exec,
|
|
r#"
|
|
var el, el1;
|
|
|
|
@(_ => el = _)
|
|
class A {
|
|
@(_ => el1 = _)
|
|
get foo() { return 1; }
|
|
|
|
set foo(x) { return 2; }
|
|
}
|
|
|
|
expect(el.elements).toHaveLength(1);
|
|
|
|
expect(el1).toEqual(expect.objectContaining({
|
|
descriptor: expect.objectContaining({
|
|
get: expect.any(Function),
|
|
set: expect.any(Function)
|
|
})
|
|
}));
|
|
|
|
var desc = Object.getOwnPropertyDescriptor(A.prototype, "foo");
|
|
expect(desc.get()).toBe(1);
|
|
expect(desc.set()).toBe(2);
|
|
|
|
"#
|
|
);
|
|
// misc
|
|
// transformation_extends_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
transformation_extends_exec,
|
|
r#"
|
|
class B {}
|
|
|
|
@(_ => _)
|
|
class A extends B {}
|
|
|
|
expect(new A).toBeInstanceOf(A);
|
|
expect(new A).toBeInstanceOf(B);
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_create_existing_element_from_class_decorator_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_create_existing_element_from_class_decorator_exec,
|
|
r#"
|
|
function pushElement(e) {
|
|
return function (c) { c.elements.push(e); return c };
|
|
}
|
|
|
|
expect(() => {
|
|
@pushElement({
|
|
kind: "method",
|
|
key: "foo",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
value: function() {},
|
|
}
|
|
})
|
|
class A {
|
|
foo() {}
|
|
}
|
|
}).toThrow(TypeError);
|
|
|
|
|
|
|
|
"#
|
|
);
|
|
// duplicated_keys_computed_keys_same_value_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
duplicated_keys_computed_keys_same_value_exec,
|
|
r#"
|
|
var i = 0;
|
|
var j = 0;
|
|
|
|
function getKeyI() {
|
|
return (i++).toString();
|
|
}
|
|
function getKeyJ() {
|
|
return (j++).toString();
|
|
}
|
|
|
|
var desc;
|
|
|
|
@(_ => desc = _)
|
|
class Foo {
|
|
[getKeyI()]() {
|
|
return 1;
|
|
}
|
|
|
|
[getKeyJ()]() {
|
|
return 2;
|
|
}
|
|
}
|
|
|
|
expect(desc.elements).toHaveLength(1);
|
|
|
|
expect(desc.elements[0].key).toBe("0");
|
|
expect(desc.elements[0].descriptor.value()).toBe(2);
|
|
|
|
expect(i).toBe(1);
|
|
expect(j).toBe(1);
|
|
|
|
"#
|
|
);
|
|
// element_descriptors_original_own_field_without_initiailzer_exec
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| tr(),
|
|
element_descriptors_original_own_field_without_initiailzer_exec,
|
|
r#"
|
|
var el = null;
|
|
|
|
class A {
|
|
@(_ => el = _)
|
|
foo;
|
|
}
|
|
|
|
expect(el).toEqual(Object.defineProperty({
|
|
kind: "field",
|
|
key: "foo",
|
|
placement: "own",
|
|
descriptor: {
|
|
enumerable: true,
|
|
configurable: true,
|
|
writable: true,
|
|
},
|
|
initializer: undefined,
|
|
}, Symbol.toStringTag, { value: "Descriptor" }));
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_constructors_return_new_constructor
|
|
test_exec!(
|
|
syntax(true),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_constructors_return_new_constructor_exec,
|
|
r#"
|
|
function dec(cls){
|
|
return class Child extends cls {
|
|
child(){}
|
|
};
|
|
}
|
|
|
|
@dec
|
|
class Parent {
|
|
parent(){}
|
|
}
|
|
|
|
expect(typeof Parent.prototype.parent).toBe("function");
|
|
expect(typeof Parent.prototype.child).toBe("function");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_regression_10264
|
|
test!(
|
|
syntax(true),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
simple_strip()
|
|
),
|
|
legacy_regression_10264,
|
|
r#"
|
|
function myDecorator(decoratee) {}
|
|
|
|
@myDecorator
|
|
export default class {}
|
|
|
|
"#,
|
|
r#"
|
|
var _class;
|
|
function myDecorator(decoratee) {
|
|
}
|
|
let _class1 = _class = myDecorator((_class = class {
|
|
}) || _class) || _class;
|
|
export { _class1 as default }
|
|
|
|
|
|
"#
|
|
);
|
|
|
|
//// legacy_regression_7030
|
|
//test!(
|
|
// syntax(false),
|
|
// |_| tr(r#"{
|
|
// "presets": ["env"]
|
|
//}
|
|
//"#),
|
|
// legacy_regression_7030,
|
|
// r#"
|
|
//function generateAsyncAction(type) {
|
|
// type = type.toUpperCase()
|
|
// const request = createAction(type+'_REQUEST',
|
|
// undefined, requestMetaCreator
|
|
// )
|
|
// request.request = request // crazy
|
|
// request.success = createAction(type+'_SUCCESS', undefined, metaCreator)
|
|
// request.error = createAction(type+'_ERROR', undefined, metaCreator)
|
|
// request.cancel = createAction(type+'_CANCEL', undefined, metaCreator)
|
|
// request.progress = createAction(type+'_PROGRESS', undefined, metaCreator)
|
|
// request.process = createAction(type+'_PROCESS', undefined, metaCreator)
|
|
//
|
|
// return request
|
|
//}
|
|
//
|
|
//class A extends B {
|
|
// constructor(timestamp) {
|
|
// super()
|
|
// this.timestamp = timestamp
|
|
// this.moment = moment(timestamp)
|
|
// }
|
|
//}
|
|
//
|
|
//"#,
|
|
// r#"
|
|
//function _typeof(obj) { if (typeof Symbol === "function" && typeof
|
|
// Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return
|
|
// typeof obj; }; } else { _typeof = function _typeof(obj) { return obj &&
|
|
// typeof Symbol === "function" && obj.constructor === Symbol && obj !==
|
|
// Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
|
|
//
|
|
//function _classCallCheck(instance, Constructor) { if (!(instance instanceof
|
|
// Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
|
//
|
|
//function _possibleConstructorReturn(self, call) { if (call && (_typeof(call)
|
|
// === "object" || typeof call === "function")) { return call; } return
|
|
// _assertThisInitialized(self); }
|
|
//
|
|
//function _assertThisInitialized(self) { if (self === void 0) { throw new
|
|
// ReferenceError("this hasn't been initialised - super() hasn't been called");
|
|
// } return self; }
|
|
//
|
|
//function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ?
|
|
// Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ ||
|
|
// Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
|
|
//
|
|
//function _inherits(subClass, superClass) { if (typeof superClass !==
|
|
// "function" && superClass !== null) { throw new TypeError("Super expression
|
|
// must either be null or a function"); } subClass.prototype =
|
|
// Object.create(superClass && superClass.prototype, { constructor: { value:
|
|
// subClass, writable: true, configurable: true } }); if (superClass)
|
|
// _setPrototypeOf(subClass, superClass); }
|
|
//
|
|
//function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ||
|
|
// function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return
|
|
// _setPrototypeOf(o, p); }
|
|
//
|
|
//function generateAsyncAction(type) {
|
|
// type = type.toUpperCase();
|
|
// var request = createAction(type + '_REQUEST', undefined,
|
|
// requestMetaCreator); request.request = request; // crazy
|
|
//
|
|
// request.success = createAction(type + '_SUCCESS', undefined, metaCreator);
|
|
// request.error = createAction(type + '_ERROR', undefined, metaCreator);
|
|
// request.cancel = createAction(type + '_CANCEL', undefined, metaCreator);
|
|
// request.progress = createAction(type + '_PROGRESS', undefined, metaCreator);
|
|
// request.process = createAction(type + '_PROCESS', undefined, metaCreator);
|
|
// return request;
|
|
//}
|
|
//
|
|
//var A =
|
|
// /*#__PURE__*/
|
|
//function (_B) {
|
|
// "use strict";
|
|
//
|
|
// _inherits(A, _B);
|
|
//
|
|
// function A(timestamp) {
|
|
// var _this;
|
|
//
|
|
// _classCallCheck(this, A);
|
|
//
|
|
// _this = _possibleConstructorReturn(this, _getPrototypeOf(A).call(this));
|
|
// _this.timestamp = timestamp;
|
|
// _this.moment = moment(timestamp);
|
|
// return _this;
|
|
// }
|
|
//
|
|
// return A;
|
|
//}(B);
|
|
//
|
|
//"#
|
|
//);
|
|
|
|
//// legacy_class_static_methods_numeric_props
|
|
//test_exec!(
|
|
// syntax(false),
|
|
// |_| tr(r#"{
|
|
// "presets": ["env"],
|
|
// "plugins": [
|
|
// ["proposal-decorators", { "legacy": true }],
|
|
// [class_properties(class_properties::Config { loose: false }), { "loose":
|
|
// true }] ]
|
|
//}
|
|
//"#),
|
|
// legacy_class_static_methods_numeric_props_exec,
|
|
// r#"
|
|
//function dec(target, name, descriptor){
|
|
// expect(target).toBeTruthy();
|
|
// expect(name).toBe(4);
|
|
// expect(typeof descriptor).toBe("object");
|
|
//}
|
|
//
|
|
//class Example {
|
|
// @dec
|
|
// static 4() {}
|
|
//}
|
|
//
|
|
//"#
|
|
//);
|
|
|
|
//// legacy_class_prototype_properties_mutate_descriptor
|
|
//test_exec!(
|
|
// syntax(false),
|
|
// |_| tr(r#"{
|
|
// "presets": ["env"],
|
|
// "plugins": [
|
|
// ["proposal-decorators", { "legacy": true }],
|
|
// [class_properties(class_properties::Config { loose: false }), { "loose":
|
|
// true }] ]
|
|
//}
|
|
//"#),
|
|
// legacy_class_prototype_properties_mutate_descriptor_exec,
|
|
// r#"
|
|
//function dec(target, name, descriptor) {
|
|
// expect(target).toBeTruthy();
|
|
// expect(typeof name).toBe("string");
|
|
// expect(typeof descriptor).toBe("object");
|
|
//
|
|
// target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
//
|
|
// let initializer = descriptor.initializer;
|
|
// Object.assign(descriptor, {
|
|
// enumerable: name.indexOf('enum') !== -1,
|
|
// configurable: name.indexOf('conf') !== -1,
|
|
// writable: name.indexOf('write') !== -1,
|
|
// initializer: function(...args){
|
|
// return '__' + initializer.apply(this, args) + '__';
|
|
// },
|
|
// });
|
|
//}
|
|
//
|
|
//function plainDec(target, name, descriptor) {
|
|
// expect(target).toBeTruthy();
|
|
// expect(typeof name).toBe("string");
|
|
// expect(typeof descriptor).toBe("object");
|
|
//
|
|
// target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
//
|
|
// return descriptor;
|
|
//}
|
|
//
|
|
//class Example {
|
|
// @dec
|
|
// enumconfwrite = 1;
|
|
//
|
|
// @dec
|
|
// enumconf = 2;
|
|
//
|
|
// @dec
|
|
// enumwrite = 3;
|
|
//
|
|
// @dec
|
|
// enum = 4;
|
|
//
|
|
// @dec
|
|
// confwrite = 5;
|
|
//
|
|
// @dec
|
|
// conf = 6;
|
|
//
|
|
// @dec
|
|
// write = 7;
|
|
//
|
|
// @dec
|
|
// _ = 8;
|
|
//
|
|
// @plainDec
|
|
// plain = 9;
|
|
//}
|
|
//
|
|
//const inst = new Example();
|
|
//
|
|
//expect(Example.prototype).toHaveProperty("decoratedProps");
|
|
//expect(inst.decoratedProps).toEqual([
|
|
// "enumconfwrite",
|
|
// "enumconf",
|
|
// "enumwrite",
|
|
// "enum",
|
|
// "confwrite",
|
|
// "conf",
|
|
// "write",
|
|
// "_",
|
|
// "plain",
|
|
//]);
|
|
//
|
|
//const descs = Object.getOwnPropertyDescriptors(inst);
|
|
//
|
|
//expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
//expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
//expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
//expect(inst.enumconfwrite).toBe("__1__");
|
|
//
|
|
//expect(descs.enumconf.enumerable).toBeTruthy();
|
|
//expect(descs.enumconf.writable).toBe(false);
|
|
//expect(descs.enumconf.configurable).toBeTruthy();
|
|
//expect(inst.enumconf).toBe("__2__");
|
|
//
|
|
//expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
//expect(descs.enumwrite.writable).toBeTruthy();
|
|
//expect(descs.enumwrite.configurable).toBe(false);
|
|
//expect(inst.enumwrite).toBe("__3__");
|
|
//
|
|
//expect(descs.enum.enumerable).toBeTruthy();
|
|
//expect(descs.enum.writable).toBe(false);
|
|
//expect(descs.enum.configurable).toBe(false);
|
|
//expect(inst.enum).toBe("__4__");
|
|
//
|
|
//expect(descs.confwrite.enumerable).toBe(false);
|
|
//expect(descs.confwrite.writable).toBeTruthy();
|
|
//expect(descs.confwrite.configurable).toBeTruthy();
|
|
//expect(inst.confwrite).toBe("__5__");
|
|
//
|
|
//expect(descs.conf.enumerable).toBe(false);
|
|
//expect(descs.conf.writable).toBe(false);
|
|
//expect(descs.conf.configurable).toBeTruthy();
|
|
//expect(inst.conf).toBe("__6__");
|
|
//
|
|
//expect(descs.write.enumerable).toBe(false);
|
|
//expect(descs.write.writable).toBeTruthy();
|
|
//expect(descs.write.configurable).toBe(false);
|
|
//expect(inst.write).toBe("__7__");
|
|
//
|
|
//expect(descs._.enumerable).toBe(false);
|
|
//expect(descs._.writable).toBe(false);
|
|
//expect(descs._.configurable).toBe(false);
|
|
//expect(inst._).toBe("__8__");
|
|
//
|
|
//expect(descs.plain.enumerable).toBeTruthy();
|
|
//expect(descs.plain.writable).toBeTruthy();
|
|
//expect(descs.plain.configurable).toBeTruthy();
|
|
//expect(inst.plain).toBe(9);
|
|
//
|
|
//"#
|
|
//);
|
|
|
|
//// legacy_object_properties_mutate_descriptor
|
|
//test_exec!(
|
|
// syntax(false),
|
|
// |_| tr(r#"{
|
|
// "presets": ["env"],
|
|
// "plugins": [
|
|
// ["proposal-decorators", { "legacy": true }],
|
|
// [class_properties(class_properties::Config { loose: false }), { "loose":
|
|
// true }] ]
|
|
//}
|
|
//"#),
|
|
// legacy_object_properties_mutate_descriptor_exec,
|
|
// r#"
|
|
//function dec(target, name, descriptor) {
|
|
// expect(target).toBeTruthy();
|
|
// expect(typeof name).toBe("string");
|
|
// expect(typeof descriptor).toBe("object");
|
|
//
|
|
// target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
//
|
|
// let initializer = descriptor.initializer;
|
|
// Object.assign(descriptor, {
|
|
// enumerable: name.indexOf("enum") !== -1,
|
|
// configurable: name.indexOf("conf") !== -1,
|
|
// writable: name.indexOf("write") !== -1,
|
|
// initializer: function(...args){
|
|
// return '__' + initializer.apply(this, args) + '__';
|
|
// },
|
|
// });
|
|
//}
|
|
//
|
|
//const inst = {
|
|
// @dec
|
|
// enumconfwrite: 1,
|
|
//
|
|
// @dec
|
|
// enumconf: 2,
|
|
//
|
|
// @dec
|
|
// enumwrite: 3,
|
|
//
|
|
// @dec
|
|
// enum: 4,
|
|
//
|
|
// @dec
|
|
// confwrite: 5,
|
|
//
|
|
// @dec
|
|
// conf: 6,
|
|
//
|
|
// @dec
|
|
// write: 7,
|
|
//
|
|
// @dec
|
|
// _: 8,
|
|
//};
|
|
//
|
|
//
|
|
//expect(inst).toHaveProperty("decoratedProps");
|
|
//expect(inst.decoratedProps).toEqual([
|
|
// "enumconfwrite",
|
|
// "enumconf",
|
|
// "enumwrite",
|
|
// "enum",
|
|
// "confwrite",
|
|
// "conf",
|
|
// "write",
|
|
// "_",
|
|
//]);
|
|
//
|
|
//const descs = Object.getOwnPropertyDescriptors(inst);
|
|
//
|
|
//expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
//expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
//expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
//expect(inst.enumconfwrite).toBe("__1__");
|
|
//
|
|
//expect(descs.enumconf.enumerable).toBeTruthy();
|
|
//expect(descs.enumconf.writable).toBe(false);
|
|
//expect(descs.enumconf.configurable).toBeTruthy();
|
|
//expect(inst.enumconf).toBe("__2__");
|
|
//
|
|
//expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
//expect(descs.enumwrite.writable).toBeTruthy();
|
|
//expect(descs.enumwrite.configurable).toBe(false);
|
|
//expect(inst.enumwrite).toBe("__3__");
|
|
//
|
|
//expect(descs.enum.enumerable).toBeTruthy();
|
|
//expect(descs.enum.writable).toBe(false);
|
|
//expect(descs.enum.configurable).toBe(false);
|
|
//expect(inst.enum).toBe("__4__");
|
|
//
|
|
//expect(descs.confwrite.enumerable).toBe(false);
|
|
//expect(descs.confwrite.writable).toBeTruthy();
|
|
//expect(descs.confwrite.configurable).toBeTruthy();
|
|
//expect(inst.confwrite).toBe("__5__");
|
|
//
|
|
//expect(descs.conf.enumerable).toBe(false);
|
|
//expect(descs.conf.writable).toBe(false);
|
|
//expect(descs.conf.configurable).toBeTruthy();
|
|
//expect(inst.conf).toBe("__6__");
|
|
//
|
|
//expect(descs.write.enumerable).toBe(false);
|
|
//expect(descs.write.writable).toBeTruthy();
|
|
//expect(descs.write.configurable).toBe(false);
|
|
//expect(inst.write).toBe("__7__");
|
|
//
|
|
//expect(descs._.enumerable).toBe(false);
|
|
//expect(descs._.writable).toBe(false);
|
|
//expect(descs._.configurable).toBe(false);
|
|
//expect(inst._).toBe("__8__");
|
|
//
|
|
//"#
|
|
//);
|
|
|
|
// legacy_decl_to_expression_class_decorators
|
|
test!(
|
|
syntax(false),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
legacy_decl_to_expression_class_decorators,
|
|
r#"
|
|
export default @dec class A {}
|
|
@dec class B {}
|
|
"#,
|
|
r#"
|
|
var _class, _class1;
|
|
export default _class = dec((_class = class A {
|
|
}) || _class) || _class;
|
|
let B = _class1 = dec((_class1 = class B {
|
|
}) || _class1) || _class1;
|
|
"#
|
|
);
|
|
|
|
// legacy_class_prototype_methods_numeric_props
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_prototype_methods_numeric_props_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(name).toBe(4);
|
|
expect(typeof descriptor).toBe("object");
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
4() {};
|
|
}
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_static_properties_mutate_descriptor
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_static_properties_mutate_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let initializer = descriptor.initializer;
|
|
Object.assign(descriptor, {
|
|
enumerable: name.indexOf("enum") !== -1,
|
|
configurable: name.indexOf("conf") !== -1,
|
|
writable: name.indexOf("write") !== -1,
|
|
initializer: function(...args){
|
|
return '__' + initializer.apply(this, args) + '__';
|
|
},
|
|
});
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
static enumconfwrite = 1;
|
|
|
|
@dec
|
|
static enumconf = 2;
|
|
|
|
@dec
|
|
static enumwrite = 3;
|
|
|
|
@dec
|
|
static enum = 4;
|
|
|
|
@dec
|
|
static confwrite = 5;
|
|
|
|
@dec
|
|
static conf = 6;
|
|
|
|
@dec
|
|
static write = 7;
|
|
|
|
@dec
|
|
static _ = 8;
|
|
}
|
|
|
|
const inst = new Example();
|
|
|
|
expect(Example).toHaveProperty("decoratedProps");
|
|
expect(Example.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(Example);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(Example.enumconfwrite).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(Example.enumconf).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(Example.enumwrite).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(Example.enum).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable).toBeTruthy();
|
|
expect(Example.confwrite).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable).toBeTruthy();
|
|
expect(Example.conf).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(Example.write).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(Example._).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_static_methods_string_props
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_static_methods_string_props_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(name).toBe("str");
|
|
expect(typeof descriptor).toBe("object");
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
static "str"() {};
|
|
}
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_prototype_properties_string_literal_properties
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_prototype_properties_string_literal_properties_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
return descriptor;
|
|
}
|
|
|
|
class Example {
|
|
@dec "a-prop";
|
|
}
|
|
|
|
let inst = new Example();
|
|
|
|
expect(Example.prototype).toHaveProperty("decoratedProps");
|
|
expect(inst.decoratedProps).toEqual([
|
|
"a-prop"
|
|
]);
|
|
|
|
expect(inst).toHaveProperty("a-prop");
|
|
expect(inst["a-prop"]).toBeUndefined();
|
|
|
|
// const descs = Object.getOwnPropertyDescriptors(inst);
|
|
|
|
// expect(descs["a-prop"].enumerable).toBeTruthy();
|
|
// expect(descs["a-prop"].writable).toBeTruthy();
|
|
// expect(descs["a-prop"].configurable).toBeTruthy();
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_prototype_methods_mutate_descriptor
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_prototype_methods_mutate_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let value = descriptor.value;
|
|
Object.assign(descriptor, {
|
|
enumerable: name.indexOf("enum") !== -1,
|
|
configurable: name.indexOf("conf") !== -1,
|
|
writable: name.indexOf("write") !== -1,
|
|
value: function(...args) {
|
|
return "__" + value.apply(this, args) + "__";
|
|
},
|
|
});
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
enumconfwrite(){
|
|
return 1;
|
|
}
|
|
|
|
@dec
|
|
enumconf(){
|
|
return 2;
|
|
}
|
|
|
|
@dec
|
|
enumwrite(){
|
|
return 3;
|
|
}
|
|
|
|
@dec
|
|
enum(){
|
|
return 4;
|
|
}
|
|
|
|
@dec
|
|
confwrite(){
|
|
return 5;
|
|
}
|
|
|
|
@dec
|
|
conf(){
|
|
return 6;
|
|
}
|
|
|
|
@dec
|
|
write(){
|
|
return 7;
|
|
}
|
|
|
|
@dec
|
|
_(){
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
expect(Example.prototype).toHaveProperty('decoratedProps');
|
|
expect(Example.prototype.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
const inst = new Example();
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(Example.prototype);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(inst.enumconfwrite()).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(inst.enumconf()).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(inst.enumwrite()).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(inst.enum()).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable).toBeTruthy();
|
|
expect(inst.confwrite()).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable).toBeTruthy();
|
|
expect(inst.conf()).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(inst.write()).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(inst._()).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_object_properties_numeric_props
|
|
test_exec!(
|
|
// Legacy decorator for object literals
|
|
ignore,
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_object_properties_numeric_props_exec,
|
|
r#"
|
|
function dec(target, name, descriptor){
|
|
expect(target).toBeTruthy();
|
|
expect(name).toBe(4);
|
|
expect(typeof descriptor).toBe("object");
|
|
}
|
|
|
|
const inst = {
|
|
@dec
|
|
4: 1
|
|
};
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_decl_to_expression_method_decorators
|
|
test!(
|
|
syntax(false),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
legacy_decl_to_expression_method_decorators,
|
|
r#"
|
|
export default class A {
|
|
@dec foo() {}
|
|
}
|
|
class B {
|
|
@dec foo() {}
|
|
}
|
|
"#,
|
|
r#"
|
|
var _class, _class1;
|
|
let A = ((_class = class A{
|
|
foo() {
|
|
}
|
|
}) || _class, _applyDecoratedDescriptor(_class.prototype, 'foo', [dec], Object.getOwnPropertyDescriptor(_class.prototype, 'foo'), _class.prototype), _class);
|
|
let B = ((_class1 = class B{
|
|
foo() {
|
|
}
|
|
}) || _class1, _applyDecoratedDescriptor(_class1.prototype, 'foo', [dec], Object.getOwnPropertyDescriptor(_class1.prototype, 'foo'), _class1.prototype), _class1);
|
|
export { A as default }
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_prototype_properties_return_descriptor
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_prototype_properties_return_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let initializer = descriptor.initializer;
|
|
return {
|
|
enumerable: name.indexOf('enum') !== -1,
|
|
configurable: name.indexOf('conf') !== -1,
|
|
writable: name.indexOf('write') !== -1,
|
|
initializer: function(...args){
|
|
return '__' + initializer.apply(this, args) + '__';
|
|
},
|
|
};
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
enumconfwrite = 1;
|
|
|
|
@dec
|
|
enumconf = 2;
|
|
|
|
@dec
|
|
enumwrite = 3;
|
|
|
|
@dec
|
|
enum = 4;
|
|
|
|
@dec
|
|
confwrite = 5;
|
|
|
|
@dec
|
|
conf = 6;
|
|
|
|
@dec
|
|
write = 7;
|
|
|
|
@dec
|
|
_ = 8;
|
|
}
|
|
|
|
const inst = new Example();
|
|
|
|
expect(Example.prototype).toHaveProperty("decoratedProps");
|
|
expect(inst.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(inst);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(inst.enumconfwrite).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(inst.enumconf).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(inst.enumwrite).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(inst.enum).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable).toBeTruthy();
|
|
expect(inst.confwrite).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable).toBeTruthy();
|
|
expect(inst.conf).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(inst.write).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(inst._).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_object_properties_string_props
|
|
test_exec!(
|
|
// Legacy decorator for object literals
|
|
ignore,
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_object_properties_string_props_exec,
|
|
r#"
|
|
function dec(target, name, descriptor){
|
|
expect(target).toBeTruthy();
|
|
expect(name).toBe("str");
|
|
expect(typeof descriptor).toBe("object");
|
|
}
|
|
|
|
const inst = {
|
|
@dec
|
|
"str": 1
|
|
};
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_object_properties_return_descriptor
|
|
test_exec!(
|
|
// Legacy decorator for object literals
|
|
ignore,
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_object_properties_return_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let initializer = descriptor.initializer;
|
|
return {
|
|
enumerable: name.indexOf('enum') !== -1,
|
|
configurable: name.indexOf('conf') !== -1,
|
|
writable: name.indexOf('write') !== -1,
|
|
initializer: function(...args){
|
|
return '__' + initializer.apply(this, args) + '__';
|
|
},
|
|
};
|
|
}
|
|
|
|
const inst = {
|
|
@dec
|
|
enumconfwrite: 1,
|
|
|
|
@dec
|
|
enumconf: 2,
|
|
|
|
@dec
|
|
enumwrite: 3,
|
|
|
|
@dec
|
|
enum: 4,
|
|
|
|
@dec
|
|
confwrite: 5,
|
|
|
|
@dec
|
|
conf: 6,
|
|
|
|
@dec
|
|
write: 7,
|
|
|
|
@dec
|
|
_: 8,
|
|
};
|
|
|
|
expect(inst).toHaveProperty("decoratedProps");
|
|
expect(inst.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(inst);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(inst.enumconfwrite).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(inst.enumconf).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(inst.enumwrite).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(inst.enum).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable).toBeTruthy();
|
|
expect(inst.confwrite).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable).toBeTruthy();
|
|
expect(inst.conf).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(inst.write).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(inst._).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_prototype_methods_string_props
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_prototype_methods_string_props_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(name).toBe("str");
|
|
expect(typeof descriptor).toBe("object");
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
"str"() {};
|
|
}
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_regression_8041
|
|
test!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_regression_8041,
|
|
r#"
|
|
export default class {
|
|
@foo
|
|
bar() {}
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
var _class;
|
|
let _class2 = ((_class = class _class1 {
|
|
bar() {
|
|
}
|
|
}) || _class, _applyDecoratedDescriptor(_class.prototype, "bar", [
|
|
foo
|
|
], Object.getOwnPropertyDescriptor(_class.prototype, "bar"), _class.prototype), _class);
|
|
export { _class2 as default };
|
|
"#
|
|
);
|
|
|
|
// legacy_class_prototype_methods_return_descriptor
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_prototype_methods_return_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let value = descriptor.value;
|
|
return {
|
|
enumerable: name.indexOf('enum') !== -1,
|
|
configurable: name.indexOf('conf') !== -1,
|
|
writable: name.indexOf('write') !== -1,
|
|
value: function(...args){
|
|
return '__' + value.apply(this, args) + '__';
|
|
},
|
|
};
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
enumconfwrite() {
|
|
return 1;
|
|
}
|
|
|
|
@dec
|
|
enumconf() {
|
|
return 2;
|
|
}
|
|
|
|
@dec
|
|
enumwrite() {
|
|
return 3;
|
|
}
|
|
|
|
@dec
|
|
enum() {
|
|
return 4;
|
|
}
|
|
|
|
@dec
|
|
confwrite() {
|
|
return 5;
|
|
}
|
|
|
|
@dec
|
|
conf() {
|
|
return 6;
|
|
}
|
|
|
|
@dec
|
|
write() {
|
|
return 7;
|
|
}
|
|
|
|
@dec
|
|
_() {
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
|
|
expect(Example.prototype).toHaveProperty('decoratedProps');
|
|
expect(Example.prototype.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
|
|
const inst = new Example();
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(Example.prototype);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(inst.enumconfwrite()).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(inst.enumconf()).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(inst.enumwrite()).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(inst.enum()).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable).toBeTruthy();
|
|
expect(inst.confwrite()).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable).toBeTruthy();
|
|
expect(inst.conf()).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(inst.write()).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(inst._()).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_object_ordering_reverse_order
|
|
test_exec!(
|
|
// Legacy decorator for object literals
|
|
ignore,
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_object_ordering_reverse_order_exec,
|
|
r#"
|
|
const calls = [];
|
|
function dec(id){
|
|
return function(){
|
|
calls.push(id);
|
|
};
|
|
}
|
|
|
|
const obj = {
|
|
@dec(2)
|
|
@dec(1)
|
|
method1(){},
|
|
|
|
@dec(4)
|
|
@dec(3)
|
|
prop1: 1,
|
|
|
|
@dec(6)
|
|
@dec(5)
|
|
method2(){},
|
|
|
|
@dec(8)
|
|
@dec(7)
|
|
prop2: 2,
|
|
}
|
|
|
|
expect(calls).toEqual([1, 2, 3, 4, 5, 6, 7, 8]);
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_object_methods_numeric_props
|
|
test_exec!(
|
|
// Legacy decorator for object literals
|
|
ignore,
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_object_methods_numeric_props_exec,
|
|
r#"
|
|
function dec(target, name, descriptor){
|
|
expect(target).toBeTruthy();
|
|
expect(name).toBe(4);
|
|
expect(typeof descriptor).toBe("object");
|
|
}
|
|
|
|
const inst = {
|
|
@dec
|
|
4(){
|
|
}
|
|
};
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_static_properties_return_descriptor
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_static_properties_return_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let initializer = descriptor.initializer;
|
|
return {
|
|
enumerable: name.indexOf('enum') !== -1,
|
|
configurable: name.indexOf('conf') !== -1,
|
|
writable: name.indexOf('write') !== -1,
|
|
initializer: function(...args){
|
|
return '__' + initializer.apply(this, args) + '__';
|
|
},
|
|
};
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
static enumconfwrite = 1;
|
|
|
|
@dec
|
|
static enumconf = 2;
|
|
|
|
@dec
|
|
static enumwrite = 3;
|
|
|
|
@dec
|
|
static enum = 4;
|
|
|
|
@dec
|
|
static confwrite = 5;
|
|
|
|
@dec
|
|
static conf = 6;
|
|
|
|
@dec
|
|
static write = 7;
|
|
|
|
@dec
|
|
static _ = 8;
|
|
}
|
|
|
|
const inst = new Example();
|
|
|
|
expect(Example).toHaveProperty("decoratedProps");
|
|
expect(Example.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(Example);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(Example.enumconfwrite).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(Example.enumconf).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(Example.enumwrite).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(Example.enum).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable).toBeTruthy();
|
|
expect(Example.confwrite).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable);
|
|
expect(Example.conf).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(Example.write).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(Example._).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_export_default
|
|
test_exec!(
|
|
// We wrap exec tests in a function like it('should work', function(){
|
|
// // .. code
|
|
// }), but it prevents swc_ecma_parser from parsing the code
|
|
// below correctly.
|
|
ignore,
|
|
syntax(true),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_export_default_exec,
|
|
r#"
|
|
const calls = [];
|
|
|
|
function foo(target) {
|
|
calls.push(target.name);
|
|
}
|
|
|
|
@foo
|
|
export default class Foo {
|
|
bar() {
|
|
class Baz {}
|
|
}
|
|
}
|
|
|
|
expect(calls).toEqual(["Foo"]);
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_ordering_reverse_order
|
|
test_exec!(
|
|
syntax(true),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_ordering_reverse_order_exec,
|
|
r#"
|
|
const calls = [];
|
|
|
|
function dec(id){
|
|
return function(){
|
|
calls.push(id);
|
|
};
|
|
}
|
|
|
|
@dec(10)
|
|
@dec(9)
|
|
class Example2 {
|
|
@dec(2)
|
|
@dec(1)
|
|
method1() {};
|
|
|
|
@dec(4)
|
|
@dec(3)
|
|
prop1 = 1;
|
|
|
|
@dec(6)
|
|
@dec(5)
|
|
method2() {};
|
|
|
|
@dec(8)
|
|
@dec(7)
|
|
prop2 = 2;
|
|
}
|
|
|
|
expect(calls).toEqual([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_object_methods_mutate_descriptor
|
|
test_exec!(
|
|
// Legacy decorator for object literals
|
|
ignore,
|
|
syntax(true),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_object_methods_mutate_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let value = descriptor.value;
|
|
Object.assign(descriptor, {
|
|
enumerable: name.indexOf("enum") !== -1,
|
|
configurable: name.indexOf("conf") !== -1,
|
|
writable: name.indexOf("write") !== -1,
|
|
value: function(...args) {
|
|
return "__" + value.apply(this, args) + "__";
|
|
},
|
|
});
|
|
}
|
|
|
|
const inst = {
|
|
@dec
|
|
enumconfwrite(){
|
|
return 1;
|
|
},
|
|
|
|
@dec
|
|
enumconf(){
|
|
return 2;
|
|
},
|
|
|
|
@dec
|
|
enumwrite(){
|
|
return 3;
|
|
},
|
|
|
|
@dec
|
|
enum(){
|
|
return 4;
|
|
},
|
|
|
|
@dec
|
|
confwrite(){
|
|
return 5;
|
|
},
|
|
|
|
@dec
|
|
conf(){
|
|
return 6;
|
|
},
|
|
|
|
@dec
|
|
write(){
|
|
return 7;
|
|
},
|
|
|
|
@dec
|
|
_(){
|
|
return 8;
|
|
},
|
|
}
|
|
|
|
expect(inst).toHaveProperty('decoratedProps');
|
|
expect(inst.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(inst);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(inst.enumconfwrite()).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(inst.enumconf()).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(inst.enumwrite()).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(inst.enum()).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable);
|
|
expect(inst.confwrite()).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable).toBeTruthy();
|
|
expect(inst.conf()).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(inst.write()).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(inst._()).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_static_methods_return_descriptor
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_static_methods_return_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let value = descriptor.value;
|
|
return {
|
|
enumerable: name.indexOf('enum') !== -1,
|
|
configurable: name.indexOf('conf') !== -1,
|
|
writable: name.indexOf('write') !== -1,
|
|
value: function(...args){
|
|
return '__' + value.apply(this, args) + '__';
|
|
},
|
|
};
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
static enumconfwrite() {
|
|
return 1;
|
|
}
|
|
|
|
@dec
|
|
static enumconf() {
|
|
return 2;
|
|
}
|
|
|
|
@dec
|
|
static enumwrite() {
|
|
return 3;
|
|
}
|
|
|
|
@dec
|
|
static enum() {
|
|
return 4;
|
|
}
|
|
|
|
@dec
|
|
static confwrite() {
|
|
return 5;
|
|
}
|
|
|
|
@dec
|
|
static conf() {
|
|
return 6;
|
|
}
|
|
|
|
@dec
|
|
static write() {
|
|
return 7;
|
|
}
|
|
|
|
@dec
|
|
static _() {
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
|
|
expect(Example).toHaveProperty("decoratedProps");
|
|
expect(Example.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(Example);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(Example.enumconfwrite()).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(Example.enumconf()).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(Example.enumwrite()).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(Example.enum()).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable);
|
|
expect(Example.confwrite()).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable).toBeTruthy();
|
|
expect(Example.conf()).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(Example.write()).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(Example._()).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_object_methods_return_descriptor
|
|
test_exec!(
|
|
// Legacy decorator for object literals
|
|
ignore,
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_object_methods_return_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let value = descriptor.value;
|
|
return {
|
|
enumerable: name.indexOf('enum') !== -1,
|
|
configurable: name.indexOf('conf') !== -1,
|
|
writable: name.indexOf('write') !== -1,
|
|
value: function(...args){
|
|
return '__' + value.apply(this, args) + '__';
|
|
},
|
|
};
|
|
}
|
|
|
|
const inst = {
|
|
@dec
|
|
enumconfwrite(){
|
|
return 1;
|
|
},
|
|
|
|
@dec
|
|
enumconf(){
|
|
return 2;
|
|
},
|
|
|
|
@dec
|
|
enumwrite(){
|
|
return 3;
|
|
},
|
|
|
|
@dec
|
|
enum(){
|
|
return 4;
|
|
},
|
|
|
|
@dec
|
|
confwrite(){
|
|
return 5;
|
|
},
|
|
|
|
@dec
|
|
conf(){
|
|
return 6;
|
|
},
|
|
|
|
@dec
|
|
write(){
|
|
return 7;
|
|
},
|
|
|
|
@dec
|
|
_(){
|
|
return 8;
|
|
},
|
|
}
|
|
|
|
expect(inst).toHaveProperty('decoratedProps');
|
|
expect(inst.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(inst);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(inst.enumconfwrite()).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(inst.enumconf()).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(inst.enumwrite()).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(inst.enum()).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable).toBeTruthy();
|
|
expect(inst.confwrite()).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable).toBeTruthy();
|
|
expect(inst.conf()).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(inst.write()).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(inst._()).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_object_methods_string_props
|
|
test_exec!(
|
|
// Legacy decorator for object literals
|
|
ignore,
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_object_methods_string_props_exec,
|
|
r#"
|
|
function dec(target, name, descriptor){
|
|
expect(target).toBeTruthy();
|
|
expect(name).toBe("str");
|
|
expect(typeof descriptor).toBe("object");
|
|
}
|
|
|
|
const inst = {
|
|
@dec
|
|
"str"(){
|
|
|
|
}
|
|
};
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_prototype_properties_child_classes_properties
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_prototype_properties_child_classes_properties_exec,
|
|
r#"
|
|
function dec(target, name, descriptor){
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let initializer = descriptor.initializer;
|
|
descriptor.initializer = function(...args){
|
|
return "__" + initializer.apply(this, args) + "__";
|
|
};
|
|
}
|
|
|
|
class Base {
|
|
@dec
|
|
prop2 = 4;
|
|
}
|
|
|
|
class Example extends Base {
|
|
@dec
|
|
prop = 3;
|
|
}
|
|
|
|
let inst = new Example();
|
|
|
|
expect(inst.prop).toBe("__3__");
|
|
expect(inst.prop2).toBe("__4__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_class_static_methods_mutate_descriptor
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
),
|
|
legacy_class_static_methods_mutate_descriptor_exec,
|
|
r#"
|
|
function dec(target, name, descriptor) {
|
|
expect(target).toBeTruthy();
|
|
expect(typeof name).toBe("string");
|
|
expect(typeof descriptor).toBe("object");
|
|
|
|
target.decoratedProps = (target.decoratedProps || []).concat([name]);
|
|
|
|
let value = descriptor.value;
|
|
Object.assign(descriptor, {
|
|
enumerable: name.indexOf("enum") !== -1,
|
|
configurable: name.indexOf("conf") !== -1,
|
|
writable: name.indexOf("write") !== -1,
|
|
value: function(...args) {
|
|
return "__" + value.apply(this, args) + "__";
|
|
},
|
|
});
|
|
}
|
|
|
|
class Example {
|
|
@dec
|
|
static enumconfwrite(){
|
|
return 1;
|
|
}
|
|
|
|
@dec
|
|
static enumconf(){
|
|
return 2;
|
|
}
|
|
|
|
@dec
|
|
static enumwrite(){
|
|
return 3;
|
|
}
|
|
|
|
@dec
|
|
static enum(){
|
|
return 4;
|
|
}
|
|
|
|
@dec
|
|
static confwrite(){
|
|
return 5;
|
|
}
|
|
|
|
@dec
|
|
static conf(){
|
|
return 6;
|
|
}
|
|
|
|
@dec
|
|
static write(){
|
|
return 7;
|
|
}
|
|
|
|
@dec
|
|
static _(){
|
|
return 8;
|
|
}
|
|
}
|
|
|
|
expect(Example).toHaveProperty("decoratedProps");
|
|
expect(Example.decoratedProps).toEqual([
|
|
"enumconfwrite",
|
|
"enumconf",
|
|
"enumwrite",
|
|
"enum",
|
|
"confwrite",
|
|
"conf",
|
|
"write",
|
|
"_",
|
|
]);
|
|
|
|
const descs = Object.getOwnPropertyDescriptors(Example);
|
|
|
|
expect(descs.enumconfwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumconfwrite.writable).toBeTruthy();
|
|
expect(descs.enumconfwrite.configurable).toBeTruthy();
|
|
expect(Example.enumconfwrite()).toBe("__1__");
|
|
|
|
expect(descs.enumconf.enumerable).toBeTruthy();
|
|
expect(descs.enumconf.writable).toBe(false);
|
|
expect(descs.enumconf.configurable).toBeTruthy();
|
|
expect(Example.enumconf()).toBe("__2__");
|
|
|
|
expect(descs.enumwrite.enumerable).toBeTruthy();
|
|
expect(descs.enumwrite.writable).toBeTruthy();
|
|
expect(descs.enumwrite.configurable).toBe(false);
|
|
expect(Example.enumwrite()).toBe("__3__");
|
|
|
|
expect(descs.enum.enumerable).toBeTruthy();
|
|
expect(descs.enum.writable).toBe(false);
|
|
expect(descs.enum.configurable).toBe(false);
|
|
expect(Example.enum()).toBe("__4__");
|
|
|
|
expect(descs.confwrite.enumerable).toBe(false);
|
|
expect(descs.confwrite.writable).toBeTruthy();
|
|
expect(descs.confwrite.configurable).toBeTruthy();
|
|
expect(Example.confwrite()).toBe("__5__");
|
|
|
|
expect(descs.conf.enumerable).toBe(false);
|
|
expect(descs.conf.writable).toBe(false);
|
|
expect(descs.conf.configurable).toBeTruthy();
|
|
expect(Example.conf()).toBe("__6__");
|
|
|
|
expect(descs.write.enumerable).toBe(false);
|
|
expect(descs.write.writable).toBeTruthy();
|
|
expect(descs.write.configurable).toBe(false);
|
|
expect(Example.write()).toBe("__7__");
|
|
|
|
expect(descs._.enumerable).toBe(false);
|
|
expect(descs._.writable).toBe(false);
|
|
expect(descs._.configurable).toBe(false);
|
|
expect(Example._()).toBe("__8__");
|
|
|
|
"#
|
|
);
|
|
|
|
// legacy_regression_8512
|
|
test_exec!(
|
|
syntax(false),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
legacy_regression_8512_exec,
|
|
r#"
|
|
function dec(Class, key, desc) {
|
|
return desc;
|
|
}
|
|
|
|
class Foo {
|
|
@dec
|
|
get bar() {}
|
|
}
|
|
|
|
"#
|
|
);
|
|
|
|
test!(
|
|
syntax(false),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
issue_591_1,
|
|
"
|
|
export class Example {
|
|
@foo() bar = '1';
|
|
@foo() baz = '2';
|
|
}",
|
|
"
|
|
var _class, _descriptor, _dec, _descriptor1, _dec1;
|
|
export let Example = ((_class = class Example {
|
|
constructor(){
|
|
_initializerDefineProperty(this, 'bar', _descriptor, this);
|
|
_initializerDefineProperty(this, 'baz', _descriptor1, this);
|
|
}
|
|
}) || _class, _dec = foo(), _dec1 = foo(), _descriptor = \
|
|
_applyDecoratedDescriptor(_class.prototype, 'bar', [
|
|
_dec
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: function() {
|
|
return '1';
|
|
}
|
|
}), _descriptor1 = _applyDecoratedDescriptor(_class.prototype, 'baz', [
|
|
_dec1
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: function() {
|
|
return '2';
|
|
}
|
|
}), _class);
|
|
"
|
|
);
|
|
|
|
test!(
|
|
syntax(false),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
issue_591_2,
|
|
"class Example {
|
|
@foo() bar = '1';
|
|
@foo() baz = '2';
|
|
}",
|
|
"
|
|
var _class, _descriptor, _dec, _descriptor1, _dec1;
|
|
let Example = ((_class = class Example {
|
|
constructor(){
|
|
_initializerDefineProperty(this, 'bar', _descriptor, this);
|
|
_initializerDefineProperty(this, 'baz', _descriptor1, this);
|
|
}
|
|
}) || _class, _dec = foo(), _dec1 = foo(), _descriptor = \
|
|
_applyDecoratedDescriptor(_class.prototype, 'bar', [
|
|
_dec
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: function() {
|
|
return '1';
|
|
}
|
|
}), _descriptor1 = _applyDecoratedDescriptor(_class.prototype, 'baz', [
|
|
_dec1
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: function() {
|
|
return '2';
|
|
}
|
|
}), _class);
|
|
"
|
|
);
|
|
|
|
test!(
|
|
Syntax::Typescript(TsConfig {
|
|
decorators: true,
|
|
..Default::default()
|
|
}),
|
|
|_| chain!(
|
|
decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
simple_strip()
|
|
),
|
|
issue_823_1,
|
|
"import {Debounce} from 'lodash-decorators';
|
|
class Person {
|
|
private static debounceTime: number = 500 as const;
|
|
|
|
@Debounce(Person.debounceTime)
|
|
save() {
|
|
console.log('Hello World!');
|
|
}
|
|
}
|
|
|
|
const p = new Person();
|
|
p.save();",
|
|
"var _class;
|
|
var _class1, _dec;
|
|
import { Debounce } from 'lodash-decorators';
|
|
let Person = ((_class1 = (_class = class Person {
|
|
save() {
|
|
console.log('Hello World!');
|
|
}
|
|
}, _class.debounceTime = 500, _class)) || _class1, _dec = Debounce(_class1.debounceTime), \
|
|
_applyDecoratedDescriptor(_class1.prototype, 'save', [
|
|
_dec
|
|
], Object.getOwnPropertyDescriptor(_class1.prototype, 'save'), _class1.prototype), _class1);
|
|
const p = new Person();
|
|
p.save();"
|
|
);
|
|
|
|
test!(
|
|
Syntax::Typescript(TsConfig {
|
|
decorators: true,
|
|
..Default::default()
|
|
}),
|
|
|_| chain!(
|
|
decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
simple_strip(),
|
|
// classes(Some(t.comments.clone())),
|
|
),
|
|
issue_823_2,
|
|
"import {Debounce} from 'lodash-decorators';
|
|
class Person {
|
|
private static debounceTime: number = 500 as const;
|
|
|
|
@Debounce(Person.debounceTime)
|
|
save() {
|
|
console.log('Hello World!');
|
|
}
|
|
}
|
|
|
|
const p = new Person();
|
|
p.save();",
|
|
"var _class;
|
|
var _class1, _dec;
|
|
import { Debounce } from 'lodash-decorators';
|
|
let Person = ((_class1 = (_class = class Person {
|
|
save() {
|
|
console.log('Hello World!');
|
|
}
|
|
}, _class.debounceTime = 500, _class)) || _class1, _dec = Debounce(_class1.debounceTime), \
|
|
_applyDecoratedDescriptor(_class1.prototype, 'save', [
|
|
_dec
|
|
], Object.getOwnPropertyDescriptor(_class1.prototype, 'save'), _class1.prototype), _class1);
|
|
const p = new Person();
|
|
p.save();
|
|
"
|
|
);
|
|
|
|
test!(
|
|
Syntax::Typescript(TsConfig {
|
|
decorators: true,
|
|
..Default::default()
|
|
}),
|
|
|t| chain!(
|
|
decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
simple_strip(),
|
|
classes(Some(t.comments.clone())),
|
|
),
|
|
issue_823_3,
|
|
"import {Debounce} from 'lodash-decorators';
|
|
class Person {
|
|
private static debounceTime: number = 500 as const;
|
|
|
|
@Debounce(Person.debounceTime)
|
|
save() {
|
|
console.log('Hello World!');
|
|
}
|
|
}
|
|
|
|
const p = new Person();
|
|
p.save();",
|
|
"var _class;
|
|
var _class1, _dec;
|
|
import { Debounce } from 'lodash-decorators';
|
|
let Person = ((_class1 = (_class = function() {
|
|
'use strict';
|
|
function Person() {
|
|
_classCallCheck(this, Person);
|
|
}
|
|
_createClass(Person, [
|
|
{
|
|
key: 'save',
|
|
value: function save() {
|
|
console.log('Hello World!');
|
|
}
|
|
}
|
|
]);
|
|
return Person;
|
|
}(), _class.debounceTime = 500, _class)) || _class1, _dec = Debounce(_class1.debounceTime), \
|
|
_applyDecoratedDescriptor(_class1.prototype, 'save', [
|
|
_dec
|
|
], Object.getOwnPropertyDescriptor(_class1.prototype, 'save'), _class1.prototype), _class1);
|
|
const p = new Person();
|
|
p.save();"
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| ts_transform(),
|
|
issue_862_1,
|
|
"
|
|
@Entity()
|
|
export class Product extends TimestampedEntity {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
public id!: string;
|
|
|
|
@Column()
|
|
public price!: number;
|
|
|
|
@Column({ enum: ProductType })
|
|
public type!: ProductType;
|
|
|
|
@Column()
|
|
public productEntityId!: string;
|
|
|
|
/* ANCHOR: Relations ------------------------------------------------------ */
|
|
@OneToMany(() => Order, (order) => order.product)
|
|
public orders!: Order[];
|
|
|
|
@OneToMany(() => Discount, (discount) => discount.product)
|
|
public discounts!: Discount[];
|
|
}
|
|
",
|
|
"var _class, _descriptor, _dec, _descriptor1, _dec1, _descriptor2, _dec2, _descriptor3, \
|
|
_dec3, _descriptor4, _dec4, _descriptor5, _dec5;
|
|
var _dec6 = Entity();
|
|
export let Product = _class = _dec6(((_class = class Product extends TimestampedEntity {
|
|
constructor(...args){
|
|
super(...args);
|
|
_initializerDefineProperty(this, 'id', _descriptor, this);
|
|
_initializerDefineProperty(this, 'price', _descriptor1, this);
|
|
_initializerDefineProperty(this, 'type', _descriptor2, this);
|
|
_initializerDefineProperty(this, 'productEntityId', _descriptor3, this);
|
|
_initializerDefineProperty(this, 'orders', _descriptor4, this);
|
|
_initializerDefineProperty(this, 'discounts', _descriptor5, this);
|
|
}
|
|
}) || _class, _dec = PrimaryGeneratedColumn('uuid'), _dec1 = Column(), _dec2 = Column({
|
|
enum: ProductType
|
|
}), _dec3 = Column(), _dec4 = OneToMany(()=>Order
|
|
, (order)=>order.product
|
|
), _dec5 = OneToMany(()=>Discount
|
|
, (discount)=>discount.product
|
|
), _descriptor = _applyDecoratedDescriptor(_class.prototype,'id', [
|
|
_dec
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0,
|
|
}), _descriptor1 = _applyDecoratedDescriptor(_class.prototype, 'price', [
|
|
_dec1
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0,
|
|
}), _descriptor2 = _applyDecoratedDescriptor(_class.prototype, 'type', [
|
|
_dec2
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0,
|
|
}), _descriptor3 = _applyDecoratedDescriptor(_class.prototype, 'productEntityId', [
|
|
_dec3
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0,
|
|
}), _descriptor4 = _applyDecoratedDescriptor(_class.prototype, 'orders', [
|
|
_dec4
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0,
|
|
}), _descriptor5 = _applyDecoratedDescriptor(_class.prototype, 'discounts', [
|
|
_dec5
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0
|
|
}), _class)) || _class;
|
|
"
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| ts_transform(),
|
|
issue_862_2,
|
|
"@Entity()
|
|
export class Product extends TimestampedEntity {
|
|
@PrimaryGeneratedColumn('uuid')
|
|
public id!: string;
|
|
}
|
|
",
|
|
"
|
|
var _class, _descriptor, _dec;
|
|
var _dec1 = Entity();
|
|
export let Product = _class = _dec1(((_class = class Product extends TimestampedEntity {
|
|
constructor(...args){
|
|
super(...args);
|
|
_initializerDefineProperty(this, 'id', _descriptor, this);
|
|
}
|
|
}) || _class, _dec = PrimaryGeneratedColumn('uuid'), _descriptor = \
|
|
_applyDecoratedDescriptor(_class.prototype, 'id', [
|
|
_dec
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0
|
|
}), _class)) || _class;
|
|
"
|
|
);
|
|
|
|
test_exec!(
|
|
ts(),
|
|
|_| ts_transform(),
|
|
issue_862_3,
|
|
"var log: number[] = [];
|
|
function push(x: number) { log.push(x); return x; }
|
|
|
|
function saveOrder(x: number) {
|
|
return function (el: any) {
|
|
log.push(x);
|
|
return el;
|
|
};
|
|
}
|
|
|
|
@saveOrder(1)
|
|
class Product {
|
|
@saveOrder(0)
|
|
public id!: string;
|
|
}
|
|
|
|
var nums = Array.from({ length: 2 }, (_, i) => i);
|
|
expect(log).toEqual(nums)"
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| ts_transform(),
|
|
issue_863_1,
|
|
"class ProductController {
|
|
@bar()
|
|
findById(
|
|
@foo()
|
|
id: number
|
|
) {
|
|
// ...
|
|
}
|
|
}",
|
|
" var _class, _dec;
|
|
let ProductController = ((_class = class ProductController {
|
|
findById(id) {
|
|
}
|
|
}) || _class, foo()(_class.prototype, 'findById', 0), _dec = bar(), \
|
|
_applyDecoratedDescriptor(_class.prototype, 'findById', [
|
|
_dec
|
|
], Object.getOwnPropertyDescriptor(_class.prototype, 'findById'), _class.prototype), _class);"
|
|
);
|
|
|
|
test_exec!(
|
|
ts(),
|
|
|_| ts_transform(),
|
|
issue_863_2,
|
|
"const logs: number[] = [];
|
|
|
|
function foo() {
|
|
return function (target: any, member: any, ix: any) {
|
|
logs.push(0);
|
|
};
|
|
}
|
|
function bar() {
|
|
return function (target: any, member: any, ix: any) {
|
|
logs.push(1);
|
|
};
|
|
}
|
|
|
|
class ProductController {
|
|
findById(
|
|
@foo()
|
|
@bar()
|
|
id: number
|
|
) {
|
|
// ...
|
|
}
|
|
}
|
|
|
|
expect(logs).toEqual([0, 1])
|
|
|
|
const c = new ProductController();
|
|
c.findById(100);
|
|
"
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| chain!(
|
|
inlining::inlining(inlining::Config {}),
|
|
decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
simple_strip(),
|
|
),
|
|
issue_879_1,
|
|
"export default class X {
|
|
@networked
|
|
prop: string = '';
|
|
}",
|
|
"var _class, _descriptor;
|
|
let X = ((_class = class X {
|
|
constructor(){
|
|
_initializerDefineProperty(this, 'prop', _descriptor, this);
|
|
}
|
|
}) || _class, _descriptor = _applyDecoratedDescriptor(_class.prototype, 'prop', [
|
|
networked
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: function() {
|
|
return '';
|
|
}
|
|
}), _class);
|
|
export { X as default };
|
|
"
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
}),
|
|
legacy_metadata_generics_base,
|
|
"@Decorate
|
|
class MyClass {
|
|
constructor(
|
|
private generic: Generic<A>,
|
|
generic2: Generic<A, B>
|
|
) {}
|
|
|
|
@Run
|
|
method(
|
|
generic: Inter<A>,
|
|
@Arg() generic2: InterGen<A, B>
|
|
) {}
|
|
}",
|
|
r#"
|
|
var _class, _dec, _dec1, _dec2;
|
|
var _dec3 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Generic === "undefined" ? Object : Generic,
|
|
typeof Generic === "undefined" ? Object : Generic
|
|
]), _dec4 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function);
|
|
let MyClass = _class = Decorate(_class = _dec4(_class = _dec3(((_class = class MyClass {
|
|
constructor(private generic: Generic<A>, generic2: Generic<A, B>){
|
|
}
|
|
method(generic: Inter<A>, generic2: InterGen<A, B>) {
|
|
}
|
|
}) || _class, _dec = function(target, key) {
|
|
return Arg()(target, key, 1);
|
|
}, _dec1 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec2 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Inter === "undefined" ? Object : Inter,
|
|
typeof InterGen === "undefined" ? Object : InterGen
|
|
]), _applyDecoratedDescriptor(_class.prototype, "method", [
|
|
Run,
|
|
_dec,
|
|
_dec1,
|
|
_dec2
|
|
], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype), _class)) || _class) || _class) || _class;
|
|
"#
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
}),
|
|
legacy_metadata_generics_1,
|
|
"@Decorate
|
|
class MyClass {
|
|
constructor(
|
|
private generic: Generic<A>,
|
|
generic2: Generic<A, B>
|
|
) {}
|
|
}",
|
|
r#"var _class;
|
|
var _dec = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Generic === "undefined" ? Object : Generic,
|
|
typeof Generic === "undefined" ? Object : Generic
|
|
]), _dec1 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function);
|
|
let MyClass = _class = Decorate(_class = _dec1(_class = _dec((_class = class MyClass {
|
|
constructor(private generic: Generic<A>, generic2: Generic<A, B>){
|
|
}
|
|
}) || _class) || _class) || _class) || _class;
|
|
"#
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
}),
|
|
legacy_metadata_nest_injection,
|
|
"import { AppService } from './app.service';
|
|
|
|
import { Session, Res } from '@nestjs/common';
|
|
import * as express from 'express';
|
|
|
|
@Controller()
|
|
export class AppController {
|
|
constructor(private appService: AppService) {}
|
|
|
|
@Inject()
|
|
appService: AppService;
|
|
|
|
@Inject()
|
|
private appService2: AppService;
|
|
|
|
@Get()
|
|
getHello(): string {
|
|
return this.appService.getHello();
|
|
}
|
|
|
|
@Get('/callback')
|
|
async callback(@Res() res: express.Response, @Session() session: express.Express.Session) {
|
|
const token = await this.getToken(code)
|
|
const user = await this.getUserInfo(token.access_token)
|
|
|
|
session.oauth2Token = token
|
|
session.user = user
|
|
return res.redirect(state.returnUrl ?? '/')
|
|
}
|
|
}",
|
|
r#"
|
|
var _class, _descriptor, _dec, _dec1, _descriptor1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8, _dec9, _dec10, _dec11;
|
|
import { AppService } from "./app.service";
|
|
import { Session, Res } from "@nestjs/common";
|
|
import * as express from "express";
|
|
var _dec12 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof AppService === "undefined" ? Object : AppService
|
|
]), _dec13 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec14 = Controller();
|
|
export let AppController = _class = _dec14(_class = _dec13(_class = _dec12(((_class = class AppController {
|
|
constructor(private appService: AppService){
|
|
_initializerDefineProperty(this, "appService", _descriptor, this);
|
|
_initializerDefineProperty(this, "appService2", _descriptor1, this);
|
|
}
|
|
getHello(): string {
|
|
return this.appService.getHello();
|
|
}
|
|
async callback(res: express.Response, session: express.Express.Session) {
|
|
const token = await this.getToken(code);
|
|
const user = await this.getUserInfo(token.access_token);
|
|
session.oauth2Token = token;
|
|
session.user = user;
|
|
return res.redirect(state.returnUrl ?? "/");
|
|
}
|
|
}) || _class, _dec = Inject(), _dec1 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", typeof AppService === "undefined" ? Object : AppService), _dec2 = Inject(), _dec3 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", typeof AppService === "undefined" ? Object : AppService), _descriptor = _applyDecoratedDescriptor(_class.prototype, "appService", [
|
|
_dec,
|
|
_dec1
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0
|
|
}), _descriptor1 = _applyDecoratedDescriptor(_class.prototype, "appService2", [
|
|
_dec2,
|
|
_dec3
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0
|
|
}), _dec4 = Get(), _dec5 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec6 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", []), _applyDecoratedDescriptor(_class.prototype, "getHello", [
|
|
_dec4,
|
|
_dec5,
|
|
_dec6
|
|
], Object.getOwnPropertyDescriptor(_class.prototype, "getHello"), _class.prototype), _dec7 = Get("/callback"), _dec8 = function(target, key) {
|
|
return Res()(target, key, 0);
|
|
}, _dec9 = function(target, key) {
|
|
return Session()(target, key, 1);
|
|
}, _dec10 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec11 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof express === "undefined" || typeof express.Response === "undefined" ? Object : express.Response,
|
|
typeof express === "undefined" || typeof express.Express === "undefined" || typeof express.Express.Session === "undefined" ? Object : express.Express.Session
|
|
]), _applyDecoratedDescriptor(_class.prototype, "callback", [
|
|
_dec7,
|
|
_dec8,
|
|
_dec9,
|
|
_dec10,
|
|
_dec11
|
|
], Object.getOwnPropertyDescriptor(_class.prototype, "callback"), _class.prototype), _class)) || _class) || _class) || _class;
|
|
"#
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
}),
|
|
legacy_metadata_parameter_decorated_types,
|
|
"class Injected {}
|
|
|
|
class MyClass {
|
|
constructor(@inject() parameter: Injected) {}
|
|
}
|
|
|
|
class MyOtherClass {
|
|
constructor(
|
|
@inject() private readonly parameter: Injected,
|
|
@inject('KIND') otherParam: Injected
|
|
) {}
|
|
|
|
methodUndecorated(@demo() param: string, otherParam) {}
|
|
|
|
@decorate('named')
|
|
method(@inject() param: Injected, @arg() schema: Schema) {}
|
|
}
|
|
|
|
@Decorate
|
|
class DecoratedClass {
|
|
constructor(
|
|
@inject() private readonly module: Injected,
|
|
@inject() otherModule: Injected
|
|
) {}
|
|
|
|
@decorate('example')
|
|
method(@inject() param: string) {}
|
|
}",
|
|
r##"
|
|
var _class, _class1, _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _class2, _dec8, _dec9, _dec10, _dec11;
|
|
class Injected {
|
|
}
|
|
var _dec12 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Injected === "undefined" ? Object : Injected
|
|
]), _dec13 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec14 = function(target, key) {
|
|
return inject()(target, undefined, 0);
|
|
};
|
|
let MyClass = _class = _dec14(_class = _dec13(_class = _dec12((_class = class MyClass {
|
|
constructor(parameter: Injected){
|
|
}
|
|
}) || _class) || _class) || _class) || _class;
|
|
var _dec15 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Injected === "undefined" ? Object : Injected,
|
|
typeof Injected === "undefined" ? Object : Injected
|
|
]), _dec16 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec17 = function(target, key) {
|
|
return inject("KIND")(target, undefined, 1);
|
|
}, _dec18 = function(target, key) {
|
|
return inject()(target, undefined, 0);
|
|
};
|
|
let MyOtherClass = _class1 = _dec18(_class1 = _dec17(_class1 = _dec16(_class1 = _dec15(((_class1 = class MyOtherClass {
|
|
constructor(private readonly parameter: Injected, otherParam: Injected){
|
|
}
|
|
methodUndecorated(param: string, otherParam) {
|
|
}
|
|
method(param: Injected, schema: Schema) {
|
|
}
|
|
}) || _class1, _dec = function(target, key) {
|
|
return demo()(target, key, 0);
|
|
}, _dec1 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec2 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
String,
|
|
void 0
|
|
]), _applyDecoratedDescriptor(_class1.prototype, "methodUndecorated", [
|
|
_dec,
|
|
_dec1,
|
|
_dec2
|
|
], Object.getOwnPropertyDescriptor(_class1.prototype, "methodUndecorated"), _class1.prototype), _dec3 = decorate("named"), _dec4 = function(target, key) {
|
|
return inject()(target, key, 0);
|
|
}, _dec5 = function(target, key) {
|
|
return arg()(target, key, 1);
|
|
}, _dec6 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec7 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Injected === "undefined" ? Object : Injected,
|
|
typeof Schema === "undefined" ? Object : Schema
|
|
]), _applyDecoratedDescriptor(_class1.prototype, "method", [
|
|
_dec3,
|
|
_dec4,
|
|
_dec5,
|
|
_dec6,
|
|
_dec7
|
|
], Object.getOwnPropertyDescriptor(_class1.prototype, "method"), _class1.prototype), _class1)) || _class1) || _class1) || _class1) || _class1;
|
|
var _dec55 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Injected === "undefined" ? Object : Injected,
|
|
typeof Injected === "undefined" ? Object : Injected
|
|
]), _dec56 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec57 = function(target, key) {
|
|
return inject()(target, undefined, 1);
|
|
}, _dec58 = function(target, key) {
|
|
return inject()(target, undefined, 0);
|
|
};
|
|
let DecoratedClass = _class2 = Decorate(_class2 = _dec58(_class2 = _dec57(_class2 = _dec56(_class2 = _dec55(((_class2 = class DecoratedClass {
|
|
constructor(private readonly module: Injected, otherModule: Injected){
|
|
}
|
|
method(param: string) {
|
|
}
|
|
}) || _class2, _dec8 = decorate("example"), _dec9 = function(target, key) {
|
|
return inject()(target, key, 0);
|
|
}, _dec10 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec11 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
String
|
|
]), _applyDecoratedDescriptor(_class2.prototype, "method", [
|
|
_dec8,
|
|
_dec9,
|
|
_dec10,
|
|
_dec11
|
|
], Object.getOwnPropertyDescriptor(_class2.prototype, "method"), _class2.prototype), _class2)) || _class2) || _class2) || _class2) || _class2) || _class2;
|
|
"##
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
}),
|
|
legacy_metadata_type_serialization,
|
|
"import { Service } from './service';
|
|
import { Decorate } from './Decorate';
|
|
|
|
const sym = Symbol();
|
|
|
|
@Decorate()
|
|
class Sample {
|
|
constructor(
|
|
private p0: String,
|
|
p1: Number,
|
|
p2: 10,
|
|
p3: 'ABC',
|
|
p4: boolean,
|
|
p5: string,
|
|
p6: number,
|
|
p7: Object,
|
|
p8: () => any,
|
|
p9: 'abc' | 'def',
|
|
p10: String | Number,
|
|
p11: Function,
|
|
p12: null,
|
|
p13: undefined,
|
|
p14: any,
|
|
p15: (abc: any) => void,
|
|
p16: false,
|
|
p17: true,
|
|
p18: string = 'abc'
|
|
) {}
|
|
|
|
@Decorate
|
|
method(
|
|
@Arg() p0: Symbol,
|
|
p1: typeof sym,
|
|
p2: string | null,
|
|
p3: never,
|
|
p4: string | never,
|
|
p5: (string | null),
|
|
p6: Maybe<string>,
|
|
p7: Object | string,
|
|
p8: string & MyStringType,
|
|
p9: string[],
|
|
p10: [string, number],
|
|
p11: void,
|
|
p12: this is number,
|
|
p13: null | undefined,
|
|
p14: (string | (string | null)),
|
|
p15: Object,
|
|
p16: any,
|
|
p17: bigint,
|
|
) {}
|
|
|
|
/**
|
|
* Member Expression
|
|
*/
|
|
@Decorate()
|
|
method2(
|
|
p0: Decorate.Name = 'abc',
|
|
p1: Decorate.Name
|
|
) {}
|
|
|
|
/**
|
|
* Assignments
|
|
*/
|
|
@Decorate()
|
|
assignments(
|
|
p0: string = 'abc'
|
|
) {}
|
|
}",
|
|
r##"var _class, _dec, _dec1, _dec2, _dec3, _dec4, _dec5, _dec6, _dec7, _dec8;
|
|
import { Service } from "./service";
|
|
import { Decorate } from "./Decorate";
|
|
const sym = Symbol();
|
|
var _dec9 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof String === "undefined" ? Object : String,
|
|
typeof Number === "undefined" ? Object : Number,
|
|
Number,
|
|
String,
|
|
Boolean,
|
|
String,
|
|
Number,
|
|
typeof Object === "undefined" ? Object : Object,
|
|
Function,
|
|
String,
|
|
Object,
|
|
typeof Function === "undefined" ? Object : Function,
|
|
void 0,
|
|
void 0,
|
|
Object,
|
|
Function,
|
|
Boolean,
|
|
Boolean,
|
|
String
|
|
]), _dec10 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec11 = Decorate();
|
|
let Sample = _class = _dec11(_class = _dec10(_class = _dec9(((_class = class Sample {
|
|
constructor(private p0: String, p1: Number, p2: 10, p3: "ABC", p4: boolean, p5: string, p6: number, p7: Object, p8: () => any, p9: "abc" | "def", p10: String | Number, p11: Function, p12: null, p13: undefined, p14: any, p15: (abc: any) => void, p16: false, p17: true, p18: string = "abc"){
|
|
}
|
|
method(p0: Symbol, p1: typeof sym, p2: string | null, p3: never, p4: string | never, p5: (string | null), p6: Maybe<string>, p7: Object | string, p8: string & MyStringType, p9: string[], p10: [string, number], p11: void, p12: this is number, p13: null | undefined, p14: (string | (string | null)), p15: Object, p16: any, p17: bigint) {
|
|
}
|
|
method2(p0: Decorate.Name. = "abc", p1: Decorate.Name.) {
|
|
}
|
|
assignments(p0: string = "abc") {
|
|
}
|
|
}) || _class, _dec = function(target, key) {
|
|
return Arg()(target, key, 0);
|
|
}, _dec1 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec2 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Symbol === "undefined" ? Object : Symbol,
|
|
Object,
|
|
void 0,
|
|
void 0,
|
|
void 0,
|
|
void 0,
|
|
typeof Maybe === "undefined" ? Object : Maybe,
|
|
Object,
|
|
Object,
|
|
Array,
|
|
Array,
|
|
void 0,
|
|
Boolean,
|
|
void 0,
|
|
Object,
|
|
typeof Object === "undefined" ? Object : Object,
|
|
Object,
|
|
Number
|
|
]), _applyDecoratedDescriptor(_class.prototype, "method", [
|
|
Decorate,
|
|
_dec,
|
|
_dec1,
|
|
_dec2
|
|
], Object.getOwnPropertyDescriptor(_class.prototype, "method"), _class.prototype), _dec3 = Decorate(), _dec4 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec5 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Decorate === "undefined" || typeof Decorate.Name === "undefined" ? Object : Decorate.Name,
|
|
typeof Decorate === "undefined" || typeof Decorate.Name === "undefined" ? Object : Decorate.Name
|
|
]), _applyDecoratedDescriptor(_class.prototype, "method2", [
|
|
_dec3,
|
|
_dec4,
|
|
_dec5
|
|
], Object.getOwnPropertyDescriptor(_class.prototype, "method2"), _class.prototype), _dec6 = Decorate(), _dec7 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec8 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
String
|
|
]), _applyDecoratedDescriptor(_class.prototype, "assignments", [
|
|
_dec6,
|
|
_dec7,
|
|
_dec8
|
|
], Object.getOwnPropertyDescriptor(_class.prototype, "assignments"), _class.prototype), _class)) || _class) || _class) || _class;"##,
|
|
ok_if_code_eq
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
}),
|
|
issue_1160_1,
|
|
"
|
|
enum MyEnum {
|
|
x = \"xxx\",
|
|
y = \"yyy\"
|
|
}
|
|
|
|
class Xpto {
|
|
@Decorator()
|
|
value!: MyEnum;
|
|
}
|
|
|
|
function Decorator() {
|
|
return function (...args) {};
|
|
}
|
|
",
|
|
"
|
|
var _class, _descriptor, _dec, _dec1;
|
|
enum MyEnum {
|
|
x = 'xxx',
|
|
y = 'yyy'
|
|
}
|
|
let Xpto = ((_class = class Xpto {
|
|
constructor(){
|
|
_initializerDefineProperty(this, 'value', _descriptor, this);
|
|
}
|
|
}) || _class, _dec = Decorator(), _dec1 = typeof Reflect !== 'undefined' && typeof \
|
|
Reflect.metadata === 'function' && Reflect.metadata('design:type', String), _descriptor = \
|
|
_applyDecoratedDescriptor(_class.prototype, 'value', [
|
|
_dec,
|
|
_dec1
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0
|
|
}), _class);
|
|
function Decorator() {
|
|
return function(...args) {
|
|
};
|
|
}
|
|
",
|
|
ok_if_code_eq
|
|
);
|
|
|
|
// decorators_legacy_interop_local_define_property
|
|
test!(
|
|
// See: https://github.com/swc-project/swc/issues/421
|
|
ignore,
|
|
Default::default(),
|
|
|t| chain!(
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
class_properties(class_properties::Config { loose: false }),
|
|
classes(Some(t.comments.clone()),)
|
|
),
|
|
decorators_legacy_interop_local_define_property,
|
|
r#"
|
|
function dec() {}
|
|
|
|
// Create a local function binding so babel has to change the name of the helper
|
|
function _defineProperty() {}
|
|
|
|
class A {
|
|
@dec a;
|
|
|
|
@dec b = 123;
|
|
|
|
c = 456;
|
|
}
|
|
|
|
"#,
|
|
r#"
|
|
var _class, _descriptor, _descriptor2, _temp;
|
|
|
|
function dec() {} // Create a local function binding so babel has to change the name of the helper
|
|
|
|
|
|
function _defineProperty() {}
|
|
|
|
let A = (_class = (_temp = function A() {
|
|
"use strict";
|
|
|
|
_classCallCheck(this, A);
|
|
|
|
_initializerDefineProperty(this, "a", _descriptor, this);
|
|
|
|
_initializerDefineProperty(this, "b", _descriptor2, this);
|
|
|
|
_defineProperty2(this, "c", 456);
|
|
}, _temp), (_descriptor = _applyDecoratedDescriptor(_class.prototype, "a", [dec], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: null
|
|
}), _descriptor2 = _applyDecoratedDescriptor(_class.prototype, "b", [dec], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: function () {
|
|
return 123;
|
|
}
|
|
})), _class);
|
|
|
|
"#
|
|
);
|
|
|
|
fn issue_395_syntax() -> ::swc_ecma_parser::Syntax {
|
|
::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsConfig {
|
|
decorators: true,
|
|
..Default::default()
|
|
})
|
|
}
|
|
|
|
test!(
|
|
issue_395_syntax(),
|
|
|_| chain!(
|
|
decorators(Default::default()),
|
|
common_js(
|
|
Mark::fresh(Mark::root()),
|
|
common_js::Config {
|
|
strict: false,
|
|
strict_mode: true,
|
|
no_interop: true,
|
|
..Default::default()
|
|
},
|
|
None
|
|
),
|
|
),
|
|
issue_395_1,
|
|
"
|
|
import Test from './moduleA.js'
|
|
|
|
@Test('0.0.1')
|
|
class Demo {
|
|
constructor() {
|
|
this.author = 'alan'
|
|
}
|
|
}
|
|
",
|
|
"
|
|
'use strict';
|
|
var _moduleAJs = require('./moduleA.js');
|
|
let Demo = _decorate([(0, _moduleAJs).default('0.0.1')], function(_initialize) {
|
|
class Demo{
|
|
constructor(){
|
|
_initialize(this);
|
|
this.author = 'alan';
|
|
}
|
|
}
|
|
return {
|
|
F: Demo,
|
|
d: []
|
|
};
|
|
});
|
|
|
|
"
|
|
);
|
|
|
|
test!(
|
|
issue_395_syntax(),
|
|
|_| chain!(
|
|
decorators(Default::default()),
|
|
common_js::common_js(
|
|
Mark::fresh(Mark::root()),
|
|
common_js::Config {
|
|
strict: false,
|
|
strict_mode: true,
|
|
no_interop: true,
|
|
..Default::default()
|
|
},
|
|
None
|
|
),
|
|
),
|
|
issue_395_2,
|
|
"
|
|
const Test = (version) => {
|
|
return (target) => {
|
|
target.version = version
|
|
}
|
|
}
|
|
|
|
export default Test
|
|
",
|
|
"
|
|
'use strict';
|
|
Object.defineProperty(exports, '__esModule', {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
const Test = (version)=>{
|
|
return (target)=>{
|
|
target.version = version;
|
|
};
|
|
};
|
|
var _default = Test;
|
|
exports.default = _default;
|
|
"
|
|
);
|
|
|
|
// function_name_function_assignment
|
|
test!(
|
|
ignore,
|
|
Default::default(),
|
|
|t| chain!(
|
|
resolver(),
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
classes(Some(t.comments.clone())),
|
|
function_name(),
|
|
),
|
|
function_name_function_assignment,
|
|
r#"
|
|
var foo;
|
|
foo = function() {
|
|
};
|
|
|
|
var baz;
|
|
baz = function() {
|
|
baz();
|
|
};
|
|
baz = 12;
|
|
|
|
bar = function() {
|
|
bar();
|
|
};
|
|
|
|
"#,
|
|
r#"
|
|
var foo;
|
|
|
|
foo = function foo() {};
|
|
|
|
var _baz;
|
|
|
|
_baz = function baz() {
|
|
_baz();
|
|
};
|
|
|
|
_baz = 12;
|
|
|
|
bar = function (_bar) {
|
|
function bar() {
|
|
return _bar.apply(this, arguments);
|
|
}
|
|
|
|
bar.toString = function () {
|
|
return _bar.toString();
|
|
};
|
|
|
|
return bar;
|
|
}(function () {
|
|
bar();
|
|
});
|
|
|
|
"#
|
|
);
|
|
|
|
// function_name_shorthand_property
|
|
test!(
|
|
// not important
|
|
ignore,
|
|
Default::default(),
|
|
|t| chain!(
|
|
resolver(),
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
classes(Some(t.comments.clone())),
|
|
function_name(),
|
|
),
|
|
function_name_shorthand_property,
|
|
r#"
|
|
var Utils = {
|
|
get: function() {}
|
|
};
|
|
|
|
var { get } = Utils;
|
|
|
|
var bar = {
|
|
get: function(arg) {
|
|
get(arg, "baz");
|
|
}
|
|
};
|
|
|
|
var f = function ({ foo = "bar" }) {
|
|
var obj = {
|
|
// same name as parameter
|
|
foo: function () {
|
|
foo;
|
|
}
|
|
};
|
|
};
|
|
|
|
"#,
|
|
r#"
|
|
var Utils = {
|
|
get: function get() {}
|
|
};
|
|
var {
|
|
get: _get
|
|
} = Utils;
|
|
var bar = {
|
|
get: function get(arg) {
|
|
_get(arg, "baz");
|
|
}
|
|
};
|
|
|
|
var f = function f({
|
|
foo: _foo = "bar"
|
|
}) {
|
|
var obj = {
|
|
// same name as parameter
|
|
foo: function foo() {
|
|
_foo;
|
|
}
|
|
};
|
|
};
|
|
|
|
"#
|
|
);
|
|
|
|
// function_name_object
|
|
test!(
|
|
ignore,
|
|
Default::default(),
|
|
|t| chain!(
|
|
resolver(),
|
|
function_name(),
|
|
classes(Some(t.comments.clone())),
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
})
|
|
),
|
|
function_name_object,
|
|
r#"
|
|
var obj = {
|
|
f: function () {
|
|
(function f() {
|
|
console.log(f);
|
|
})();
|
|
},
|
|
|
|
h: function () {
|
|
console.log(h);
|
|
},
|
|
|
|
m: function () {
|
|
doSmth();
|
|
}
|
|
};
|
|
|
|
"#,
|
|
r#"
|
|
var obj = {
|
|
f: function f() {
|
|
(function f() {
|
|
console.log(f);
|
|
})();
|
|
},
|
|
h: function (_h) {
|
|
function h() {
|
|
return _h.apply(this, arguments);
|
|
}
|
|
|
|
h.toString = function () {
|
|
return _h.toString();
|
|
};
|
|
|
|
return h;
|
|
}(function () {
|
|
console.log(h);
|
|
}),
|
|
m: function m() {
|
|
doSmth();
|
|
}
|
|
};
|
|
|
|
"#
|
|
);
|
|
|
|
// function_name_export
|
|
test!(
|
|
// not important
|
|
ignore,
|
|
Default::default(),
|
|
|t| chain!(
|
|
resolver(),
|
|
function_name(),
|
|
classes(Some(t.comments.clone())),
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
})
|
|
),
|
|
function_name_export,
|
|
r#"
|
|
export var foo = "yes", foob = "no";
|
|
|
|
export function whatever() {}
|
|
|
|
export default function wowzers() {}
|
|
|
|
var bar = {
|
|
foo: function () {
|
|
foo;
|
|
},
|
|
|
|
whatever: function () {
|
|
whatever;
|
|
},
|
|
|
|
wowzers: function () {
|
|
wowzers;
|
|
}
|
|
};
|
|
|
|
"#,
|
|
r#"
|
|
var _foo = "yes",
|
|
foob = "no";
|
|
export { _foo as foo, foob };
|
|
|
|
function _whatever() {}
|
|
|
|
export { _whatever as whatever };
|
|
|
|
function _wowzers() {}
|
|
|
|
export { _wowzers as default };
|
|
var bar = {
|
|
foo: function foo() {
|
|
_foo;
|
|
},
|
|
whatever: function whatever() {
|
|
_whatever;
|
|
},
|
|
wowzers: function wowzers() {
|
|
_wowzers;
|
|
}
|
|
};
|
|
|
|
"#
|
|
);
|
|
|
|
// function_name_global
|
|
test!(
|
|
// Cost of development is too high.
|
|
ignore,
|
|
Default::default(),
|
|
|t| chain!(
|
|
resolver(),
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
function_name(),
|
|
classes(Some(t.comments.clone())),
|
|
),
|
|
function_name_global,
|
|
r#"
|
|
var test = {
|
|
setInterval: function(fn, ms) {
|
|
setInterval(fn, ms);
|
|
}
|
|
};
|
|
|
|
"#,
|
|
r#"
|
|
var test = {
|
|
setInterval: function (_setInterval) {
|
|
function setInterval(_x, _x2) {
|
|
return _setInterval.apply(this, arguments);
|
|
}
|
|
|
|
setInterval.toString = function () {
|
|
return _setInterval.toString();
|
|
};
|
|
|
|
return setInterval;
|
|
}(function (fn, ms) {
|
|
setInterval(fn, ms);
|
|
})
|
|
};
|
|
|
|
"#
|
|
);
|
|
|
|
// function_name_modules
|
|
test!(
|
|
Default::default(),
|
|
|t| chain!(
|
|
resolver(),
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
classes(Some(t.comments.clone())),
|
|
function_name(),
|
|
common_js(Mark::fresh(Mark::root()), Default::default(), None),
|
|
),
|
|
function_name_modules,
|
|
r#"
|
|
import events from "events";
|
|
|
|
class Template {
|
|
events() {
|
|
return events;
|
|
}
|
|
}
|
|
|
|
console.log(new Template().events());
|
|
|
|
"#,
|
|
r#"
|
|
"use strict";
|
|
|
|
var _events = _interopRequireDefault(require("events"));
|
|
|
|
let Template =
|
|
/*#__PURE__*/
|
|
function () {
|
|
'use strict';
|
|
function Template() {
|
|
_classCallCheck(this, Template);
|
|
}
|
|
|
|
_createClass(Template, [{
|
|
key: "events",
|
|
value: function events() {
|
|
return _events.default;
|
|
}
|
|
}]);
|
|
return Template;
|
|
}();
|
|
|
|
console.log(new Template().events());
|
|
|
|
"#
|
|
);
|
|
|
|
// function_name_eval
|
|
test!(
|
|
Default::default(),
|
|
|t| chain!(
|
|
resolver(),
|
|
function_name(),
|
|
classes(Some(t.comments.clone())),
|
|
decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
})
|
|
),
|
|
function_name_eval,
|
|
r#"
|
|
var a = {
|
|
eval: function () {
|
|
return eval;
|
|
}
|
|
};
|
|
|
|
"#,
|
|
r#"
|
|
var a = {
|
|
eval: function _eval() {
|
|
return eval;
|
|
}
|
|
};
|
|
|
|
"#
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(decorators::Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
swc_node_210,
|
|
"
|
|
class Foo{
|
|
@dec
|
|
[foo]() {
|
|
}
|
|
}
|
|
",
|
|
"
|
|
var _class;
|
|
let Foo = ((_class = class Foo {
|
|
[foo]() {
|
|
}
|
|
}) || _class, _applyDecoratedDescriptor(_class.prototype, foo, [
|
|
dec
|
|
], Object.getOwnPropertyDescriptor(_class.prototype, foo), _class.prototype), _class);
|
|
"
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(decorators::Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
..Default::default()
|
|
}),
|
|
issue_1421_1,
|
|
"
|
|
class User {
|
|
@column() currency!: 'usd' | 'eur' | 'yen';
|
|
}
|
|
",
|
|
"
|
|
var _class, _descriptor, _dec, _dec1;
|
|
let User = ((_class = class User {
|
|
constructor(){
|
|
_initializerDefineProperty(this, 'currency', _descriptor, this);
|
|
}
|
|
}) || _class, _dec = column(), _dec1 = typeof Reflect !== 'undefined' && typeof \
|
|
Reflect.metadata === 'function' && Reflect.metadata('design:type', String), _descriptor = \
|
|
_applyDecoratedDescriptor(_class.prototype, 'currency', [
|
|
_dec,
|
|
_dec1
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0
|
|
}), _class);
|
|
"
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(decorators::Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
..Default::default()
|
|
}),
|
|
issue_1456_1,
|
|
"
|
|
class MyClass {
|
|
constructor(@Inject() param1: Injected) {}
|
|
}
|
|
",
|
|
r#"
|
|
var _class;
|
|
var _dec = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:paramtypes", [
|
|
typeof Injected === "undefined" ? Object : Injected
|
|
]), _dec1 = typeof Reflect !== "undefined" && typeof Reflect.metadata === "function" && Reflect.metadata("design:type", Function), _dec2 = function(target, key) {
|
|
return Inject()(target, undefined, 0);
|
|
};
|
|
let MyClass = _class = _dec2(_class = _dec1(_class = _dec((_class = class MyClass {
|
|
constructor(param1: Injected){
|
|
}
|
|
}) || _class) || _class) || _class) || _class;
|
|
"#
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(decorators::Config {
|
|
..Default::default()
|
|
}),
|
|
issue_846_1,
|
|
"
|
|
class SomeClass {
|
|
@dec
|
|
someMethod() {}
|
|
}
|
|
|
|
class OtherClass extends SomeClass {
|
|
@dec
|
|
anotherMethod() {
|
|
super.someMethod()
|
|
}
|
|
}
|
|
",
|
|
"
|
|
let SomeClass = _decorate([], function(_initialize) {
|
|
class SomeClass {
|
|
constructor(){
|
|
_initialize(this);
|
|
}
|
|
}
|
|
return {
|
|
F: SomeClass,
|
|
d: [
|
|
{
|
|
kind: 'method',
|
|
decorators: [
|
|
dec
|
|
],
|
|
key: 'someMethod',
|
|
value: function someMethod() {
|
|
}
|
|
}
|
|
]
|
|
};
|
|
});
|
|
let OtherClass = _decorate([], function(_initialize, _SomeClass) {
|
|
class OtherClass extends _SomeClass {
|
|
constructor(...args){
|
|
super(...args);
|
|
_initialize(this);
|
|
}
|
|
}
|
|
return {
|
|
F: OtherClass,
|
|
d: [
|
|
{
|
|
kind: 'method',
|
|
decorators: [
|
|
dec
|
|
],
|
|
key: 'anotherMethod',
|
|
value: function anotherMethod() {
|
|
_get(_getPrototypeOf(OtherClass.prototype), 'someMethod', this).call(this);
|
|
}
|
|
}
|
|
]
|
|
};
|
|
}, SomeClass);
|
|
"
|
|
);
|
|
|
|
test!(
|
|
ts(),
|
|
|_| decorators(decorators::Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
..Default::default()
|
|
}),
|
|
issue_1278_1,
|
|
"
|
|
function MyDecorator(klass) {
|
|
return () => {
|
|
// do something
|
|
console.log(klass);
|
|
}
|
|
}
|
|
|
|
class MyClass {
|
|
@MyDecorator(MyClass) prop: '';
|
|
}
|
|
|
|
console.log(new MyClass());
|
|
",
|
|
"
|
|
var _class, _descriptor, _dec, _dec1;
|
|
function MyDecorator(klass) {
|
|
return ()=>{
|
|
console.log(klass);
|
|
};
|
|
}
|
|
let MyClass = ((_class = class MyClass {
|
|
constructor(){
|
|
_initializerDefineProperty(this, 'prop', _descriptor, this);
|
|
}
|
|
}) || _class, _dec = MyDecorator(_class), _dec1 = typeof Reflect !== 'undefined' && typeof \
|
|
Reflect.metadata === 'function' && Reflect.metadata('design:type', String), _descriptor = \
|
|
_applyDecoratedDescriptor(_class.prototype, 'prop', [
|
|
_dec,
|
|
_dec1
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: void 0
|
|
}), _class);
|
|
console.log(new MyClass());
|
|
"
|
|
);
|
|
|
|
test!(
|
|
syntax(false),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
issue_1913_1,
|
|
"
|
|
class Store {
|
|
constructor() {
|
|
this.doSomething();
|
|
}
|
|
|
|
@action
|
|
doSomething = () => {
|
|
console.log('run');
|
|
}
|
|
}",
|
|
"
|
|
var _class, _descriptor;
|
|
let Store = ((_class = class Store {
|
|
constructor(){
|
|
_initializerDefineProperty(this, 'doSomething', _descriptor, this);
|
|
this.doSomething();
|
|
}
|
|
}) || _class, _descriptor = _applyDecoratedDescriptor(_class.prototype, 'doSomething', [
|
|
action
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: function() {
|
|
return ()=>{
|
|
console.log('run');
|
|
};
|
|
}
|
|
}), _class);
|
|
"
|
|
);
|
|
|
|
test!(
|
|
syntax(false),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
issue_1913_2,
|
|
"
|
|
class Store extends BaseStore{
|
|
constructor() {
|
|
super();
|
|
this.doSomething();
|
|
}
|
|
|
|
@action
|
|
doSomething = () => {
|
|
console.log('run');
|
|
}
|
|
}",
|
|
"
|
|
var _class, _descriptor;
|
|
let Store = ((_class = class Store extends BaseStore {
|
|
constructor(){
|
|
super();
|
|
_initializerDefineProperty(this, 'doSomething', _descriptor, this);
|
|
this.doSomething();
|
|
}
|
|
}) || _class, _descriptor = _applyDecoratedDescriptor(_class.prototype, 'doSomething', [
|
|
action
|
|
], {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
initializer: function() {
|
|
return ()=>{
|
|
console.log('run');
|
|
};
|
|
}
|
|
}), _class);
|
|
"
|
|
);
|
|
|
|
test!(
|
|
syntax(false),
|
|
|_| decorators(Config {
|
|
legacy: true,
|
|
..Default::default()
|
|
}),
|
|
issue_1869_1,
|
|
"
|
|
@someClassDecorator
|
|
class TestClass {
|
|
static Something = 'hello';
|
|
|
|
static SomeProperties = {
|
|
firstProp: TestClass.Something,
|
|
};
|
|
}
|
|
|
|
function someClassDecorator(c) {
|
|
return c;
|
|
}
|
|
",
|
|
"
|
|
var _class;
|
|
let TestClass = _class = someClassDecorator((_class = class TestClass {
|
|
static Something = 'hello';
|
|
static SomeProperties = {
|
|
firstProp: TestClass.Something
|
|
};
|
|
}) || _class) || _class;
|
|
function someClassDecorator(c) {
|
|
return c;
|
|
}
|
|
"
|
|
);
|
|
|
|
test_exec!(
|
|
Syntax::Typescript(TsConfig {
|
|
decorators: true,
|
|
..Default::default()
|
|
}),
|
|
|_| {
|
|
chain!(
|
|
decorators(Config {
|
|
legacy: true,
|
|
emit_metadata: true,
|
|
..Default::default()
|
|
}),
|
|
strip()
|
|
)
|
|
},
|
|
issue_1362_1,
|
|
"
|
|
const { IsString } = require('class-validator');
|
|
|
|
class CreateUserDto {
|
|
@IsString()
|
|
id!: string;
|
|
}
|
|
"
|
|
);
|