Destructuring consistency fixes (#1417)

- Use AST_Destructuring for lhf assignment patterns
- Use AST_DefaultAssign for default assignments
- Add more checks for lhs expressions
- Add lots of testing
- Cleanup ast (e.g. remove default property)
- Fix #1402 based on a patch from @kzc
- Refine spread allowance in array destructring pattern
- Add destructuring AST tree checker
This commit is contained in:
Anthony Van de Gejuchte
2017-02-24 01:49:19 +01:00
committed by Alex Lam S.L
parent 85c1cba760
commit 07734b000a
16 changed files with 1253 additions and 141 deletions

View File

@@ -641,13 +641,10 @@ function OutputStream(options) {
|| p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|| (p instanceof AST_SymbolConst && p.default === this) // const { xCover = (0, function() {}) }
|| (p instanceof AST_SymbolLet && p.default === this) // let { xCover = (0, function() {}) }
|| (p instanceof AST_SymbolVar && p.default === this) // var { xCover = (0, function() {}) }
|| (p instanceof AST_SymbolCatch && p.default === this) // } catch (xCover = (0, function() {}) ) {
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
* ==> 20 (side effect, set a := 10 and b := 20) */
|| p instanceof AST_Arrow // x => (x, x)
|| p instanceof AST_DefaultAssign // x => (x = (0, function(){}))
;
});
@@ -761,6 +758,9 @@ function OutputStream(options) {
// (a = foo)["prop"] —or— (a = foo).prop
if (p instanceof AST_PropAccess && p.expression === this)
return true;
// ({a, b} = {a: 1, b: 2}), a destructuring assignment
if (this instanceof AST_Assign && this.left instanceof AST_Destructuring && this.left.is_array === false)
return true;
});
/* -----[ PRINTERS ]----- */
@@ -789,12 +789,6 @@ function OutputStream(options) {
output.comma();
})
output.print(self.is_array ? "]" : "}");
if (self.default) {
output.space();
output.print('=');
output.space();
self.default.print(output)
}
});
DEFPRINT(AST_Debugger, function(self, output){
@@ -1003,7 +997,7 @@ function OutputStream(options) {
parent instanceof AST_Unary ||
(parent instanceof AST_Call && self === parent.expression);
if (needs_parens) { output.print("(") }
if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol && !self.argnames[0].default) {
if (self.argnames.length === 1 && self.argnames[0] instanceof AST_Symbol) {
self.argnames[0].print(output);
} else {
output.with_parens(function(){
@@ -1497,15 +1491,27 @@ function OutputStream(options) {
});
DEFPRINT(AST_ObjectKeyVal, function(self, output){
function get_name(self) {
var def = self.value.definition();
return def ? def.mangled_name || def.name : self.value.name;
var def = self.definition();
return def ? def.mangled_name || def.name : self.name;
}
if (output.option("shorthand") &&
var allowShortHand = output.option("shorthand");
if (allowShortHand &&
self.value instanceof AST_Symbol &&
is_identifier_string(self.key) &&
get_name(self) === self.key
get_name(self.value) === self.key
) {
self.print_property_name(self.key, self.quote, output);
} else if (allowShortHand &&
self.value instanceof AST_DefaultAssign &&
self.value.left instanceof AST_Symbol &&
is_identifier_string(self.key) &&
get_name(self.value.left) === self.key
) {
self.print_property_name(self.key, self.quote, output);
output.print("=");
self.value.right.print(output);
} else {
if (!(self.key instanceof AST_Node)) {
self.print_property_name(self.key, self.quote, output);
@@ -1517,12 +1523,6 @@ function OutputStream(options) {
output.colon();
self.value.print(output);
}
if (self.default) {
output.space();
output.print('=');
output.space();
self.default.print(output);
}
});
AST_ObjectProperty.DEFMETHOD("_print_getter_setter", function(type, self, output) {
if (self.static) {
@@ -1573,12 +1573,6 @@ function OutputStream(options) {
});
DEFPRINT(AST_SymbolDeclaration, function(self, output){
self._do_print(output);
if (self.default) {
output.space();
output.print('=');
output.space();
self.default.print(output)
}
});
DEFPRINT(AST_Undefined, function(self, output){
output.print("void 0");