From 8b8e3ddbec46c27646e281878f89c2cb3b50760d Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Sun, 6 Mar 2016 18:14:25 -0800 Subject: [PATCH 1/7] Flatten inShadow logic for readability. --- packages/babel-traverse/src/path/ancestry.js | 62 +++++++++++++------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/packages/babel-traverse/src/path/ancestry.js b/packages/babel-traverse/src/path/ancestry.js index 7e52857056..8578f7d3e8 100644 --- a/packages/babel-traverse/src/path/ancestry.js +++ b/packages/babel-traverse/src/path/ancestry.js @@ -188,30 +188,52 @@ export function inType() { } /** - * Check if we're inside a shadowed function. + * Checks whether the binding for 'key' is a local binding in its current function context. + * + * Checks if the current path either is, or has a direct parent function that is, inside + * of a function that is marked for shadowing of a binding matching 'key'. Also returns + * the parent path if the parent path is an arrow, since arrow functions pass through + * binding values to their parent, meaning they have no local bindings. + * + * Shadowing means that when the given binding is transformed, it will read the binding + * value from the container containing the shadow function, rather than from inside the + * shadow function. + * + * Function shadowing is acheieved by adding a "shadow" property on "FunctionExpression" + * and "FunctionDeclaration" node types. + * + * Node's "shadow" props have the following behavior: + * + * - Boolean true will cause the function to shadow both "this" and "arguments". + * - {this: false} Shadows "arguments" but not "this". + * - {arguments: false} Shadows "this" but not "arguments". + * + * Separately, individual identifiers can be flagged with two flags: + * + * - _forceShadow - If truthy, this specific identifier will be bound in the closest + * Function that is not flagged "shadow", or the Program. + * - _shadowedFunctionLiteral - When set to a NodePath, this specific identifier will be bound + * to this NodePath/Node or the Program. */ export function inShadow(key?) { - let path = this; - do { - if (path.isFunction()) { - let shadow = path.node.shadow; - if (shadow) { - // this is because sometimes we may have a `shadow` value of: - // - // { this: false } - // - // we need to catch this case if `inShadow` has been passed a `key` - if (!key || shadow[key] !== false) { - return path; - } - } else if (path.isArrowFunctionExpression()) { - return path; - } + let parentFn = this.isFunction() ? this : this.findParent((p) => p.isFunction()); + if (!parentFn) return; - // normal function, we've found our function context - return null; + let shadow = parentFn.node.shadow; + if (shadow) { + // this is because sometimes we may have a `shadow` value of: + // + // { this: false } + // + // we need to catch this case if `inShadow` has been passed a `key` + if (!key || shadow[key] !== false) { + return parentFn; } - } while (path = path.parentPath); + } else if (parentFn.isArrowFunctionExpression()) { + return parentFn; + } + + // normal function, we've found our function context return null; } From 836f3986199378f7646897091afd3f37dc482003 Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Sun, 6 Mar 2016 03:16:11 -0800 Subject: [PATCH 2/7] Re-use central inShadow logic. --- packages/babel-helper-replace-supers/src/index.js | 6 +----- packages/babel-traverse/src/path/ancestry.js | 7 ++++--- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/packages/babel-helper-replace-supers/src/index.js b/packages/babel-helper-replace-supers/src/index.js index 76b05d7ad4..7010cb1670 100644 --- a/packages/babel-helper-replace-supers/src/index.js +++ b/packages/babel-helper-replace-supers/src/index.js @@ -20,11 +20,7 @@ function isMemberExpressionSuper(node) { } let visitor = { - "ObjectMethod|ClassMethod"(path) { - path.skip(); - }, - - "FunctionDeclaration|FunctionExpression"(path) { + Function(path) { if (!path.inShadow("this")) { path.skip(); } diff --git a/packages/babel-traverse/src/path/ancestry.js b/packages/babel-traverse/src/path/ancestry.js index 8578f7d3e8..f98934c6b7 100644 --- a/packages/babel-traverse/src/path/ancestry.js +++ b/packages/babel-traverse/src/path/ancestry.js @@ -220,14 +220,15 @@ export function inShadow(key?) { let parentFn = this.isFunction() ? this : this.findParent((p) => p.isFunction()); if (!parentFn) return; - let shadow = parentFn.node.shadow; - if (shadow) { + if (parentFn.isFunctionExpression() || parentFn.isFunctionDeclaration()) { + let shadow = parentFn.node.shadow; + // this is because sometimes we may have a `shadow` value of: // // { this: false } // // we need to catch this case if `inShadow` has been passed a `key` - if (!key || shadow[key] !== false) { + if (shadow && (!key || shadow[key] !== false)) { return parentFn; } } else if (parentFn.isArrowFunctionExpression()) { From 2e210927d81c92e6cf65519438cb1e25d31bdb39 Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Sun, 6 Mar 2016 16:32:19 -0800 Subject: [PATCH 3/7] Move the necessary exec transforms to the exec test. --- .../test/fixtures/regression/T6882/options.json | 9 +++++++++ .../test/fixtures/regression/options.json | 5 ++++- 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T6882/options.json diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T6882/options.json b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T6882/options.json new file mode 100644 index 0000000000..d5312adc2d --- /dev/null +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T6882/options.json @@ -0,0 +1,9 @@ +{ + "plugins": [ + "external-helpers", + "transform-async-to-generator", + "transform-es2015-block-scoping", + "transform-es2015-arrow-functions", + "transform-regenerator" + ] +} diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/options.json b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/options.json index 94bdeeb0eb..6b5744a918 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/options.json +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/options.json @@ -1,3 +1,6 @@ { - "plugins": ["external-helpers", "transform-es2015-block-scoping", "transform-regenerator", "transform-async-to-generator"] + "plugins": [ + "external-helpers", + "transform-async-to-generator" + ] } From db3a43869cb81076179288db3839fd77f294756a Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Sun, 6 Mar 2016 16:58:54 -0800 Subject: [PATCH 4/7] Remap across arrow function boundaries - fixes T7108 --- .../internal-plugins/shadow-functions.js | 4 +- .../test/fixtures/regression/T7108/actual.js | 33 ++++++++++ .../fixtures/regression/T7108/expected.js | 61 +++++++++++++++++++ 3 files changed, 96 insertions(+), 2 deletions(-) create mode 100644 packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/actual.js create mode 100644 packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/expected.js diff --git a/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js b/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js index 13e5e955ac..76e137002c 100644 --- a/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js +++ b/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js @@ -19,7 +19,7 @@ function shouldShadow(path, shadowPath) { if (path.is("_forceShadow")) { return true; } else { - return shadowPath && !shadowPath.isArrowFunctionExpression(); + return shadowPath; } } @@ -39,7 +39,7 @@ function remap(path, key, create) { if (path.isProgram()) { return true; - } else if (path.isFunction()) { + } else if (path.isFunction() && !path.isArrowFunctionExpression()) { if (shadowFunction) { return path === shadowFunction || path.node === shadowFunction.node; } else { diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/actual.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/actual.js new file mode 100644 index 0000000000..68075431ac --- /dev/null +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/actual.js @@ -0,0 +1,33 @@ +class Test{ + static async method1() { + console.log(this); + + setTimeout(async () => { + console.log(this); + }); + } + + static async method2() { + console.log(this); + + setTimeout(async (arg) => { + console.log(this); + }); + } + + async method1() { + console.log(this); + + setTimeout(async () => { + console.log(this); + }); + } + + async method2() { + console.log(this); + + setTimeout(async (arg) => { + console.log(this); + }); + } +} diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/expected.js new file mode 100644 index 0000000000..f3fc39332c --- /dev/null +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/expected.js @@ -0,0 +1,61 @@ +class Test { + static method1() { + var _this = this; + + return babelHelpers.asyncToGenerator(function* () { + console.log(_this); + + setTimeout(babelHelpers.asyncToGenerator(function* () { + console.log(_this); + })); + })(); + } + + static method2() { + var _this2 = this; + + return babelHelpers.asyncToGenerator(function* () { + console.log(_this2); + + setTimeout((() => { + var ref = babelHelpers.asyncToGenerator(function* (arg) { + console.log(_this2); + }), + _this = _this2; + return function (_x) { + return ref.apply(_this, arguments); + }; + })()); + })(); + } + + method1() { + var _this3 = this; + + return babelHelpers.asyncToGenerator(function* () { + console.log(_this3); + + setTimeout(babelHelpers.asyncToGenerator(function* () { + console.log(_this3); + })); + })(); + } + + method2() { + var _this4 = this; + + return babelHelpers.asyncToGenerator(function* () { + console.log(_this4); + + setTimeout((() => { + var ref = babelHelpers.asyncToGenerator(function* (arg) { + console.log(_this4); + }), + _this = _this4; + return function (_x2) { + return ref.apply(_this, arguments); + }; + })()); + })(); + } +} From 51ddeade8a6a423f2edfa6d7024f6ac64325720c Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Sun, 6 Mar 2016 17:06:19 -0800 Subject: [PATCH 5/7] Avoid renaming this bindings in simple arrow function cases. --- .../internal-plugins/shadow-functions.js | 14 +++- .../deeply-nested-asyncs/expected.js | 71 +++++++++---------- 2 files changed, 46 insertions(+), 39 deletions(-) diff --git a/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js b/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js index 76e137002c..ccd753cc55 100644 --- a/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js +++ b/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js @@ -30,6 +30,7 @@ function remap(path, key, create) { let shadowFunction = path.node._shadowedFunctionLiteral; let currentFunction; + let passedShadowFunction = false; let fnPath = path.findParent(function (path) { if (path.isProgram() || path.isFunction()) { @@ -38,13 +39,18 @@ function remap(path, key, create) { } if (path.isProgram()) { + passedShadowFunction = true; + return true; } else if (path.isFunction() && !path.isArrowFunctionExpression()) { if (shadowFunction) { - return path === shadowFunction || path.node === shadowFunction.node; + if (path === shadowFunction || path.node === shadowFunction.node) return true; } else { - return !path.is("shadow"); + if (!path.is("shadow")) return true; } + + passedShadowFunction = true; + return false; } return false; @@ -53,6 +59,10 @@ function remap(path, key, create) { // no point in realiasing if we're in this function if (fnPath === currentFunction) return; + // If the only functions that were encountered are arrow functions, skip remapping the + // binding since arrow function syntax already does that. + if (!passedShadowFunction) return; + let cached = fnPath.getData(key); if (cached) return path.replaceWith(cached); diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js index 9bc186bfde..b32aae134c 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js @@ -1,37 +1,34 @@ -let s = function () { - var ref = babelHelpers.asyncToGenerator(function* (x) { - let t = (() => { - var _this3 = this; - - var ref = babelHelpers.asyncToGenerator(function* (y, a) { - let r = (() => { - var _this2 = this; - - var ref = babelHelpers.asyncToGenerator(function* (z, b) { - yield z; - return _this2.x; - }), - _this = this; - - return function r(_x4, _x5) { - return ref.apply(_this, arguments); - }; - })(); - yield r(); - - return _this3.g(r); - }), - _this = this; - - return function t(_x2, _x3) { - return ref.apply(_this, arguments); - }; - })(); - - yield t(); - return this.h(t); - }); - return function s(_x) { - return ref.apply(this, arguments); - }; -}(); +let s = function () { + var ref = babelHelpers.asyncToGenerator(function* (x) { + var _this2 = this; + + let t = (() => { + var ref = babelHelpers.asyncToGenerator(function* (y, a) { + let r = (() => { + var ref = babelHelpers.asyncToGenerator(function* (z, b) { + yield z; + return _this2.x; + }), + _this = _this2; + + return function r(_x4, _x5) { + return ref.apply(_this, arguments); + }; + })(); + yield r(); + + return _this2.g(r); + }), + _this = this; + return function t(_x2, _x3) { + return ref.apply(_this, arguments); + }; + })(); + + yield t(); + return this.h(t); + }); + return function s(_x) { + return ref.apply(this, arguments); + }; +}(); From 42d3844f2435df74505146c30152d265ff254033 Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Sat, 5 Mar 2016 22:28:49 -0800 Subject: [PATCH 6/7] Revert special arrow wrapper and avoid shadowing arguments. --- .../src/index.js | 20 ++--------- .../async-arrow-in-method/expected.js | 36 +++++++++---------- .../deeply-nested-asyncs/expected.js | 21 +++++------ .../async-to-generator/expression/expected.js | 4 +-- .../named-expression/expected.js | 4 +-- .../async-to-generator/parameters/expected.js | 4 +-- .../async-to-generator/statement/expected.js | 4 +-- .../import-and-export/expected.js | 4 +-- .../export-async/lone-export/expected.js | 4 +-- .../fixtures/regression/T7108/expected.js | 10 +++--- .../expression/expected.js | 4 +-- .../named-expression/expected.js | 4 +-- .../bluebird-coroutines/statement/expected.js | 4 +-- 13 files changed, 50 insertions(+), 73 deletions(-) diff --git a/packages/babel-helper-remap-async-to-generator/src/index.js b/packages/babel-helper-remap-async-to-generator/src/index.js index f22ab48e35..c1aa6d34a2 100644 --- a/packages/babel-helper-remap-async-to-generator/src/index.js +++ b/packages/babel-helper-remap-async-to-generator/src/index.js @@ -6,7 +6,7 @@ import template from "babel-template"; import * as t from "babel-types"; let buildWrapper = template(` - (function () { + (() => { var ref = FUNCTION; return function NAME(PARAMS) { return ref.apply(this, arguments); @@ -15,7 +15,7 @@ let buildWrapper = template(` `); let namedBuildWrapper = template(` - (function () { + (() => { var ref = FUNCTION; function NAME(PARAMS) { return ref.apply(this, arguments); @@ -24,15 +24,6 @@ let namedBuildWrapper = template(` }) `); -let arrowBuildWrapper = template(` - (() => { - var ref = FUNCTION, _this = this; - return function(PARAMS) { - return ref.apply(_this, arguments); - }; - }) -`); - let awaitVisitor = { ArrowFunctionExpression(path) { if (!path.node.async) { @@ -69,19 +60,12 @@ function plainFunction(path: NodePath, callId: Object) { if (path.isArrowFunctionExpression()) { path.arrowFunctionToShadowed(); - wrapper = arrowBuildWrapper; } else if (!isDeclaration && asyncFnId) { wrapper = namedBuildWrapper; } node.async = false; node.generator = true; - // Either the wrapped generator is invoked with `.apply(this, arguments)` or it has no params, - // so it should capture `arguments` - if (node.shadow) { - // node.shadow may be `true` or an object - node.shadow = Object.assign({}, node.shadow, { arguments: false }); - } node.id = null; diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/async-arrow-in-method/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/async-arrow-in-method/expected.js index 3d421469f5..a307b98c83 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/async-arrow-in-method/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/async-arrow-in-method/expected.js @@ -1,19 +1,17 @@ -let TestClass = { - name: "John Doe", - - testMethodFailure() { - return new Promise((() => { - var _this2 = this; - - var ref = babelHelpers.asyncToGenerator(function* (resolve) { - console.log(_this2); - setTimeout(resolve, 1000); - }), - _this = this; - - return function (_x) { - return ref.apply(_this, arguments); - }; - })()); - } -}; +let TestClass = { + name: "John Doe", + + testMethodFailure() { + var _this = this; + + return new Promise((() => { + var ref = babelHelpers.asyncToGenerator(function* (resolve) { + console.log(_this); + setTimeout(resolve, 1000); + }); + return function (_x) { + return ref.apply(this, arguments); + }; + })()); + } +}; diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js index b32aae134c..691a0b30d1 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js @@ -1,27 +1,24 @@ -let s = function () { +let s = (() => { var ref = babelHelpers.asyncToGenerator(function* (x) { - var _this2 = this; + var _this = this; let t = (() => { var ref = babelHelpers.asyncToGenerator(function* (y, a) { let r = (() => { var ref = babelHelpers.asyncToGenerator(function* (z, b) { yield z; - return _this2.x; - }), - _this = _this2; - + return _this.x; + }); return function r(_x4, _x5) { - return ref.apply(_this, arguments); + return ref.apply(this, arguments); }; })(); yield r(); - return _this2.g(r); - }), - _this = this; + return _this.g(r); + }); return function t(_x2, _x3) { - return ref.apply(_this, arguments); + return ref.apply(this, arguments); }; })(); @@ -31,4 +28,4 @@ let s = function () { return function s(_x) { return ref.apply(this, arguments); }; -}(); +})(); diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/expression/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/expression/expected.js index e3c7d2218f..baff50e27f 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/expression/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/expression/expected.js @@ -1,8 +1,8 @@ -var foo = function () { +var foo = (() => { var ref = babelHelpers.asyncToGenerator(function* () { var wat = yield bar(); }); return function foo() { return ref.apply(this, arguments); }; -}(); +})(); diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/named-expression/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/named-expression/expected.js index c6282326b3..fabf097a50 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/named-expression/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/named-expression/expected.js @@ -1,4 +1,4 @@ -var foo = function () { +var foo = (() => { var ref = babelHelpers.asyncToGenerator(function* () { console.log(bar); }); @@ -8,4 +8,4 @@ var foo = function () { } return bar; -}(); +})(); diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/parameters/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/parameters/expected.js index 2cbaf5139e..bee7bb6870 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/parameters/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/parameters/expected.js @@ -1,6 +1,6 @@ -let foo = function () { +let foo = (() => { var ref = babelHelpers.asyncToGenerator(function* (bar) {}); return function foo(_x) { return ref.apply(this, arguments); }; -}(); +})(); diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/statement/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/statement/expected.js index 51140320d4..4fa3965734 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/statement/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/statement/expected.js @@ -1,8 +1,8 @@ -let foo = function () { +let foo = (() => { var ref = babelHelpers.asyncToGenerator(function* () { var wat = yield bar(); }); return function foo() { return ref.apply(this, arguments); }; -}(); +})(); diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/export-async/import-and-export/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/export-async/import-and-export/expected.js index 7ea795d5ca..5ac84b7eb0 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/export-async/import-and-export/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/export-async/import-and-export/expected.js @@ -5,12 +5,12 @@ Object.defineProperty(exports, "__esModule", { }); exports.foo = undefined; -let foo = exports.foo = function () { +let foo = exports.foo = (() => { var ref = babelHelpers.asyncToGenerator(function* () {}); return function foo() { return ref.apply(this, arguments); }; -}(); +})(); var _bar = require('bar'); diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/export-async/lone-export/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/export-async/lone-export/expected.js index 3f1072c7e3..99b7a1da10 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/export-async/lone-export/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/export-async/lone-export/expected.js @@ -4,9 +4,9 @@ Object.defineProperty(exports, "__esModule", { value: true }); -let foo = exports.foo = function () { +let foo = exports.foo = (() => { var ref = babelHelpers.asyncToGenerator(function* () {}); return function foo() { return ref.apply(this, arguments); }; -}(); +})(); diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/expected.js index f3fc39332c..a2dd94f127 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/regression/T7108/expected.js @@ -20,10 +20,9 @@ class Test { setTimeout((() => { var ref = babelHelpers.asyncToGenerator(function* (arg) { console.log(_this2); - }), - _this = _this2; + }); return function (_x) { - return ref.apply(_this, arguments); + return ref.apply(this, arguments); }; })()); })(); @@ -50,10 +49,9 @@ class Test { setTimeout((() => { var ref = babelHelpers.asyncToGenerator(function* (arg) { console.log(_this4); - }), - _this = _this4; + }); return function (_x2) { - return ref.apply(_this, arguments); + return ref.apply(this, arguments); }; })()); })(); diff --git a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/expression/expected.js b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/expression/expected.js index 1d7bf3bba5..d4567b0dea 100644 --- a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/expression/expected.js +++ b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/expression/expected.js @@ -1,5 +1,5 @@ import { coroutine as _coroutine } from "bluebird"; -var foo = function () { +var foo = (() => { var ref = _coroutine(function* () { var wat = yield bar(); }); @@ -7,4 +7,4 @@ var foo = function () { return function foo() { return ref.apply(this, arguments); }; -}(); +})(); diff --git a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/named-expression/expected.js b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/named-expression/expected.js index 082562347d..91a3c61229 100644 --- a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/named-expression/expected.js +++ b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/named-expression/expected.js @@ -1,5 +1,5 @@ import { coroutine as _coroutine } from "bluebird"; -var foo = function () { +var foo = (() => { var ref = _coroutine(function* () { console.log(bar); }); @@ -9,4 +9,4 @@ var foo = function () { } return bar; -}(); +})(); diff --git a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/statement/expected.js b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/statement/expected.js index ef7b97d56b..72167461b0 100644 --- a/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/statement/expected.js +++ b/packages/babel-plugin-transform-async-to-module-method/test/fixtures/bluebird-coroutines/statement/expected.js @@ -1,6 +1,6 @@ import { coroutine as _coroutine } from "bluebird"; -let foo = function () { +let foo = (() => { var ref = _coroutine(function* () { var wat = yield bar(); }); @@ -8,4 +8,4 @@ let foo = function () { return function foo() { return ref.apply(this, arguments); }; -}(); +})(); From de21f2ef77e293ee3d2ab1dac1a5027d0ff68494 Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Sun, 6 Mar 2016 17:54:47 -0800 Subject: [PATCH 7/7] Resolve 'arguments' for rest args relative to direct parent. --- .../internal-plugins/shadow-functions.js | 8 +++++ .../deeply-nested-asyncs/actual.js | 30 ++++++++++--------- .../deeply-nested-asyncs/expected.js | 13 +++++++- .../fixtures/async-to-generator/options.json | 6 +++- packages/babel-traverse/src/path/ancestry.js | 6 +++- 5 files changed, 46 insertions(+), 17 deletions(-) diff --git a/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js b/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js index ccd753cc55..5a5681d67c 100644 --- a/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js +++ b/packages/babel-core/src/transformation/internal-plugins/shadow-functions.js @@ -29,6 +29,7 @@ function remap(path, key, create) { if (!shouldShadow(path, shadowPath)) return; let shadowFunction = path.node._shadowedFunctionLiteral; + let currentFunction; let passedShadowFunction = false; @@ -56,6 +57,13 @@ function remap(path, key, create) { return false; }); + if (shadowFunction && fnPath.isProgram() && !shadowFunction.isProgram()){ + // If the shadow wasn't found, take the closest function as a backup. + // This is a bit of a hack, but it will allow the parameter transforms to work properly + // without introducing yet another shadow-controlling flag. + fnPath = path.findParent((p) => p.isProgram() || p.isFunction()); + } + // no point in realiasing if we're in this function if (fnPath === currentFunction) return; diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/actual.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/actual.js index 7d51e3957f..54b9fa5000 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/actual.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/actual.js @@ -1,14 +1,16 @@ -async function s(x) { - let t = async (y, a) => { - let r = async (z, b) => { - await z; - return this.x; - } - await r(); - - return this.g(r); - } - - await t(); - return this.h(t); -} +async function s(x, ...args) { + let t = async (y, a) => { + let r = async (z, b, ...innerArgs) => { + await z; + console.log(this, innerArgs, arguments); + return this.x; + } + await r(); + + console.log(this, args, arguments); + return this.g(r); + } + + await t(); + return this.h(t); +} diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js index 691a0b30d1..94c5622431 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/deeply-nested-asyncs/expected.js @@ -1,12 +1,22 @@ let s = (() => { var ref = babelHelpers.asyncToGenerator(function* (x) { - var _this = this; + var _this = this, + _arguments = arguments; + + for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } let t = (() => { var ref = babelHelpers.asyncToGenerator(function* (y, a) { let r = (() => { var ref = babelHelpers.asyncToGenerator(function* (z, b) { + for (var _len2 = arguments.length, innerArgs = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) { + innerArgs[_key2 - 2] = arguments[_key2]; + } + yield z; + console.log(_this, innerArgs, _arguments); return _this.x; }); return function r(_x4, _x5) { @@ -15,6 +25,7 @@ let s = (() => { })(); yield r(); + console.log(_this, args, _arguments); return _this.g(r); }); return function t(_x2, _x3) { diff --git a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/options.json b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/options.json index 54b64ad0fb..78b845844f 100644 --- a/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/options.json +++ b/packages/babel-plugin-transform-async-to-generator/test/fixtures/async-to-generator/options.json @@ -1,3 +1,7 @@ { - "plugins": ["external-helpers", "transform-async-to-generator"] + "plugins": [ + "external-helpers", + "transform-es2015-parameters", + "transform-async-to-generator" + ] } diff --git a/packages/babel-traverse/src/path/ancestry.js b/packages/babel-traverse/src/path/ancestry.js index f98934c6b7..e7c3217093 100644 --- a/packages/babel-traverse/src/path/ancestry.js +++ b/packages/babel-traverse/src/path/ancestry.js @@ -213,7 +213,11 @@ export function inType() { * - _forceShadow - If truthy, this specific identifier will be bound in the closest * Function that is not flagged "shadow", or the Program. * - _shadowedFunctionLiteral - When set to a NodePath, this specific identifier will be bound - * to this NodePath/Node or the Program. + * to this NodePath/Node or the Program. If this path is not found relative to the + * starting location path, the closest function will be used. + * + * Please Note, these flags are for private internal use only and should be avoided. + * Only "shadow" is a public property that other transforms may manipulate. */ export function inShadow(key?) {