Actualizacion maquina principal
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / eslint / lib / rules / prefer-numeric-literals.js
1 /**
2  * @fileoverview Rule to disallow `parseInt()` in favor of binary, octal, and hexadecimal literals
3  * @author Annie Zhang, Henry Zhu
4  */
5
6 "use strict";
7
8 //------------------------------------------------------------------------------
9 // Requirements
10 //------------------------------------------------------------------------------
11
12 const astUtils = require("./utils/ast-utils");
13
14 //------------------------------------------------------------------------------
15 // Helpers
16 //------------------------------------------------------------------------------
17
18 const radixMap = new Map([
19     [2, { system: "binary", literalPrefix: "0b" }],
20     [8, { system: "octal", literalPrefix: "0o" }],
21     [16, { system: "hexadecimal", literalPrefix: "0x" }]
22 ]);
23
24 /**
25  * Checks to see if a CallExpression's callee node is `parseInt` or
26  * `Number.parseInt`.
27  * @param {ASTNode} calleeNode The callee node to evaluate.
28  * @returns {boolean} True if the callee is `parseInt` or `Number.parseInt`,
29  * false otherwise.
30  */
31 function isParseInt(calleeNode) {
32     switch (calleeNode.type) {
33         case "Identifier":
34             return calleeNode.name === "parseInt";
35         case "MemberExpression":
36             return calleeNode.object.type === "Identifier" &&
37                 calleeNode.object.name === "Number" &&
38                 calleeNode.property.type === "Identifier" &&
39                 calleeNode.property.name === "parseInt";
40
41         // no default
42     }
43
44     return false;
45 }
46
47 //------------------------------------------------------------------------------
48 // Rule Definition
49 //------------------------------------------------------------------------------
50
51 module.exports = {
52     meta: {
53         type: "suggestion",
54
55         docs: {
56             description: "disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals",
57             category: "ECMAScript 6",
58             recommended: false,
59             url: "https://eslint.org/docs/rules/prefer-numeric-literals"
60         },
61
62         schema: [],
63
64         messages: {
65             useLiteral: "Use {{system}} literals instead of {{functionName}}()."
66         },
67
68         fixable: "code"
69     },
70
71     create(context) {
72         const sourceCode = context.getSourceCode();
73
74         //----------------------------------------------------------------------
75         // Public
76         //----------------------------------------------------------------------
77
78         return {
79
80             "CallExpression[arguments.length=2]"(node) {
81                 const [strNode, radixNode] = node.arguments,
82                     str = strNode.value,
83                     radix = radixNode.value;
84
85                 if (
86                     strNode.type === "Literal" &&
87                     radixNode.type === "Literal" &&
88                     typeof str === "string" &&
89                     typeof radix === "number" &&
90                     radixMap.has(radix) &&
91                     isParseInt(node.callee)
92                 ) {
93
94                     const { system, literalPrefix } = radixMap.get(radix);
95
96                     context.report({
97                         node,
98                         messageId: "useLiteral",
99                         data: {
100                             system,
101                             functionName: sourceCode.getText(node.callee)
102                         },
103                         fix(fixer) {
104                             if (sourceCode.getCommentsInside(node).length) {
105                                 return null;
106                             }
107
108                             const replacement = `${literalPrefix}${str}`;
109
110                             if (+replacement !== parseInt(str, radix)) {
111
112                                 /*
113                                  * If the newly-produced literal would be invalid, (e.g. 0b1234),
114                                  * or it would yield an incorrect parseInt result for some other reason, don't make a fix.
115                                  */
116                                 return null;
117                             }
118
119                             const tokenBefore = sourceCode.getTokenBefore(node),
120                                 tokenAfter = sourceCode.getTokenAfter(node);
121                             let prefix = "",
122                                 suffix = "";
123
124                             if (
125                                 tokenBefore &&
126                                 tokenBefore.range[1] === node.range[0] &&
127                                 !astUtils.canTokensBeAdjacent(tokenBefore, replacement)
128                             ) {
129                                 prefix = " ";
130                             }
131
132                             if (
133                                 tokenAfter &&
134                                 node.range[1] === tokenAfter.range[0] &&
135                                 !astUtils.canTokensBeAdjacent(replacement, tokenAfter)
136                             ) {
137                                 suffix = " ";
138                             }
139
140                             return fixer.replaceText(node, `${prefix}${replacement}${suffix}`);
141                         }
142                     });
143                 }
144             }
145         };
146     }
147 };