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(){
}
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];
}));
};
+ 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
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,
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")) {
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") {
a.push(new AST_ObjectKeyVal({
start : start,
quote : start.quote,
- key : name,
+ key : "" + name,
value : expression(false),
end : prev()
}));
}
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"
+}
' 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"]);',