eslint 8.2.0 → 8.5.0

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.
Files changed (304) hide show
  1. package/README.md +7 -11
  2. package/conf/globals.js +144 -0
  3. package/lib/cli.js +1 -1
  4. package/lib/config/default-config.js +11 -2
  5. package/lib/config/flat-config-array.js +2 -2
  6. package/lib/config/flat-config-helpers.js +67 -0
  7. package/lib/config/flat-config-schema.js +13 -8
  8. package/lib/config/rule-validator.js +28 -27
  9. package/lib/eslint/eslint.js +11 -3
  10. package/lib/linter/code-path-analysis/code-path-analyzer.js +6 -1
  11. package/lib/linter/code-path-analysis/code-path.js +1 -1
  12. package/lib/linter/linter.js +457 -45
  13. package/lib/options.js +6 -6
  14. package/lib/rule-tester/rule-tester.js +14 -0
  15. package/lib/rules/accessor-pairs.js +1 -0
  16. package/lib/rules/array-bracket-newline.js +1 -0
  17. package/lib/rules/array-bracket-spacing.js +1 -0
  18. package/lib/rules/array-callback-return.js +1 -0
  19. package/lib/rules/array-element-newline.js +1 -0
  20. package/lib/rules/arrow-body-style.js +1 -0
  21. package/lib/rules/arrow-parens.js +1 -0
  22. package/lib/rules/arrow-spacing.js +1 -0
  23. package/lib/rules/block-scoped-var.js +3 -0
  24. package/lib/rules/block-spacing.js +11 -3
  25. package/lib/rules/brace-style.js +7 -0
  26. package/lib/rules/callback-return.js +1 -0
  27. package/lib/rules/camelcase.js +1 -0
  28. package/lib/rules/capitalized-comments.js +1 -0
  29. package/lib/rules/class-methods-use-this.js +11 -1
  30. package/lib/rules/comma-dangle.js +1 -0
  31. package/lib/rules/comma-spacing.js +1 -0
  32. package/lib/rules/comma-style.js +1 -0
  33. package/lib/rules/complexity.js +15 -6
  34. package/lib/rules/computed-property-spacing.js +1 -0
  35. package/lib/rules/consistent-return.js +1 -0
  36. package/lib/rules/consistent-this.js +1 -0
  37. package/lib/rules/constructor-super.js +1 -0
  38. package/lib/rules/curly.js +1 -0
  39. package/lib/rules/default-case-last.js +1 -0
  40. package/lib/rules/default-case.js +1 -0
  41. package/lib/rules/default-param-last.js +1 -0
  42. package/lib/rules/dot-location.js +1 -0
  43. package/lib/rules/dot-notation.js +1 -0
  44. package/lib/rules/eol-last.js +1 -0
  45. package/lib/rules/eqeqeq.js +1 -0
  46. package/lib/rules/for-direction.js +1 -0
  47. package/lib/rules/func-call-spacing.js +1 -0
  48. package/lib/rules/func-name-matching.js +1 -0
  49. package/lib/rules/func-names.js +1 -0
  50. package/lib/rules/func-style.js +1 -0
  51. package/lib/rules/function-call-argument-newline.js +1 -0
  52. package/lib/rules/function-paren-newline.js +1 -0
  53. package/lib/rules/generator-star-spacing.js +1 -0
  54. package/lib/rules/getter-return.js +1 -0
  55. package/lib/rules/global-require.js +1 -0
  56. package/lib/rules/grouped-accessor-pairs.js +1 -0
  57. package/lib/rules/guard-for-in.js +1 -0
  58. package/lib/rules/handle-callback-err.js +1 -0
  59. package/lib/rules/id-blacklist.js +1 -0
  60. package/lib/rules/id-denylist.js +1 -0
  61. package/lib/rules/id-length.js +1 -0
  62. package/lib/rules/id-match.js +24 -0
  63. package/lib/rules/implicit-arrow-linebreak.js +1 -0
  64. package/lib/rules/indent-legacy.js +1 -0
  65. package/lib/rules/indent.js +22 -0
  66. package/lib/rules/index.js +1 -0
  67. package/lib/rules/init-declarations.js +1 -0
  68. package/lib/rules/jsx-quotes.js +1 -0
  69. package/lib/rules/key-spacing.js +1 -0
  70. package/lib/rules/keyword-spacing.js +2 -0
  71. package/lib/rules/line-comment-position.js +1 -0
  72. package/lib/rules/linebreak-style.js +1 -0
  73. package/lib/rules/lines-around-comment.js +55 -7
  74. package/lib/rules/lines-around-directive.js +1 -0
  75. package/lib/rules/lines-between-class-members.js +1 -0
  76. package/lib/rules/max-classes-per-file.js +1 -0
  77. package/lib/rules/max-depth.js +3 -0
  78. package/lib/rules/max-len.js +1 -0
  79. package/lib/rules/max-lines-per-function.js +1 -0
  80. package/lib/rules/max-lines.js +1 -0
  81. package/lib/rules/max-nested-callbacks.js +1 -0
  82. package/lib/rules/max-params.js +1 -0
  83. package/lib/rules/max-statements-per-line.js +1 -0
  84. package/lib/rules/max-statements.js +11 -0
  85. package/lib/rules/multiline-comment-style.js +1 -0
  86. package/lib/rules/multiline-ternary.js +1 -0
  87. package/lib/rules/new-cap.js +1 -0
  88. package/lib/rules/new-parens.js +1 -0
  89. package/lib/rules/newline-after-var.js +1 -0
  90. package/lib/rules/newline-before-return.js +1 -0
  91. package/lib/rules/newline-per-chained-call.js +1 -0
  92. package/lib/rules/no-alert.js +1 -0
  93. package/lib/rules/no-array-constructor.js +1 -0
  94. package/lib/rules/no-async-promise-executor.js +1 -0
  95. package/lib/rules/no-await-in-loop.js +1 -0
  96. package/lib/rules/no-bitwise.js +1 -0
  97. package/lib/rules/no-buffer-constructor.js +1 -0
  98. package/lib/rules/no-caller.js +1 -0
  99. package/lib/rules/no-case-declarations.js +1 -0
  100. package/lib/rules/no-catch-shadow.js +1 -0
  101. package/lib/rules/no-class-assign.js +1 -0
  102. package/lib/rules/no-compare-neg-zero.js +1 -0
  103. package/lib/rules/no-cond-assign.js +1 -0
  104. package/lib/rules/no-confusing-arrow.js +1 -0
  105. package/lib/rules/no-console.js +1 -0
  106. package/lib/rules/no-const-assign.js +1 -0
  107. package/lib/rules/no-constant-condition.js +4 -1
  108. package/lib/rules/no-constructor-return.js +1 -0
  109. package/lib/rules/no-continue.js +1 -0
  110. package/lib/rules/no-control-regex.js +1 -0
  111. package/lib/rules/no-debugger.js +1 -0
  112. package/lib/rules/no-delete-var.js +1 -0
  113. package/lib/rules/no-div-regex.js +1 -0
  114. package/lib/rules/no-dupe-args.js +1 -0
  115. package/lib/rules/no-dupe-class-members.js +1 -0
  116. package/lib/rules/no-dupe-else-if.js +1 -0
  117. package/lib/rules/no-dupe-keys.js +1 -0
  118. package/lib/rules/no-duplicate-case.js +1 -0
  119. package/lib/rules/no-duplicate-imports.js +1 -0
  120. package/lib/rules/no-else-return.js +1 -0
  121. package/lib/rules/no-empty-character-class.js +1 -0
  122. package/lib/rules/no-empty-function.js +1 -0
  123. package/lib/rules/no-empty-pattern.js +1 -0
  124. package/lib/rules/no-empty.js +1 -0
  125. package/lib/rules/no-eq-null.js +1 -0
  126. package/lib/rules/no-eval.js +3 -0
  127. package/lib/rules/no-ex-assign.js +1 -0
  128. package/lib/rules/no-extend-native.js +1 -0
  129. package/lib/rules/no-extra-bind.js +1 -0
  130. package/lib/rules/no-extra-boolean-cast.js +1 -0
  131. package/lib/rules/no-extra-label.js +1 -0
  132. package/lib/rules/no-extra-parens.js +1 -0
  133. package/lib/rules/no-extra-semi.js +2 -1
  134. package/lib/rules/no-fallthrough.js +1 -0
  135. package/lib/rules/no-floating-decimal.js +1 -0
  136. package/lib/rules/no-func-assign.js +1 -0
  137. package/lib/rules/no-global-assign.js +1 -0
  138. package/lib/rules/no-implicit-coercion.js +1 -0
  139. package/lib/rules/no-implicit-globals.js +1 -0
  140. package/lib/rules/no-implied-eval.js +1 -0
  141. package/lib/rules/no-import-assign.js +1 -0
  142. package/lib/rules/no-inline-comments.js +1 -0
  143. package/lib/rules/no-inner-declarations.js +27 -4
  144. package/lib/rules/no-invalid-regexp.js +1 -0
  145. package/lib/rules/no-invalid-this.js +5 -0
  146. package/lib/rules/no-irregular-whitespace.js +1 -0
  147. package/lib/rules/no-iterator.js +1 -0
  148. package/lib/rules/no-label-var.js +1 -0
  149. package/lib/rules/no-labels.js +1 -0
  150. package/lib/rules/no-lone-blocks.js +9 -2
  151. package/lib/rules/no-lonely-if.js +1 -0
  152. package/lib/rules/no-loop-func.js +1 -0
  153. package/lib/rules/no-loss-of-precision.js +1 -0
  154. package/lib/rules/no-magic-numbers.js +1 -0
  155. package/lib/rules/no-misleading-character-class.js +1 -0
  156. package/lib/rules/no-mixed-operators.js +1 -0
  157. package/lib/rules/no-mixed-requires.js +1 -0
  158. package/lib/rules/no-mixed-spaces-and-tabs.js +1 -0
  159. package/lib/rules/no-multi-assign.js +1 -0
  160. package/lib/rules/no-multi-spaces.js +1 -0
  161. package/lib/rules/no-multi-str.js +1 -0
  162. package/lib/rules/no-multiple-empty-lines.js +1 -0
  163. package/lib/rules/no-native-reassign.js +1 -0
  164. package/lib/rules/no-negated-condition.js +1 -0
  165. package/lib/rules/no-negated-in-lhs.js +1 -0
  166. package/lib/rules/no-nested-ternary.js +1 -0
  167. package/lib/rules/no-new-func.js +1 -0
  168. package/lib/rules/no-new-object.js +1 -0
  169. package/lib/rules/no-new-require.js +1 -0
  170. package/lib/rules/no-new-symbol.js +1 -0
  171. package/lib/rules/no-new-wrappers.js +1 -0
  172. package/lib/rules/no-new.js +1 -0
  173. package/lib/rules/no-nonoctal-decimal-escape.js +1 -0
  174. package/lib/rules/no-obj-calls.js +1 -0
  175. package/lib/rules/no-octal-escape.js +1 -0
  176. package/lib/rules/no-octal.js +1 -0
  177. package/lib/rules/no-param-reassign.js +1 -0
  178. package/lib/rules/no-path-concat.js +1 -0
  179. package/lib/rules/no-plusplus.js +1 -0
  180. package/lib/rules/no-process-env.js +1 -0
  181. package/lib/rules/no-process-exit.js +1 -0
  182. package/lib/rules/no-promise-executor-return.js +1 -0
  183. package/lib/rules/no-proto.js +1 -0
  184. package/lib/rules/no-prototype-builtins.js +1 -0
  185. package/lib/rules/no-redeclare.js +3 -0
  186. package/lib/rules/no-regex-spaces.js +1 -0
  187. package/lib/rules/no-restricted-exports.js +1 -0
  188. package/lib/rules/no-restricted-globals.js +1 -0
  189. package/lib/rules/no-restricted-imports.js +1 -0
  190. package/lib/rules/no-restricted-modules.js +1 -0
  191. package/lib/rules/no-restricted-properties.js +1 -0
  192. package/lib/rules/no-restricted-syntax.js +1 -0
  193. package/lib/rules/no-return-assign.js +1 -0
  194. package/lib/rules/no-return-await.js +1 -0
  195. package/lib/rules/no-script-url.js +1 -0
  196. package/lib/rules/no-self-assign.js +1 -0
  197. package/lib/rules/no-self-compare.js +1 -0
  198. package/lib/rules/no-sequences.js +1 -0
  199. package/lib/rules/no-setter-return.js +1 -0
  200. package/lib/rules/no-shadow-restricted-names.js +1 -0
  201. package/lib/rules/no-shadow.js +1 -0
  202. package/lib/rules/no-spaced-func.js +1 -0
  203. package/lib/rules/no-sparse-arrays.js +1 -0
  204. package/lib/rules/no-sync.js +1 -0
  205. package/lib/rules/no-tabs.js +1 -0
  206. package/lib/rules/no-template-curly-in-string.js +1 -0
  207. package/lib/rules/no-ternary.js +1 -0
  208. package/lib/rules/no-this-before-super.js +1 -0
  209. package/lib/rules/no-throw-literal.js +1 -0
  210. package/lib/rules/no-trailing-spaces.js +1 -0
  211. package/lib/rules/no-undef-init.js +1 -0
  212. package/lib/rules/no-undef.js +1 -0
  213. package/lib/rules/no-undefined.js +1 -0
  214. package/lib/rules/no-underscore-dangle.js +1 -0
  215. package/lib/rules/no-unexpected-multiline.js +1 -0
  216. package/lib/rules/no-unmodified-loop-condition.js +1 -0
  217. package/lib/rules/no-unneeded-ternary.js +1 -0
  218. package/lib/rules/no-unreachable-loop.js +1 -0
  219. package/lib/rules/no-unreachable.js +1 -0
  220. package/lib/rules/no-unsafe-finally.js +1 -0
  221. package/lib/rules/no-unsafe-negation.js +1 -0
  222. package/lib/rules/no-unsafe-optional-chaining.js +1 -0
  223. package/lib/rules/no-unused-expressions.js +7 -0
  224. package/lib/rules/no-unused-labels.js +1 -0
  225. package/lib/rules/no-unused-private-class-members.js +1 -0
  226. package/lib/rules/no-unused-vars.js +1 -0
  227. package/lib/rules/no-use-before-define.js +33 -9
  228. package/lib/rules/no-useless-backreference.js +1 -0
  229. package/lib/rules/no-useless-call.js +1 -0
  230. package/lib/rules/no-useless-catch.js +1 -0
  231. package/lib/rules/no-useless-computed-key.js +1 -0
  232. package/lib/rules/no-useless-concat.js +1 -0
  233. package/lib/rules/no-useless-constructor.js +1 -0
  234. package/lib/rules/no-useless-escape.js +1 -0
  235. package/lib/rules/no-useless-rename.js +1 -0
  236. package/lib/rules/no-useless-return.js +1 -0
  237. package/lib/rules/no-var.js +1 -0
  238. package/lib/rules/no-void.js +1 -0
  239. package/lib/rules/no-warning-comments.js +1 -0
  240. package/lib/rules/no-whitespace-before-property.js +1 -0
  241. package/lib/rules/no-with.js +1 -0
  242. package/lib/rules/nonblock-statement-body-position.js +1 -0
  243. package/lib/rules/object-curly-newline.js +1 -0
  244. package/lib/rules/object-curly-spacing.js +1 -0
  245. package/lib/rules/object-property-newline.js +1 -0
  246. package/lib/rules/object-shorthand.js +1 -0
  247. package/lib/rules/one-var-declaration-per-line.js +1 -0
  248. package/lib/rules/one-var.js +6 -1
  249. package/lib/rules/operator-assignment.js +1 -0
  250. package/lib/rules/operator-linebreak.js +1 -0
  251. package/lib/rules/padded-blocks.js +9 -0
  252. package/lib/rules/padding-line-between-statements.js +3 -0
  253. package/lib/rules/prefer-arrow-callback.js +1 -0
  254. package/lib/rules/prefer-const.js +2 -1
  255. package/lib/rules/prefer-destructuring.js +1 -0
  256. package/lib/rules/prefer-exponentiation-operator.js +1 -0
  257. package/lib/rules/prefer-named-capture-group.js +1 -0
  258. package/lib/rules/prefer-numeric-literals.js +1 -0
  259. package/lib/rules/prefer-object-has-own.js +112 -0
  260. package/lib/rules/prefer-object-spread.js +1 -0
  261. package/lib/rules/prefer-promise-reject-errors.js +1 -0
  262. package/lib/rules/prefer-reflect.js +1 -0
  263. package/lib/rules/prefer-regex-literals.js +218 -1
  264. package/lib/rules/prefer-rest-params.js +1 -0
  265. package/lib/rules/prefer-spread.js +1 -0
  266. package/lib/rules/prefer-template.js +2 -1
  267. package/lib/rules/quote-props.js +1 -0
  268. package/lib/rules/quotes.js +1 -0
  269. package/lib/rules/radix.js +1 -0
  270. package/lib/rules/require-atomic-updates.js +15 -2
  271. package/lib/rules/require-await.js +1 -0
  272. package/lib/rules/require-jsdoc.js +1 -0
  273. package/lib/rules/require-unicode-regexp.js +1 -0
  274. package/lib/rules/require-yield.js +1 -0
  275. package/lib/rules/rest-spread-spacing.js +1 -0
  276. package/lib/rules/semi-spacing.js +1 -0
  277. package/lib/rules/semi-style.js +9 -2
  278. package/lib/rules/semi.js +19 -9
  279. package/lib/rules/sort-imports.js +1 -0
  280. package/lib/rules/sort-keys.js +1 -0
  281. package/lib/rules/sort-vars.js +1 -0
  282. package/lib/rules/space-before-blocks.js +1 -0
  283. package/lib/rules/space-before-function-paren.js +1 -0
  284. package/lib/rules/space-in-parens.js +1 -0
  285. package/lib/rules/space-infix-ops.js +1 -0
  286. package/lib/rules/space-unary-ops.js +1 -0
  287. package/lib/rules/spaced-comment.js +1 -0
  288. package/lib/rules/strict.js +1 -0
  289. package/lib/rules/switch-colon-spacing.js +1 -0
  290. package/lib/rules/symbol-description.js +1 -0
  291. package/lib/rules/template-curly-spacing.js +1 -0
  292. package/lib/rules/template-tag-spacing.js +1 -0
  293. package/lib/rules/unicode-bom.js +1 -0
  294. package/lib/rules/use-isnan.js +1 -0
  295. package/lib/rules/utils/ast-utils.js +15 -3
  296. package/lib/rules/valid-jsdoc.js +1 -0
  297. package/lib/rules/valid-typeof.js +1 -0
  298. package/lib/rules/vars-on-top.js +26 -12
  299. package/lib/rules/wrap-iife.js +1 -0
  300. package/lib/rules/wrap-regex.js +1 -0
  301. package/lib/rules/yield-star-spacing.js +1 -0
  302. package/lib/rules/yoda.js +1 -0
  303. package/lib/shared/types.js +10 -0
  304. package/package.json +8 -8
@@ -11,11 +11,15 @@
11
11
 
12
12
  const astUtils = require("./utils/ast-utils");
13
13
  const { CALL, CONSTRUCT, ReferenceTracker, findVariable } = require("eslint-utils");
14
+ const { RegExpValidator, visitRegExpAST, RegExpParser } = require("regexpp");
15
+ const { canTokensBeAdjacent } = require("./utils/ast-utils");
14
16
 
15
17
  //------------------------------------------------------------------------------
16
18
  // Helpers
17
19
  //------------------------------------------------------------------------------
18
20
 
21
+ const REGEXPP_LATEST_ECMA_VERSION = 2022;
22
+
19
23
  /**
20
24
  * Determines whether the given node is a string literal.
21
25
  * @param {ASTNode} node Node to check.
@@ -43,11 +47,77 @@ function isStaticTemplateLiteral(node) {
43
47
  return node.type === "TemplateLiteral" && node.expressions.length === 0;
44
48
  }
45
49
 
50
+ const validPrecedingTokens = [
51
+ "(",
52
+ ";",
53
+ "[",
54
+ ",",
55
+ "=",
56
+ "+",
57
+ "*",
58
+ "-",
59
+ "?",
60
+ "~",
61
+ "%",
62
+ "**",
63
+ "!",
64
+ "typeof",
65
+ "instanceof",
66
+ "&&",
67
+ "||",
68
+ "??",
69
+ "return",
70
+ "...",
71
+ "delete",
72
+ "void",
73
+ "in",
74
+ "<",
75
+ ">",
76
+ "<=",
77
+ ">=",
78
+ "==",
79
+ "===",
80
+ "!=",
81
+ "!==",
82
+ "<<",
83
+ ">>",
84
+ ">>>",
85
+ "&",
86
+ "|",
87
+ "^",
88
+ ":",
89
+ "{",
90
+ "=>",
91
+ "*=",
92
+ "<<=",
93
+ ">>=",
94
+ ">>>=",
95
+ "^=",
96
+ "|=",
97
+ "&=",
98
+ "??=",
99
+ "||=",
100
+ "&&=",
101
+ "**=",
102
+ "+=",
103
+ "-=",
104
+ "/=",
105
+ "%=",
106
+ "/",
107
+ "do",
108
+ "break",
109
+ "continue",
110
+ "debugger",
111
+ "case",
112
+ "throw"
113
+ ];
114
+
46
115
 
47
116
  //------------------------------------------------------------------------------
48
117
  // Rule Definition
49
118
  //------------------------------------------------------------------------------
50
119
 
120
+ /** @type {import('../shared/types').Rule} */
51
121
  module.exports = {
52
122
  meta: {
53
123
  type: "suggestion",
@@ -58,6 +128,8 @@ module.exports = {
58
128
  url: "https://eslint.org/docs/rules/prefer-regex-literals"
59
129
  },
60
130
 
131
+ hasSuggestions: true,
132
+
61
133
  schema: [
62
134
  {
63
135
  type: "object",
@@ -73,6 +145,7 @@ module.exports = {
73
145
 
74
146
  messages: {
75
147
  unexpectedRegExp: "Use a regular expression literal instead of the 'RegExp' constructor.",
148
+ replaceWithLiteral: "Replace with an equivalent regular expression literal.",
76
149
  unexpectedRedundantRegExp: "Regular expression literal is unnecessarily wrapped within a 'RegExp' constructor.",
77
150
  unexpectedRedundantRegExpWithFlags: "Use regular expression literal with flags instead of the 'RegExp' constructor."
78
151
  }
@@ -80,6 +153,7 @@ module.exports = {
80
153
 
81
154
  create(context) {
82
155
  const [{ disallowRedundantWrapping = false } = {}] = context.options;
156
+ const sourceCode = context.getSourceCode();
83
157
 
84
158
  /**
85
159
  * Determines whether the given identifier node is a reference to a global variable.
@@ -106,6 +180,27 @@ module.exports = {
106
180
  isStaticTemplateLiteral(node.quasi);
107
181
  }
108
182
 
183
+ /**
184
+ * Gets the value of a string
185
+ * @param {ASTNode} node The node to get the string of.
186
+ * @returns {string|null} The value of the node.
187
+ */
188
+ function getStringValue(node) {
189
+ if (isStringLiteral(node)) {
190
+ return node.value;
191
+ }
192
+
193
+ if (isStaticTemplateLiteral(node)) {
194
+ return node.quasis[0].value.cooked;
195
+ }
196
+
197
+ if (isStringRawTaggedStaticTemplateLiteral(node)) {
198
+ return node.quasi.quasis[0].value.raw;
199
+ }
200
+
201
+ return null;
202
+ }
203
+
109
204
  /**
110
205
  * Determines whether the given node is considered to be a static string by the logic of this rule.
111
206
  * @param {ASTNode} node Node to check.
@@ -151,6 +246,53 @@ module.exports = {
151
246
  return false;
152
247
  }
153
248
 
249
+ /**
250
+ * Returns a ecmaVersion compatible for regexpp.
251
+ * @param {any} ecmaVersion The ecmaVersion to convert.
252
+ * @returns {import("regexpp/ecma-versions").EcmaVersion} The resulting ecmaVersion compatible for regexpp.
253
+ */
254
+ function getRegexppEcmaVersion(ecmaVersion) {
255
+ if (typeof ecmaVersion !== "number" || ecmaVersion <= 5) {
256
+ return 5;
257
+ }
258
+ return Math.min(ecmaVersion + 2009, REGEXPP_LATEST_ECMA_VERSION);
259
+ }
260
+
261
+ /**
262
+ * Makes a character escaped or else returns null.
263
+ * @param {string} character The character to escape.
264
+ * @returns {string} The resulting escaped character.
265
+ */
266
+ function resolveEscapes(character) {
267
+ switch (character) {
268
+ case "\n":
269
+ case "\\\n":
270
+ return "\\n";
271
+
272
+ case "\r":
273
+ case "\\\r":
274
+ return "\\r";
275
+
276
+ case "\t":
277
+ case "\\\t":
278
+ return "\\t";
279
+
280
+ case "\v":
281
+ case "\\\v":
282
+ return "\\v";
283
+
284
+ case "\f":
285
+ case "\\\f":
286
+ return "\\f";
287
+
288
+ case "/":
289
+ return "\\/";
290
+
291
+ default:
292
+ return null;
293
+ }
294
+ }
295
+
154
296
  return {
155
297
  Program() {
156
298
  const scope = context.getScope();
@@ -170,7 +312,82 @@ module.exports = {
170
312
  context.report({ node, messageId: "unexpectedRedundantRegExp" });
171
313
  }
172
314
  } else if (hasOnlyStaticStringArguments(node)) {
173
- context.report({ node, messageId: "unexpectedRegExp" });
315
+ let regexContent = getStringValue(node.arguments[0]);
316
+ let noFix = false;
317
+ let flags;
318
+
319
+ if (node.arguments[1]) {
320
+ flags = getStringValue(node.arguments[1]);
321
+ }
322
+
323
+ const regexppEcmaVersion = getRegexppEcmaVersion(context.parserOptions.ecmaVersion);
324
+ const RegExpValidatorInstance = new RegExpValidator({ ecmaVersion: regexppEcmaVersion });
325
+
326
+ try {
327
+ RegExpValidatorInstance.validatePattern(regexContent, 0, regexContent.length, flags ? flags.includes("u") : false);
328
+ if (flags) {
329
+ RegExpValidatorInstance.validateFlags(flags);
330
+ }
331
+ } catch {
332
+ noFix = true;
333
+ }
334
+
335
+ const tokenBefore = sourceCode.getTokenBefore(node);
336
+
337
+ if (tokenBefore && !validPrecedingTokens.includes(tokenBefore.value)) {
338
+ noFix = true;
339
+ }
340
+
341
+ if (!/^[-a-zA-Z0-9\\[\](){} \t\r\n\v\f!@#$%^&*+^_=/~`.><?,'"|:;]*$/u.test(regexContent)) {
342
+ noFix = true;
343
+ }
344
+
345
+ if (sourceCode.getCommentsInside(node).length > 0) {
346
+ noFix = true;
347
+ }
348
+
349
+ if (regexContent && !noFix) {
350
+ let charIncrease = 0;
351
+
352
+ const ast = new RegExpParser({ ecmaVersion: regexppEcmaVersion }).parsePattern(regexContent, 0, regexContent.length, flags ? flags.includes("u") : false);
353
+
354
+ visitRegExpAST(ast, {
355
+ onCharacterEnter(characterNode) {
356
+ const escaped = resolveEscapes(characterNode.raw);
357
+
358
+ if (escaped) {
359
+ regexContent =
360
+ regexContent.slice(0, characterNode.start + charIncrease) +
361
+ escaped +
362
+ regexContent.slice(characterNode.end + charIncrease);
363
+
364
+ if (characterNode.raw.length === 1) {
365
+ charIncrease += 1;
366
+ }
367
+ }
368
+ }
369
+ });
370
+ }
371
+
372
+ const newRegExpValue = `/${regexContent || "(?:)"}/${flags || ""}`;
373
+
374
+ context.report({
375
+ node,
376
+ messageId: "unexpectedRegExp",
377
+ suggest: noFix ? [] : [{
378
+ messageId: "replaceWithLiteral",
379
+ fix(fixer) {
380
+ const tokenAfter = sourceCode.getTokenAfter(node);
381
+
382
+ return fixer.replaceText(
383
+ node,
384
+ (tokenBefore && !canTokensBeAdjacent(tokenBefore, newRegExpValue) && tokenBefore.range[1] === node.range[0] ? " " : "") +
385
+ newRegExpValue +
386
+ (tokenAfter && !canTokensBeAdjacent(newRegExpValue, tokenAfter) && node.range[1] === tokenAfter.range[0] ? " " : "")
387
+ );
388
+ }
389
+ }]
390
+ });
174
391
  }
175
392
  }
176
393
  }
@@ -59,6 +59,7 @@ function isNotNormalMemberAccess(reference) {
59
59
  // Rule Definition
60
60
  //------------------------------------------------------------------------------
61
61
 
62
+ /** @type {import('../shared/types').Rule} */
62
63
  module.exports = {
63
64
  meta: {
64
65
  type: "suggestion",
@@ -43,6 +43,7 @@ function isValidThisArg(expectedThis, thisArg, context) {
43
43
  // Rule Definition
44
44
  //------------------------------------------------------------------------------
45
45
 
46
+ /** @type {import('../shared/types').Rule} */
46
47
  module.exports = {
47
48
  meta: {
48
49
  type: "suggestion",
@@ -122,6 +122,7 @@ function endsWithTemplateCurly(node) {
122
122
  // Rule Definition
123
123
  //------------------------------------------------------------------------------
124
124
 
125
+ /** @type {import('../shared/types').Rule} */
125
126
  module.exports = {
126
127
  meta: {
127
128
  type: "suggestion",
@@ -187,7 +188,7 @@ module.exports = {
187
188
  return sourceCode.getText(currentNode);
188
189
  }
189
190
 
190
- if (isConcatenation(currentNode) && hasStringLiteral(currentNode) && hasNonStringLiteral(currentNode)) {
191
+ if (isConcatenation(currentNode) && hasStringLiteral(currentNode)) {
191
192
  const plusSign = sourceCode.getFirstTokenBetween(currentNode.left, currentNode.right, token => token.value === "+");
192
193
  const textBeforePlus = getTextBetween(currentNode.left, plusSign);
193
194
  const textAfterPlus = getTextBetween(plusSign, currentNode.right);
@@ -16,6 +16,7 @@ const keywords = require("./utils/keywords");
16
16
  // Rule Definition
17
17
  //------------------------------------------------------------------------------
18
18
 
19
+ /** @type {import('../shared/types').Rule} */
19
20
  module.exports = {
20
21
  meta: {
21
22
  type: "suggestion",
@@ -74,6 +74,7 @@ const AVOID_ESCAPE = "avoid-escape";
74
74
  // Rule Definition
75
75
  //------------------------------------------------------------------------------
76
76
 
77
+ /** @type {import('../shared/types').Rule} */
77
78
  module.exports = {
78
79
  meta: {
79
80
  type: "layout",
@@ -74,6 +74,7 @@ function isDefaultRadix(radix) {
74
74
  // Rule Definition
75
75
  //------------------------------------------------------------------------------
76
76
 
77
+ /** @type {import('../shared/types').Rule} */
77
78
  module.exports = {
78
79
  meta: {
79
80
  type: "suggestion",
@@ -165,6 +165,7 @@ class SegmentInfo {
165
165
  // Rule Definition
166
166
  //------------------------------------------------------------------------------
167
167
 
168
+ /** @type {import('../shared/types').Rule} */
168
169
  module.exports = {
169
170
  meta: {
170
171
  type: "problem",
@@ -176,7 +177,17 @@ module.exports = {
176
177
  },
177
178
 
178
179
  fixable: null,
179
- schema: [],
180
+
181
+ schema: [{
182
+ type: "object",
183
+ properties: {
184
+ allowProperties: {
185
+ type: "boolean",
186
+ default: false
187
+ }
188
+ },
189
+ additionalProperties: false
190
+ }],
180
191
 
181
192
  messages: {
182
193
  nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`.",
@@ -185,6 +196,8 @@ module.exports = {
185
196
  },
186
197
 
187
198
  create(context) {
199
+ const allowProperties = !!context.options[0] && context.options[0].allowProperties;
200
+
188
201
  const sourceCode = context.getSourceCode();
189
202
  const assignmentReferences = new Map();
190
203
  const segmentInfo = new SegmentInfo();
@@ -284,7 +297,7 @@ module.exports = {
284
297
  value: variable.name
285
298
  }
286
299
  });
287
- } else {
300
+ } else if (!allowProperties) {
288
301
  context.report({
289
302
  node: node.parent,
290
303
  messageId: "nonAtomicObjectUpdate",
@@ -28,6 +28,7 @@ function capitalizeFirstLetter(text) {
28
28
  // Rule Definition
29
29
  //------------------------------------------------------------------------------
30
30
 
31
+ /** @type {import('../shared/types').Rule} */
31
32
  module.exports = {
32
33
  meta: {
33
34
  type: "suggestion",
@@ -5,6 +5,7 @@
5
5
  */
6
6
  "use strict";
7
7
 
8
+ /** @type {import('../shared/types').Rule} */
8
9
  module.exports = {
9
10
  meta: {
10
11
  type: "suggestion",
@@ -20,6 +20,7 @@ const {
20
20
  // Rule Definition
21
21
  //------------------------------------------------------------------------------
22
22
 
23
+ /** @type {import('../shared/types').Rule} */
23
24
  module.exports = {
24
25
  meta: {
25
26
  type: "suggestion",
@@ -9,6 +9,7 @@
9
9
  // Rule Definition
10
10
  //------------------------------------------------------------------------------
11
11
 
12
+ /** @type {import('../shared/types').Rule} */
12
13
  module.exports = {
13
14
  meta: {
14
15
  type: "suggestion",
@@ -9,6 +9,7 @@
9
9
  // Rule Definition
10
10
  //------------------------------------------------------------------------------
11
11
 
12
+ /** @type {import('../shared/types').Rule} */
12
13
  module.exports = {
13
14
  meta: {
14
15
  type: "layout",
@@ -11,6 +11,7 @@ const astUtils = require("./utils/ast-utils");
11
11
  // Rule Definition
12
12
  //------------------------------------------------------------------------------
13
13
 
14
+ /** @type {import('../shared/types').Rule} */
14
15
  module.exports = {
15
16
  meta: {
16
17
  type: "layout",
@@ -25,7 +25,8 @@ const SELECTOR = [
25
25
 
26
26
  /**
27
27
  * Get the child node list of a given node.
28
- * This returns `Program#body`, `BlockStatement#body`, or `SwitchCase#consequent`.
28
+ * This returns `BlockStatement#body`, `StaticBlock#body`, `Program#body`,
29
+ * `ClassBody#body`, or `SwitchCase#consequent`.
29
30
  * This is used to check whether a node is the first/last child.
30
31
  * @param {Node} node A node to get child node list.
31
32
  * @returns {Node[]|null} The child node list.
@@ -33,7 +34,12 @@ const SELECTOR = [
33
34
  function getChildren(node) {
34
35
  const t = node.type;
35
36
 
36
- if (t === "BlockStatement" || t === "Program" || t === "ClassBody") {
37
+ if (
38
+ t === "BlockStatement" ||
39
+ t === "StaticBlock" ||
40
+ t === "Program" ||
41
+ t === "ClassBody"
42
+ ) {
37
43
  return node.body;
38
44
  }
39
45
  if (t === "SwitchCase") {
@@ -61,6 +67,7 @@ function isLastChild(node) {
61
67
  return nodeList !== null && nodeList[nodeList.length - 1] === node; // before `}` or etc.
62
68
  }
63
69
 
70
+ /** @type {import('../shared/types').Rule} */
64
71
  module.exports = {
65
72
  meta: {
66
73
  type: "layout",
package/lib/rules/semi.js CHANGED
@@ -15,6 +15,7 @@ const astUtils = require("./utils/ast-utils");
15
15
  // Rule Definition
16
16
  //------------------------------------------------------------------------------
17
17
 
18
+ /** @type {import('../shared/types').Rule} */
18
19
  module.exports = {
19
20
  meta: {
20
21
  type: "layout",
@@ -306,22 +307,31 @@ module.exports = {
306
307
  }
307
308
 
308
309
  /**
309
- * Checks a node to see if it's in a one-liner block statement.
310
+ * Checks a node to see if it's the last item in a one-liner block.
311
+ * Block is any `BlockStatement` or `StaticBlock` node. Block is a one-liner if its
312
+ * braces (and consequently everything between them) are on the same line.
310
313
  * @param {ASTNode} node The node to check.
311
- * @returns {boolean} whether the node is in a one-liner block statement.
314
+ * @returns {boolean} whether the node is the last item in a one-liner block.
312
315
  */
313
- function isOneLinerBlock(node) {
316
+ function isLastInOneLinerBlock(node) {
314
317
  const parent = node.parent;
315
318
  const nextToken = sourceCode.getTokenAfter(node);
316
319
 
317
320
  if (!nextToken || nextToken.value !== "}") {
318
321
  return false;
319
322
  }
320
- return (
321
- !!parent &&
322
- parent.type === "BlockStatement" &&
323
- parent.loc.start.line === parent.loc.end.line
324
- );
323
+
324
+ if (parent.type === "BlockStatement") {
325
+ return parent.loc.start.line === parent.loc.end.line;
326
+ }
327
+
328
+ if (parent.type === "StaticBlock") {
329
+ const openingBrace = sourceCode.getFirstToken(parent, { skip: 1 }); // skip the `static` token
330
+
331
+ return openingBrace.loc.start.line === parent.loc.end.line;
332
+ }
333
+
334
+ return false;
325
335
  }
326
336
 
327
337
  /**
@@ -343,7 +353,7 @@ module.exports = {
343
353
  report(node);
344
354
  }
345
355
  } else {
346
- const oneLinerBlock = (exceptOneLine && isOneLinerBlock(node));
356
+ const oneLinerBlock = (exceptOneLine && isLastInOneLinerBlock(node));
347
357
 
348
358
  if (isSemi && oneLinerBlock) {
349
359
  report(node, true);
@@ -9,6 +9,7 @@
9
9
  // Rule Definition
10
10
  //------------------------------------------------------------------------------
11
11
 
12
+ /** @type {import('../shared/types').Rule} */
12
13
  module.exports = {
13
14
  meta: {
14
15
  type: "suggestion",
@@ -75,6 +75,7 @@ const isValidOrders = {
75
75
  // Rule Definition
76
76
  //------------------------------------------------------------------------------
77
77
 
78
+ /** @type {import('../shared/types').Rule} */
78
79
  module.exports = {
79
80
  meta: {
80
81
  type: "suggestion",
@@ -9,6 +9,7 @@
9
9
  // Rule Definition
10
10
  //------------------------------------------------------------------------------
11
11
 
12
+ /** @type {import('../shared/types').Rule} */
12
13
  module.exports = {
13
14
  meta: {
14
15
  type: "suggestion",
@@ -34,6 +34,7 @@ function isFunctionBody(node) {
34
34
  // Rule Definition
35
35
  //------------------------------------------------------------------------------
36
36
 
37
+ /** @type {import('../shared/types').Rule} */
37
38
  module.exports = {
38
39
  meta: {
39
40
  type: "layout",
@@ -14,6 +14,7 @@ const astUtils = require("./utils/ast-utils");
14
14
  // Rule Definition
15
15
  //------------------------------------------------------------------------------
16
16
 
17
+ /** @type {import('../shared/types').Rule} */
17
18
  module.exports = {
18
19
  meta: {
19
20
  type: "layout",
@@ -10,6 +10,7 @@ const astUtils = require("./utils/ast-utils");
10
10
  // Rule Definition
11
11
  //------------------------------------------------------------------------------
12
12
 
13
+ /** @type {import('../shared/types').Rule} */
13
14
  module.exports = {
14
15
  meta: {
15
16
  type: "layout",
@@ -10,6 +10,7 @@ const { isEqToken } = require("./utils/ast-utils");
10
10
  // Rule Definition
11
11
  //------------------------------------------------------------------------------
12
12
 
13
+ /** @type {import('../shared/types').Rule} */
13
14
  module.exports = {
14
15
  meta: {
15
16
  type: "layout",
@@ -14,6 +14,7 @@ const astUtils = require("./utils/ast-utils");
14
14
  // Rule Definition
15
15
  //------------------------------------------------------------------------------
16
16
 
17
+ /** @type {import('../shared/types').Rule} */
17
18
  module.exports = {
18
19
  meta: {
19
20
  type: "layout",
@@ -146,6 +146,7 @@ function createNeverStylePattern(markers) {
146
146
  // Rule Definition
147
147
  //------------------------------------------------------------------------------
148
148
 
149
+ /** @type {import('../shared/types').Rule} */
149
150
  module.exports = {
150
151
  meta: {
151
152
  type: "suggestion",
@@ -63,6 +63,7 @@ function isSimpleParameterList(params) {
63
63
  // Rule Definition
64
64
  //------------------------------------------------------------------------------
65
65
 
66
+ /** @type {import('../shared/types').Rule} */
66
67
  module.exports = {
67
68
  meta: {
68
69
  type: "suggestion",
@@ -15,6 +15,7 @@ const astUtils = require("./utils/ast-utils");
15
15
  // Rule Definition
16
16
  //------------------------------------------------------------------------------
17
17
 
18
+ /** @type {import('../shared/types').Rule} */
18
19
  module.exports = {
19
20
  meta: {
20
21
  type: "layout",
@@ -16,6 +16,7 @@ const astUtils = require("./utils/ast-utils");
16
16
  //------------------------------------------------------------------------------
17
17
 
18
18
 
19
+ /** @type {import('../shared/types').Rule} */
19
20
  module.exports = {
20
21
  meta: {
21
22
  type: "suggestion",
@@ -15,6 +15,7 @@ const astUtils = require("./utils/ast-utils");
15
15
  // Rule Definition
16
16
  //------------------------------------------------------------------------------
17
17
 
18
+ /** @type {import('../shared/types').Rule} */
18
19
  module.exports = {
19
20
  meta: {
20
21
  type: "layout",
@@ -9,6 +9,7 @@
9
9
  // Rule Definition
10
10
  //------------------------------------------------------------------------------
11
11
 
12
+ /** @type {import('../shared/types').Rule} */
12
13
  module.exports = {
13
14
  meta: {
14
15
  type: "layout",