eslint 5.6.0 → 5.9.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 (273) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/bin/eslint.js +0 -1
  3. package/lib/cli-engine.js +128 -31
  4. package/lib/cli.js +6 -1
  5. package/lib/linter.js +9 -0
  6. package/lib/options.js +5 -0
  7. package/lib/rules/accessor-pairs.js +4 -0
  8. package/lib/rules/array-bracket-newline.js +5 -0
  9. package/lib/rules/array-bracket-spacing.js +5 -0
  10. package/lib/rules/array-callback-return.js +2 -0
  11. package/lib/rules/array-element-newline.js +4 -0
  12. package/lib/rules/arrow-body-style.js +2 -0
  13. package/lib/rules/arrow-parens.js +2 -0
  14. package/lib/rules/arrow-spacing.js +2 -0
  15. package/lib/rules/block-scoped-var.js +2 -0
  16. package/lib/rules/block-spacing.js +2 -0
  17. package/lib/rules/brace-style.js +2 -0
  18. package/lib/rules/callback-return.js +2 -0
  19. package/lib/rules/camelcase.js +38 -8
  20. package/lib/rules/capitalized-comments.js +4 -0
  21. package/lib/rules/class-methods-use-this.js +3 -0
  22. package/lib/rules/comma-dangle.js +4 -0
  23. package/lib/rules/comma-spacing.js +2 -0
  24. package/lib/rules/comma-style.js +5 -0
  25. package/lib/rules/complexity.js +2 -0
  26. package/lib/rules/computed-property-spacing.js +2 -0
  27. package/lib/rules/consistent-return.js +2 -0
  28. package/lib/rules/consistent-this.js +2 -0
  29. package/lib/rules/constructor-super.js +2 -0
  30. package/lib/rules/curly.js +2 -0
  31. package/lib/rules/default-case.js +2 -0
  32. package/lib/rules/dot-location.js +2 -0
  33. package/lib/rules/dot-notation.js +2 -0
  34. package/lib/rules/eol-last.js +5 -0
  35. package/lib/rules/eqeqeq.js +2 -0
  36. package/lib/rules/for-direction.js +4 -0
  37. package/lib/rules/func-call-spacing.js +4 -0
  38. package/lib/rules/func-name-matching.js +3 -0
  39. package/lib/rules/func-names.js +3 -0
  40. package/lib/rules/func-style.js +3 -0
  41. package/lib/rules/function-paren-newline.js +5 -0
  42. package/lib/rules/generator-star-spacing.js +3 -0
  43. package/lib/rules/getter-return.js +5 -0
  44. package/lib/rules/global-require.js +2 -0
  45. package/lib/rules/guard-for-in.js +2 -0
  46. package/lib/rules/handle-callback-err.js +2 -0
  47. package/lib/rules/id-blacklist.js +2 -0
  48. package/lib/rules/id-length.js +2 -0
  49. package/lib/rules/id-match.js +101 -27
  50. package/lib/rules/implicit-arrow-linebreak.js +4 -0
  51. package/lib/rules/indent-legacy.js +4 -1
  52. package/lib/rules/indent.js +2 -0
  53. package/lib/rules/init-declarations.js +2 -0
  54. package/lib/rules/jsx-quotes.js +2 -0
  55. package/lib/rules/key-spacing.js +4 -3
  56. package/lib/rules/keyword-spacing.js +2 -0
  57. package/lib/rules/line-comment-position.js +2 -0
  58. package/lib/rules/linebreak-style.js +2 -0
  59. package/lib/rules/lines-around-comment.js +2 -0
  60. package/lib/rules/lines-around-directive.js +6 -2
  61. package/lib/rules/lines-between-class-members.js +2 -0
  62. package/lib/rules/max-classes-per-file.js +4 -0
  63. package/lib/rules/max-depth.js +2 -0
  64. package/lib/rules/max-len.js +2 -0
  65. package/lib/rules/max-lines-per-function.js +2 -0
  66. package/lib/rules/max-lines.js +2 -0
  67. package/lib/rules/max-nested-callbacks.js +2 -0
  68. package/lib/rules/max-params.js +2 -0
  69. package/lib/rules/max-statements-per-line.js +2 -0
  70. package/lib/rules/max-statements.js +2 -0
  71. package/lib/rules/multiline-comment-style.js +3 -0
  72. package/lib/rules/multiline-ternary.js +3 -0
  73. package/lib/rules/new-cap.js +2 -0
  74. package/lib/rules/new-parens.js +2 -1
  75. package/lib/rules/newline-after-var.js +5 -2
  76. package/lib/rules/newline-before-return.js +5 -2
  77. package/lib/rules/newline-per-chained-call.js +4 -0
  78. package/lib/rules/no-alert.js +2 -0
  79. package/lib/rules/no-array-constructor.js +2 -0
  80. package/lib/rules/no-async-promise-executor.js +3 -0
  81. package/lib/rules/no-await-in-loop.js +4 -0
  82. package/lib/rules/no-bitwise.js +2 -0
  83. package/lib/rules/no-buffer-constructor.js +4 -0
  84. package/lib/rules/no-caller.js +2 -0
  85. package/lib/rules/no-case-declarations.js +2 -0
  86. package/lib/rules/no-catch-shadow.js +6 -3
  87. package/lib/rules/no-class-assign.js +2 -0
  88. package/lib/rules/no-compare-neg-zero.js +4 -0
  89. package/lib/rules/no-cond-assign.js +2 -0
  90. package/lib/rules/no-confusing-arrow.js +2 -0
  91. package/lib/rules/no-console.js +2 -0
  92. package/lib/rules/no-const-assign.js +2 -0
  93. package/lib/rules/no-constant-condition.js +2 -0
  94. package/lib/rules/no-continue.js +2 -0
  95. package/lib/rules/no-control-regex.js +4 -2
  96. package/lib/rules/no-debugger.js +4 -0
  97. package/lib/rules/no-delete-var.js +2 -0
  98. package/lib/rules/no-div-regex.js +2 -0
  99. package/lib/rules/no-dupe-args.js +2 -0
  100. package/lib/rules/no-dupe-class-members.js +2 -0
  101. package/lib/rules/no-dupe-keys.js +2 -0
  102. package/lib/rules/no-duplicate-case.js +2 -0
  103. package/lib/rules/no-duplicate-imports.js +2 -0
  104. package/lib/rules/no-else-return.js +2 -0
  105. package/lib/rules/no-empty-character-class.js +2 -0
  106. package/lib/rules/no-empty-function.js +2 -0
  107. package/lib/rules/no-empty-pattern.js +2 -0
  108. package/lib/rules/no-empty.js +2 -0
  109. package/lib/rules/no-eq-null.js +2 -0
  110. package/lib/rules/no-eval.js +2 -0
  111. package/lib/rules/no-ex-assign.js +2 -0
  112. package/lib/rules/no-extend-native.js +2 -0
  113. package/lib/rules/no-extra-bind.js +24 -1
  114. package/lib/rules/no-extra-boolean-cast.js +2 -1
  115. package/lib/rules/no-extra-label.js +2 -1
  116. package/lib/rules/no-extra-parens.js +5 -6
  117. package/lib/rules/no-extra-semi.js +2 -0
  118. package/lib/rules/no-fallthrough.js +2 -0
  119. package/lib/rules/no-floating-decimal.js +2 -1
  120. package/lib/rules/no-func-assign.js +2 -0
  121. package/lib/rules/no-global-assign.js +2 -0
  122. package/lib/rules/no-implicit-coercion.js +3 -0
  123. package/lib/rules/no-implicit-globals.js +2 -0
  124. package/lib/rules/no-implied-eval.js +2 -0
  125. package/lib/rules/no-inline-comments.js +2 -0
  126. package/lib/rules/no-inner-declarations.js +2 -0
  127. package/lib/rules/no-invalid-regexp.js +2 -0
  128. package/lib/rules/no-invalid-this.js +2 -0
  129. package/lib/rules/no-irregular-whitespace.js +6 -8
  130. package/lib/rules/no-iterator.js +2 -0
  131. package/lib/rules/no-label-var.js +2 -0
  132. package/lib/rules/no-labels.js +2 -0
  133. package/lib/rules/no-lone-blocks.js +2 -0
  134. package/lib/rules/no-lonely-if.js +2 -1
  135. package/lib/rules/no-loop-func.js +2 -0
  136. package/lib/rules/no-magic-numbers.js +3 -0
  137. package/lib/rules/no-misleading-character-class.js +4 -0
  138. package/lib/rules/no-mixed-operators.js +3 -0
  139. package/lib/rules/no-mixed-requires.js +2 -0
  140. package/lib/rules/no-mixed-spaces-and-tabs.js +2 -0
  141. package/lib/rules/no-multi-assign.js +3 -0
  142. package/lib/rules/no-multi-spaces.js +2 -0
  143. package/lib/rules/no-multi-str.js +2 -0
  144. package/lib/rules/no-multiple-empty-lines.js +2 -0
  145. package/lib/rules/no-native-reassign.js +4 -1
  146. package/lib/rules/no-negated-condition.js +2 -0
  147. package/lib/rules/no-negated-in-lhs.js +5 -2
  148. package/lib/rules/no-nested-ternary.js +2 -0
  149. package/lib/rules/no-new-func.js +2 -0
  150. package/lib/rules/no-new-object.js +2 -0
  151. package/lib/rules/no-new-require.js +2 -0
  152. package/lib/rules/no-new-symbol.js +2 -0
  153. package/lib/rules/no-new-wrappers.js +2 -0
  154. package/lib/rules/no-new.js +2 -0
  155. package/lib/rules/no-obj-calls.js +2 -0
  156. package/lib/rules/no-octal-escape.js +2 -0
  157. package/lib/rules/no-octal.js +2 -0
  158. package/lib/rules/no-param-reassign.js +2 -0
  159. package/lib/rules/no-path-concat.js +2 -0
  160. package/lib/rules/no-plusplus.js +2 -0
  161. package/lib/rules/no-process-env.js +2 -0
  162. package/lib/rules/no-process-exit.js +2 -0
  163. package/lib/rules/no-proto.js +2 -0
  164. package/lib/rules/no-prototype-builtins.js +2 -0
  165. package/lib/rules/no-redeclare.js +2 -0
  166. package/lib/rules/no-regex-spaces.js +2 -1
  167. package/lib/rules/no-restricted-globals.js +2 -0
  168. package/lib/rules/no-restricted-imports.js +40 -22
  169. package/lib/rules/no-restricted-modules.js +2 -0
  170. package/lib/rules/no-restricted-properties.js +2 -0
  171. package/lib/rules/no-restricted-syntax.js +2 -0
  172. package/lib/rules/no-return-assign.js +2 -0
  173. package/lib/rules/no-return-await.js +4 -0
  174. package/lib/rules/no-script-url.js +2 -0
  175. package/lib/rules/no-self-assign.js +2 -0
  176. package/lib/rules/no-self-compare.js +2 -0
  177. package/lib/rules/no-sequences.js +2 -0
  178. package/lib/rules/no-shadow-restricted-names.js +2 -0
  179. package/lib/rules/no-shadow.js +2 -0
  180. package/lib/rules/no-spaced-func.js +4 -1
  181. package/lib/rules/no-sparse-arrays.js +2 -0
  182. package/lib/rules/no-sync.js +2 -0
  183. package/lib/rules/no-tabs.js +25 -6
  184. package/lib/rules/no-template-curly-in-string.js +2 -0
  185. package/lib/rules/no-ternary.js +2 -0
  186. package/lib/rules/no-this-before-super.js +2 -0
  187. package/lib/rules/no-throw-literal.js +2 -0
  188. package/lib/rules/no-trailing-spaces.js +2 -0
  189. package/lib/rules/no-undef-init.js +2 -1
  190. package/lib/rules/no-undef.js +2 -0
  191. package/lib/rules/no-undefined.js +2 -0
  192. package/lib/rules/no-underscore-dangle.js +2 -0
  193. package/lib/rules/no-unexpected-multiline.js +2 -0
  194. package/lib/rules/no-unmodified-loop-condition.js +2 -0
  195. package/lib/rules/no-unneeded-ternary.js +2 -0
  196. package/lib/rules/no-unreachable.js +2 -1
  197. package/lib/rules/no-unsafe-finally.js +2 -0
  198. package/lib/rules/no-unsafe-negation.js +3 -0
  199. package/lib/rules/no-unused-expressions.js +2 -0
  200. package/lib/rules/no-unused-labels.js +2 -1
  201. package/lib/rules/no-unused-vars.js +37 -13
  202. package/lib/rules/no-use-before-define.js +2 -0
  203. package/lib/rules/no-useless-call.js +2 -0
  204. package/lib/rules/no-useless-computed-key.js +2 -1
  205. package/lib/rules/no-useless-concat.js +2 -0
  206. package/lib/rules/no-useless-constructor.js +2 -0
  207. package/lib/rules/no-useless-escape.js +2 -0
  208. package/lib/rules/no-useless-rename.js +4 -0
  209. package/lib/rules/no-useless-return.js +3 -0
  210. package/lib/rules/no-var.js +2 -0
  211. package/lib/rules/no-void.js +2 -0
  212. package/lib/rules/no-warning-comments.js +2 -0
  213. package/lib/rules/no-whitespace-before-property.js +2 -0
  214. package/lib/rules/no-with.js +2 -0
  215. package/lib/rules/nonblock-statement-body-position.js +4 -0
  216. package/lib/rules/object-curly-newline.js +4 -0
  217. package/lib/rules/object-curly-spacing.js +2 -0
  218. package/lib/rules/object-property-newline.js +3 -2
  219. package/lib/rules/object-shorthand.js +2 -0
  220. package/lib/rules/one-var-declaration-per-line.js +2 -0
  221. package/lib/rules/one-var.js +13 -1
  222. package/lib/rules/operator-assignment.js +2 -0
  223. package/lib/rules/operator-linebreak.js +2 -0
  224. package/lib/rules/padded-blocks.js +2 -0
  225. package/lib/rules/padding-line-between-statements.js +7 -0
  226. package/lib/rules/prefer-arrow-callback.js +2 -0
  227. package/lib/rules/prefer-const.js +116 -11
  228. package/lib/rules/prefer-destructuring.js +3 -0
  229. package/lib/rules/prefer-numeric-literals.js +2 -1
  230. package/lib/rules/prefer-object-spread.js +4 -0
  231. package/lib/rules/prefer-promise-reject-errors.js +4 -0
  232. package/lib/rules/prefer-reflect.js +4 -1
  233. package/lib/rules/prefer-rest-params.js +2 -0
  234. package/lib/rules/prefer-spread.js +2 -1
  235. package/lib/rules/prefer-template.js +2 -1
  236. package/lib/rules/quote-props.js +2 -0
  237. package/lib/rules/quotes.js +2 -0
  238. package/lib/rules/radix.js +2 -0
  239. package/lib/rules/require-atomic-updates.js +91 -30
  240. package/lib/rules/require-await.js +3 -0
  241. package/lib/rules/require-jsdoc.js +2 -0
  242. package/lib/rules/require-unicode-regexp.js +4 -0
  243. package/lib/rules/require-yield.js +2 -0
  244. package/lib/rules/rest-spread-spacing.js +4 -0
  245. package/lib/rules/semi-spacing.js +2 -0
  246. package/lib/rules/semi-style.js +3 -0
  247. package/lib/rules/semi.js +2 -0
  248. package/lib/rules/sort-imports.js +2 -0
  249. package/lib/rules/sort-keys.js +3 -0
  250. package/lib/rules/sort-vars.js +2 -0
  251. package/lib/rules/space-before-blocks.js +46 -35
  252. package/lib/rules/space-before-function-paren.js +2 -0
  253. package/lib/rules/space-in-parens.js +2 -0
  254. package/lib/rules/space-infix-ops.js +18 -25
  255. package/lib/rules/space-unary-ops.js +2 -0
  256. package/lib/rules/spaced-comment.js +2 -0
  257. package/lib/rules/strict.js +2 -0
  258. package/lib/rules/switch-colon-spacing.js +4 -0
  259. package/lib/rules/symbol-description.js +2 -0
  260. package/lib/rules/template-curly-spacing.js +2 -0
  261. package/lib/rules/template-tag-spacing.js +2 -0
  262. package/lib/rules/unicode-bom.js +2 -0
  263. package/lib/rules/use-isnan.js +2 -0
  264. package/lib/rules/valid-jsdoc.js +2 -0
  265. package/lib/rules/valid-typeof.js +2 -0
  266. package/lib/rules/vars-on-top.js +2 -0
  267. package/lib/rules/wrap-iife.js +2 -0
  268. package/lib/rules/wrap-regex.js +3 -1
  269. package/lib/rules/yield-star-spacing.js +2 -0
  270. package/lib/rules/yoda.js +2 -0
  271. package/lib/testers/rule-tester.js +2 -2
  272. package/lib/util/source-code-fixer.js +1 -1
  273. package/package.json +12 -12
@@ -12,14 +12,18 @@ const astUtils = require("../util/ast-utils");
12
12
 
13
13
  module.exports = {
14
14
  meta: {
15
+ type: "problem",
16
+
15
17
  docs: {
16
18
  description: "disallow assignments that can lead to race conditions due to usage of `await` or `yield`",
17
19
  category: "Possible Errors",
18
20
  recommended: false,
19
21
  url: "https://eslint.org/docs/rules/require-atomic-updates"
20
22
  },
23
+
21
24
  fixable: null,
22
25
  schema: [],
26
+
23
27
  messages: {
24
28
  nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`."
25
29
  }
@@ -119,6 +123,66 @@ module.exports = {
119
123
  });
120
124
  }
121
125
 
126
+ const alreadyReportedAssignments = new WeakSet();
127
+
128
+ class AssignmentTrackerState {
129
+ constructor({ openAssignmentsWithoutReads = new Set(), openAssignmentsWithReads = new Set() } = {}) {
130
+ this.openAssignmentsWithoutReads = openAssignmentsWithoutReads;
131
+ this.openAssignmentsWithReads = openAssignmentsWithReads;
132
+ }
133
+
134
+ copy() {
135
+ return new AssignmentTrackerState({
136
+ openAssignmentsWithoutReads: new Set(this.openAssignmentsWithoutReads),
137
+ openAssignmentsWithReads: new Set(this.openAssignmentsWithReads)
138
+ });
139
+ }
140
+
141
+ merge(other) {
142
+ const initialAssignmentsWithoutReadsCount = this.openAssignmentsWithoutReads.size;
143
+ const initialAssignmentsWithReadsCount = this.openAssignmentsWithReads.size;
144
+
145
+ other.openAssignmentsWithoutReads.forEach(assignment => this.openAssignmentsWithoutReads.add(assignment));
146
+ other.openAssignmentsWithReads.forEach(assignment => this.openAssignmentsWithReads.add(assignment));
147
+
148
+ return this.openAssignmentsWithoutReads.size > initialAssignmentsWithoutReadsCount ||
149
+ this.openAssignmentsWithReads.size > initialAssignmentsWithReadsCount;
150
+ }
151
+
152
+ enterAssignment(assignmentExpression) {
153
+ (assignmentExpression.operator === "=" ? this.openAssignmentsWithoutReads : this.openAssignmentsWithReads).add(assignmentExpression);
154
+ }
155
+
156
+ exitAssignment(assignmentExpression) {
157
+ this.openAssignmentsWithoutReads.delete(assignmentExpression);
158
+ this.openAssignmentsWithReads.delete(assignmentExpression);
159
+ }
160
+
161
+ exitAwaitOrYield(node, surroundingFunction) {
162
+ return [...this.openAssignmentsWithReads]
163
+ .filter(assignment => !isLocalVariableWithoutEscape(assignment.left, surroundingFunction))
164
+ .forEach(assignment => {
165
+ if (!alreadyReportedAssignments.has(assignment)) {
166
+ reportAssignment(assignment);
167
+ alreadyReportedAssignments.add(assignment);
168
+ }
169
+ });
170
+ }
171
+
172
+ exitIdentifierOrMemberExpression(node) {
173
+ [...this.openAssignmentsWithoutReads]
174
+ .filter(assignment => (
175
+ assignment.left !== node &&
176
+ assignment.left.type === node.type &&
177
+ astUtils.equalTokens(assignment.left, node, sourceCode)
178
+ ))
179
+ .forEach(assignment => {
180
+ this.openAssignmentsWithoutReads.delete(assignment);
181
+ this.openAssignmentsWithReads.add(assignment);
182
+ });
183
+ }
184
+ }
185
+
122
186
  /**
123
187
  * If the control flow graph of a function enters an assignment expression, then does the
124
188
  * both of the following steps in order (possibly with other steps in between) before exiting the
@@ -135,54 +199,51 @@ module.exports = {
135
199
  codePathSegment,
136
200
  surroundingFunction,
137
201
  {
138
- seenSegments = new Set(),
139
- openAssignmentsWithoutReads = new Set(),
140
- openAssignmentsWithReads = new Set()
202
+ stateBySegmentStart = new WeakMap(),
203
+ stateBySegmentEnd = new WeakMap()
141
204
  } = {}
142
205
  ) {
143
- if (seenSegments.has(codePathSegment)) {
144
-
145
- // An AssignmentExpression can't contain loops, so it's not necessary to reenter them with new state.
146
- return;
206
+ if (!stateBySegmentStart.has(codePathSegment)) {
207
+ stateBySegmentStart.set(codePathSegment, new AssignmentTrackerState());
147
208
  }
148
209
 
210
+ const currentState = stateBySegmentStart.get(codePathSegment).copy();
211
+
149
212
  expressionsByCodePathSegment.get(codePathSegment).forEach(({ entering, node }) => {
150
213
  if (node.type === "AssignmentExpression") {
151
214
  if (entering) {
152
- (node.operator === "=" ? openAssignmentsWithoutReads : openAssignmentsWithReads).add(node);
215
+ currentState.enterAssignment(node);
153
216
  } else {
154
- openAssignmentsWithoutReads.delete(node);
155
- openAssignmentsWithReads.delete(node);
217
+ currentState.exitAssignment(node);
156
218
  }
157
219
  } else if (!entering && (node.type === "AwaitExpression" || node.type === "YieldExpression")) {
158
- [...openAssignmentsWithReads]
159
- .filter(assignment => !isLocalVariableWithoutEscape(assignment.left, surroundingFunction))
160
- .forEach(reportAssignment);
161
-
162
- openAssignmentsWithReads.clear();
220
+ currentState.exitAwaitOrYield(node, surroundingFunction);
163
221
  } else if (!entering && (node.type === "Identifier" || node.type === "MemberExpression")) {
164
- [...openAssignmentsWithoutReads]
165
- .filter(assignment => (
166
- assignment.left !== node &&
167
- assignment.left.type === node.type &&
168
- astUtils.equalTokens(assignment.left, node, sourceCode)
169
- ))
170
- .forEach(assignment => {
171
- openAssignmentsWithoutReads.delete(assignment);
172
- openAssignmentsWithReads.add(assignment);
173
- });
222
+ currentState.exitIdentifierOrMemberExpression(node);
174
223
  }
175
224
  });
176
225
 
226
+ stateBySegmentEnd.set(codePathSegment, currentState);
227
+
177
228
  codePathSegment.nextSegments.forEach(nextSegment => {
229
+ if (stateBySegmentStart.has(nextSegment)) {
230
+ if (!stateBySegmentStart.get(nextSegment).merge(currentState)) {
231
+
232
+ /*
233
+ * This segment has already been processed with the given set of inputs;
234
+ * no need to do it again. After no new state is available to process
235
+ * for any control flow segment in the graph, the analysis reaches a fixpoint and
236
+ * traversal stops.
237
+ */
238
+ return;
239
+ }
240
+ } else {
241
+ stateBySegmentStart.set(nextSegment, currentState.copy());
242
+ }
178
243
  findOutdatedReads(
179
244
  nextSegment,
180
245
  surroundingFunction,
181
- {
182
- seenSegments: new Set(seenSegments).add(codePathSegment),
183
- openAssignmentsWithoutReads: new Set(openAssignmentsWithoutReads),
184
- openAssignmentsWithReads: new Set(openAssignmentsWithReads)
185
- }
246
+ { stateBySegmentStart, stateBySegmentEnd }
186
247
  );
187
248
  });
188
249
  }
@@ -31,12 +31,15 @@ function capitalizeFirstLetter(text) {
31
31
 
32
32
  module.exports = {
33
33
  meta: {
34
+ type: "suggestion",
35
+
34
36
  docs: {
35
37
  description: "disallow async functions which have no `await` expression",
36
38
  category: "Best Practices",
37
39
  recommended: false,
38
40
  url: "https://eslint.org/docs/rules/require-await"
39
41
  },
42
+
40
43
  schema: []
41
44
  },
42
45
 
@@ -6,6 +6,8 @@
6
6
 
7
7
  module.exports = {
8
8
  meta: {
9
+ type: "suggestion",
10
+
9
11
  docs: {
10
12
  description: "require JSDoc comments",
11
13
  category: "Stylistic Issues",
@@ -22,15 +22,19 @@ const {
22
22
 
23
23
  module.exports = {
24
24
  meta: {
25
+ type: "suggestion",
26
+
25
27
  docs: {
26
28
  description: "enforce the use of `u` flag on RegExp",
27
29
  category: "Best Practices",
28
30
  recommended: false,
29
31
  url: "https://eslint.org/docs/rules/require-unicode-regexp"
30
32
  },
33
+
31
34
  messages: {
32
35
  requireUFlag: "Use the 'u' flag."
33
36
  },
37
+
34
38
  schema: []
35
39
  },
36
40
 
@@ -11,6 +11,8 @@
11
11
 
12
12
  module.exports = {
13
13
  meta: {
14
+ type: "suggestion",
15
+
14
16
  docs: {
15
17
  description: "require generator functions to contain `yield`",
16
18
  category: "ECMAScript 6",
@@ -11,13 +11,17 @@
11
11
 
12
12
  module.exports = {
13
13
  meta: {
14
+ type: "layout",
15
+
14
16
  docs: {
15
17
  description: "enforce spacing between rest and spread operators and their expressions",
16
18
  category: "ECMAScript 6",
17
19
  recommended: false,
18
20
  url: "https://eslint.org/docs/rules/rest-spread-spacing"
19
21
  },
22
+
20
23
  fixable: "whitespace",
24
+
21
25
  schema: [
22
26
  {
23
27
  enum: ["always", "never"]
@@ -13,6 +13,8 @@ const astUtils = require("../util/ast-utils");
13
13
 
14
14
  module.exports = {
15
15
  meta: {
16
+ type: "layout",
17
+
16
18
  docs: {
17
19
  description: "enforce consistent spacing before and after semicolons",
18
20
  category: "Stylistic Issues",
@@ -65,12 +65,15 @@ function isLastChild(node) {
65
65
 
66
66
  module.exports = {
67
67
  meta: {
68
+ type: "layout",
69
+
68
70
  docs: {
69
71
  description: "enforce location of semicolons",
70
72
  category: "Stylistic Issues",
71
73
  recommended: false,
72
74
  url: "https://eslint.org/docs/rules/semi-style"
73
75
  },
76
+
74
77
  schema: [{ enum: ["last", "first"] }],
75
78
  fixable: "whitespace"
76
79
  },
package/lib/rules/semi.js CHANGED
@@ -17,6 +17,8 @@ const astUtils = require("../util/ast-utils");
17
17
 
18
18
  module.exports = {
19
19
  meta: {
20
+ type: "layout",
21
+
20
22
  docs: {
21
23
  description: "require or disallow semicolons instead of ASI",
22
24
  category: "Stylistic Issues",
@@ -11,6 +11,8 @@
11
11
 
12
12
  module.exports = {
13
13
  meta: {
14
+ type: "suggestion",
15
+
14
16
  docs: {
15
17
  description: "enforce sorted import declarations within modules",
16
18
  category: "ECMAScript 6",
@@ -73,12 +73,15 @@ const isValidOrders = {
73
73
 
74
74
  module.exports = {
75
75
  meta: {
76
+ type: "suggestion",
77
+
76
78
  docs: {
77
79
  description: "require object keys to be sorted",
78
80
  category: "Stylistic Issues",
79
81
  recommended: false,
80
82
  url: "https://eslint.org/docs/rules/sort-keys"
81
83
  },
84
+
82
85
  schema: [
83
86
  {
84
87
  enum: ["asc", "desc"]
@@ -11,6 +11,8 @@
11
11
 
12
12
  module.exports = {
13
13
  meta: {
14
+ type: "suggestion",
15
+
14
16
  docs: {
15
17
  description: "require variables within the same declaration block to be sorted",
16
18
  category: "Stylistic Issues",
@@ -13,6 +13,8 @@ const astUtils = require("../util/ast-utils");
13
13
 
14
14
  module.exports = {
15
15
  meta: {
16
+ type: "layout",
17
+
16
18
  docs: {
17
19
  description: "enforce consistent spacing before blocks",
18
20
  category: "Stylistic Issues",
@@ -32,13 +34,13 @@ module.exports = {
32
34
  type: "object",
33
35
  properties: {
34
36
  keywords: {
35
- enum: ["always", "never"]
37
+ enum: ["always", "never", "off"]
36
38
  },
37
39
  functions: {
38
- enum: ["always", "never"]
40
+ enum: ["always", "never", "off"]
39
41
  },
40
42
  classes: {
41
- enum: ["always", "never"]
43
+ enum: ["always", "never", "off"]
42
44
  }
43
45
  },
44
46
  additionalProperties: false
@@ -51,18 +53,27 @@ module.exports = {
51
53
  create(context) {
52
54
  const config = context.options[0],
53
55
  sourceCode = context.getSourceCode();
54
- let checkFunctions = true,
55
- checkKeywords = true,
56
- checkClasses = true;
56
+ let alwaysFunctions = true,
57
+ alwaysKeywords = true,
58
+ alwaysClasses = true,
59
+ neverFunctions = false,
60
+ neverKeywords = false,
61
+ neverClasses = false;
57
62
 
58
63
  if (typeof config === "object") {
59
- checkFunctions = config.functions !== "never";
60
- checkKeywords = config.keywords !== "never";
61
- checkClasses = config.classes !== "never";
64
+ alwaysFunctions = config.functions === "always";
65
+ alwaysKeywords = config.keywords === "always";
66
+ alwaysClasses = config.classes === "always";
67
+ neverFunctions = config.functions === "never";
68
+ neverKeywords = config.keywords === "never";
69
+ neverClasses = config.classes === "never";
62
70
  } else if (config === "never") {
63
- checkFunctions = false;
64
- checkKeywords = false;
65
- checkClasses = false;
71
+ alwaysFunctions = false;
72
+ alwaysKeywords = false;
73
+ alwaysClasses = false;
74
+ neverFunctions = true;
75
+ neverKeywords = true;
76
+ neverClasses = true;
66
77
  }
67
78
 
68
79
  /**
@@ -88,35 +99,35 @@ module.exports = {
88
99
  const hasSpace = sourceCode.isSpaceBetweenTokens(precedingToken, node);
89
100
  const parent = context.getAncestors().pop();
90
101
  let requireSpace;
102
+ let requireNoSpace;
91
103
 
92
104
  if (parent.type === "FunctionExpression" || parent.type === "FunctionDeclaration") {
93
- requireSpace = checkFunctions;
105
+ requireSpace = alwaysFunctions;
106
+ requireNoSpace = neverFunctions;
94
107
  } else if (node.type === "ClassBody") {
95
- requireSpace = checkClasses;
108
+ requireSpace = alwaysClasses;
109
+ requireNoSpace = neverClasses;
96
110
  } else {
97
- requireSpace = checkKeywords;
111
+ requireSpace = alwaysKeywords;
112
+ requireNoSpace = neverKeywords;
98
113
  }
99
114
 
100
- if (requireSpace) {
101
- if (!hasSpace) {
102
- context.report({
103
- node,
104
- message: "Missing space before opening brace.",
105
- fix(fixer) {
106
- return fixer.insertTextBefore(node, " ");
107
- }
108
- });
109
- }
110
- } else {
111
- if (hasSpace) {
112
- context.report({
113
- node,
114
- message: "Unexpected space before opening brace.",
115
- fix(fixer) {
116
- return fixer.removeRange([precedingToken.range[1], node.range[0]]);
117
- }
118
- });
119
- }
115
+ if (requireSpace && !hasSpace) {
116
+ context.report({
117
+ node,
118
+ message: "Missing space before opening brace.",
119
+ fix(fixer) {
120
+ return fixer.insertTextBefore(node, " ");
121
+ }
122
+ });
123
+ } else if (requireNoSpace && hasSpace) {
124
+ context.report({
125
+ node,
126
+ message: "Unexpected space before opening brace.",
127
+ fix(fixer) {
128
+ return fixer.removeRange([precedingToken.range[1], node.range[0]]);
129
+ }
130
+ });
120
131
  }
121
132
  }
122
133
  }
@@ -16,6 +16,8 @@ const astUtils = require("../util/ast-utils");
16
16
 
17
17
  module.exports = {
18
18
  meta: {
19
+ type: "layout",
20
+
19
21
  docs: {
20
22
  description: "enforce consistent spacing before `function` definition opening parenthesis",
21
23
  category: "Stylistic Issues",
@@ -12,6 +12,8 @@ const astUtils = require("../util/ast-utils");
12
12
 
13
13
  module.exports = {
14
14
  meta: {
15
+ type: "layout",
16
+
15
17
  docs: {
16
18
  description: "enforce consistent spacing inside parentheses",
17
19
  category: "Stylistic Issues",
@@ -10,6 +10,8 @@
10
10
 
11
11
  module.exports = {
12
12
  meta: {
13
+ type: "layout",
14
+
13
15
  docs: {
14
16
  description: "require spacing around infix operators",
15
17
  category: "Stylistic Issues",
@@ -34,37 +36,25 @@ module.exports = {
34
36
 
35
37
  create(context) {
36
38
  const int32Hint = context.options[0] ? context.options[0].int32Hint === true : false;
37
-
38
- const OPERATORS = [
39
- "*", "/", "%", "+", "-", "<<", ">>", ">>>", "<", "<=", ">", ">=", "in",
40
- "instanceof", "==", "!=", "===", "!==", "&", "^", "|", "&&", "||", "=",
41
- "+=", "-=", "*=", "/=", "%=", "<<=", ">>=", ">>>=", "&=", "^=", "|=",
42
- "?", ":", ",", "**"
43
- ];
44
-
45
39
  const sourceCode = context.getSourceCode();
46
40
 
47
41
  /**
48
42
  * Returns the first token which violates the rule
49
43
  * @param {ASTNode} left - The left node of the main node
50
44
  * @param {ASTNode} right - The right node of the main node
45
+ * @param {string} op - The operator of the main node
51
46
  * @returns {Object} The violator token or null
52
47
  * @private
53
48
  */
54
- function getFirstNonSpacedToken(left, right) {
55
- const tokens = sourceCode.getTokensBetween(left, right, 1);
56
-
57
- for (let i = 1, l = tokens.length - 1; i < l; ++i) {
58
- const op = tokens[i];
59
-
60
- if (
61
- (op.type === "Punctuator" || op.type === "Keyword") &&
62
- OPERATORS.indexOf(op.value) >= 0 &&
63
- (tokens[i - 1].range[1] >= op.range[0] || op.range[1] >= tokens[i + 1].range[0])
64
- ) {
65
- return op;
66
- }
49
+ function getFirstNonSpacedToken(left, right, op) {
50
+ const operator = sourceCode.getFirstTokenBetween(left, right, token => token.value === op);
51
+ const prev = sourceCode.getTokenBefore(operator);
52
+ const next = sourceCode.getTokenAfter(operator);
53
+
54
+ if (!sourceCode.isSpaceBetweenTokens(prev, operator) || !sourceCode.isSpaceBetweenTokens(operator, next)) {
55
+ return operator;
67
56
  }
57
+
68
58
  return null;
69
59
  }
70
60
 
@@ -110,7 +100,10 @@ module.exports = {
110
100
  const leftNode = (node.left.typeAnnotation) ? node.left.typeAnnotation : node.left;
111
101
  const rightNode = node.right;
112
102
 
113
- const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode);
103
+ // search for = in AssignmentPattern nodes
104
+ const operator = node.operator || "=";
105
+
106
+ const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, operator);
114
107
 
115
108
  if (nonSpacedNode) {
116
109
  if (!(int32Hint && sourceCode.getText(node).endsWith("|0"))) {
@@ -126,8 +119,8 @@ module.exports = {
126
119
  * @private
127
120
  */
128
121
  function checkConditional(node) {
129
- const nonSpacedConsequesntNode = getFirstNonSpacedToken(node.test, node.consequent);
130
- const nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate);
122
+ const nonSpacedConsequesntNode = getFirstNonSpacedToken(node.test, node.consequent, "?");
123
+ const nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate, ":");
131
124
 
132
125
  if (nonSpacedConsequesntNode) {
133
126
  report(node, nonSpacedConsequesntNode);
@@ -147,7 +140,7 @@ module.exports = {
147
140
  const rightNode = node.init;
148
141
 
149
142
  if (rightNode) {
150
- const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode);
143
+ const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, "=");
151
144
 
152
145
  if (nonSpacedNode) {
153
146
  report(node, nonSpacedNode);
@@ -16,6 +16,8 @@ const astUtils = require("../util/ast-utils");
16
16
 
17
17
  module.exports = {
18
18
  meta: {
19
+ type: "layout",
20
+
19
21
  docs: {
20
22
  description: "enforce consistent spacing before or after unary operators",
21
23
  category: "Stylistic Issues",
@@ -151,6 +151,8 @@ function createNeverStylePattern(markers) {
151
151
 
152
152
  module.exports = {
153
153
  meta: {
154
+ type: "suggestion",
155
+
154
156
  docs: {
155
157
  description: "enforce consistent spacing after the `//` or `/*` in a comment",
156
158
  category: "Stylistic Issues",
@@ -80,6 +80,8 @@ function isSimpleParameterList(params) {
80
80
 
81
81
  module.exports = {
82
82
  meta: {
83
+ type: "suggestion",
84
+
83
85
  docs: {
84
86
  description: "require or disallow strict mode directives",
85
87
  category: "Strict Mode",
@@ -17,12 +17,15 @@ const astUtils = require("../util/ast-utils");
17
17
 
18
18
  module.exports = {
19
19
  meta: {
20
+ type: "layout",
21
+
20
22
  docs: {
21
23
  description: "enforce spacing around colons of switch statements",
22
24
  category: "Stylistic Issues",
23
25
  recommended: false,
24
26
  url: "https://eslint.org/docs/rules/switch-colon-spacing"
25
27
  },
28
+
26
29
  schema: [
27
30
  {
28
31
  type: "object",
@@ -33,6 +36,7 @@ module.exports = {
33
36
  additionalProperties: false
34
37
  }
35
38
  ],
39
+
36
40
  fixable: "whitespace"
37
41
  },
38
42
 
@@ -18,6 +18,8 @@ const astUtils = require("../util/ast-utils");
18
18
 
19
19
  module.exports = {
20
20
  meta: {
21
+ type: "suggestion",
22
+
21
23
  docs: {
22
24
  description: "require symbol descriptions",
23
25
  category: "ECMAScript 6",
@@ -24,6 +24,8 @@ const CLOSE_PAREN = /^\}/;
24
24
 
25
25
  module.exports = {
26
26
  meta: {
27
+ type: "layout",
28
+
27
29
  docs: {
28
30
  description: "require or disallow spacing around embedded expressions of template strings",
29
31
  category: "ECMAScript 6",
@@ -11,6 +11,8 @@
11
11
 
12
12
  module.exports = {
13
13
  meta: {
14
+ type: "layout",
15
+
14
16
  docs: {
15
17
  description: "require or disallow spacing between template tags and their literals",
16
18
  category: "Stylistic Issues",
@@ -10,6 +10,8 @@
10
10
 
11
11
  module.exports = {
12
12
  meta: {
13
+ type: "layout",
14
+
13
15
  docs: {
14
16
  description: "require or disallow Unicode byte order mark (BOM)",
15
17
  category: "Stylistic Issues",
@@ -11,6 +11,8 @@
11
11
 
12
12
  module.exports = {
13
13
  meta: {
14
+ type: "problem",
15
+
14
16
  docs: {
15
17
  description: "require calls to `isNaN()` when checking for `NaN`",
16
18
  category: "Possible Errors",
@@ -16,6 +16,8 @@ const doctrine = require("doctrine");
16
16
 
17
17
  module.exports = {
18
18
  meta: {
19
+ type: "suggestion",
20
+
19
21
  docs: {
20
22
  description: "enforce valid JSDoc comments",
21
23
  category: "Possible Errors",