From 8166eb0a3834546f2f1934a87a84d92d0f13a18b Mon Sep 17 00:00:00 2001 From: Lukas Taegert-Atkinson Date: Wed, 20 Mar 2019 07:40:07 +0100 Subject: [PATCH] Handle member expressions in array patterns (#2760) * Debug array patterns * Handle member expressions in patterns (resolves #2750) --- src/ast/nodes/ExportDefaultDeclaration.ts | 1 + src/ast/nodes/MemberExpression.ts | 5 +++- .../pattern-member-expressions/_config.js | 3 ++ .../_expected/amd.js | 23 +++++++++++++++ .../_expected/cjs.js | 21 ++++++++++++++ .../_expected/es.js | 19 +++++++++++++ .../_expected/iife.js | 24 ++++++++++++++++ .../_expected/system.js | 28 +++++++++++++++++++ .../_expected/umd.js | 26 +++++++++++++++++ .../pattern-member-expressions/main.js | 19 +++++++++++++ 10 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 test/form/samples/pattern-member-expressions/_config.js create mode 100644 test/form/samples/pattern-member-expressions/_expected/amd.js create mode 100644 test/form/samples/pattern-member-expressions/_expected/cjs.js create mode 100644 test/form/samples/pattern-member-expressions/_expected/es.js create mode 100644 test/form/samples/pattern-member-expressions/_expected/iife.js create mode 100644 test/form/samples/pattern-member-expressions/_expected/system.js create mode 100644 test/form/samples/pattern-member-expressions/_expected/umd.js create mode 100644 test/form/samples/pattern-member-expressions/main.js diff --git a/src/ast/nodes/ExportDefaultDeclaration.ts b/src/ast/nodes/ExportDefaultDeclaration.ts index 2840fd3e582..55c20418a84 100644 --- a/src/ast/nodes/ExportDefaultDeclaration.ts +++ b/src/ast/nodes/ExportDefaultDeclaration.ts @@ -44,6 +44,7 @@ export default class ExportDefaultDeclaration extends NodeBase { scope: ModuleScope; type: NodeType.tExportDefaultDeclaration; variable: ExportDefaultVariable; + private declarationName: string; include(includeAllChildrenRecursively: boolean) { diff --git a/src/ast/nodes/MemberExpression.ts b/src/ast/nodes/MemberExpression.ts index fbca8714740..9c2472aba30 100644 --- a/src/ast/nodes/MemberExpression.ts +++ b/src/ast/nodes/MemberExpression.ts @@ -24,6 +24,7 @@ import Identifier from './Identifier'; import Literal from './Literal'; import * as NodeType from './NodeType'; import { ExpressionNode, Node, NodeBase } from './shared/Node'; +import { PatternNode } from './shared/Pattern'; function getResolvablePropertyKey(memberExpression: MemberExpression): string | null { return memberExpression.computed @@ -72,7 +73,7 @@ export function isMemberExpression(node: Node): node is MemberExpression { return node.type === NodeType.MemberExpression; } -export default class MemberExpression extends NodeBase implements DeoptimizableEntity { +export default class MemberExpression extends NodeBase implements DeoptimizableEntity, PatternNode { computed: boolean; object: ExpressionNode; property: ExpressionNode; @@ -84,6 +85,8 @@ export default class MemberExpression extends NodeBase implements DeoptimizableE private expressionsToBeDeoptimized: DeoptimizableEntity[]; private replacement: string | null; + addExportedVariables(): void {} + bind() { if (this.bound) return; this.bound = true; diff --git a/test/form/samples/pattern-member-expressions/_config.js b/test/form/samples/pattern-member-expressions/_config.js new file mode 100644 index 00000000000..aa93889f9e6 --- /dev/null +++ b/test/form/samples/pattern-member-expressions/_config.js @@ -0,0 +1,3 @@ +module.exports = { + description: 'handles member expressions in patterns (#2750)' +}; diff --git a/test/form/samples/pattern-member-expressions/_expected/amd.js b/test/form/samples/pattern-member-expressions/_expected/amd.js new file mode 100644 index 00000000000..79926d37cc2 --- /dev/null +++ b/test/form/samples/pattern-member-expressions/_expected/amd.js @@ -0,0 +1,23 @@ +define(function () { 'use strict'; + + const array = [false]; + const obj1 = {value: false}; + const obj2 = {value: false}; + + ([array[0]] = [true]); + ({a: obj1.value} = {a: true}); + ({[globalVar1]: obj2[globalVar2]} = {[globalVar3]: true}); + + if (array[0]) { + console.log('retained'); + } + + if (obj1.value) { + console.log('retained'); + } + + if (obj2.value) { + console.log('retained'); + } + +}); diff --git a/test/form/samples/pattern-member-expressions/_expected/cjs.js b/test/form/samples/pattern-member-expressions/_expected/cjs.js new file mode 100644 index 00000000000..cc195f4e43d --- /dev/null +++ b/test/form/samples/pattern-member-expressions/_expected/cjs.js @@ -0,0 +1,21 @@ +'use strict'; + +const array = [false]; +const obj1 = {value: false}; +const obj2 = {value: false}; + +([array[0]] = [true]); +({a: obj1.value} = {a: true}); +({[globalVar1]: obj2[globalVar2]} = {[globalVar3]: true}); + +if (array[0]) { + console.log('retained'); +} + +if (obj1.value) { + console.log('retained'); +} + +if (obj2.value) { + console.log('retained'); +} diff --git a/test/form/samples/pattern-member-expressions/_expected/es.js b/test/form/samples/pattern-member-expressions/_expected/es.js new file mode 100644 index 00000000000..b39488c0d71 --- /dev/null +++ b/test/form/samples/pattern-member-expressions/_expected/es.js @@ -0,0 +1,19 @@ +const array = [false]; +const obj1 = {value: false}; +const obj2 = {value: false}; + +([array[0]] = [true]); +({a: obj1.value} = {a: true}); +({[globalVar1]: obj2[globalVar2]} = {[globalVar3]: true}); + +if (array[0]) { + console.log('retained'); +} + +if (obj1.value) { + console.log('retained'); +} + +if (obj2.value) { + console.log('retained'); +} diff --git a/test/form/samples/pattern-member-expressions/_expected/iife.js b/test/form/samples/pattern-member-expressions/_expected/iife.js new file mode 100644 index 00000000000..6e33e092356 --- /dev/null +++ b/test/form/samples/pattern-member-expressions/_expected/iife.js @@ -0,0 +1,24 @@ +(function () { + 'use strict'; + + const array = [false]; + const obj1 = {value: false}; + const obj2 = {value: false}; + + ([array[0]] = [true]); + ({a: obj1.value} = {a: true}); + ({[globalVar1]: obj2[globalVar2]} = {[globalVar3]: true}); + + if (array[0]) { + console.log('retained'); + } + + if (obj1.value) { + console.log('retained'); + } + + if (obj2.value) { + console.log('retained'); + } + +}()); diff --git a/test/form/samples/pattern-member-expressions/_expected/system.js b/test/form/samples/pattern-member-expressions/_expected/system.js new file mode 100644 index 00000000000..397eec1dab8 --- /dev/null +++ b/test/form/samples/pattern-member-expressions/_expected/system.js @@ -0,0 +1,28 @@ +System.register([], function (exports, module) { + 'use strict'; + return { + execute: function () { + + const array = [false]; + const obj1 = {value: false}; + const obj2 = {value: false}; + + ([array[0]] = [true]); + ({a: obj1.value} = {a: true}); + ({[globalVar1]: obj2[globalVar2]} = {[globalVar3]: true}); + + if (array[0]) { + console.log('retained'); + } + + if (obj1.value) { + console.log('retained'); + } + + if (obj2.value) { + console.log('retained'); + } + + } + }; +}); diff --git a/test/form/samples/pattern-member-expressions/_expected/umd.js b/test/form/samples/pattern-member-expressions/_expected/umd.js new file mode 100644 index 00000000000..a56a2604097 --- /dev/null +++ b/test/form/samples/pattern-member-expressions/_expected/umd.js @@ -0,0 +1,26 @@ +(function (factory) { + typeof define === 'function' && define.amd ? define(factory) : + factory(); +}(function () { 'use strict'; + + const array = [false]; + const obj1 = {value: false}; + const obj2 = {value: false}; + + ([array[0]] = [true]); + ({a: obj1.value} = {a: true}); + ({[globalVar1]: obj2[globalVar2]} = {[globalVar3]: true}); + + if (array[0]) { + console.log('retained'); + } + + if (obj1.value) { + console.log('retained'); + } + + if (obj2.value) { + console.log('retained'); + } + +})); diff --git a/test/form/samples/pattern-member-expressions/main.js b/test/form/samples/pattern-member-expressions/main.js new file mode 100644 index 00000000000..b39488c0d71 --- /dev/null +++ b/test/form/samples/pattern-member-expressions/main.js @@ -0,0 +1,19 @@ +const array = [false]; +const obj1 = {value: false}; +const obj2 = {value: false}; + +([array[0]] = [true]); +({a: obj1.value} = {a: true}); +({[globalVar1]: obj2[globalVar2]} = {[globalVar3]: true}); + +if (array[0]) { + console.log('retained'); +} + +if (obj1.value) { + console.log('retained'); +} + +if (obj2.value) { + console.log('retained'); +}