diff --git a/src/babel/transformation/file.js b/src/babel/transformation/file.js index b22d7eee4b..c508fe147c 100644 --- a/src/babel/transformation/file.js +++ b/src/babel/transformation/file.js @@ -118,7 +118,7 @@ export default class File { for (var key in opts) { if (key[0] !== "_" && File.validOptions.indexOf(key) < 0) { - throw new ReferenceError("Unknown option: " + key); + throw new ReferenceError(`Unknown option: ${key}`); } } @@ -248,7 +248,7 @@ export default class File { debug(msg) { var parts = this.opts.filename; - if (msg) parts += ": " + msg; + if (msg) parts += `: ${msg}`; util.debug(parts); } @@ -261,7 +261,7 @@ export default class File { } if (!ModuleFormatter) { - throw new ReferenceError("Unknown module formatter type " + JSON.stringify(type)); + throw new ReferenceError(`Unknown module formatter type ${JSON.stringify(type)}`); } return new ModuleFormatter(this); @@ -338,7 +338,7 @@ export default class File { addHelper(name) { if (!includes(File.helpers, name)) { - throw new ReferenceError("Unknown helper " + name); + throw new ReferenceError(`Unknown helper ${name}`); } var program = this.ast.program; @@ -371,7 +371,7 @@ export default class File { errorWithNode(node, msg, Error = SyntaxError) { var loc = node.loc.start; - var err = new Error("Line " + loc.line + ": " + msg); + var err = new Error(`Line ${loc.line}: ${msg}`); err.loc = loc; return err; } @@ -430,6 +430,13 @@ export default class File { } checkNode(node, scope) { + if (Array.isArray(node)) { + for (var i = 0; i < node.length; i++) { + this.checkNode(node[i], scope); + } + return; + } + var stack = this.transformerStack; scope ||= this.scope; @@ -463,7 +470,7 @@ export default class File { if (this.shebang) { // add back shebang - result.code = this.shebang + "\n" + result.code; + result.code = `${this.shebang}\n${result.code}`; } if (opts.sourceMap === "inline") { diff --git a/src/babel/transformation/transformers/es6/destructuring.js b/src/babel/transformation/transformers/es6/destructuring.js index 284df2b7aa..2648647e98 100644 --- a/src/babel/transformation/transformers/es6/destructuring.js +++ b/src/babel/transformation/transformers/es6/destructuring.js @@ -56,12 +56,12 @@ export { ForOfStatement as ForInStatement }; exports.Function = function (node, parent, scope, file) { var nodes = []; - var hasDestructuringTransformer = false; + var hasDestructuring = false; node.params = node.params.map(function (pattern, i) { if (!t.isPattern(pattern)) return pattern; - hasDestructuringTransformer = true; + hasDestructuring = true; var ref = scope.generateUidIdentifier("ref"); var destructuring = new DestructuringTransformer({ @@ -69,15 +69,16 @@ exports.Function = function (node, parent, scope, file) { nodes: nodes, scope: scope, file: file, - kind: "var", + kind: "let" }); destructuring.init(pattern, ref); return ref; }); - if (!hasDestructuringTransformer) return; + if (!hasDestructuring) return; + file.checkNode(nodes); t.ensureBlock(node); var block = node.body; diff --git a/src/babel/transformation/transformers/es6/parameters.default.js b/src/babel/transformation/transformers/es6/parameters.default.js index 9632e9db72..e0068685ca 100644 --- a/src/babel/transformation/transformers/es6/parameters.default.js +++ b/src/babel/transformation/transformers/es6/parameters.default.js @@ -61,7 +61,7 @@ exports.Function = function (node, parent, scope, file) { scope.traverse(param, iifeVisitor, state); } - if (file.transformers["es6.blockScopingTDZ"].canRun()) { + if (file.transformers["es6.blockScopingTDZ"].canRun() && t.isIdentifier(param)) { pushDefNode(param, t.identifier("undefined"), i); } diff --git a/src/babel/transformation/transformers/es6/parameters.rest.js b/src/babel/transformation/transformers/es6/parameters.rest.js index bdf156a107..c3d0f49bf9 100644 --- a/src/babel/transformation/transformers/es6/parameters.rest.js +++ b/src/babel/transformation/transformers/es6/parameters.rest.js @@ -55,7 +55,7 @@ var hasRest = function (node) { return t.isRestElement(node.params[node.params.length - 1]); }; -exports.Function = function (node, parent, scope) { +exports.Function = function (node, parent, scope, file) { if (!hasRest(node)) return; var rest = node.params.pop().argument; @@ -69,10 +69,12 @@ exports.Function = function (node, parent, scope) { if (t.isPattern(rest)) { var pattern = rest; rest = scope.generateUidIdentifier("ref"); - var declar = t.variableDeclaration("var", pattern.elements.map(function (elem, index) { + + var declar = t.variableDeclaration("let", pattern.elements.map(function (elem, index) { var accessExpr = t.memberExpression(rest, t.literal(index), true); return t.variableDeclarator(elem, accessExpr); })); + file.checkNode(declar); node.body.body.unshift(declar); } diff --git a/test/fixtures/transformation/es6-block-scoping-tdz-fail/destructuring.js b/test/fixtures/transformation/es6-block-scoping-tdz-fail/destructuring.js new file mode 100644 index 0000000000..bfc4f6e119 --- /dev/null +++ b/test/fixtures/transformation/es6-block-scoping-tdz-fail/destructuring.js @@ -0,0 +1,9 @@ +function foo( + { x: { y: { z: a = b } = {}, w: b = 20 }, a: c = 30 } +) { + assert.equal(a, 10); + assert.equal(b, 20); + assert.equal(c, 30); +} + +foo({ x: {} }); diff --git a/test/fixtures/transformation/es6-block-scoping-tdz-pass/destructuring.js b/test/fixtures/transformation/es6-block-scoping-tdz-pass/destructuring.js new file mode 100644 index 0000000000..3a9e4b23b2 --- /dev/null +++ b/test/fixtures/transformation/es6-block-scoping-tdz-pass/destructuring.js @@ -0,0 +1,9 @@ +function foo( + { x: { y: { z: a = 10 } = {}, w: b = 20 }, a: c = 30 } +) { + assert.equal(a, 10); + assert.equal(b, 20); + assert.equal(c, 30); +} + +foo({ x: {} });