From: Alex Lam S.L Date: Thu, 18 Jan 2018 16:36:30 +0000 (+0800) Subject: compress `undefined` property names (#2811) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=082e004b872ecb158e5a28702898688742b5da86;p=UglifyJS.git compress `undefined` property names (#2811) - enforce property names as string - handle `void 0` as `undefined` in `hoist_props` & `reduce_vars` --- diff --git a/lib/ast.js b/lib/ast.js index 19f6bfb5..9b88b088 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -689,8 +689,8 @@ var AST_Object = DEFNODE("Object", "properties", { var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", { $documentation: "Base class for literal object properties", $propdoc: { - key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an AST_SymbolAccessor.", - value: "[AST_Node] property value. For setters and getters this is an AST_Accessor." + key: "[string|AST_SymbolAccessor] property name. For ObjectKeyVal this is a string. For getters and setters this is an AST_SymbolAccessor.", + value: "[AST_Node] property value. For getters and setters this is an AST_Accessor." }, _walk: function(visitor) { return visitor._visit(this, function(){ diff --git a/lib/compress.js b/lib/compress.js index 89056796..bda5d7a6 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -404,14 +404,15 @@ merge(Compressor.prototype, { } function read_property(obj, key) { - if (key instanceof AST_Constant) key = key.getValue(); - if (key instanceof AST_Node) return null; + key = get_value(key); + if (key instanceof AST_Node) return; var value; if (obj instanceof AST_Array) { var elements = obj.elements; if (key == "length") return make_node_from_constant(elements.length, obj); if (typeof key == "number" && key in elements) value = elements[key]; } else if (obj instanceof AST_Object) { + key = "" + key; var props = obj.properties; for (var i = props.length; --i >= 0;) { var prop = props[i]; @@ -1855,6 +1856,18 @@ merge(Compressor.prototype, { })); }; + function get_value(key) { + if (key instanceof AST_Constant) { + return key.getValue(); + } + if (key instanceof AST_UnaryPrefix + && key.operator == "void" + && key.expression instanceof AST_Constant) { + return; + } + return key; + } + function is_undefined(node, compressor) { return node.is_undefined || node instanceof AST_Undefined @@ -3295,9 +3308,7 @@ merge(Compressor.prototype, { if (node instanceof AST_PropAccess && node.expression instanceof AST_SymbolRef) { var defs = defs_by_id[node.expression.definition().id]; if (defs) { - var key = node.property; - if (key instanceof AST_Node) key = key.getValue(); - var def = defs.get(key); + var def = defs.get(get_value(node.property)); var sym = make_node(AST_SymbolRef, node, { name: def.name, scope: node.expression.scope, diff --git a/lib/output.js b/lib/output.js index 805f0339..bd1a70c2 100644 --- a/lib/output.js +++ b/lib/output.js @@ -1349,11 +1349,8 @@ function OutputStream(options) { function print_property_name(key, quote, output) { if (output.option("quote_keys")) { - output.print_string(key + ""); - } else if ((typeof key == "number" - || !output.option("beautify") - && +key + "" == key) - && parseFloat(key) >= 0) { + output.print_string(key); + } else if ("" + +key == key && key >= 0) { output.print(make_num(key)); } else if (RESERVED_WORDS(key) ? !output.option("ie8") : is_identifier_string(key)) { if (quote && output.option("keep_quoted_props")) { diff --git a/lib/parse.js b/lib/parse.js index eba833dc..af631149 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -1365,7 +1365,7 @@ function parse($TEXT, options) { if (type == "name" && !is("punc", ":")) { var key = new AST_SymbolAccessor({ start: S.token, - name: as_property_name(), + name: "" + as_property_name(), end: prev() }); if (name == "get") { @@ -1391,7 +1391,7 @@ function parse($TEXT, options) { a.push(new AST_ObjectKeyVal({ start : start, quote : start.quote, - key : name, + key : "" + name, value : expression(false), end : prev() })); diff --git a/test/compress/hoist_props.js b/test/compress/hoist_props.js index 012a3fca..03867f78 100644 --- a/test/compress/hoist_props.js +++ b/test/compress/hoist_props.js @@ -664,3 +664,25 @@ issue_2519: { } expect_stdout: "5.5" } + +undefined_key: { + options = { + evaluate: true, + hoist_props: true, + join_vars: true, + passes: 4, + reduce_vars: true, + toplevel: true, + unused: true, + } + input: { + var a, o = {}; + o[a] = 1; + o.b = 2; + console.log(o[a] + o.b); + } + expect: { + console.log(3); + } + expect_stdout: "3" +} diff --git a/test/compress/issue-1770.js b/test/compress/issue-1770.js index f63f8453..7a529b2c 100644 --- a/test/compress/issue-1770.js +++ b/test/compress/issue-1770.js @@ -84,12 +84,12 @@ numeric_literal: { ' 0: 0,', ' "-0": 1,', ' 42: 2,', - ' "42": 3,', + ' 42: 3,', ' 37: 4,', ' o: 5,', ' 1e42: 6,', ' b: 7,', - ' "1e+42": 8', + ' 1e42: 8', '};', '', 'console.log(obj[-0], obj[-""], obj["-0"]);',