UNPKG

react-magnetic-di

Version:
115 lines (104 loc) 3.43 kB
"use strict"; var _require = require('../utils'), getDiIdentifier = _require.getDiIdentifier, getDiStatements = _require.getDiStatements, getParentDiBlock = _require.getParentDiBlock, getDiVars = _require.getDiVars; module.exports = { meta: { type: 'suggestion', docs: { description: 'Disallow injecting dependencies not being used', category: 'Possible Errors', recommended: true }, // fixable: 'code', schema: [{ type: 'object', properties: { ignore: { type: 'array', items: { type: 'string' } } }, additionalProperties: false }], messages: { extraneousInjectable: "Extraneous dependency: '{{name}}'. " + 'If it is not being used, remove it from the injectable list' } }, create: function create(context) { var diIdentifier; var blockReferences = new WeakMap(); var report = function report(node) { return context.report({ node: node, messageId: 'extraneousInjectable', data: { name: node.name } // fix(fixer) { // const lastArg = diStatement.expression.arguments.slice(-1)[0]; // return fixer.insertTextAfter(lastArg, `, ${node.name}`); // }, }); }; return { ImportDeclaration: function ImportDeclaration(node) { if (!diIdentifier) diIdentifier = getDiIdentifier(node); }, // this is to handle hooks and components recognised as used variables // it does not cover JSX variables BlockStatement: function BlockStatement(node) { if (!diIdentifier) return; var diStatements = getDiStatements(node, diIdentifier); // ignore locations where di was not explicitly set if (!diStatements.length) return; var diVars = getDiVars(diStatements); blockReferences.set(node, { di: diVars, through: context.getScope().through.map(function (v) { return v.identifier; }) }); }, // as JSX elements are not treated as variables, for each JSX tag // we check if there is a block with di() above and collect the tag as var 'JSXOpeningElement:exit': function JSXOpeningElementExit(node) { if (!diIdentifier) return; var varNode; switch (node.name.type) { case 'JSXIdentifier': { varNode = node.name; break; } case 'JSXNamespacedName': // TODO handle foo:Bar return; case 'JSXMemberExpression': // TODO handle foo.Bar (but ignoring this.Bar) return; default: return; } var parentBlock = getParentDiBlock(varNode, diIdentifier); var blockVars = blockReferences.get(parentBlock); if (!blockVars) return; blockVars.through.push(varNode); }, 'BlockStatement:exit': function BlockStatementExit(node) { if (!diIdentifier) return; var blockVars = blockReferences.get(node); if (!blockVars) return; blockVars.di.forEach(function (varNode) { var occurrences = blockVars.through.filter(function (v) { return v.name === varNode.name; }); if (occurrences.length > 1) return; report(varNode); }); } }; } };