]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/radix.js
2 * @fileoverview Rule to flag use of parseInt without a radix argument
3 * @author James Allardice
8 //------------------------------------------------------------------------------
10 //------------------------------------------------------------------------------
12 const astUtils
= require("./utils/ast-utils");
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
18 const MODE_ALWAYS
= "always",
19 MODE_AS_NEEDED
= "as-needed";
21 const validRadixValues
= new Set(Array
.from({ length
: 37 - 2 }, (_
, index
) => index
+ 2));
24 * Checks whether a given variable is shadowed or not.
25 * @param {eslint-scope.Variable} variable A variable to check.
26 * @returns {boolean} `true` if the variable is shadowed.
28 function isShadowed(variable
) {
29 return variable
.defs
.length
>= 1;
33 * Checks whether a given node is a MemberExpression of `parseInt` method or not.
34 * @param {ASTNode} node A node to check.
35 * @returns {boolean} `true` if the node is a MemberExpression of `parseInt`
38 function isParseIntMethod(node
) {
40 node
.type
=== "MemberExpression" &&
42 node
.property
.type
=== "Identifier" &&
43 node
.property
.name
=== "parseInt"
48 * Checks whether a given node is a valid value of radix or not.
50 * The following values are invalid.
52 * - A literal except integers between 2 and 36.
54 * @param {ASTNode} radix A node of radix to check.
55 * @returns {boolean} `true` if the node is valid.
57 function isValidRadix(radix
) {
59 (radix
.type
=== "Literal" && !validRadixValues
.has(radix
.value
)) ||
60 (radix
.type
=== "Identifier" && radix
.name
=== "undefined")
65 * Checks whether a given node is a default value of radix or not.
66 * @param {ASTNode} radix A node of radix to check.
67 * @returns {boolean} `true` if the node is the literal node of `10`.
69 function isDefaultRadix(radix
) {
70 return radix
.type
=== "Literal" && radix
.value
=== 10;
73 //------------------------------------------------------------------------------
75 //------------------------------------------------------------------------------
82 description
: "enforce the consistent use of the radix argument when using `parseInt()`",
83 category
: "Best Practices",
85 url
: "https://eslint.org/docs/rules/radix"
90 enum: ["always", "as-needed"]
95 missingParameters
: "Missing parameters.",
96 redundantRadix
: "Redundant radix parameter.",
97 missingRadix
: "Missing radix parameter.",
98 invalidRadix
: "Invalid radix parameter, must be an integer between 2 and 36."
103 const mode
= context
.options
[0] || MODE_ALWAYS
;
106 * Checks the arguments of a given CallExpression node and reports it if it
108 * @param {ASTNode} node A CallExpression node to check.
111 function checkArguments(node
) {
112 const args
= node
.arguments
;
114 switch (args
.length
) {
118 messageId
: "missingParameters"
123 if (mode
=== MODE_ALWAYS
) {
126 messageId
: "missingRadix"
132 if (mode
=== MODE_AS_NEEDED
&& isDefaultRadix(args
[1])) {
135 messageId
: "redundantRadix"
137 } else if (!isValidRadix(args
[1])) {
140 messageId
: "invalidRadix"
149 const scope
= context
.getScope();
152 // Check `parseInt()`
153 variable
= astUtils
.getVariableByName(scope
, "parseInt");
154 if (variable
&& !isShadowed(variable
)) {
155 variable
.references
.forEach(reference
=> {
156 const node
= reference
.identifier
;
158 if (astUtils
.isCallee(node
)) {
159 checkArguments(node
.parent
);
164 // Check `Number.parseInt()`
165 variable
= astUtils
.getVariableByName(scope
, "Number");
166 if (variable
&& !isShadowed(variable
)) {
167 variable
.references
.forEach(reference
=> {
168 const node
= reference
.identifier
.parent
;
169 const maybeCallee
= node
.parent
.type
=== "ChainExpression"
173 if (isParseIntMethod(node
) && astUtils
.isCallee(maybeCallee
)) {
174 checkArguments(maybeCallee
.parent
);