@babel/plugin-proposal-function-bind
Version:
Compile function bind operator to ES5
61 lines (58 loc) • 2.08 kB
JavaScript
import { declare } from '@babel/helper-plugin-utils';
import { types } from '@babel/core';
const index = declare(api => {
api.assertVersion("^7.0.0-0 || ^8.0.0");
function getTempId(scope) {
let id = scope.path.getData("functionBind");
if (id) return types.cloneNode(id);
id = scope.generateDeclaredUidIdentifier("context");
return scope.path.setData("functionBind", id);
}
function getObject(bind) {
if (types.isExpression(bind.object)) {
return bind.object;
}
return bind.callee.object;
}
function getStaticContext(bind, scope) {
const object = getObject(bind);
return scope.isStatic(object) && (types.isSuper(object) ? types.thisExpression() : object);
}
function inferBindContext(bind, scope) {
const staticContext = getStaticContext(bind, scope);
if (staticContext) return types.cloneNode(staticContext);
const tempId = getTempId(scope);
if (bind.object) {
bind.callee = types.sequenceExpression([types.assignmentExpression("=", tempId, bind.object), bind.callee]);
} else if (types.isMemberExpression(bind.callee)) {
bind.callee.object = types.assignmentExpression("=", tempId, bind.callee.object);
}
return types.cloneNode(tempId);
}
return {
name: "proposal-function-bind",
manipulateOptions: (_, parser) => parser.plugins.push("functionBind"),
visitor: {
CallExpression({
node,
scope
}) {
const bind = node.callee;
if (!types.isBindExpression(bind)) return;
const context = inferBindContext(bind, scope);
node.callee = types.memberExpression(bind.callee, types.identifier("call"));
node.arguments.unshift(context);
},
BindExpression(path) {
const {
node,
scope
} = path;
const context = inferBindContext(node, scope);
path.replaceWith(types.callExpression(types.memberExpression(node.callee, types.identifier("bind")), [context]));
}
}
};
});
export { index as default };
//# sourceMappingURL=index.js.map