support destructured literals (#4278)
This commit is contained in:
@@ -69,6 +69,7 @@ function OutputStream(options) {
|
||||
semicolons : true,
|
||||
shebang : true,
|
||||
source_map : null,
|
||||
v8 : false,
|
||||
webkit : false,
|
||||
width : 80,
|
||||
wrap_iife : false,
|
||||
@@ -499,11 +500,11 @@ function OutputStream(options) {
|
||||
}
|
||||
}
|
||||
if (/comment[134]/.test(c.type)) {
|
||||
print("//" + c.value.replace(/[@#]__PURE__/g, ' ') + "\n");
|
||||
print("//" + c.value.replace(/[@#]__PURE__/g, " ") + "\n");
|
||||
indent();
|
||||
last_nlb = true;
|
||||
} else if (c.type == "comment2") {
|
||||
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
||||
print("/*" + c.value.replace(/[@#]__PURE__/g, " ") + "*/");
|
||||
last_nlb = false;
|
||||
}
|
||||
});
|
||||
@@ -557,10 +558,10 @@ function OutputStream(options) {
|
||||
space();
|
||||
}
|
||||
if (/comment[134]/.test(c.type)) {
|
||||
print("//" + c.value.replace(/[@#]__PURE__/g, ' '));
|
||||
print("//" + c.value.replace(/[@#]__PURE__/g, " "));
|
||||
need_newline_indented = true;
|
||||
} else if (c.type == "comment2") {
|
||||
print("/*" + c.value.replace(/[@#]__PURE__/g, ' ') + "*/");
|
||||
print("/*" + c.value.replace(/[@#]__PURE__/g, " ") + "*/");
|
||||
need_space = true;
|
||||
}
|
||||
});
|
||||
@@ -610,7 +611,7 @@ function OutputStream(options) {
|
||||
},
|
||||
parent : function(n) {
|
||||
return stack[stack.length - 2 - (n || 0)];
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -652,13 +653,7 @@ function OutputStream(options) {
|
||||
/* -----[ PARENTHESES ]----- */
|
||||
|
||||
function PARENS(nodetype, func) {
|
||||
if (Array.isArray(nodetype)) {
|
||||
nodetype.forEach(function(nodetype) {
|
||||
PARENS(nodetype, func);
|
||||
});
|
||||
} else {
|
||||
nodetype.DEFMETHOD("needs_parens", func);
|
||||
}
|
||||
nodetype.DEFMETHOD("needs_parens", func);
|
||||
}
|
||||
|
||||
PARENS(AST_Node, return_false);
|
||||
@@ -667,11 +662,11 @@ function OutputStream(options) {
|
||||
// the first token to appear in a statement.
|
||||
PARENS(AST_Function, function(output) {
|
||||
if (!output.has_parens() && first_in_statement(output)) return true;
|
||||
if (output.option('webkit')) {
|
||||
if (output.option("webkit")) {
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_PropAccess && p.expression === this) return true;
|
||||
}
|
||||
if (output.option('wrap_iife')) {
|
||||
if (output.option("wrap_iife")) {
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_Call && p.expression === this) return true;
|
||||
}
|
||||
@@ -679,9 +674,10 @@ function OutputStream(options) {
|
||||
|
||||
// same goes for an object literal, because otherwise it would be
|
||||
// interpreted as a block of code.
|
||||
PARENS(AST_Object, function(output) {
|
||||
function needs_parens_obj(output) {
|
||||
return !output.has_parens() && first_in_statement(output);
|
||||
});
|
||||
}
|
||||
PARENS(AST_Object, needs_parens_obj);
|
||||
|
||||
PARENS(AST_Unary, function(output) {
|
||||
var p = output.parent();
|
||||
@@ -701,6 +697,7 @@ function OutputStream(options) {
|
||||
|| p instanceof AST_Conditional
|
||||
// { [(1, 2)]: 3 }[2] ==> 3
|
||||
// { foo: (1, 2) }.foo ==> 2
|
||||
|| p instanceof AST_DestructuredKeyVal
|
||||
|| p instanceof AST_ObjectProperty
|
||||
// (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|
||||
|| p instanceof AST_PropAccess && p.expression === this
|
||||
@@ -747,7 +744,7 @@ function OutputStream(options) {
|
||||
var p = output.parent();
|
||||
if (p instanceof AST_New) return p.expression === this;
|
||||
// https://bugs.webkit.org/show_bug.cgi?id=123506
|
||||
if (output.option('webkit')) {
|
||||
if (output.option("webkit")) {
|
||||
var g = output.parent(1);
|
||||
return this.expression instanceof AST_Function
|
||||
&& p instanceof AST_PropAccess
|
||||
@@ -776,18 +773,29 @@ function OutputStream(options) {
|
||||
}
|
||||
});
|
||||
|
||||
PARENS([ AST_Assign, AST_Conditional ], function(output) {
|
||||
function needs_parens_assign_cond(self, output) {
|
||||
var p = output.parent();
|
||||
// 1 + (a = 2) + 3 → 6, side effect setting a = 2
|
||||
if (p instanceof AST_Binary) return !(p instanceof AST_Assign);
|
||||
// (a = func)() —or— new (a = Object)()
|
||||
if (p instanceof AST_Call) return p.expression === this;
|
||||
if (p instanceof AST_Call) return p.expression === self;
|
||||
// (a = foo) ? bar : baz
|
||||
if (p instanceof AST_Conditional) return p.condition === this;
|
||||
if (p instanceof AST_Conditional) return p.condition === self;
|
||||
// (a = foo)["prop"] —or— (a = foo).prop
|
||||
if (p instanceof AST_PropAccess) return p.expression === this;
|
||||
if (p instanceof AST_PropAccess) return p.expression === self;
|
||||
// !(a = false) → true
|
||||
if (p instanceof AST_Unary) return true;
|
||||
}
|
||||
PARENS(AST_Assign, function(output) {
|
||||
if (needs_parens_assign_cond(this, output)) return true;
|
||||
// v8 parser bug => workaround
|
||||
// f([1], [a] = []) => f([1], ([a] = []))
|
||||
if (output.option("v8")) return this.left instanceof AST_Destructured;
|
||||
// ({ p: a } = o);
|
||||
if (this.left instanceof AST_DestructuredObject) return needs_parens_obj(output);
|
||||
});
|
||||
PARENS(AST_Conditional, function(output) {
|
||||
return needs_parens_assign_cond(this, output);
|
||||
});
|
||||
|
||||
/* -----[ PRINTERS ]----- */
|
||||
@@ -1274,6 +1282,38 @@ function OutputStream(options) {
|
||||
output.space();
|
||||
} : noop);
|
||||
});
|
||||
DEFPRINT(AST_DestructuredArray, function(output) {
|
||||
var a = this.elements, len = a.length;
|
||||
output.with_square(len > 0 ? function() {
|
||||
output.space();
|
||||
a.forEach(function(exp, i) {
|
||||
if (i) output.comma();
|
||||
exp.print(output);
|
||||
// If the final element is a hole, we need to make sure it
|
||||
// doesn't look like a trailing comma, by inserting an actual
|
||||
// trailing comma.
|
||||
if (i === len - 1 && exp instanceof AST_Hole)
|
||||
output.comma();
|
||||
});
|
||||
output.space();
|
||||
} : noop);
|
||||
});
|
||||
DEFPRINT(AST_DestructuredKeyVal, print_key_value);
|
||||
DEFPRINT(AST_DestructuredObject, function(output) {
|
||||
var props = this.properties;
|
||||
if (props.length > 0) output.with_block(function() {
|
||||
props.forEach(function(prop, i) {
|
||||
if (i) {
|
||||
output.print(",");
|
||||
output.newline();
|
||||
}
|
||||
output.indent();
|
||||
prop.print(output);
|
||||
});
|
||||
output.newline();
|
||||
});
|
||||
else print_braced_empty(this, output);
|
||||
});
|
||||
DEFPRINT(AST_Object, function(output) {
|
||||
var props = this.properties;
|
||||
if (props.length > 0) output.with_block(function() {
|
||||
@@ -1314,12 +1354,13 @@ function OutputStream(options) {
|
||||
}
|
||||
}
|
||||
|
||||
DEFPRINT(AST_ObjectKeyVal, function(output) {
|
||||
function print_key_value(output) {
|
||||
var self = this;
|
||||
print_property_key(self, output);
|
||||
output.colon();
|
||||
self.value.print(output);
|
||||
});
|
||||
}
|
||||
DEFPRINT(AST_ObjectKeyVal, print_key_value);
|
||||
function print_accessor(type) {
|
||||
return function(output) {
|
||||
var self = this;
|
||||
@@ -1483,6 +1524,7 @@ function OutputStream(options) {
|
||||
AST_Constant,
|
||||
AST_Debugger,
|
||||
AST_Definitions,
|
||||
AST_Destructured,
|
||||
AST_Finally,
|
||||
AST_Jump,
|
||||
AST_Lambda,
|
||||
@@ -1497,7 +1539,7 @@ function OutputStream(options) {
|
||||
output.add_mapping(this.start);
|
||||
});
|
||||
|
||||
DEFMAP([ AST_ObjectProperty ], function(output) {
|
||||
DEFMAP([ AST_DestructuredKeyVal, AST_ObjectProperty ], function(output) {
|
||||
if (typeof this.key == "string") output.add_mapping(this.start, this.key);
|
||||
});
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user