UNPKG

@admc.com/eslint-plugin-sn

Version:
59 lines (55 loc) 2.79 kB
"use strict"; /** * In attempt to get this covering the most common use cases, I'm purposefully checking only * for cases where has inline for tst 'i < x.length' or 'x.length > i'. * If code (for efficiency or index base preference or whatever) sets the length with an * intermediate variable or uses 1-base indexing with test 'i <= x.length' then things won't * work. * * We purposefully do not match partial loops (not iterating over every member) nor reverse * order loops because though in many cases Array iterators are still superior for this, we can't * confidently recommend this without much more detailed checking. */ const message = "'for (const x of array)' (for ES12) or Array.x(function) safer than legacy for int loop"; const messageId = // eslint-disable-next-line prefer-template (require("path").basename(__filename).replace(/[.]js$/, "") + "_msg").toUpperCase(); const esLintObj = { meta: { type: "suggestion", docs: { description: // eslint-disable-next-line max-len "Legacy for/int usually inferior to ES12 for...of, and unsafe in ES5 compared to native Array iterators with function params.", category: "Suggestions", }, messages: { }, }, create: context => { return { ForStatement: node => { if (node.init === null || !node.init.right) return; /* LHS harder to use than the other segments, because it may be a VariableDeclaration * or an AssigmentExpression. if (node.init.type !== "AssignmentExpression" || node.init.operator !== "=") return; */ if (node.init.right.type !== "Literal" || node.init.right.value !== 0) return; if (!node.test.left || !node.test.operator || !node.test.right) return; if (node.test.left.type === "Identifier" // i < arr.length case && node.test.right.type === "MemberExpression" && node.test.right.object !== undefined && node.test.right.object.type === "Identifier" && node.test.right.property !== undefined && node.test.right.property.name === "length" && node.test.operator === "<" || node.test.right.type === "Identifier" // arr.length > i case && node.test.left.type === "MemberExpression" && node.test.left.object !== undefined && node.test.left.object.type === "Identifier" && node.test.left.property !== undefined && node.test.left.property.name === "length" && node.test.operator === ">") context.report({node, messageId}); } }; } }; esLintObj.meta.messages[messageId] = message; module.exports = esLintObj;