From deaf03dd28a757fe4f20e5649360e659364fee8b Mon Sep 17 00:00:00 2001 From: Ingvar Stepanyan Date: Wed, 10 Jun 2015 12:28:10 +0300 Subject: [PATCH] Fixes & optimizations to es6.spec.arrowFunctions. --- .../templates/helper-new-arrow-check.js | 4 ++-- .../transformers/es6/spec.arrow-functions.js | 13 ++++--------- .../transformers/internal/shadow-functions.js | 6 ++---- src/babel/traversal/path/ancestry.js | 6 +++++- .../es6.arrow-functions/spec/expected.js | 19 +++++++------------ .../es6.arrow-functions/spec/options.json | 1 + 6 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/babel/transformation/templates/helper-new-arrow-check.js b/src/babel/transformation/templates/helper-new-arrow-check.js index a6e9a64308..3841b83f34 100644 --- a/src/babel/transformation/templates/helper-new-arrow-check.js +++ b/src/babel/transformation/templates/helper-new-arrow-check.js @@ -1,5 +1,5 @@ -(function (instance, arrowFn) { - if (instance instanceof arrowFn) { +(function (innerThis, boundThis) { + if (innerThis !== boundThis) { throw new TypeError("Cannot instantiate an arrow function"); } }); diff --git a/src/babel/transformation/transformers/es6/spec.arrow-functions.js b/src/babel/transformation/transformers/es6/spec.arrow-functions.js index 5a5b07d595..6a6b03b595 100644 --- a/src/babel/transformation/transformers/es6/spec.arrow-functions.js +++ b/src/babel/transformation/transformers/es6/spec.arrow-functions.js @@ -8,19 +8,14 @@ export function ArrowFunctionExpression(node, parent, scope, file) { if (node.shadow) return; node.shadow = { this: false }; - var {id} = node; - var expr = node; - - if (!id) { - id = scope.parent.generateDeclaredUidIdentifier("arrow"); - expr = t.assignmentExpression("=", id, expr); - } + var boundThis = t.thisExpression(); + boundThis._shadowedFunctionLiteral = false; // make sure that arrow function won't be instantiated t.ensureBlock(node).body.unshift(t.expressionStatement(t.callExpression(file.addHelper("new-arrow-check"), [ t.thisExpression(), - id + boundThis ]))); - return t.callExpression(t.memberExpression(expr, t.identifier("bind")), [t.thisExpression()]); + return t.callExpression(t.memberExpression(node, t.identifier("bind")), [t.thisExpression()]); } diff --git a/src/babel/transformation/transformers/internal/shadow-functions.js b/src/babel/transformation/transformers/internal/shadow-functions.js index 17b3810e14..17e0a5bce5 100644 --- a/src/babel/transformation/transformers/internal/shadow-functions.js +++ b/src/babel/transformation/transformers/internal/shadow-functions.js @@ -23,13 +23,11 @@ function remap(path, key, create) { } export function ThisExpression(node) { - if (!node._shadowedFunctionLiteral) { - return remap(this, "this", () => t.thisExpression()); - } + return remap(this, "this", () => t.thisExpression()); } export function ReferencedIdentifier(node) { - if (node.name === "arguments" && !node._shadowedFunctionLiteral) { + if (node.name === "arguments") { return remap(this, "arguments", () => t.identifier("arguments")); } } diff --git a/src/babel/traversal/path/ancestry.js b/src/babel/traversal/path/ancestry.js index 61893d71c2..61bac476ab 100644 --- a/src/babel/traversal/path/ancestry.js +++ b/src/babel/traversal/path/ancestry.js @@ -64,9 +64,13 @@ export function inType(types) { export function inShadow(key) { var path = this; + var dontShadow = path.node._shadowedFunctionLiteral; + if (dontShadow !== undefined) { + return !dontShadow; + } while (path) { if (path.isFunction()) { - var {shadow} = path.node; + var { shadow } = path.node; if (shadow && (shadow === true || shadow[key] !== false)) { return path; } else { diff --git a/test/core/fixtures/transformation/es6.arrow-functions/spec/expected.js b/test/core/fixtures/transformation/es6.arrow-functions/spec/expected.js index 3b11cfbb65..c1ecf7a56c 100644 --- a/test/core/fixtures/transformation/es6.arrow-functions/spec/expected.js +++ b/test/core/fixtures/transformation/es6.arrow-functions/spec/expected.js @@ -1,25 +1,20 @@ "use strict"; -var _arrow; - -function _newArrowCheck(instance, arrowFn) { if (instance instanceof arrowFn) { throw new TypeError("Cannot instantiate an arrow function"); } } - -arr.map((_arrow = function (x) { - _newArrowCheck(this, _arrow); +var _this = this; +arr.map((function (x) { + babelHelpers.newArrowCheck(this, _this); return x * x; }).bind(this)); var f = (function f(x, y) { - _newArrowCheck(this, f); - + babelHelpers.newArrowCheck(this, _this); return x * y; }).bind(this); (function () { - var _arrow2; - - return (_arrow2 = function () { - _newArrowCheck(this, _arrow2); + var _this2 = this; + return (function () { + babelHelpers.newArrowCheck(this, _this2); return this; }).bind(this); })(); diff --git a/test/core/fixtures/transformation/es6.arrow-functions/spec/options.json b/test/core/fixtures/transformation/es6.arrow-functions/spec/options.json index 18c0abf7f1..b6a0032986 100644 --- a/test/core/fixtures/transformation/es6.arrow-functions/spec/options.json +++ b/test/core/fixtures/transformation/es6.arrow-functions/spec/options.json @@ -1,3 +1,4 @@ { + "externalHelpers": true, "optional": ["es6.spec.arrowFunctions"] }