| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 | /** * @fileoverview Rule to disallow `parseInt()` in favor of binary, octal, and hexadecimal literals * @author Annie Zhang, Henry Zhu */"use strict";//------------------------------------------------------------------------------// Helpers//------------------------------------------------------------------------------/** * Checks to see if a CallExpression's callee node is `parseInt` or * `Number.parseInt`. * @param {ASTNode} calleeNode The callee node to evaluate. * @returns {boolean} True if the callee is `parseInt` or `Number.parseInt`, * false otherwise. */function isParseInt(calleeNode) {    switch (calleeNode.type) {        case "Identifier":            return calleeNode.name === "parseInt";        case "MemberExpression":            return calleeNode.object.type === "Identifier" &&                calleeNode.object.name === "Number" &&                calleeNode.property.type === "Identifier" &&                calleeNode.property.name === "parseInt";        // no default    }    return false;}//------------------------------------------------------------------------------// Rule Definition//------------------------------------------------------------------------------module.exports = {    meta: {        docs: {            description: "disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals",            category: "ECMAScript 6",            recommended: false,            url: "https://eslint.org/docs/rules/prefer-numeric-literals"        },        schema: [],        fixable: "code"    },    create(context) {        const sourceCode = context.getSourceCode();        const radixMap = {            2: "binary",            8: "octal",            16: "hexadecimal"        };        const prefixMap = {            2: "0b",            8: "0o",            16: "0x"        };        //----------------------------------------------------------------------        // Public        //----------------------------------------------------------------------        return {            CallExpression(node) {                // doesn't check parseInt() if it doesn't have a radix argument                if (node.arguments.length !== 2) {                    return;                }                // only error if the radix is 2, 8, or 16                const radixName = radixMap[node.arguments[1].value];                if (isParseInt(node.callee) &&                    radixName &&                    node.arguments[0].type === "Literal"                ) {                    context.report({                        node,                        message: "Use {{radixName}} literals instead of {{functionName}}().",                        data: {                            radixName,                            functionName: sourceCode.getText(node.callee)                        },                        fix(fixer) {                            const newPrefix = prefixMap[node.arguments[1].value];                            if (+(newPrefix + node.arguments[0].value) !== parseInt(node.arguments[0].value, node.arguments[1].value)) {                                /*                                 * If the newly-produced literal would be invalid, (e.g. 0b1234),                                 * or it would yield an incorrect parseInt result for some other reason, don't make a fix.                                 */                                return null;                            }                            return fixer.replaceText(node, prefixMap[node.arguments[1].value] + node.arguments[0].value);                        }                    });                }            }        };    }};
 |