.
This commit is contained in:
		
							
								
								
									
										198
									
								
								qwen/nodejs/node_modules/eslint/lib/rules/radix.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								qwen/nodejs/node_modules/eslint/lib/rules/radix.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,198 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @fileoverview Rule to flag use of parseInt without a radix argument
 | 
			
		||||
 * @author James Allardice
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Requirements
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const astUtils = require("./utils/ast-utils");
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Helpers
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
const MODE_ALWAYS = "always",
 | 
			
		||||
    MODE_AS_NEEDED = "as-needed";
 | 
			
		||||
 | 
			
		||||
const validRadixValues = new Set(Array.from({ length: 37 - 2 }, (_, index) => index + 2));
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether a given variable is shadowed or not.
 | 
			
		||||
 * @param {eslint-scope.Variable} variable A variable to check.
 | 
			
		||||
 * @returns {boolean} `true` if the variable is shadowed.
 | 
			
		||||
 */
 | 
			
		||||
function isShadowed(variable) {
 | 
			
		||||
    return variable.defs.length >= 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether a given node is a MemberExpression of `parseInt` method or not.
 | 
			
		||||
 * @param {ASTNode} node A node to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is a MemberExpression of `parseInt`
 | 
			
		||||
 *      method.
 | 
			
		||||
 */
 | 
			
		||||
function isParseIntMethod(node) {
 | 
			
		||||
    return (
 | 
			
		||||
        node.type === "MemberExpression" &&
 | 
			
		||||
        !node.computed &&
 | 
			
		||||
        node.property.type === "Identifier" &&
 | 
			
		||||
        node.property.name === "parseInt"
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether a given node is a valid value of radix or not.
 | 
			
		||||
 *
 | 
			
		||||
 * The following values are invalid.
 | 
			
		||||
 *
 | 
			
		||||
 * - A literal except integers between 2 and 36.
 | 
			
		||||
 * - undefined.
 | 
			
		||||
 * @param {ASTNode} radix A node of radix to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is valid.
 | 
			
		||||
 */
 | 
			
		||||
function isValidRadix(radix) {
 | 
			
		||||
    return !(
 | 
			
		||||
        (radix.type === "Literal" && !validRadixValues.has(radix.value)) ||
 | 
			
		||||
        (radix.type === "Identifier" && radix.name === "undefined")
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Checks whether a given node is a default value of radix or not.
 | 
			
		||||
 * @param {ASTNode} radix A node of radix to check.
 | 
			
		||||
 * @returns {boolean} `true` if the node is the literal node of `10`.
 | 
			
		||||
 */
 | 
			
		||||
function isDefaultRadix(radix) {
 | 
			
		||||
    return radix.type === "Literal" && radix.value === 10;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
// Rule Definition
 | 
			
		||||
//------------------------------------------------------------------------------
 | 
			
		||||
 | 
			
		||||
/** @type {import('../shared/types').Rule} */
 | 
			
		||||
module.exports = {
 | 
			
		||||
    meta: {
 | 
			
		||||
        type: "suggestion",
 | 
			
		||||
 | 
			
		||||
        docs: {
 | 
			
		||||
            description: "Enforce the consistent use of the radix argument when using `parseInt()`",
 | 
			
		||||
            recommended: false,
 | 
			
		||||
            url: "https://eslint.org/docs/latest/rules/radix"
 | 
			
		||||
        },
 | 
			
		||||
 | 
			
		||||
        hasSuggestions: true,
 | 
			
		||||
 | 
			
		||||
        schema: [
 | 
			
		||||
            {
 | 
			
		||||
                enum: ["always", "as-needed"]
 | 
			
		||||
            }
 | 
			
		||||
        ],
 | 
			
		||||
 | 
			
		||||
        messages: {
 | 
			
		||||
            missingParameters: "Missing parameters.",
 | 
			
		||||
            redundantRadix: "Redundant radix parameter.",
 | 
			
		||||
            missingRadix: "Missing radix parameter.",
 | 
			
		||||
            invalidRadix: "Invalid radix parameter, must be an integer between 2 and 36.",
 | 
			
		||||
            addRadixParameter10: "Add radix parameter `10` for parsing decimal numbers."
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    create(context) {
 | 
			
		||||
        const mode = context.options[0] || MODE_ALWAYS;
 | 
			
		||||
        const sourceCode = context.sourceCode;
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Checks the arguments of a given CallExpression node and reports it if it
 | 
			
		||||
         * offends this rule.
 | 
			
		||||
         * @param {ASTNode} node A CallExpression node to check.
 | 
			
		||||
         * @returns {void}
 | 
			
		||||
         */
 | 
			
		||||
        function checkArguments(node) {
 | 
			
		||||
            const args = node.arguments;
 | 
			
		||||
 | 
			
		||||
            switch (args.length) {
 | 
			
		||||
                case 0:
 | 
			
		||||
                    context.report({
 | 
			
		||||
                        node,
 | 
			
		||||
                        messageId: "missingParameters"
 | 
			
		||||
                    });
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                case 1:
 | 
			
		||||
                    if (mode === MODE_ALWAYS) {
 | 
			
		||||
                        context.report({
 | 
			
		||||
                            node,
 | 
			
		||||
                            messageId: "missingRadix",
 | 
			
		||||
                            suggest: [
 | 
			
		||||
                                {
 | 
			
		||||
                                    messageId: "addRadixParameter10",
 | 
			
		||||
                                    fix(fixer) {
 | 
			
		||||
                                        const tokens = sourceCode.getTokens(node);
 | 
			
		||||
                                        const lastToken = tokens[tokens.length - 1]; // Parenthesis.
 | 
			
		||||
                                        const secondToLastToken = tokens[tokens.length - 2]; // May or may not be a comma.
 | 
			
		||||
                                        const hasTrailingComma = secondToLastToken.type === "Punctuator" && secondToLastToken.value === ",";
 | 
			
		||||
 | 
			
		||||
                                        return fixer.insertTextBefore(lastToken, hasTrailingComma ? " 10," : ", 10");
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                            ]
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
 | 
			
		||||
                default:
 | 
			
		||||
                    if (mode === MODE_AS_NEEDED && isDefaultRadix(args[1])) {
 | 
			
		||||
                        context.report({
 | 
			
		||||
                            node,
 | 
			
		||||
                            messageId: "redundantRadix"
 | 
			
		||||
                        });
 | 
			
		||||
                    } else if (!isValidRadix(args[1])) {
 | 
			
		||||
                        context.report({
 | 
			
		||||
                            node,
 | 
			
		||||
                            messageId: "invalidRadix"
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return {
 | 
			
		||||
            "Program:exit"(node) {
 | 
			
		||||
                const scope = sourceCode.getScope(node);
 | 
			
		||||
                let variable;
 | 
			
		||||
 | 
			
		||||
                // Check `parseInt()`
 | 
			
		||||
                variable = astUtils.getVariableByName(scope, "parseInt");
 | 
			
		||||
                if (variable && !isShadowed(variable)) {
 | 
			
		||||
                    variable.references.forEach(reference => {
 | 
			
		||||
                        const idNode = reference.identifier;
 | 
			
		||||
 | 
			
		||||
                        if (astUtils.isCallee(idNode)) {
 | 
			
		||||
                            checkArguments(idNode.parent);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                // Check `Number.parseInt()`
 | 
			
		||||
                variable = astUtils.getVariableByName(scope, "Number");
 | 
			
		||||
                if (variable && !isShadowed(variable)) {
 | 
			
		||||
                    variable.references.forEach(reference => {
 | 
			
		||||
                        const parentNode = reference.identifier.parent;
 | 
			
		||||
                        const maybeCallee = parentNode.parent.type === "ChainExpression"
 | 
			
		||||
                            ? parentNode.parent
 | 
			
		||||
                            : parentNode;
 | 
			
		||||
 | 
			
		||||
                        if (isParseIntMethod(parentNode) && astUtils.isCallee(maybeCallee)) {
 | 
			
		||||
                            checkArguments(maybeCallee.parent);
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user