Skip to content

Commit

Permalink
[Refactor] improve performance of rule merging
Browse files Browse the repository at this point in the history
  • Loading branch information
golopot committed May 2, 2022
1 parent c8833f3 commit 1db241c
Showing 1 changed file with 43 additions and 32 deletions.
75 changes: 43 additions & 32 deletions lib/util/Components.js
Expand Up @@ -247,6 +247,40 @@ function getWrapperFunctions(context, pragma) {
]);
}

// eslint-disable-next-line valid-jsdoc
/**
* Merge many eslint rules into one
* @param {{[_: string]: Function}[]} rules the returned values for eslint rule.create(context)
* @returns {{[_: string]: Function}} merged rule
*/
function mergeRules(rules) {
/** @type {Map<string, Function[]>} */
const handlersByKey = new Map();
for (const rule of rules) {
for (const key of Object.keys(rule)) {
const fns = handlersByKey.get(key);
if (!fns) {
handlersByKey.set(key, [rule[key]]);
} else {
fns.push(rule[key]);
}
}
}

/** @type {{[key: string]: Function}} */
const rule = {};
for (const key of handlersByKey.keys()) {
const fns = handlersByKey.get(key);
rule[key] = function mergedHandler(node) {
for (const fn of fns) {
fn(node);
}
};
}

return rule;
}

function componentRule(rule, context) {
const pragma = pragmaUtil.getFromContext(context);
const sourceCode = context.getSourceCode();
Expand Down Expand Up @@ -859,44 +893,21 @@ function componentRule(rule, context) {
},
};

// Update the provided rule instructions to add the component detection
const ruleInstructions = rule(context, components, utils);
const updatedRuleInstructions = Object.assign({}, ruleInstructions);
const propTypesInstructions = propTypesUtil(context, components, utils);
const usedPropTypesInstructions = usedPropTypesUtil(context, components, utils);
const defaultPropsInstructions = defaultPropsUtil(context, components, utils);
const allKeys = new Set(Object.keys(detectionInstructions).concat(
Object.keys(propTypesInstructions),
Object.keys(usedPropTypesInstructions),
Object.keys(defaultPropsInstructions),
Object.keys(reactImportInstructions)
));

allKeys.forEach((instruction) => {
updatedRuleInstructions[instruction] = (node) => {
if (instruction in detectionInstructions) {
detectionInstructions[instruction](node);
}
if (instruction in propTypesInstructions) {
propTypesInstructions[instruction](node);
}
if (instruction in usedPropTypesInstructions) {
usedPropTypesInstructions[instruction](node);
}
if (instruction in defaultPropsInstructions) {
defaultPropsInstructions[instruction](node);
}
if (instruction in reactImportInstructions) {
reactImportInstructions[instruction](node);
}
if (ruleInstructions[instruction]) {
return ruleInstructions[instruction](node);
}
};
});
const mergedRule = mergeRules([
detectionInstructions,
propTypesInstructions,
usedPropTypesInstructions,
defaultPropsInstructions,
reactImportInstructions,
ruleInstructions,
]);

// Return the updated rule instructions
return updatedRuleInstructions;
return mergedRule;
}

module.exports = Object.assign(Components, {
Expand Down

0 comments on commit 1db241c

Please sign in to comment.