From 8e0b09179555213ed7679fd88a590efa9a0e96d6 Mon Sep 17 00:00:00 2001 From: Klaus Meinhardt Date: Sat, 25 Jan 2020 00:50:29 +0100 Subject: [PATCH] es2018: visit other binding elements when transforming object destructuring with rest (#35872) * es2018: visit other binding elements when transforming object destructuring with rest fixes: #35771 * more tests --- src/compiler/transformers/destructuring.ts | 2 +- tests/baselines/reference/objectRestSpread.js | 54 +++++++++++++++++++ tests/cases/compiler/objectRestSpread.ts | 25 +++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/objectRestSpread.js create mode 100644 tests/cases/compiler/objectRestSpread.ts diff --git a/src/compiler/transformers/destructuring.ts b/src/compiler/transformers/destructuring.ts index 23f19ef9da81f..5567dba270860 100644 --- a/src/compiler/transformers/destructuring.ts +++ b/src/compiler/transformers/destructuring.ts @@ -325,7 +325,7 @@ namespace ts { && !(element.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread)) && !(getTargetOfBindingOrAssignmentElement(element)!.transformFlags & (TransformFlags.ContainsRestOrSpread | TransformFlags.ContainsObjectRestOrSpread)) && !isComputedPropertyName(propertyName)) { - bindingElements = append(bindingElements, element); + bindingElements = append(bindingElements, visitNode(element, flattenContext.visitor)); } else { if (bindingElements) { diff --git a/tests/baselines/reference/objectRestSpread.js b/tests/baselines/reference/objectRestSpread.js new file mode 100644 index 0000000000000..0bc455c43863b --- /dev/null +++ b/tests/baselines/reference/objectRestSpread.js @@ -0,0 +1,54 @@ +//// [objectRestSpread.ts] +let obj = {}; + +({...obj}); +let { + prop = { ...obj }, + more = { ...obj } = { ...obj }, + ['' + 'other']: other = { ...obj }, + yetAnother: {nested: { ['nested' + 'prop']: nestedProp = { ...obj }, ...nestedRest } = { ...obj }} = { ...obj }, + fn = async function*() {}, + ...props +} = {} as any; + +({ + prop = { ...obj }, + ['' + 'other']: other = { ...obj }, + ...props +} = {} as any) + +function test({ + prop = { ...obj }, + ...props +}) {} + +//// [objectRestSpread.js] +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +}; +var __await = (this && this.__await) || function (v) { return this instanceof __await ? (this.v = v, this) : new __await(v); } +var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } +}; +var _a, _b, _c, _d; +let obj = {}; +(Object.assign({}, obj)); +let _e = {}, { prop = Object.assign({}, obj), more = _a = Object.assign({}, obj), obj = __rest(_a, []), _a } = _e, _f = '' + 'other', _g = _e[_f], other = _g === void 0 ? Object.assign({}, obj) : _g, _h = _e.yetAnother, _j = (_h === void 0 ? Object.assign({}, obj) : _h).nested, _k = _j === void 0 ? Object.assign({}, obj) : _j, _l = 'nested' + 'prop', _m = _k[_l], nestedProp = _m === void 0 ? Object.assign({}, obj) : _m, nestedRest = __rest(_k, [typeof _l === "symbol" ? _l : _l + ""]), { fn = function () { return __asyncGenerator(this, arguments, function* () { }); } } = _e, props = __rest(_e, ["prop", "more", typeof _f === "symbol" ? _f : _f + "", "yetAnother", "fn"]); +(_b = {}, { prop = Object.assign({}, obj) } = _b, _c = '' + 'other', _d = _b[_c], other = _d === void 0 ? Object.assign({}, obj) : _d, props = __rest(_b, ["prop", typeof _c === "symbol" ? _c : _c + ""])); +function test(_a) { var { prop = Object.assign({}, obj) } = _a, props = __rest(_a, ["prop"]); } diff --git a/tests/cases/compiler/objectRestSpread.ts b/tests/cases/compiler/objectRestSpread.ts new file mode 100644 index 0000000000000..25c1512618273 --- /dev/null +++ b/tests/cases/compiler/objectRestSpread.ts @@ -0,0 +1,25 @@ +// @target: es2017 +// @lib: es2018 +// @noTypesAndSymbols: true +let obj = {}; + +({...obj}); +let { + prop = { ...obj }, + more = { ...obj } = { ...obj }, + ['' + 'other']: other = { ...obj }, + yetAnother: {nested: { ['nested' + 'prop']: nestedProp = { ...obj }, ...nestedRest } = { ...obj }} = { ...obj }, + fn = async function*() {}, + ...props +} = {} as any; + +({ + prop = { ...obj }, + ['' + 'other']: other = { ...obj }, + ...props +} = {} as any) + +function test({ + prop = { ...obj }, + ...props +}) {} \ No newline at end of file