babel-plugin-transform-reblend-function-to-class
Version:
131 lines • 5.72 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.processHookMemberAccess = processHookMemberAccess;
const t = __importStar(require("@babel/types"));
const utils_1 = require("./utils");
const crypto_1 = require("crypto");
function processHookMemberAccess(path) {
path.traverse({
MemberExpression(innerPath) {
var _a, _b;
const propertyName = innerPath.node.property.name;
if (!(0, utils_1.isHookName)(propertyName) || isAlreadyBound(innerPath)) {
return;
}
if (((_b = (_a = innerPath.node.object) === null || _a === void 0 ? void 0 : _a.object) === null || _b === void 0 ? void 0 : _b.type) === 'ThisExpression') {
// If the object is already bound to `this`, we don't need to do anything
return;
}
let parentPath = t.isSequenceExpression(innerPath.parent)
? innerPath.parentPath.parentPath
: innerPath.parentPath;
parentPath = !parentPath
? parentPath
: getNonTypescriptParent(parentPath);
bindThis(innerPath, innerPath.node.property, (parentPath === null || parentPath === void 0 ? void 0 : parentPath.node).arguments, parentPath === null || parentPath === void 0 ? void 0 : parentPath.parent, {
object: innerPath.node.object,
property: innerPath.node.property,
computed: innerPath.node.computed,
});
},
CallExpression(p) {
if (!t.isIdentifier(p.node.callee) || !(0, utils_1.isHookName)(p.node.callee.name)) {
return;
}
const parentPath = getNonTypescriptParent(p);
bindThis(p, p.node.callee, p.node.arguments, parentPath.parent);
},
});
}
function bindThis(path, callee, calleeArguments, parent, asMemberObject) {
//Bind custom hooks call to `this`
const newCallExpression = asMemberObject
? t.callExpression(t.memberExpression(t.memberExpression(asMemberObject.object, asMemberObject.property, asMemberObject.computed), t.identifier('bind')), [t.thisExpression()])
: t.callExpression(t.callExpression(t.memberExpression(callee, t.identifier('bind')), [
t.thisExpression(),
]), calleeArguments);
const includeForDependencyArgument = [
'useEffect',
'useMemo',
'useEffectAfter',
];
const dep = calleeArguments[1];
const shouldIncludeDependency = dep && includeForDependencyArgument.includes(callee.name);
if (shouldIncludeDependency) {
const arrowFn = t.arrowFunctionExpression([], dep);
const boundArrowFn = t.callExpression(t.memberExpression(arrowFn, t.identifier('bind')), [t.thisExpression()]);
calleeArguments[1] = boundArrowFn;
}
const includeForVariableDeclarator = [
'useState',
'useReducer',
'useMemo',
'useContext',
];
if (includeForVariableDeclarator.includes(callee.name) &&
t.isVariableDeclarator(parent)) {
let variableName = t.identifier('');
if (t.isArrayPattern(parent.id)) {
variableName = parent.id.elements[0];
}
else if (t.isIdentifier(parent.id)) {
variableName = parent.id;
}
calleeArguments.push(t.stringLiteral((variableName === null || variableName === void 0 ? void 0 : variableName.name) || `unneededIdentifier_${(0, crypto_1.randomUUID)()}`));
}
if (shouldIncludeDependency && callee.name == 'useMemo') {
if (calleeArguments.length >= 2) {
const lastIdx = calleeArguments.length - 1;
const temp = calleeArguments[lastIdx];
calleeArguments[lastIdx] = calleeArguments[lastIdx - 1];
calleeArguments[lastIdx - 1] = temp;
}
}
path.replaceWith(newCallExpression);
return newCallExpression;
}
function isAlreadyBound(path) {
return (t.isMemberExpression(path.parent) &&
path.parent.property.name === 'bind');
}
function getNonTypescriptParent(path) {
let parentPath = path;
while (parentPath && (0, utils_1.isTypescriptNode)(parentPath.parent)) {
parentPath = parentPath.parentPath;
}
return parentPath;
}
//# sourceMappingURL=processHookMemberAccess.js.map