not-an-aardvark / eslint-rule-composer

A utility for composing ESLint rules from other ESLint rules

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

filterReports by parsing sourceCode.

DianaSuvorova opened this issue · comments

Hello,

I am looking for a help. I am trying to use filterReports, although my predicate function has to be a bit more involved then any readme example or tests I saw in the lib.
I actually need to parse a whole sourceCode in similar way I would have parsed for a eslint rule.

Here is somewhat pseudocode to illustrate what I need.

const ruleComposer = require('eslint-rule-composer');

const noUnusedPropTypesReact = require('eslint-plugin-react').rules['no-unused-prop-types'];

const getPropsUsedInRedux = (sourceCode) => {
  const usedInRedux = [];

  somehowRunThis({
    FunctionDeclaration(node) {
      if (node.id && node.id.name === 'mapDispatchToProps') {
        usedInRedux.push[node.body];
      }
    },
  });

  return usedInRedux;
};


module.exports = ruleComposer.filterReports(
  noUnusedPropTypesReact,
  (problem, metadata) => {
    const usedInRedux = getPropsUsedInRedux(metadata.sourceCode);
    return !usedInRedux.contains(problem.node)
  },
);

It seems like I need some combination of filterReports and joinReports. Or maybe there is some other obvious way or another util I can use. Would be very grateful for any suggestions.

Thanks,
Diana

Hi, thanks for creating an issue.

Would it work to put the mapDispatchToProps check inside the filterReports call? Then you wouldn't need to have the separate FunctionDeclaration listener.

module.exports = ruleComposer.filterReports(
  noUnusedPropTypesReact,
  (problem, metadata) => {
    const node = problem.node;
    if (node.parent.body !== node) {
        return true;
    }
    return !(node.parent.id && node.parent.id.name === 'mapDispatchToProps');
  },
);

I do need that FunctionDeclaration listener and some others. I pretty much need to filter result of one rule by the result of another rule. Just problem.node is not enough, I need to analyze whole sourceCode to make a decision.

Here is particular issue I am working on: DianaSuvorova/eslint-plugin-react-redux#28

I have created a function for what I need to get done.

It unfortunately requires a lot of helper functions copied from your lib and might not be generic enough, but it works for my purpose.
I will follow up if I get to cleaning it up, so I can offer it as a contribution for your library.

const filterReports = (rule, filterNode, filterAll) => Object.freeze({
  create(context) {
    const removeNodesFromReport = [];
    let allNodesFiltered = false;
    return getRuleCreateFunc(rule)(Object.freeze(Object.create(
      context,
      {
        report: {
          enumerable: true,
          value() {
            const reportDescriptor = getReportNormalizer(rule)(...arguments);
            if (filterAll(reportDescriptor)) {
              allNodesFiltered = true;
            }
            if (filterNode(reportDescriptor)) {
              removeNodesFromReport.push(reportDescriptor.node);
            } else if (!allNodesFiltered && !removeNodesFromReport.includes(reportDescriptor.node)) {
              context.report(removeMessageIfMessageIdPresent(reportDescriptor));
            }
          },
        },
      },
    )));
  },
  schema: rule.schema,
  meta: getRuleMeta(rule),
});

module.exports = (rules, filterNode, filterAll) => filterReports(ruleComposer.joinReports(rules), filterNode, filterAll);

Thanks a lot for creating this library - it was super helpful for me!
Diana