eslint 4.16.0 → 4.18.2

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 (89) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/conf/environments.js +3 -1
  3. package/conf/eslint-recommended.js +0 -0
  4. package/lib/linter.js +368 -366
  5. package/lib/rules/accessor-pairs.js +7 -3
  6. package/lib/rules/array-bracket-newline.js +11 -5
  7. package/lib/rules/array-bracket-spacing.js +11 -5
  8. package/lib/rules/array-callback-return.js +11 -5
  9. package/lib/rules/array-element-newline.js +8 -3
  10. package/lib/rules/arrow-body-style.js +16 -8
  11. package/lib/rules/arrow-parens.js +13 -9
  12. package/lib/rules/arrow-spacing.js +13 -5
  13. package/lib/rules/block-scoped-var.js +6 -2
  14. package/lib/rules/block-spacing.js +13 -6
  15. package/lib/rules/brace-style.js +16 -14
  16. package/lib/rules/callback-return.js +6 -2
  17. package/lib/rules/camelcase.js +6 -2
  18. package/lib/rules/capitalized-comments.js +11 -8
  19. package/lib/rules/class-methods-use-this.js +7 -3
  20. package/lib/rules/comma-dangle.js +7 -4
  21. package/lib/rules/comma-spacing.js +13 -10
  22. package/lib/rules/comma-style.js +9 -4
  23. package/lib/rules/complexity.js +6 -2
  24. package/lib/rules/computed-property-spacing.js +13 -5
  25. package/lib/rules/consistent-return.js +12 -7
  26. package/lib/rules/consistent-this.js +9 -4
  27. package/lib/rules/constructor-super.js +17 -8
  28. package/lib/rules/curly.js +59 -80
  29. package/lib/rules/default-case.js +6 -2
  30. package/lib/rules/dot-location.js +8 -3
  31. package/lib/rules/dot-notation.js +10 -5
  32. package/lib/rules/eol-last.js +7 -3
  33. package/lib/rules/eqeqeq.js +6 -2
  34. package/lib/rules/indent.js +0 -1
  35. package/lib/rules/key-spacing.js +3 -2
  36. package/lib/rules/keyword-spacing.js +6 -1
  37. package/lib/rules/max-len.js +2 -1
  38. package/lib/rules/no-alert.js +19 -18
  39. package/lib/rules/no-array-constructor.js +6 -2
  40. package/lib/rules/no-await-in-loop.js +75 -57
  41. package/lib/rules/no-bitwise.js +6 -2
  42. package/lib/rules/no-buffer-constructor.js +6 -3
  43. package/lib/rules/no-caller.js +6 -2
  44. package/lib/rules/no-case-declarations.js +6 -2
  45. package/lib/rules/no-catch-shadow.js +6 -2
  46. package/lib/rules/no-class-assign.js +6 -2
  47. package/lib/rules/no-compare-neg-zero.js +5 -2
  48. package/lib/rules/no-cond-assign.js +10 -4
  49. package/lib/rules/no-confusing-arrow.js +6 -2
  50. package/lib/rules/no-console.js +6 -2
  51. package/lib/rules/no-const-assign.js +6 -2
  52. package/lib/rules/no-constant-condition.js +6 -3
  53. package/lib/rules/no-continue.js +6 -2
  54. package/lib/rules/no-control-regex.js +7 -3
  55. package/lib/rules/no-debugger.js +5 -2
  56. package/lib/rules/no-delete-var.js +6 -2
  57. package/lib/rules/no-div-regex.js +6 -2
  58. package/lib/rules/no-dupe-args.js +6 -2
  59. package/lib/rules/no-dupe-class-members.js +6 -2
  60. package/lib/rules/no-dupe-keys.js +6 -2
  61. package/lib/rules/no-duplicate-case.js +6 -2
  62. package/lib/rules/no-else-return.js +7 -2
  63. package/lib/rules/no-empty-character-class.js +6 -2
  64. package/lib/rules/no-empty-function.js +6 -2
  65. package/lib/rules/no-empty-pattern.js +7 -3
  66. package/lib/rules/no-empty.js +7 -3
  67. package/lib/rules/no-eq-null.js +6 -2
  68. package/lib/rules/no-eval.js +6 -2
  69. package/lib/rules/no-ex-assign.js +6 -2
  70. package/lib/rules/no-extend-native.js +6 -2
  71. package/lib/rules/no-extra-bind.js +6 -2
  72. package/lib/rules/no-extra-boolean-cast.js +8 -3
  73. package/lib/rules/no-extra-label.js +6 -2
  74. package/lib/rules/no-extra-parens.js +5 -1
  75. package/lib/rules/no-extra-semi.js +6 -2
  76. package/lib/rules/no-self-assign.js +3 -1
  77. package/lib/rules/no-unused-vars.js +1 -1
  78. package/lib/rules/object-curly-newline.js +67 -19
  79. package/lib/rules/object-shorthand.js +9 -7
  80. package/lib/rules/padding-line-between-statements.js +6 -0
  81. package/lib/rules/require-await.js +5 -0
  82. package/lib/rules/rest-spread-spacing.js +6 -0
  83. package/lib/rules/space-unary-ops.js +1 -10
  84. package/lib/rules/template-tag-spacing.js +0 -0
  85. package/lib/util/glob-util.js +17 -4
  86. package/lib/util/interpolate.js +5 -1
  87. package/lib/util/npm-util.js +1 -1
  88. package/package.json +2 -2
  89. package/conf/default-config-options.js +0 -29
@@ -124,14 +124,17 @@ module.exports = {
124
124
  ]
125
125
  }
126
126
  ]
127
+ },
128
+
129
+ messages: {
130
+ unexpected: "Unexpected trailing comma.",
131
+ missing: "Missing trailing comma."
127
132
  }
128
133
  },
129
134
 
130
135
  create(context) {
131
136
  const options = normalizeOptions(context.options[0]);
132
137
  const sourceCode = context.getSourceCode();
133
- const UNEXPECTED_MESSAGE = "Unexpected trailing comma.";
134
- const MISSING_MESSAGE = "Missing trailing comma.";
135
138
 
136
139
  /**
137
140
  * Gets the last item of the given node.
@@ -230,7 +233,7 @@ module.exports = {
230
233
  context.report({
231
234
  node: lastItem,
232
235
  loc: trailingToken.loc.start,
233
- message: UNEXPECTED_MESSAGE,
236
+ messageId: "unexpected",
234
237
  fix(fixer) {
235
238
  return fixer.remove(trailingToken);
236
239
  }
@@ -267,7 +270,7 @@ module.exports = {
267
270
  context.report({
268
271
  node: lastItem,
269
272
  loc: trailingToken.loc.end,
270
- message: MISSING_MESSAGE,
273
+ messageId: "missing",
271
274
  fix(fixer) {
272
275
  return fixer.insertTextAfter(trailingToken, ",");
273
276
  }
@@ -34,7 +34,12 @@ module.exports = {
34
34
  },
35
35
  additionalProperties: false
36
36
  }
37
- ]
37
+ ],
38
+
39
+ messages: {
40
+ missing: "A space is required {{loc}} ','.",
41
+ unexpected: "There should be no space {{loc}} ','."
42
+ }
38
43
  },
39
44
 
40
45
  create(context) {
@@ -57,17 +62,17 @@ module.exports = {
57
62
  /**
58
63
  * Reports a spacing error with an appropriate message.
59
64
  * @param {ASTNode} node The binary expression node to report.
60
- * @param {string} dir Is the error "before" or "after" the comma?
65
+ * @param {string} loc Is the error "before" or "after" the comma?
61
66
  * @param {ASTNode} otherNode The node at the left or right of `node`
62
67
  * @returns {void}
63
68
  * @private
64
69
  */
65
- function report(node, dir, otherNode) {
70
+ function report(node, loc, otherNode) {
66
71
  context.report({
67
72
  node,
68
73
  fix(fixer) {
69
- if (options[dir]) {
70
- if (dir === "before") {
74
+ if (options[loc]) {
75
+ if (loc === "before") {
71
76
  return fixer.insertTextBefore(node, " ");
72
77
  }
73
78
  return fixer.insertTextAfter(node, " ");
@@ -76,7 +81,7 @@ module.exports = {
76
81
  let start, end;
77
82
  const newText = "";
78
83
 
79
- if (dir === "before") {
84
+ if (loc === "before") {
80
85
  start = otherNode.range[1];
81
86
  end = node.range[0];
82
87
  } else {
@@ -87,11 +92,9 @@ module.exports = {
87
92
  return fixer.replaceTextRange([start, end], newText);
88
93
 
89
94
  },
90
- message: options[dir]
91
- ? "A space is required {{dir}} ','."
92
- : "There should be no space {{dir}} ','.",
95
+ messageId: options[loc] ? "missing" : "unexpected",
93
96
  data: {
94
- dir
97
+ loc
95
98
  }
96
99
  });
97
100
  }
@@ -36,7 +36,12 @@ module.exports = {
36
36
  },
37
37
  additionalProperties: false
38
38
  }
39
- ]
39
+ ],
40
+ messages: {
41
+ unexpectedLineBeforeAndAfterComma: "Bad line breaking before and after ','.",
42
+ expectedCommaFirst: "',' should be placed first.",
43
+ expectedCommaLast: "',' should be placed last."
44
+ }
40
45
  },
41
46
 
42
47
  create(context) {
@@ -135,7 +140,7 @@ module.exports = {
135
140
  line: commaToken.loc.end.line,
136
141
  column: commaToken.loc.start.column
137
142
  },
138
- message: "Bad line breaking before and after ','.",
143
+ messageId: "unexpectedLineBeforeAndAfterComma",
139
144
  fix: getFixerFunction("between", previousItemToken, commaToken, currentItemToken)
140
145
  });
141
146
 
@@ -143,7 +148,7 @@ module.exports = {
143
148
 
144
149
  context.report({
145
150
  node: reportItem,
146
- message: "',' should be placed first.",
151
+ messageId: "expectedCommaFirst",
147
152
  fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
148
153
  });
149
154
 
@@ -155,7 +160,7 @@ module.exports = {
155
160
  line: commaToken.loc.end.line,
156
161
  column: commaToken.loc.end.column
157
162
  },
158
- message: "',' should be placed last.",
163
+ messageId: "expectedCommaLast",
159
164
  fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken)
160
165
  });
161
166
  }
@@ -50,7 +50,11 @@ module.exports = {
50
50
  }
51
51
  ]
52
52
  }
53
- ]
53
+ ],
54
+
55
+ messages: {
56
+ complex: "{{name}} has a complexity of {{complexity}}."
57
+ }
54
58
  },
55
59
 
56
60
  create(context) {
@@ -96,7 +100,7 @@ module.exports = {
96
100
  if (complexity > THRESHOLD) {
97
101
  context.report({
98
102
  node,
99
- message: "{{name}} has a complexity of {{complexity}}.",
103
+ messageId: "complex",
100
104
  data: { name, complexity }
101
105
  });
102
106
  }
@@ -25,7 +25,15 @@ module.exports = {
25
25
  {
26
26
  enum: ["always", "never"]
27
27
  }
28
- ]
28
+ ],
29
+
30
+ messages: {
31
+ unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.",
32
+ unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.",
33
+
34
+ missingSpaceBefore: "A space is required before '{{tokenValue}}'.",
35
+ missingSpaceAfter: "A space is required after '{{tokenValue}}'."
36
+ }
29
37
  },
30
38
 
31
39
  create(context) {
@@ -47,7 +55,7 @@ module.exports = {
47
55
  context.report({
48
56
  node,
49
57
  loc: token.loc.start,
50
- message: "There should be no space after '{{tokenValue}}'.",
58
+ messageId: "unexpectedSpaceAfter",
51
59
  data: {
52
60
  tokenValue: token.value
53
61
  },
@@ -68,7 +76,7 @@ module.exports = {
68
76
  context.report({
69
77
  node,
70
78
  loc: token.loc.start,
71
- message: "There should be no space before '{{tokenValue}}'.",
79
+ messageId: "unexpectedSpaceBefore",
72
80
  data: {
73
81
  tokenValue: token.value
74
82
  },
@@ -88,7 +96,7 @@ module.exports = {
88
96
  context.report({
89
97
  node,
90
98
  loc: token.loc.start,
91
- message: "A space is required after '{{tokenValue}}'.",
99
+ messageId: "missingSpaceAfter",
92
100
  data: {
93
101
  tokenValue: token.value
94
102
  },
@@ -108,7 +116,7 @@ module.exports = {
108
116
  context.report({
109
117
  node,
110
118
  loc: token.loc.start,
111
- message: "A space is required before '{{tokenValue}}'.",
119
+ messageId: "missingSpaceBefore",
112
120
  data: {
113
121
  tokenValue: token.value
114
122
  },
@@ -68,7 +68,13 @@ module.exports = {
68
68
  }
69
69
  },
70
70
  additionalProperties: false
71
- }]
71
+ }],
72
+
73
+ messages: {
74
+ missingReturn: "Expected to return a value at the end of {{name}}.",
75
+ missingReturnValue: "{{name}} expected a return value.",
76
+ unexpectedReturnValue: "{{name}} expected no return value."
77
+ }
72
78
  },
73
79
 
74
80
  create(context) {
@@ -129,7 +135,7 @@ module.exports = {
129
135
  context.report({
130
136
  node,
131
137
  loc,
132
- message: "Expected to return a value at the end of {{name}}.",
138
+ messageId: "missingReturn",
133
139
  data: { name }
134
140
  });
135
141
  }
@@ -143,7 +149,7 @@ module.exports = {
143
149
  codePath,
144
150
  hasReturn: false,
145
151
  hasReturnValue: false,
146
- message: "",
152
+ messageId: "",
147
153
  node
148
154
  };
149
155
  },
@@ -163,17 +169,16 @@ module.exports = {
163
169
  if (!funcInfo.hasReturn) {
164
170
  funcInfo.hasReturn = true;
165
171
  funcInfo.hasReturnValue = hasReturnValue;
166
- funcInfo.message = "{{name}} expected {{which}} return value.";
172
+ funcInfo.messageId = hasReturnValue ? "missingReturnValue" : "unexpectedReturnValue";
167
173
  funcInfo.data = {
168
174
  name: funcInfo.node.type === "Program"
169
175
  ? "Program"
170
- : lodash.upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node)),
171
- which: hasReturnValue ? "a" : "no"
176
+ : lodash.upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node))
172
177
  };
173
178
  } else if (funcInfo.hasReturnValue !== hasReturnValue) {
174
179
  context.report({
175
180
  node,
176
- message: funcInfo.message,
181
+ messageId: funcInfo.messageId,
177
182
  data: funcInfo.data
178
183
  });
179
184
  }
@@ -24,6 +24,11 @@ module.exports = {
24
24
  minLength: 1
25
25
  },
26
26
  uniqueItems: true
27
+ },
28
+
29
+ messages: {
30
+ aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.",
31
+ unexpectedAlias: "Unexpected alias '{{name}}' for 'this'."
27
32
  }
28
33
  },
29
34
 
@@ -40,11 +45,11 @@ module.exports = {
40
45
  * Reports that a variable declarator or assignment expression is assigning
41
46
  * a non-'this' value to the specified alias.
42
47
  * @param {ASTNode} node - The assigning node.
43
- * @param {string} alias - the name of the alias that was incorrectly used.
48
+ * @param {string} name - the name of the alias that was incorrectly used.
44
49
  * @returns {void}
45
50
  */
46
- function reportBadAssignment(node, alias) {
47
- context.report({ node, message: "Designated alias '{{alias}}' is not assigned to 'this'.", data: { alias } });
51
+ function reportBadAssignment(node, name) {
52
+ context.report({ node, messageId: "aliasNotAssignedToThis", data: { name } });
48
53
  }
49
54
 
50
55
  /**
@@ -63,7 +68,7 @@ module.exports = {
63
68
  reportBadAssignment(node, name);
64
69
  }
65
70
  } else if (isThis) {
66
- context.report({ node, message: "Unexpected alias '{{name}}' for 'this'.", data: { name } });
71
+ context.report({ node, messageId: "unexpectedAlias", data: { name } });
67
72
  }
68
73
  }
69
74
 
@@ -99,7 +99,16 @@ module.exports = {
99
99
  url: "https://eslint.org/docs/rules/constructor-super"
100
100
  },
101
101
 
102
- schema: []
102
+ schema: [],
103
+
104
+ messages: {
105
+ missingSome: "Lacked a call of 'super()' in some code paths.",
106
+ missingAll: "Expected to call 'super()'.",
107
+
108
+ duplicate: "Unexpected duplicate 'super()'.",
109
+ badSuper: "Unexpected 'super()' because 'super' is not a constructor.",
110
+ unexpected: "Unexpected 'super()'."
111
+ }
103
112
  },
104
113
 
105
114
  create(context) {
@@ -210,9 +219,9 @@ module.exports = {
210
219
 
211
220
  if (!calledInEveryPaths) {
212
221
  context.report({
213
- message: calledInSomePaths
214
- ? "Lacked a call of 'super()' in some code paths."
215
- : "Expected to call 'super()'.",
222
+ messageId: calledInSomePaths
223
+ ? "missingSome"
224
+ : "missingAll",
216
225
  node: node.parent
217
226
  });
218
227
  }
@@ -281,7 +290,7 @@ module.exports = {
281
290
  const node = nodes[i];
282
291
 
283
292
  context.report({
284
- message: "Unexpected duplicate 'super()'.",
293
+ messageId: "duplicate",
285
294
  node
286
295
  });
287
296
  }
@@ -325,12 +334,12 @@ module.exports = {
325
334
  if (info) {
326
335
  if (duplicate) {
327
336
  context.report({
328
- message: "Unexpected duplicate 'super()'.",
337
+ messageId: "duplicate",
329
338
  node
330
339
  });
331
340
  } else if (!funcInfo.superIsConstructor) {
332
341
  context.report({
333
- message: "Unexpected 'super()' because 'super' is not a constructor.",
342
+ messageId: "badSuper",
334
343
  node
335
344
  });
336
345
  } else {
@@ -339,7 +348,7 @@ module.exports = {
339
348
  }
340
349
  } else if (funcInfo.codePath.currentSegments.some(isReachable)) {
341
350
  context.report({
342
- message: "Unexpected 'super()'.",
351
+ messageId: "unexpected",
343
352
  node
344
353
  });
345
354
  }
@@ -51,7 +51,14 @@ module.exports = {
51
51
  ]
52
52
  },
53
53
 
54
- fixable: "code"
54
+ fixable: "code",
55
+
56
+ messages: {
57
+ missingCurlyAfter: "Expected { after '{{name}}'.",
58
+ missingCurlyAfterCondition: "Expected { after '{{name}}' condition.",
59
+ unexpectedCurlyAfter: "Unnecessary { after '{{name}}'.",
60
+ unexpectedCurlyAfterCondition: "Unnecessary { after '{{name}}' condition."
61
+ }
55
62
  },
56
63
 
57
64
  create(context) {
@@ -142,28 +149,6 @@ module.exports = {
142
149
  return false;
143
150
  }
144
151
 
145
- /**
146
- * Reports "Expected { after ..." error
147
- * @param {ASTNode} node The node to report.
148
- * @param {ASTNode} bodyNode The body node that is incorrectly missing curly brackets
149
- * @param {string} name The name to report.
150
- * @param {string} suffix Additional string to add to the end of a report.
151
- * @returns {void}
152
- * @private
153
- */
154
- function reportExpectedBraceError(node, bodyNode, name, suffix) {
155
- context.report({
156
- node,
157
- loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
158
- message: "Expected { after '{{name}}'{{suffix}}.",
159
- data: {
160
- name,
161
- suffix: (suffix ? ` ${suffix}` : "")
162
- },
163
- fix: fixer => fixer.replaceText(bodyNode, `{${sourceCode.getText(bodyNode)}}`)
164
- });
165
- }
166
-
167
152
  /**
168
153
  * Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError.
169
154
  * @param {Token} closingBracket The } token
@@ -218,62 +203,12 @@ module.exports = {
218
203
  return false;
219
204
  }
220
205
 
221
- /**
222
- * Reports "Unnecessary { after ..." error
223
- * @param {ASTNode} node The node to report.
224
- * @param {ASTNode} bodyNode The block statement that is incorrectly surrounded by parens
225
- * @param {string} name The name to report.
226
- * @param {string} suffix Additional string to add to the end of a report.
227
- * @returns {void}
228
- * @private
229
- */
230
- function reportUnnecessaryBraceError(node, bodyNode, name, suffix) {
231
- context.report({
232
- node,
233
- loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
234
- message: "Unnecessary { after '{{name}}'{{suffix}}.",
235
- data: {
236
- name,
237
- suffix: (suffix ? ` ${suffix}` : "")
238
- },
239
- fix(fixer) {
240
-
241
- /*
242
- * `do while` expressions sometimes need a space to be inserted after `do`.
243
- * e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)`
244
- */
245
- const needsPrecedingSpace = node.type === "DoWhileStatement" &&
246
- sourceCode.getTokenBefore(bodyNode).range[1] === bodyNode.range[0] &&
247
- !astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(bodyNode, { skip: 1 }));
248
-
249
- const openingBracket = sourceCode.getFirstToken(bodyNode);
250
- const closingBracket = sourceCode.getLastToken(bodyNode);
251
- const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket);
252
-
253
- if (needsSemicolon(closingBracket)) {
254
-
255
- /*
256
- * If removing braces would cause a SyntaxError due to multiple statements on the same line (or
257
- * change the semantics of the code due to ASI), don't perform a fix.
258
- */
259
- return null;
260
- }
261
-
262
- const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) +
263
- sourceCode.getText(lastTokenInBlock) +
264
- sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]);
265
-
266
- return fixer.replaceText(bodyNode, (needsPrecedingSpace ? " " : "") + resultingBodyText);
267
- }
268
- });
269
- }
270
-
271
206
  /**
272
207
  * Prepares to check the body of a node to see if it's a block statement.
273
208
  * @param {ASTNode} node The node to report if there's a problem.
274
209
  * @param {ASTNode} body The body node to check for blocks.
275
210
  * @param {string} name The name to report if there's a problem.
276
- * @param {string} suffix Additional string to add to the end of a report.
211
+ * @param {{ condition: boolean }} opts Options to pass to the report functions
277
212
  * @returns {Object} a prepared check object, with "actual", "expected", "check" properties.
278
213
  * "actual" will be `true` or `false` whether the body is already a block statement.
279
214
  * "expected" will be `true` or `false` if the body should be a block statement or not, or
@@ -282,7 +217,7 @@ module.exports = {
282
217
  * "check" will be a function reporting appropriate problems depending on the other
283
218
  * properties.
284
219
  */
285
- function prepareCheck(node, body, name, suffix) {
220
+ function prepareCheck(node, body, name, opts) {
286
221
  const hasBlock = (body.type === "BlockStatement");
287
222
  let expected = null;
288
223
 
@@ -314,9 +249,53 @@ module.exports = {
314
249
  check() {
315
250
  if (this.expected !== null && this.expected !== this.actual) {
316
251
  if (this.expected) {
317
- reportExpectedBraceError(node, body, name, suffix);
252
+ context.report({
253
+ node,
254
+ loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
255
+ messageId: opts && opts.condition ? "missingCurlyAfterCondition" : "missingCurlyAfter",
256
+ data: {
257
+ name
258
+ },
259
+ fix: fixer => fixer.replaceText(body, `{${sourceCode.getText(body)}}`)
260
+ });
318
261
  } else {
319
- reportUnnecessaryBraceError(node, body, name, suffix);
262
+ context.report({
263
+ node,
264
+ loc: (name !== "else" ? node : getElseKeyword(node)).loc.start,
265
+ messageId: opts && opts.condition ? "unexpectedCurlyAfterCondition" : "unexpectedCurlyAfter",
266
+ data: {
267
+ name
268
+ },
269
+ fix(fixer) {
270
+
271
+ /*
272
+ * `do while` expressions sometimes need a space to be inserted after `do`.
273
+ * e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)`
274
+ */
275
+ const needsPrecedingSpace = node.type === "DoWhileStatement" &&
276
+ sourceCode.getTokenBefore(body).range[1] === body.range[0] &&
277
+ !astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(body, { skip: 1 }));
278
+
279
+ const openingBracket = sourceCode.getFirstToken(body);
280
+ const closingBracket = sourceCode.getLastToken(body);
281
+ const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket);
282
+
283
+ if (needsSemicolon(closingBracket)) {
284
+
285
+ /*
286
+ * If removing braces would cause a SyntaxError due to multiple statements on the same line (or
287
+ * change the semantics of the code due to ASI), don't perform a fix.
288
+ */
289
+ return null;
290
+ }
291
+
292
+ const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) +
293
+ sourceCode.getText(lastTokenInBlock) +
294
+ sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]);
295
+
296
+ return fixer.replaceText(body, (needsPrecedingSpace ? " " : "") + resultingBodyText);
297
+ }
298
+ });
320
299
  }
321
300
  }
322
301
  }
@@ -333,7 +312,7 @@ module.exports = {
333
312
  const preparedChecks = [];
334
313
 
335
314
  do {
336
- preparedChecks.push(prepareCheck(node, node.consequent, "if", "condition"));
315
+ preparedChecks.push(prepareCheck(node, node.consequent, "if", { condition: true }));
337
316
  if (node.alternate && node.alternate.type !== "IfStatement") {
338
317
  preparedChecks.push(prepareCheck(node, node.alternate, "else"));
339
318
  break;
@@ -377,7 +356,7 @@ module.exports = {
377
356
  },
378
357
 
379
358
  WhileStatement(node) {
380
- prepareCheck(node, node.body, "while", "condition").check();
359
+ prepareCheck(node, node.body, "while", { condition: true }).check();
381
360
  },
382
361
 
383
362
  DoWhileStatement(node) {
@@ -385,7 +364,7 @@ module.exports = {
385
364
  },
386
365
 
387
366
  ForStatement(node) {
388
- prepareCheck(node, node.body, "for", "condition").check();
367
+ prepareCheck(node, node.body, "for", { condition: true }).check();
389
368
  },
390
369
 
391
370
  ForInStatement(node) {
@@ -27,7 +27,11 @@ module.exports = {
27
27
  }
28
28
  },
29
29
  additionalProperties: false
30
- }]
30
+ }],
31
+
32
+ messages: {
33
+ missingDefaultCase: "Expected a default case."
34
+ }
31
35
  },
32
36
 
33
37
  create(context) {
@@ -82,7 +86,7 @@ module.exports = {
82
86
  }
83
87
 
84
88
  if (!comment || !commentPattern.test(comment.value.trim())) {
85
- context.report({ node, message: "Expected a default case." });
89
+ context.report({ node, messageId: "missingDefaultCase" });
86
90
  }
87
91
  }
88
92
  }
@@ -26,7 +26,12 @@ module.exports = {
26
26
  }
27
27
  ],
28
28
 
29
- fixable: "code"
29
+ fixable: "code",
30
+
31
+ messages: {
32
+ expectedDotAfterObject: "Expected dot to be on same line as object.",
33
+ expectedDotBeforeProperty: "Expected dot to be on same line as property."
34
+ }
30
35
  },
31
36
 
32
37
  create(context) {
@@ -58,7 +63,7 @@ module.exports = {
58
63
  context.report({
59
64
  node,
60
65
  loc: dot.loc.start,
61
- message: "Expected dot to be on same line as object.",
66
+ messageId: "expectedDotAfterObject",
62
67
  fix: fixer => fixer.replaceTextRange([obj.range[1], prop.range[0]], `${neededTextAfterObj}.${textBeforeDot}${textAfterDot}`)
63
68
  });
64
69
  }
@@ -66,7 +71,7 @@ module.exports = {
66
71
  context.report({
67
72
  node,
68
73
  loc: dot.loc.start,
69
- message: "Expected dot to be on same line as property.",
74
+ messageId: "expectedDotBeforeProperty",
70
75
  fix: fixer => fixer.replaceTextRange([obj.range[1], prop.range[0]], `${textBeforeDot}${textAfterDot}.`)
71
76
  });
72
77
  }
@@ -41,7 +41,12 @@ module.exports = {
41
41
  }
42
42
  ],
43
43
 
44
- fixable: "code"
44
+ fixable: "code",
45
+
46
+ messages: {
47
+ useDot: "[{{key}}] is better written in dot notation.",
48
+ useBrackets: ".{{key}} is a syntax error."
49
+ }
45
50
  },
46
51
 
47
52
  create(context) {
@@ -71,9 +76,9 @@ module.exports = {
71
76
 
72
77
  context.report({
73
78
  node: node.property,
74
- message: "[{{propertyValue}}] is better written in dot notation.",
79
+ messageId: "useDot",
75
80
  data: {
76
- propertyValue: formattedValue
81
+ key: formattedValue
77
82
  },
78
83
  fix(fixer) {
79
84
  const leftBracket = sourceCode.getTokenAfter(node.object, astUtils.isOpeningBracketToken);
@@ -124,9 +129,9 @@ module.exports = {
124
129
  ) {
125
130
  context.report({
126
131
  node: node.property,
127
- message: ".{{propertyName}} is a syntax error.",
132
+ messageId: "useBrackets",
128
133
  data: {
129
- propertyName: node.property.name
134
+ key: node.property.name
130
135
  },
131
136
  fix(fixer) {
132
137
  const dot = sourceCode.getTokenBefore(node.property);