eslint-plugin-unicorn-ts 0.0.1-security → 50.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of eslint-plugin-unicorn-ts might be problematic. Click here for more details.

Files changed (214) hide show
  1. package/configs/all.js +6 -0
  2. package/configs/flat-config-base.js +10 -0
  3. package/configs/legacy-config-base.js +10 -0
  4. package/configs/recommended.js +117 -0
  5. package/index.js +91 -0
  6. package/license +9 -0
  7. package/package.json +186 -4
  8. package/readme.md +356 -0
  9. package/rules/ast/call-or-new-expression.js +127 -0
  10. package/rules/ast/function-types.js +5 -0
  11. package/rules/ast/index.js +39 -0
  12. package/rules/ast/is-arrow-function-body.js +7 -0
  13. package/rules/ast/is-empty-node.js +20 -0
  14. package/rules/ast/is-expression-statement.js +11 -0
  15. package/rules/ast/is-function.js +8 -0
  16. package/rules/ast/is-member-expression.js +101 -0
  17. package/rules/ast/is-method-call.js +65 -0
  18. package/rules/ast/is-reference-identifier.js +156 -0
  19. package/rules/ast/is-static-require.js +14 -0
  20. package/rules/ast/is-undefined.js +7 -0
  21. package/rules/ast/literal.js +29 -0
  22. package/rules/better-regex.js +144 -0
  23. package/rules/catch-error-name.js +136 -0
  24. package/rules/consistent-destructuring.js +168 -0
  25. package/rules/consistent-function-scoping.js +223 -0
  26. package/rules/custom-error-definition.js +215 -0
  27. package/rules/empty-brace-spaces.js +72 -0
  28. package/rules/error-message.js +104 -0
  29. package/rules/escape-case.js +63 -0
  30. package/rules/expiring-todo-comments.js +580 -0
  31. package/rules/explicit-length-check.js +229 -0
  32. package/rules/filename-case.js +258 -0
  33. package/rules/fix/add-parenthesizes-to-return-or-throw-expression.js +21 -0
  34. package/rules/fix/append-argument.js +20 -0
  35. package/rules/fix/extend-fix-range.js +15 -0
  36. package/rules/fix/fix-space-around-keywords.js +35 -0
  37. package/rules/fix/index.js +23 -0
  38. package/rules/fix/remove-argument.js +32 -0
  39. package/rules/fix/remove-member-expression-property.js +11 -0
  40. package/rules/fix/remove-method-call.js +20 -0
  41. package/rules/fix/remove-parentheses.js +11 -0
  42. package/rules/fix/remove-spaces-after.js +14 -0
  43. package/rules/fix/rename-variable.js +9 -0
  44. package/rules/fix/replace-argument.js +8 -0
  45. package/rules/fix/replace-node-or-token-and-spaces-before.js +21 -0
  46. package/rules/fix/replace-reference-identifier.js +35 -0
  47. package/rules/fix/replace-string-literal.js +11 -0
  48. package/rules/fix/replace-string-raw.js +14 -0
  49. package/rules/fix/replace-template-element.js +11 -0
  50. package/rules/fix/switch-call-expression-to-new-expression.js +18 -0
  51. package/rules/fix/switch-new-expression-to-call-expression.js +34 -0
  52. package/rules/import-style.js +364 -0
  53. package/rules/new-for-builtins.js +85 -0
  54. package/rules/no-abusive-eslint-disable.js +48 -0
  55. package/rules/no-array-callback-reference.js +256 -0
  56. package/rules/no-array-for-each.js +473 -0
  57. package/rules/no-array-method-this-argument.js +188 -0
  58. package/rules/no-array-push-push.js +144 -0
  59. package/rules/no-array-reduce.js +126 -0
  60. package/rules/no-await-expression-member.js +90 -0
  61. package/rules/no-console-spaces.js +86 -0
  62. package/rules/no-document-cookie.js +25 -0
  63. package/rules/no-empty-file.js +57 -0
  64. package/rules/no-for-loop.js +427 -0
  65. package/rules/no-hex-escape.js +46 -0
  66. package/rules/no-instanceof-array.js +65 -0
  67. package/rules/no-invalid-remove-event-listener.js +60 -0
  68. package/rules/no-keyword-prefix.js +199 -0
  69. package/rules/no-lonely-if.js +151 -0
  70. package/rules/no-negated-condition.js +144 -0
  71. package/rules/no-nested-ternary.js +58 -0
  72. package/rules/no-new-array.js +104 -0
  73. package/rules/no-new-buffer.js +98 -0
  74. package/rules/no-null.js +153 -0
  75. package/rules/no-object-as-default-parameter.js +50 -0
  76. package/rules/no-process-exit.js +104 -0
  77. package/rules/no-static-only-class.js +224 -0
  78. package/rules/no-thenable.js +198 -0
  79. package/rules/no-this-assignment.js +38 -0
  80. package/rules/no-typeof-undefined.js +143 -0
  81. package/rules/no-unnecessary-await.js +107 -0
  82. package/rules/no-unnecessary-polyfills.js +176 -0
  83. package/rules/no-unreadable-array-destructuring.js +83 -0
  84. package/rules/no-unreadable-iife.js +45 -0
  85. package/rules/no-unused-properties.js +238 -0
  86. package/rules/no-useless-fallback-in-spread.js +68 -0
  87. package/rules/no-useless-length-check.js +152 -0
  88. package/rules/no-useless-promise-resolve-reject.js +212 -0
  89. package/rules/no-useless-spread.js +381 -0
  90. package/rules/no-useless-switch-case.js +71 -0
  91. package/rules/no-useless-undefined.js +301 -0
  92. package/rules/no-zero-fractions.js +79 -0
  93. package/rules/number-literal-case.js +52 -0
  94. package/rules/numeric-separators-style.js +181 -0
  95. package/rules/prefer-add-event-listener.js +188 -0
  96. package/rules/prefer-array-find.js +423 -0
  97. package/rules/prefer-array-flat-map.js +82 -0
  98. package/rules/prefer-array-flat.js +279 -0
  99. package/rules/prefer-array-index-of.js +32 -0
  100. package/rules/prefer-array-some.js +157 -0
  101. package/rules/prefer-at.js +374 -0
  102. package/rules/prefer-blob-reading-methods.js +45 -0
  103. package/rules/prefer-code-point.js +67 -0
  104. package/rules/prefer-date-now.js +135 -0
  105. package/rules/prefer-default-parameters.js +219 -0
  106. package/rules/prefer-dom-node-append.js +48 -0
  107. package/rules/prefer-dom-node-dataset.js +120 -0
  108. package/rules/prefer-dom-node-remove.js +122 -0
  109. package/rules/prefer-dom-node-text-content.js +75 -0
  110. package/rules/prefer-event-target.js +117 -0
  111. package/rules/prefer-export-from.js +413 -0
  112. package/rules/prefer-includes.js +98 -0
  113. package/rules/prefer-json-parse-buffer.js +159 -0
  114. package/rules/prefer-keyboard-event-key.js +186 -0
  115. package/rules/prefer-logical-operator-over-ternary.js +159 -0
  116. package/rules/prefer-math-trunc.js +109 -0
  117. package/rules/prefer-modern-dom-apis.js +141 -0
  118. package/rules/prefer-modern-math-apis.js +212 -0
  119. package/rules/prefer-module.js +349 -0
  120. package/rules/prefer-native-coercion-functions.js +185 -0
  121. package/rules/prefer-negative-index.js +213 -0
  122. package/rules/prefer-node-protocol.js +61 -0
  123. package/rules/prefer-number-properties.js +126 -0
  124. package/rules/prefer-object-from-entries.js +252 -0
  125. package/rules/prefer-optional-catch-binding.js +75 -0
  126. package/rules/prefer-prototype-methods.js +88 -0
  127. package/rules/prefer-query-selector.js +135 -0
  128. package/rules/prefer-reflect-apply.js +97 -0
  129. package/rules/prefer-regexp-test.js +156 -0
  130. package/rules/prefer-set-has.js +186 -0
  131. package/rules/prefer-set-size.js +103 -0
  132. package/rules/prefer-spread.js +529 -0
  133. package/rules/prefer-string-replace-all.js +145 -0
  134. package/rules/prefer-string-slice.js +182 -0
  135. package/rules/prefer-string-starts-ends-with.js +199 -0
  136. package/rules/prefer-string-trim-start-end.js +44 -0
  137. package/rules/prefer-switch.js +344 -0
  138. package/rules/prefer-ternary.js +282 -0
  139. package/rules/prefer-top-level-await.js +152 -0
  140. package/rules/prefer-type-error.js +151 -0
  141. package/rules/prevent-abbreviations.js +645 -0
  142. package/rules/relative-url-style.js +168 -0
  143. package/rules/require-array-join-separator.js +63 -0
  144. package/rules/require-number-to-fixed-digits-argument.js +54 -0
  145. package/rules/require-post-message-target-origin.js +71 -0
  146. package/rules/shared/abbreviations.js +262 -0
  147. package/rules/shared/dom-events.js +275 -0
  148. package/rules/shared/event-keys.js +52 -0
  149. package/rules/shared/negative-index.js +46 -0
  150. package/rules/shared/simple-array-search-rule.js +128 -0
  151. package/rules/shared/typed-array.js +16 -0
  152. package/rules/string-content.js +187 -0
  153. package/rules/switch-case-braces.js +109 -0
  154. package/rules/template-indent.js +219 -0
  155. package/rules/text-encoding-identifier-case.js +108 -0
  156. package/rules/throw-new-error.js +53 -0
  157. package/rules/utils/array-or-object-prototype-property.js +63 -0
  158. package/rules/utils/assert-token.js +32 -0
  159. package/rules/utils/avoid-capture.js +146 -0
  160. package/rules/utils/boolean.js +92 -0
  161. package/rules/utils/builtins.js +36 -0
  162. package/rules/utils/cartesian-product-samples.js +24 -0
  163. package/rules/utils/create-deprecated-rules.js +25 -0
  164. package/rules/utils/escape-string.js +26 -0
  165. package/rules/utils/escape-template-element-raw.js +6 -0
  166. package/rules/utils/get-ancestor.js +20 -0
  167. package/rules/utils/get-builtin-rule.js +7 -0
  168. package/rules/utils/get-call-expression-arguments-text.js +21 -0
  169. package/rules/utils/get-class-head-location.js +22 -0
  170. package/rules/utils/get-documentation-url.js +10 -0
  171. package/rules/utils/get-indent-string.js +11 -0
  172. package/rules/utils/get-previous-node.js +24 -0
  173. package/rules/utils/get-references.js +9 -0
  174. package/rules/utils/get-scopes.js +14 -0
  175. package/rules/utils/get-switch-case-head-location.js +21 -0
  176. package/rules/utils/get-variable-identifiers.js +7 -0
  177. package/rules/utils/global-reference-tracker.js +72 -0
  178. package/rules/utils/has-optional-chain-element.js +21 -0
  179. package/rules/utils/has-same-range.js +7 -0
  180. package/rules/utils/index.js +53 -0
  181. package/rules/utils/is-function-self-used-inside.js +43 -0
  182. package/rules/utils/is-left-hand-side.js +22 -0
  183. package/rules/utils/is-logical-expression.js +16 -0
  184. package/rules/utils/is-method-named.js +9 -0
  185. package/rules/utils/is-new-expression-with-parentheses.js +26 -0
  186. package/rules/utils/is-node-matches.js +53 -0
  187. package/rules/utils/is-node-value-not-dom-node.js +21 -0
  188. package/rules/utils/is-node-value-not-function.js +42 -0
  189. package/rules/utils/is-number.js +224 -0
  190. package/rules/utils/is-object-method.js +11 -0
  191. package/rules/utils/is-on-same-line.js +7 -0
  192. package/rules/utils/is-same-identifier.js +8 -0
  193. package/rules/utils/is-same-reference.js +173 -0
  194. package/rules/utils/is-shadowed.js +33 -0
  195. package/rules/utils/is-shorthand-export-local.js +9 -0
  196. package/rules/utils/is-shorthand-import-local.js +9 -0
  197. package/rules/utils/is-shorthand-property-assignment-pattern-left.js +10 -0
  198. package/rules/utils/is-shorthand-property-value.js +8 -0
  199. package/rules/utils/is-value-not-usable.js +5 -0
  200. package/rules/utils/lodash.js +1589 -0
  201. package/rules/utils/needs-semicolon.js +114 -0
  202. package/rules/utils/numeric.js +53 -0
  203. package/rules/utils/parentheses.js +73 -0
  204. package/rules/utils/resolve-variable-name.js +20 -0
  205. package/rules/utils/rule.js +190 -0
  206. package/rules/utils/should-add-parentheses-to-conditional-expression-child.js +17 -0
  207. package/rules/utils/should-add-parentheses-to-expression-statement-expression.js +26 -0
  208. package/rules/utils/should-add-parentheses-to-logical-expression-child.js +47 -0
  209. package/rules/utils/should-add-parentheses-to-member-expression-object.js +47 -0
  210. package/rules/utils/should-add-parentheses-to-new-expression-callee.js +32 -0
  211. package/rules/utils/should-add-parentheses-to-spread-element-argument.js +22 -0
  212. package/rules/utils/singular.js +18 -0
  213. package/rules/utils/to-location.js +21 -0
  214. package/README.md +0 -5
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ isParenthesized,
5
+ getParenthesizedTimes,
6
+ getParentheses,
7
+ getParenthesizedRange,
8
+ getParenthesizedText,
9
+ } = require('./parentheses.js');
10
+ const {
11
+ isArrayPrototypeProperty,
12
+ isObjectPrototypeProperty,
13
+ } = require('./array-or-object-prototype-property.js');
14
+ const {isNodeMatches, isNodeMatchesNameOrPath} = require('./is-node-matches.js');
15
+ const {isBooleanNode, getBooleanAncestor} = require('./boolean.js');
16
+
17
+ module.exports = {
18
+ avoidCapture: require('./avoid-capture.js'),
19
+ escapeString: require('./escape-string.js'),
20
+ getBooleanAncestor,
21
+ getParentheses,
22
+ getParenthesizedRange,
23
+ getParenthesizedText,
24
+ getParenthesizedTimes,
25
+ getReferences: require('./get-references.js'),
26
+ getScopes: require('./get-scopes.js'),
27
+ getVariableIdentifiers: require('./get-variable-identifiers.js'),
28
+ hasOptionalChainElement: require('./has-optional-chain-element.js'),
29
+ isArrayPrototypeProperty,
30
+ isBooleanNode,
31
+ isFunctionSelfUsedInside: require('./is-function-self-used-inside.js'),
32
+ isLeftHandSide: require('./is-left-hand-side.js'),
33
+ isLogicalExpression: require('./is-logical-expression.js'),
34
+ isMethodNamed: require('./is-method-named.js'),
35
+ isNodeMatches,
36
+ isNodeMatchesNameOrPath,
37
+ isNodeValueNotDomNode: require('./is-node-value-not-dom-node.js'),
38
+ isNodeValueNotFunction: require('./is-node-value-not-function.js'),
39
+ isObjectPrototypeProperty,
40
+ isOnSameLine: require('./is-on-same-line.js'),
41
+ isParenthesized,
42
+ isSameIdentifier: require('./is-same-identifier.js'),
43
+ isSameReference: require('./is-same-reference.js'),
44
+ isShadowed: require('./is-shadowed.js'),
45
+ isValueNotUsable: require('./is-value-not-usable.js'),
46
+ needsSemicolon: require('./needs-semicolon.js'),
47
+ shouldAddParenthesesToMemberExpressionObject: require('./should-add-parentheses-to-member-expression-object.js'),
48
+ shouldAddParenthesesToSpreadElementArgument: require('./should-add-parentheses-to-spread-element-argument.js'),
49
+ singular: require('./singular.js'),
50
+ toLocation: require('./to-location.js'),
51
+ getAncestor: require('./get-ancestor.js'),
52
+ };
53
+
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+ const {findVariable} = require('@eslint-community/eslint-utils');
3
+
4
+ const getReferences = (scope, nodeOrName) => {
5
+ const {references = []} = findVariable(scope, nodeOrName) || {};
6
+ return references;
7
+ };
8
+
9
+ /**
10
+ Check if `this`, `arguments`, or the function name is used inside of itself.
11
+
12
+ @param {Node} functionNode - The function node.
13
+ @param {Scope} functionScope - The scope of the function node.
14
+ @returns {boolean}
15
+ */
16
+ function isFunctionSelfUsedInside(functionNode, functionScope) {
17
+ /* c8 ignore next 3 */
18
+ if (functionScope.block !== functionNode) {
19
+ throw new Error('"functionScope" should be the scope of "functionNode".');
20
+ }
21
+
22
+ const {type, id} = functionNode;
23
+
24
+ if (type === 'ArrowFunctionExpression') {
25
+ return false;
26
+ }
27
+
28
+ if (functionScope.thisFound) {
29
+ return true;
30
+ }
31
+
32
+ if (getReferences(functionScope, 'arguments').some(({from}) => from === functionScope)) {
33
+ return true;
34
+ }
35
+
36
+ if (id && getReferences(functionScope, id).length > 0) {
37
+ return true;
38
+ }
39
+
40
+ return false;
41
+ }
42
+
43
+ module.exports = isFunctionSelfUsedInside;
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ const isLeftHandSide = node =>
4
+ (
5
+ (node.parent.type === 'AssignmentExpression' || node.parent.type === 'AssignmentPattern')
6
+ && node.parent.left === node
7
+ )
8
+ || (node.parent.type === 'UpdateExpression' && node.parent.argument === node)
9
+ || (node.parent.type === 'ArrayPattern' && node.parent.elements.includes(node))
10
+ || (
11
+ node.parent.type === 'Property'
12
+ && node.parent.value === node
13
+ && node.parent.parent.type === 'ObjectPattern'
14
+ && node.parent.parent.properties.includes(node.parent)
15
+ )
16
+ || (
17
+ node.parent.type === 'UnaryExpression'
18
+ && node.parent.operator === 'delete'
19
+ && node.parent.argument === node
20
+ );
21
+
22
+ module.exports = isLeftHandSide;
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ Check if the given node is a true logical expression or not.
5
+
6
+ The three binary expressions logical-or (`||`), logical-and (`&&`), and coalesce (`??`) are known as `ShortCircuitExpression`, but ESTree represents these by the `LogicalExpression` node type. This function rejects coalesce expressions of `LogicalExpression` node type.
7
+
8
+ @param {Node} node - The node to check.
9
+ @returns {boolean} `true` if the node is `&&` or `||`.
10
+ @see https://tc39.es/ecma262/#prod-ShortCircuitExpression
11
+ */
12
+ const isLogicalExpression = node =>
13
+ node?.type === 'LogicalExpression'
14
+ && (node.operator === '&&' || node.operator === '||');
15
+
16
+ module.exports = isLogicalExpression;
@@ -0,0 +1,9 @@
1
+ 'use strict';
2
+
3
+ const isMethodNamed = (node, name) =>
4
+ node.type === 'CallExpression'
5
+ && node.callee.type === 'MemberExpression'
6
+ && node.callee.property.type === 'Identifier'
7
+ && node.callee.property.name === name;
8
+
9
+ module.exports = isMethodNamed;
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ const {isOpeningParenToken, isClosingParenToken} = require('@eslint-community/eslint-utils');
4
+
5
+ /**
6
+ Determine if a constructor function is newed-up with parens.
7
+
8
+ @param {Node} node - The `NewExpression` node to be checked.
9
+ @param {SourceCode} sourceCode - The source code object.
10
+ @returns {boolean} True if the constructor is called with parens.
11
+
12
+ Copied from https://github.com/eslint/eslint/blob/cc4871369645c3409dc56ded7a555af8a9f63d51/lib/rules/no-extra-parens.js#L252
13
+ */
14
+ function isNewExpressionWithParentheses(node, sourceCode) {
15
+ if (node.arguments.length > 0) {
16
+ return true;
17
+ }
18
+
19
+ const [penultimateToken, lastToken] = sourceCode.getLastTokens(node, 2);
20
+ // The expression should end with its own parens, for example, `new new Foo()` is not a new expression with parens.
21
+ return isOpeningParenToken(penultimateToken)
22
+ && isClosingParenToken(lastToken)
23
+ && node.callee.range[1] < node.range[1];
24
+ }
25
+
26
+ module.exports = isNewExpressionWithParentheses;
@@ -0,0 +1,53 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ Check if node matches object name or key path.
5
+
6
+ @param {Node} node - The AST node to check.
7
+ @param {string} nameOrPath - The object name or key path.
8
+ @returns {boolean}
9
+ */
10
+ function isNodeMatchesNameOrPath(node, nameOrPath) {
11
+ const names = nameOrPath.trim().split('.');
12
+ for (let index = names.length - 1; index >= 0; index--) {
13
+ const name = names[index];
14
+ if (!name) {
15
+ return false;
16
+ }
17
+
18
+ if (index === 0) {
19
+ return (
20
+ (node.type === 'Identifier' && node.name === name)
21
+ || (name === 'this' && node.type === 'ThisExpression')
22
+ );
23
+ }
24
+
25
+ if (
26
+ node.type !== 'MemberExpression'
27
+ || node.optional
28
+ || node.computed
29
+ || node.property.type !== 'Identifier'
30
+ || node.property.name !== name
31
+ ) {
32
+ return false;
33
+ }
34
+
35
+ node = node.object;
36
+ }
37
+ }
38
+
39
+ /**
40
+ Check if node matches any object name or key path.
41
+
42
+ @param {Node} node - The AST node to check.
43
+ @param {string[]} nameOrPaths - The object name or key paths.
44
+ @returns {boolean}
45
+ */
46
+ function isNodeMatches(node, nameOrPaths) {
47
+ return nameOrPaths.some(nameOrPath => isNodeMatchesNameOrPath(node, nameOrPath));
48
+ }
49
+
50
+ module.exports = {
51
+ isNodeMatchesNameOrPath,
52
+ isNodeMatches,
53
+ };
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+ const {isUndefined} = require('../ast/index.js');
3
+
4
+ // AST Types:
5
+ // https://github.com/eslint/espree/blob/master/lib/ast-node-types.js#L18
6
+ // Only types possible to be `callee` or `argument` are listed
7
+ const impossibleNodeTypes = new Set([
8
+ 'ArrayExpression',
9
+ 'ArrowFunctionExpression',
10
+ 'ClassExpression',
11
+ 'FunctionExpression',
12
+ 'Literal',
13
+ 'ObjectExpression',
14
+ 'TemplateLiteral',
15
+ ]);
16
+
17
+ const isNodeValueNotDomNode = node =>
18
+ impossibleNodeTypes.has(node.type)
19
+ || isUndefined(node);
20
+
21
+ module.exports = isNodeValueNotDomNode;
@@ -0,0 +1,42 @@
1
+ 'use strict';
2
+ const {isUndefined, isCallExpression, isMethodCall} = require('../ast/index.js');
3
+
4
+ // AST Types:
5
+ // https://github.com/eslint/espree/blob/master/lib/ast-node-types.js#L18
6
+ // Only types possible to be `argument` are listed
7
+ const impossibleNodeTypes = new Set([
8
+ 'ArrayExpression',
9
+ 'BinaryExpression',
10
+ 'ClassExpression',
11
+ 'Literal',
12
+ 'ObjectExpression',
13
+ 'TemplateLiteral',
14
+ 'UnaryExpression',
15
+ 'UpdateExpression',
16
+ ]);
17
+
18
+ // Technically these nodes could be a function, but most likely not
19
+ const mostLikelyNotNodeTypes = new Set([
20
+ 'AssignmentExpression',
21
+ 'AwaitExpression',
22
+ 'LogicalExpression',
23
+ 'NewExpression',
24
+ 'TaggedTemplateExpression',
25
+ 'ThisExpression',
26
+ ]);
27
+
28
+ const isNodeValueNotFunction = node => (
29
+ impossibleNodeTypes.has(node.type)
30
+ || mostLikelyNotNodeTypes.has(node.type)
31
+ || isUndefined(node)
32
+ || (
33
+ isCallExpression(node)
34
+ && !(isMethodCall(node, {
35
+ method: 'bind',
36
+ optionalCall: false,
37
+ optionalMember: false,
38
+ }))
39
+ )
40
+ );
41
+
42
+ module.exports = isNodeValueNotFunction;
@@ -0,0 +1,224 @@
1
+ 'use strict';
2
+ const {getStaticValue} = require('@eslint-community/eslint-utils');
3
+ const {isNumberLiteral} = require('../ast/index.js');
4
+
5
+ const isStaticProperties = (node, object, properties) =>
6
+ node.type === 'MemberExpression'
7
+ && !node.computed
8
+ && !node.optional
9
+ && node.object.type === 'Identifier'
10
+ && node.object.name === object
11
+ && node.property.type === 'Identifier'
12
+ && properties.has(node.property.name);
13
+ const isFunctionCall = (node, functionName) => node.type === 'CallExpression'
14
+ && !node.optional
15
+ && node.callee.type === 'Identifier'
16
+ && node.callee.name === functionName;
17
+
18
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#static_properties
19
+ const mathProperties = new Set([
20
+ 'E',
21
+ 'LN2',
22
+ 'LN10',
23
+ 'LOG2E',
24
+ 'LOG10E',
25
+ 'PI',
26
+ 'SQRT1_2',
27
+ 'SQRT2',
28
+ ]);
29
+
30
+ // `Math.{E,LN2,LN10,LOG2E,LOG10E,PI,SQRT1_2,SQRT2}`
31
+ const isMathProperty = node => isStaticProperties(node, 'Math', mathProperties);
32
+
33
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math#static_methods
34
+ const mathMethods = new Set([
35
+ 'abs',
36
+ 'acos',
37
+ 'acosh',
38
+ 'asin',
39
+ 'asinh',
40
+ 'atan',
41
+ 'atanh',
42
+ 'atan2',
43
+ 'cbrt',
44
+ 'ceil',
45
+ 'clz32',
46
+ 'cos',
47
+ 'cosh',
48
+ 'exp',
49
+ 'expm1',
50
+ 'floor',
51
+ 'fround',
52
+ 'hypot',
53
+ 'imul',
54
+ 'log',
55
+ 'log1p',
56
+ 'log10',
57
+ 'log2',
58
+ 'max',
59
+ 'min',
60
+ 'pow',
61
+ 'random',
62
+ 'round',
63
+ 'sign',
64
+ 'sin',
65
+ 'sinh',
66
+ 'sqrt',
67
+ 'tan',
68
+ 'tanh',
69
+ 'trunc',
70
+ ]);
71
+ // `Math.{abs, …, trunc}(…)`
72
+ const isMathMethodCall = node =>
73
+ node.type === 'CallExpression'
74
+ && !node.optional
75
+ && isStaticProperties(node.callee, 'Math', mathMethods);
76
+
77
+ // `Number(…)`
78
+ const isNumberCall = node => isFunctionCall(node, 'Number');
79
+
80
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#static_properties
81
+ const numberProperties = new Set([
82
+ 'EPSILON',
83
+ 'MAX_SAFE_INTEGER',
84
+ 'MAX_VALUE',
85
+ 'MIN_SAFE_INTEGER',
86
+ 'MIN_VALUE',
87
+ 'NaN',
88
+ 'NEGATIVE_INFINITY',
89
+ 'POSITIVE_INFINITY',
90
+ ]);
91
+ const isNumberProperty = node => isStaticProperties(node, 'Number', numberProperties);
92
+
93
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#static_methods
94
+ const numberMethods = new Set([
95
+ 'parseFloat',
96
+ 'parseInt',
97
+ ]);
98
+ const isNumberMethodCall = node =>
99
+ node.type === 'CallExpression'
100
+ && !node.optional
101
+ && isStaticProperties(node.callee, 'Number', numberMethods);
102
+ const isGlobalParseToNumberFunctionCall = node => isFunctionCall(node, 'parseInt') || isFunctionCall(node, 'parseFloat');
103
+
104
+ const isStaticNumber = (node, scope) =>
105
+ typeof getStaticValue(node, scope)?.value === 'number';
106
+
107
+ const isLengthProperty = node =>
108
+ node.type === 'MemberExpression'
109
+ && !node.computed
110
+ && !node.optional
111
+ && node.property.type === 'Identifier'
112
+ && node.property.name === 'length';
113
+
114
+ // `+` and `>>>` operators are handled separately
115
+ const mathOperators = new Set(['-', '*', '/', '%', '**', '<<', '>>', '|', '^', '&']);
116
+ function isNumber(node, scope) {
117
+ if (
118
+ isNumberLiteral(node)
119
+ || isMathProperty(node)
120
+ || isMathMethodCall(node)
121
+ || isNumberCall(node)
122
+ || isNumberProperty(node)
123
+ || isNumberMethodCall(node)
124
+ || isGlobalParseToNumberFunctionCall(node)
125
+ || isLengthProperty(node)
126
+ ) {
127
+ return true;
128
+ }
129
+
130
+ switch (node.type) {
131
+ case 'AssignmentExpression': {
132
+ const {operator} = node;
133
+ if (operator === '=' && isNumber(node.right, scope)) {
134
+ return true;
135
+ }
136
+
137
+ // Fall through
138
+ }
139
+
140
+ case 'BinaryExpression': {
141
+ let {operator} = node;
142
+
143
+ if (node.type === 'AssignmentExpression') {
144
+ operator = operator.slice(0, -1);
145
+ }
146
+
147
+ if (operator === '+' && isNumber(node.left, scope) && isNumber(node.right, scope)) {
148
+ return true;
149
+ }
150
+
151
+ // `>>>` (zero-fill right shift) can't use on `BigInt`
152
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#operators
153
+ if (operator === '>>>') {
154
+ return true;
155
+ }
156
+
157
+ // `a * b` can be `BigInt`, we need make sure at least one side is number
158
+ if (mathOperators.has(operator) && (isNumber(node.left, scope) || isNumber(node.right, scope))) {
159
+ return true;
160
+ }
161
+
162
+ break;
163
+ }
164
+
165
+ case 'UnaryExpression': {
166
+ const {operator} = node;
167
+
168
+ // `+` can't use on `BigInt`
169
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#operators
170
+ if (operator === '+') {
171
+ return true;
172
+ }
173
+
174
+ if ((operator === '-' || operator === '~') && isNumber(node.argument, scope)) {
175
+ return true;
176
+ }
177
+
178
+ break;
179
+ }
180
+
181
+ case 'UpdateExpression': {
182
+ if (isNumber(node.argument, scope)) {
183
+ return true;
184
+ }
185
+
186
+ break;
187
+ }
188
+
189
+ case 'ConditionalExpression': {
190
+ const isConsequentNumber = isNumber(node.consequent, scope);
191
+ const isAlternateNumber = isNumber(node.alternate, scope);
192
+
193
+ if (isConsequentNumber && isAlternateNumber) {
194
+ return true;
195
+ }
196
+
197
+ const testStaticValueResult = getStaticValue(node.test, scope);
198
+ if (
199
+ testStaticValueResult !== null
200
+ && (
201
+ (testStaticValueResult.value && isConsequentNumber)
202
+ || (!testStaticValueResult.value && isAlternateNumber)
203
+ )
204
+ ) {
205
+ return true;
206
+ }
207
+
208
+ break;
209
+ }
210
+
211
+ case 'SequenceExpression': {
212
+ if (isNumber(node.expressions.at(-1), scope)) {
213
+ return true;
214
+ }
215
+
216
+ break;
217
+ }
218
+ // No default
219
+ }
220
+
221
+ return isStaticNumber(node, scope);
222
+ }
223
+
224
+ module.exports = isNumber;
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+ module.exports = (node, object, method) => {
3
+ const {callee} = node;
4
+ return (
5
+ callee.type === 'MemberExpression'
6
+ && callee.object.type === 'Identifier'
7
+ && callee.object.name === object
8
+ && callee.property.type === 'Identifier'
9
+ && callee.property.name === method
10
+ );
11
+ };
@@ -0,0 +1,7 @@
1
+ 'use strict';
2
+
3
+ function isOnSameLine(nodeOrTokenA, nodeOrTokenB) {
4
+ return nodeOrTokenA.loc.start.line === nodeOrTokenB.loc.start.line;
5
+ }
6
+
7
+ module.exports = isOnSameLine;
@@ -0,0 +1,8 @@
1
+ 'use strict';
2
+
3
+ const isSameIdentifier = (nodeA, nodeB) =>
4
+ nodeA.type === 'Identifier'
5
+ && nodeB.type === 'Identifier'
6
+ && nodeA.name === nodeB.name;
7
+
8
+ module.exports = isSameIdentifier;