extjs-replace-callparent
Version:
Replace Ext JS `callParent` calls with direct method calls on parent class
72 lines (53 loc) • 2.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (_ref) {
var t = _ref.types;
var findParentDefinition = (0, _definition2.default)(t);
function isThisOrMeExpression(node) {
return t.isThisExpression(node) || t.isIdentifier(node, { name: 'me' });
}
function isCallParentCallee(node) {
return t.isMemberExpression(node) && isThisOrMeExpression(node.object) && t.isIdentifier(node.property, { name: 'callParent' });
}
function isClassMethod(path) {
return path.isObjectProperty() && t.isFunction(path.node.value) || path.isObjectMethod();
}
function buildMethodRef(protoRef, methodName) {
return t.memberExpression(t.logicalExpression('||', t.memberExpression(protoRef, t.identifier('prototype')), protoRef), t.identifier(methodName));
}
function buildReplacement(methodRef, args) {
var memberExpression = t.memberExpression(methodRef, t.identifier(args.length ? 'apply' : 'call'));
return args.length ? t.callExpression(memberExpression, [t.thisExpression(), args[0]]) : t.callExpression(memberExpression, [t.thisExpression()]);
}
function getMethodName(callParentPath) {
var clsMethod = callParentPath.findParent(isClassMethod);
if (!clsMethod) {
throw path.buildCodeFrameError("Unable to find method declaration for this 'callParent'");
}
return clsMethod.node.key.name;
}
return {
visitor: {
CallExpression: function CallExpression(path, state) {
if (!isCallParentCallee(path.node.callee)) {
return;
}
// The name of the method which the `callParent` is within
var methodName = getMethodName(path);
// The definition (either `Ext.define` or `Ext.override`)
var definition = findParentDefinition(path, state.opts.extNames);
var methodRef = buildMethodRef(definition.protoRef, methodName);
if (definition.isOverride) {
methodRef = definition.prependVariableRef(methodRef);
}
path.replaceWith(buildReplacement(methodRef, path.node.arguments));
}
}
};
};
var _definition = require('./definition');
var _definition2 = _interopRequireDefault(_definition);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
;