diff --git a/lib/output.js b/lib/output.js index 2046fc92..57920e02 100644 --- a/lib/output.js +++ b/lib/output.js @@ -888,7 +888,11 @@ function OutputStream(options) { } } if (self.name instanceof AST_Symbol) { - self.name.print(output); + if (typeof self.name.name === "string" && !is_identifier_string(self.name.name)) { + output.print_string(self.name.name); + } else { + self.name.print(output); + } } else if (nokeyword && self.name instanceof AST_Node) { output.with_square(function() { self.name.print(output); // Computed method name @@ -1450,15 +1454,19 @@ function OutputStream(options) { output.colon(); self.value.print(output); }); - DEFPRINT(AST_ObjectSetter, function(self, output){ + AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, self, output) { if (self.static) { output.print("static"); output.space(); } - output.print("set"); + output.print(type); output.space(); if (self.key instanceof AST_SymbolMethod) { - self.key.print(output); + if (typeof self.key.name === "string" && !is_identifier_string(self.key.name)) { + output.print_string(self.key.name); + } else { + self.key.print(output); + } } else { output.with_square(function() { self.key.print(output); @@ -1466,21 +1474,11 @@ function OutputStream(options) { } self.value._do_print(output, true); }); + DEFPRINT(AST_ObjectSetter, function(self, output){ + self._print_getter_setter("set", self, output); + }); DEFPRINT(AST_ObjectGetter, function(self, output){ - if (self.static) { - output.print("static"); - output.space(); - } - output.print("get"); - output.space(); - if (self.key instanceof AST_SymbolMethod) { - self.key.print(output); - } else { - output.with_square(function() { - self.key.print(output); - }); - } - self.value._do_print(output, true); + self._print_getter_setter("get", self, output); }); DEFPRINT(AST_ObjectComputedKeyVal, function(self, output) { output.print("["); diff --git a/lib/parse.js b/lib/parse.js index 07f984f1..b933dde3 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1747,7 +1747,7 @@ function parse($TEXT, options) { a.push(concise); continue; } - } else if (start.value === "*") { + } else if (name === null) { unexpected(prev()); } @@ -1844,14 +1844,13 @@ function parse($TEXT, options) { function concise_method_or_getset(name, start, is_class) { var get_ast = function(name, token) { if (typeof name === "string" || typeof name === "number") { - if (name === "*") { - unexpected(token); - } return new AST_SymbolMethod({ start: token, name: name, end: prev() }); + } else if (name === null) { + unexpected(); } return name; } @@ -1861,9 +1860,12 @@ function parse($TEXT, options) { is_static = true; name = as_property_name(); } - if (name === "*") { + if (name === null) { is_generator = true; name = as_property_name(); + if (name === null) { + unexpected(); + } } if (is("punc", "(")) { name = get_ast(name, start); @@ -2017,7 +2019,10 @@ function parse($TEXT, options) { return ex; } else unexpected(tmp); case "operator": - if (["*", "delete", "in", "instanceof", "new", "typeof", "void"].indexOf(tmp.value) === -1) { + if (tmp.value === "*") { + return null; + } + if (["delete", "in", "instanceof", "new", "typeof", "void"].indexOf(tmp.value) === -1) { unexpected(tmp); } case "name": diff --git a/test/compress/object.js b/test/compress/object.js index 2e7d37a3..d13678a4 100644 --- a/test/compress/object.js +++ b/test/compress/object.js @@ -242,3 +242,100 @@ getter_setter_with_computed_value: { } expect_exact: 'class C{get["a"](){return"A"}set["a"](value){do_something(a)}}var x={get[a.b](){return 42}};class MyArray extends Array{get[Symbol.species](){return Array}}' } + +property_with_operator_value: { + input: { + var foo = { + "*": 1, + get "*"() { + return 2; + }, + *"*"() { + return 3; + }, + "%": 1, + get "%"() { + return 2; + }, + *"%"() { + return 3; + } + } + class bar { + get "*"() { + return 1 + } + *"*"() { + return 2; + } + get "%"() { + return 1 + } + *"%"() { + return 2; + } + } + } + expect_exact: 'var foo={"*":1,get"*"(){return 2},*"*"(){return 3},"%":1,get"%"(){return 2},*"%"(){return 3}};class bar{get"*"(){return 1}*"*"(){return 2}get"%"(){return 1}*"%"(){return 2}}' +} + +property_with_unprintable: { + input: { + var foo = { + "\x00\x01": "foo", + get "\x00\x01"() { + return "bar"; + }, + set "\x00\x01"(foo) { + save(foo); + }, + *"\x00\x01"() { + return "foobar"; + } + } + class bar { + get "\x00\x01"() { + return "bar" + } + set "\x00\x01"(foo) { + save(foo); + } + *"\x00\x01"() { + return "foobar"; + } + } + } + expect_exact: 'var foo={"\\0\x01":"foo",get"\\0\x01"(){return"bar"},set"\\0\x01"(foo){save(foo)},*"\\0\x01"(){return"foobar"}};class bar{get"\\0\x01"(){return"bar"}set"\\0\x01"(foo){save(foo)}*"\\0\x01"(){return"foobar"}}' +} + +property_with_unprintable_ascii_only: { + beautify = { + ascii_only: true, + } + input: { + var foo = { + "\x00\x01": "foo", + get "\x00\x01"() { + return "bar"; + }, + set "\x00\x01"(foo) { + save(foo); + }, + *"\x00\x01"() { + return "foobar"; + } + } + class bar { + get "\x00\x01"() { + return "bar" + } + set "\x00\x01"(foo) { + save(foo); + } + *"\x00\x01"() { + return "foobar"; + } + } + } + expect_exact: 'var foo={"\\0\\x01":"foo",get"\\0\\x01"(){return"bar"},set"\\0\\x01"(foo){save(foo)},*"\\0\\x01"(){return"foobar"}};class bar{get"\\0\\x01"(){return"bar"}set"\\0\\x01"(foo){save(foo)}*"\\0\\x01"(){return"foobar"}}' +} diff --git a/test/mocha/cli.js b/test/mocha/cli.js index 38b57cd7..006566d0 100644 --- a/test/mocha/cli.js +++ b/test/mocha/cli.js @@ -3,7 +3,7 @@ var exec = require("child_process").exec; describe("bin/uglifyjs", function () { it("should produce a functional build when using --self", function (done) { - this.timeout(5000); + this.timeout(15000); var uglifyjs = '"' + process.argv[0] + '" bin/uglifyjs'; var command = uglifyjs + ' --self -cm --wrap WrappedUglifyJS';