diff --git a/lib/ast.js b/lib/ast.js index 07126e7c..d9afcff4 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -921,6 +921,16 @@ var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", "quote", { } }, AST_ObjectProperty); +var AST_ObjectComputedKeyVal = DEFNODE("ObjectComputedKeyVal", null, { + $documentation: "An object property whose key is computed. Like `[Symbol.iterator]: function...` or `[routes.homepage]: renderHomepage`", + _walk: function(visitor) { + return visitor._visit(this, function(){ + this.key._walk(visitor); + this.value._walk(visitor); + }); + } +}, AST_ObjectProperty); + var AST_ObjectSymbol = DEFNODE("ObjectSymbol", "symbol", { $propdoc: { symbol: "[AST_SymbolRef] what symbol it is" diff --git a/lib/compress.js b/lib/compress.js index 7dd43e69..c990712e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -952,6 +952,9 @@ merge(Compressor.prototype, { return false; }); def(AST_ObjectProperty, function(compressor){ + if (this instanceof AST_ObjectComputedKeyVal && + this.key.has_side_effects(compressor)) + return true; return this.value.has_side_effects(compressor); }); def(AST_Array, function(compressor){ diff --git a/lib/output.js b/lib/output.js index 03cda230..5aeed667 100644 --- a/lib/output.js +++ b/lib/output.js @@ -1203,6 +1203,13 @@ function OutputStream(options) { self.key.print(output); self.value._do_print(output, true); }); + DEFPRINT(AST_ObjectComputedKeyVal, function(self, output) { + output.print("["); + self.key.print(output); + output.print("]:"); + output.space(); + self.value.print(output); + }); DEFPRINT(AST_Symbol, function(self, output){ var def = self.definition(); output.print_name(def ? def.mangled_name || def.name : self.name); diff --git a/lib/parse.js b/lib/parse.js index 5ae2a1db..c0065217 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1465,6 +1465,15 @@ function parse($TEXT, options) { continue; } } + + if (type == "punc" && start.value == "[") { + expect(":"); + a.push(new AST_ObjectComputedKeyVal({ + key: name, + value: expression(false) + })); + continue; + } if (!is("punc", ":")) { // It's one of those object destructurings, the value is its own name @@ -1495,6 +1504,12 @@ function parse($TEXT, options) { var tmp = S.token; next(); switch (tmp.type) { + case "punc": + if (tmp.value === "[") { + var ex = expression(false); + expect("]"); + return ex; + } else unexpected(); case "num": case "string": case "name": diff --git a/test/compress/harmony.js b/test/compress/harmony.js index ab0c73be..b763318e 100644 --- a/test/compress/harmony.js +++ b/test/compress/harmony.js @@ -36,6 +36,13 @@ regression_arrow_functions_and_hoist: { expect_exact: "a=>b;" } +computed_property_names: { + input: { + obj({ ["x" + "x"]: 6 }); + } + expect_exact: "obj({[\"x\"+\"x\"]:6});" +} + typeof_arrow_functions: { options = { evaluate: true