simplify computed properties for methods, getters & setters (#2555)

fixes #2554
This commit is contained in:
Alex Lam S.L
2017-12-04 00:18:48 +08:00
committed by GitHub
parent 606f7a5b37
commit 87bae623e9
2 changed files with 226 additions and 12 deletions

View File

@@ -5341,7 +5341,31 @@ merge(Compressor.prototype, {
return self;
});
// ["p"]:1 ---> p:1
// [42]:1 ---> 42:1
function lift_key(self, compressor) {
if (!compressor.option("computed_props")) return self;
// save a comparison in the typical case
if (!(self.key instanceof AST_Constant)) return self;
// whitelist acceptable props as not all AST_Constants are true constants
if (self.key instanceof AST_String || self.key instanceof AST_Number) {
if (self.key.value == "constructor"
&& compressor.parent() instanceof AST_Class) return self;
if (self instanceof AST_ObjectKeyVal) {
self.key = self.key.value;
} else {
self.key = make_node(AST_SymbolMethod, self.key, {
name: self.key.value
});
}
}
return self;
}
OPT(AST_ObjectProperty, lift_key);
OPT(AST_ConciseMethod, function(self, compressor){
lift_key(self, compressor);
// p(){return x;} ---> p:()=>x
if (compressor.option("arrows")
&& compressor.parent() instanceof AST_Object
@@ -5362,18 +5386,7 @@ merge(Compressor.prototype, {
});
OPT(AST_ObjectKeyVal, function(self, compressor){
// ["p"]:1 ---> p:1
// [42]:1 ---> 42:1
if (compressor.option("computed_props")
&& self.key instanceof AST_Constant // save a comparison in the typical case
&& (
// whitelist acceptable props as not all AST_Constants are true constants
self.key instanceof AST_String
|| self.key instanceof AST_Number
)) {
self.key = self.key.value;
// fallthrough - `return self` not needed as transformed tree in good form
}
lift_key(self, compressor);
// p:function(){} ---> p(){}
// p:function*(){} ---> *p(){}
// p:async function(){} ---> async p(){}

View File

@@ -812,3 +812,204 @@ prop_arrow_with_nested_this: {
]
node_version: ">=4"
}
issue_2554_1: {
options = {
computed_props: true,
evaluate: true,
}
input: {
var obj = {
["x" + ""]: 1,
["method" + ""]() {
this.s = "PASS";
},
get ["g" + ""]() {
return this.x;
},
set ["s" + ""](value) {
this.x = value;
}
};
obj.method();
console.log(obj.g);
}
expect: {
var obj = {
x: 1,
method() {
this.s = "PASS";
},
get g() {
return this.x;
},
set s(value) {
this.x = value;
}
};
obj.method();
console.log(obj.g);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_2554_2: {
options = {
computed_props: true,
evaluate: true,
}
input: {
var instance = new class {
constructor() {
this.x = 2;
}
["method" + ""]() {
this.s = "PASS";
}
get ["g" + ""]() {
return this.x;
}
set ["s" + ""](value) {
this.x = value;
}
}();
instance.method();
console.log(instance.g);
}
expect: {
var instance = new class {
constructor() {
this.x = 2;
}
method() {
this.s = "PASS";
}
get g() {
return this.x;
}
set s(value) {
this.x = value;
}
}();
instance.method();
console.log(instance.g);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_2554_3: {
options = {
computed_props: true,
evaluate: true,
}
input: {
var foo = {
[1 + 0]: 1,
[2 + 0]() {
this[4] = "PASS";
},
get [3 + 0]() {
return this[1];
},
set [4 + 0](value) {
this[1] = value;
}
};
foo[2]();
console.log(foo[3]);
}
expect: {
var foo = {
1: 1,
2() {
this[4] = "PASS";
},
get 3() {
return this[1];
},
set 4(value) {
this[1] = value;
}
};
foo[2]();
console.log(foo[3]);
}
expect_stdout: "PASS"
node_version: ">=4"
}
issue_2554_4: {
options = {
computed_props: true,
evaluate: true,
}
input: {
var bar = new class {
constructor() {
this[1] = 2;
}
[2 + 0]() {
this[4] = "PASS";
}
get [3 + 0]() {
return this[1];
}
set [4 + 0](value) {
this[1] = value;
}
}();
bar[2]();
console.log(bar[3]);
}
expect: {
var bar = new class {
constructor() {
this[1] = 2;
}
2() {
this[4] = "PASS";
}
get 3() {
return this[1];
}
set 4(value) {
this[1] = value;
}
}();
bar[2]();
console.log(bar[3]);
}
expect_stdout: "PASS"
node_version: ">=6"
}
issue_2554_5: {
options = {
computed_props: true,
evaluate: true,
}
input: {
new class {
["constructor"]() {
console.log("FAIL");
}
"constructor"() {
console.log("PASS");
}
}();
}
expect: {
new class {
["constructor"]() {
console.log("FAIL");
}
constructor() {
console.log("PASS");
}
}();
}
expect_stdout: "PASS"
node_version: ">=6"
}