Various computed property fixes

* Implement getter/setter with computed value
* Fix parsing getter/setter after static or generator token
* Allow storing expressions in AST_SymbolMethod
This commit is contained in:
Anthony Van de Gejuchte 2016-07-06 00:40:28 +02:00
parent 842ac27efb
commit cd6e893597
4 changed files with 137 additions and 7 deletions

View File

@ -887,8 +887,12 @@ function OutputStream(options) {
output.space();
}
}
if (self.name) {
if (self.name instanceof AST_Symbol) {
self.name.print(output);
} else if (nokeyword && self.name instanceof AST_Node) {
output.with_square(function() {
self.name.print(output);
});
}
output.with_parens(function(){
self.argnames.forEach(function(arg, i){
@ -1489,6 +1493,15 @@ function OutputStream(options) {
self.default.print(output)
}
});
DEFPRINT(AST_SymbolMethod, function(self, output) {
if (self.name instanceof AST_Node) {
output.with_square(function() {
self.name.print(output);
});
} else {
self._do_print(output);
}
});
DEFPRINT(AST_Undefined, function(self, output){
output.print("void 0");
});

View File

@ -1622,6 +1622,15 @@ function parse($TEXT, options) {
}
ret = _make_symbol(AST_SymbolRef);
break;
case "punc":
if (S.token.value === "[") {
next();
ret = expression(false);
if (S.token.type !== "punc" && S.token.value !== "]") {
unexpected();
}
break;
}
}
next();
return ret;
@ -1845,20 +1854,25 @@ function parse($TEXT, options) {
var is_generator = false;
if (is_class && name === "static" && !is("punc", "(")) {
is_static = true;
name = S.token.value;
next();
name = as_property_name();
}
if (name === "*") {
is_generator = true;
name = S.token.value;
next();
name = as_property_name();
}
if (is("punc", "(")) {
if (typeof name === "string") {
name = new AST_SymbolMethod({
start: start,
name: name,
end: prev()
});
}
return new AST_ConciseMethod({
is_generator: is_generator,
start : start,
static : is_static,
name : new AST_SymbolMethod({ name: name }),
name : name,
argnames : params_or_seq_().as_params(croak),
body : _function_body(true, is_generator),
end : prev()

View File

@ -175,6 +175,49 @@ concise_methods: {
expect_exact: "x={foo(a,b){return x}};y={foo([{a}]){return a},bar(){}};"
}
concise_methods_with_computed_property: {
options = {
evaluate: true
}
input: {
var foo = {
[Symbol.iterator]() {
return { /* stuff */ }
},
[1 + 2]() {
return 3;
}
}
}
expect: {
var foo = {
[Symbol.iterator]() {
return { /* stuff */ }
},
[3]() {
return 3;
}
}
}
}
concise_methods_with_computed_property2: {
options = {
evaluate: true
}
input: {
var foo = {
[[1]](){
return "success";
}
};
doSomething(foo[[1]]());
}
expect_exact: {
'var foo={[[1]](){return"success"}};doSomething(foo[[1]]());'
}
}
concise_methods_and_mangle_props: {
mangle_props = {
regex: /_/
@ -243,6 +286,29 @@ classes: {
expect_exact: "class SomeClass{constructor(){}foo(){}}class NoSemi{constructor(...args){}foo(){}}class ChildClass extends SomeClass{}var asExpression=class AsExpression{};var nameless=class{};"
}
getter_setter_with_computed_value: {
input: {
class C {
get ['a']() {
return 'A';
}
set ['a'](value) {
do_something(a);
}
}
}
expect: {
class C {
get ['a']() {
return 'A';
}
set ['a'](value) {
do_something(a);
}
}
}
}
class_statics: {
input: {
x = class {
@ -309,6 +375,32 @@ classes_can_have_generators: {
}
}
classes_can_have_computed_generators: {
input: {
class C4 {
*['constructor']() {}
}
}
expect: {
class C4 {
*['constructor']() {}
}
}
}
classes_can_have_computed_static: {
input: {
class C4 {
static ['constructor']() {}
}
}
expect: {
class C4 {
static ['constructor']() {}
}
}
}
new_target: {
input: {
new.target;

View File

@ -17,4 +17,15 @@ describe("Object", function() {
}
assert.throws(parse, expect);
});
});
it("Should not allow objects to have static computed properties like in classes", function() {
var code = "var foo = {static [123](){}}";
var parse = function() {
console.log(Uglify.parse(code).body[0].body[0]);
}
var expect = function(e) {
return e instanceof Uglify.JS_Parse_Error;
}
assert.throws(parse, expect);
});
});