diff --git a/src/babel/transformation/transformers/es7/function-bind.js b/src/babel/transformation/transformers/es7/function-bind.js index 2846999aa7..d8cbd0c6ed 100644 --- a/src/babel/transformation/transformers/es7/function-bind.js +++ b/src/babel/transformation/transformers/es7/function-bind.js @@ -7,28 +7,35 @@ export var metadata = { stage: 0 }; -function inferBindContext(bindExpr, scope) { - // nothing to infer - if (bindExpr.object) return bindExpr.object; - +function getTempId(scope) { var id = scope.path.getData("functionBind"); - if (!id) { - id = scope.generateTemp("context"); - scope.path.setData("functionBind", id); + if (id) return id; + id = scope.generateTemp("context"); + return scope.path.setData("functionBind", id); +} + +function inferBindContext(bind, scope) { + var tempId = getTempId(scope); + if (!bind.object) { + bind.callee.object = t.assignmentExpression("=", tempId, bind.callee.object); + } else { + bind.callee = t.sequenceExpression([ + t.assignmentExpression("=", tempId, bind.object), + bind.callee + ]); } - bindExpr.callee.object = t.assignmentExpression("=", id, bindExpr.callee.object); - return id; + return tempId; } export function CallExpression(node, parent, scope, file) { - var bindExpr = node.callee; - if (!t.isBindExpression(bindExpr)) return; - var bindCtx = inferBindContext(bindExpr, scope); - node.callee = t.memberExpression(bindExpr.callee, t.identifier("call")); - node.arguments.unshift(bindCtx); + var bind = node.callee; + if (!t.isBindExpression(bind)) return; + var context = inferBindContext(bind, scope); + node.callee = t.memberExpression(bind.callee, t.identifier("call")); + node.arguments.unshift(context); } export function BindExpression(node, parent, scope, file) { - var bindCtx = inferBindContext(node, scope); - return t.callExpression(t.memberExpression(node.callee, t.identifier("bind")), [bindCtx]); + var context = inferBindContext(node, scope); + return t.callExpression(t.memberExpression(node.callee, t.identifier("bind")), [context]); } diff --git a/test/core/fixtures/transformation/es7.function-bind/bind/expected.js b/test/core/fixtures/transformation/es7.function-bind/bind/expected.js index 41321e2ecb..7c47a86b25 100644 --- a/test/core/fixtures/transformation/es7.function-bind/bind/expected.js +++ b/test/core/fixtures/transformation/es7.function-bind/bind/expected.js @@ -2,5 +2,5 @@ var _context; -var f = ns.obj.func.bind(ctx); -var g = (_context = ns.obj).func.bind(_context); \ No newline at end of file +var f = (_context = ctx, ns.obj.func).bind(_context); +var g = (_context = ns.obj).func.bind(_context); diff --git a/test/core/fixtures/transformation/es7.function-bind/call/expected.js b/test/core/fixtures/transformation/es7.function-bind/call/expected.js index 75cc530bff..b48a0bdb3e 100644 --- a/test/core/fixtures/transformation/es7.function-bind/call/expected.js +++ b/test/core/fixtures/transformation/es7.function-bind/call/expected.js @@ -2,7 +2,7 @@ var _context; -ns.obj.func.call(ctx); +(_context = ctx, ns.obj.func).call(_context); (_context = ns.obj).func.call(_context); -ns.obj1.func.call(ns.obj2); \ No newline at end of file +(_context = ns.obj2, ns.obj1.func).call(_context); diff --git a/test/core/fixtures/transformation/es7.function-bind/complex-call/exec.js b/test/core/fixtures/transformation/es7.function-bind/complex-call/exec.js new file mode 100644 index 0000000000..5ee5f3f7d7 --- /dev/null +++ b/test/core/fixtures/transformation/es7.function-bind/complex-call/exec.js @@ -0,0 +1,27 @@ +var operations = []; + +var lib = {}; + +for (let key of ['f', 'g', 'h']) { + let func = () => operations.push(`lib.${key}()`); + Object.defineProperty(lib, key, { + get() { + operations.push(`get lib.${key}`); + return func; + } + }); +} + +({prop:'value'}) +::lib.f() +::lib.g() +::lib.h(); + +assert.deepEqual(operations, [ + 'get lib.f', + 'lib.f()', + 'get lib.g', + 'lib.g()', + 'get lib.h', + 'lib.h()' +]); diff --git a/test/core/fixtures/transformation/es7.function-bind/complex-call/expected.js b/test/core/fixtures/transformation/es7.function-bind/complex-call/expected.js index e1482fbd94..b15ae7d381 100644 --- a/test/core/fixtures/transformation/es7.function-bind/complex-call/expected.js +++ b/test/core/fixtures/transformation/es7.function-bind/complex-call/expected.js @@ -1,11 +1,13 @@ "use strict"; +var _context; + var _iterlib = require("iterlib"); -_iterlib.forEach.call(_iterlib.takeWhile.call(_iterlib.map.call(getPlayers(), function (x) { +(_context = (_context = (_context = getPlayers(), _iterlib.map).call(_context, function (x) { return x.character(); -}), function (x) { +}), _iterlib.takeWhile).call(_context, function (x) { return x.strength > 100; -}), function (x) { +}), _iterlib.forEach).call(_context, function (x) { return console.log(x); -}); \ No newline at end of file +});