eslint 7.0.0-alpha.2 → 7.1.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 (90) hide show
  1. package/CHANGELOG.md +332 -0
  2. package/README.md +9 -10
  3. package/bin/eslint.js +115 -77
  4. package/conf/category-list.json +0 -1
  5. package/conf/environments.js +2 -1
  6. package/lib/api.js +2 -0
  7. package/lib/cli-engine/cascading-config-array-factory.js +16 -2
  8. package/lib/cli-engine/cli-engine.js +53 -47
  9. package/lib/cli-engine/config-array/config-array.js +30 -1
  10. package/lib/cli-engine/config-array/ignore-pattern.js +7 -1
  11. package/lib/cli-engine/config-array-factory.js +244 -235
  12. package/lib/cli.js +181 -95
  13. package/lib/eslint/eslint.js +656 -0
  14. package/lib/eslint/index.js +7 -0
  15. package/lib/init/autoconfig.js +4 -4
  16. package/lib/init/config-file.js +2 -2
  17. package/lib/init/config-initializer.js +3 -4
  18. package/lib/init/source-code-utils.js +2 -2
  19. package/lib/linter/linter.js +2 -1
  20. package/lib/linter/node-event-generator.js +2 -2
  21. package/lib/options.js +0 -1
  22. package/lib/rule-tester/rule-tester.js +132 -22
  23. package/lib/rules/accessor-pairs.js +1 -1
  24. package/lib/rules/array-callback-return.js +3 -18
  25. package/lib/rules/arrow-parens.js +19 -3
  26. package/lib/rules/block-spacing.js +19 -2
  27. package/lib/rules/callback-return.js +4 -0
  28. package/lib/rules/camelcase.js +38 -1
  29. package/lib/rules/comma-style.js +3 -8
  30. package/lib/rules/func-call-spacing.js +4 -3
  31. package/lib/rules/getter-return.js +2 -12
  32. package/lib/rules/global-require.js +4 -0
  33. package/lib/rules/handle-callback-err.js +4 -0
  34. package/lib/rules/id-blacklist.js +138 -102
  35. package/lib/rules/index.js +1 -0
  36. package/lib/rules/key-spacing.js +1 -1
  37. package/lib/rules/linebreak-style.js +8 -2
  38. package/lib/rules/max-lines-per-function.js +1 -1
  39. package/lib/rules/new-cap.js +1 -1
  40. package/lib/rules/newline-per-chained-call.js +6 -3
  41. package/lib/rules/no-alert.js +5 -3
  42. package/lib/rules/no-buffer-constructor.js +4 -0
  43. package/lib/rules/no-empty-function.js +4 -2
  44. package/lib/rules/no-eval.js +2 -1
  45. package/lib/rules/no-extra-bind.js +1 -1
  46. package/lib/rules/no-extra-boolean-cast.js +102 -23
  47. package/lib/rules/no-extra-parens.js +9 -5
  48. package/lib/rules/no-implied-eval.js +83 -101
  49. package/lib/rules/no-inner-declarations.js +31 -39
  50. package/lib/rules/no-lone-blocks.js +1 -1
  51. package/lib/rules/no-loss-of-precision.js +198 -0
  52. package/lib/rules/no-magic-numbers.js +72 -37
  53. package/lib/rules/no-mixed-requires.js +4 -0
  54. package/lib/rules/no-new-func.js +22 -19
  55. package/lib/rules/no-new-object.js +15 -3
  56. package/lib/rules/no-new-require.js +4 -0
  57. package/lib/rules/no-new-symbol.js +2 -1
  58. package/lib/rules/no-new-wrappers.js +1 -1
  59. package/lib/rules/no-obj-calls.js +24 -5
  60. package/lib/rules/no-path-concat.js +4 -0
  61. package/lib/rules/no-plusplus.js +39 -3
  62. package/lib/rules/no-process-env.js +4 -0
  63. package/lib/rules/no-process-exit.js +4 -0
  64. package/lib/rules/no-prototype-builtins.js +1 -1
  65. package/lib/rules/no-restricted-modules.js +4 -0
  66. package/lib/rules/no-sync.js +4 -0
  67. package/lib/rules/no-unexpected-multiline.js +22 -12
  68. package/lib/rules/no-useless-concat.js +1 -1
  69. package/lib/rules/one-var-declaration-per-line.js +1 -1
  70. package/lib/rules/operator-assignment.js +3 -3
  71. package/lib/rules/operator-linebreak.js +4 -16
  72. package/lib/rules/padded-blocks.js +17 -4
  73. package/lib/rules/prefer-numeric-literals.js +3 -3
  74. package/lib/rules/prefer-object-spread.js +2 -2
  75. package/lib/rules/require-await.js +1 -1
  76. package/lib/rules/rest-spread-spacing.js +3 -6
  77. package/lib/rules/semi-spacing.js +32 -8
  78. package/lib/rules/space-before-function-paren.js +5 -2
  79. package/lib/rules/template-curly-spacing.js +59 -42
  80. package/lib/rules/utils/ast-utils.js +116 -10
  81. package/lib/rules/yoda.js +101 -51
  82. package/lib/shared/relative-module-resolver.js +1 -0
  83. package/lib/shared/types.js +9 -2
  84. package/lib/source-code/source-code.js +1 -0
  85. package/messages/extend-config-missing.txt +1 -1
  86. package/messages/no-config-found.txt +1 -1
  87. package/messages/plugin-conflict.txt +7 -0
  88. package/messages/plugin-missing.txt +1 -1
  89. package/messages/whitespace-found.txt +1 -1
  90. package/package.json +27 -26
@@ -203,10 +203,14 @@ module.exports = {
203
203
  }
204
204
 
205
205
  if (requirePaddingFor(node)) {
206
+
206
207
  if (!blockHasTopPadding) {
207
208
  context.report({
208
209
  node,
209
- loc: { line: tokenBeforeFirst.loc.start.line, column: tokenBeforeFirst.loc.start.column },
210
+ loc: {
211
+ start: tokenBeforeFirst.loc.start,
212
+ end: firstBlockToken.loc.start
213
+ },
210
214
  fix(fixer) {
211
215
  return fixer.insertTextAfter(tokenBeforeFirst, "\n");
212
216
  },
@@ -216,7 +220,10 @@ module.exports = {
216
220
  if (!blockHasBottomPadding) {
217
221
  context.report({
218
222
  node,
219
- loc: { line: tokenAfterLast.loc.end.line, column: tokenAfterLast.loc.end.column - 1 },
223
+ loc: {
224
+ end: tokenAfterLast.loc.start,
225
+ start: lastBlockToken.loc.end
226
+ },
220
227
  fix(fixer) {
221
228
  return fixer.insertTextBefore(tokenAfterLast, "\n");
222
229
  },
@@ -228,7 +235,10 @@ module.exports = {
228
235
 
229
236
  context.report({
230
237
  node,
231
- loc: { line: tokenBeforeFirst.loc.start.line, column: tokenBeforeFirst.loc.start.column },
238
+ loc: {
239
+ start: tokenBeforeFirst.loc.start,
240
+ end: firstBlockToken.loc.start
241
+ },
232
242
  fix(fixer) {
233
243
  return fixer.replaceTextRange([tokenBeforeFirst.range[1], firstBlockToken.range[0] - firstBlockToken.loc.start.column], "\n");
234
244
  },
@@ -240,7 +250,10 @@ module.exports = {
240
250
 
241
251
  context.report({
242
252
  node,
243
- loc: { line: tokenAfterLast.loc.end.line, column: tokenAfterLast.loc.end.column - 1 },
253
+ loc: {
254
+ end: tokenAfterLast.loc.start,
255
+ start: lastBlockToken.loc.end
256
+ },
244
257
  messageId: "neverPadBlock",
245
258
  fix(fixer) {
246
259
  return fixer.replaceTextRange([lastBlockToken.range[1], tokenAfterLast.range[0] - tokenAfterLast.loc.start.column], "\n");
@@ -79,13 +79,13 @@ module.exports = {
79
79
 
80
80
  "CallExpression[arguments.length=2]"(node) {
81
81
  const [strNode, radixNode] = node.arguments,
82
- str = strNode.value,
82
+ str = astUtils.getStaticStringValue(strNode),
83
83
  radix = radixNode.value;
84
84
 
85
85
  if (
86
- strNode.type === "Literal" &&
86
+ str !== null &&
87
+ astUtils.isStringLiteral(strNode) &&
87
88
  radixNode.type === "Literal" &&
88
- typeof str === "string" &&
89
89
  typeof radix === "number" &&
90
90
  radixMap.has(radix) &&
91
91
  isParseInt(node.callee)
@@ -181,8 +181,8 @@ function defineFixer(node, sourceCode) {
181
181
  const leftParen = sourceCode.getTokenAfter(node.callee, isOpeningParenToken);
182
182
  const rightParen = sourceCode.getLastToken(node);
183
183
 
184
- // Remove the callee `Object.assign`
185
- yield fixer.remove(node.callee);
184
+ // Remove everything before the opening paren: callee `Object.assign`, type arguments, and whitespace between the callee and the paren.
185
+ yield fixer.removeRange([node.range[0], leftParen.range[0]]);
186
186
 
187
187
  // Replace the parens of argument list to braces.
188
188
  if (needsParens(node, sourceCode)) {
@@ -68,7 +68,7 @@ module.exports = {
68
68
  * @returns {void}
69
69
  */
70
70
  function exitFunction(node) {
71
- if (node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) {
71
+ if (!node.generator && node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) {
72
72
  context.report({
73
73
  node,
74
74
  loc: astUtils.getFunctionHeadLoc(node, sourceCode),
@@ -79,10 +79,7 @@ module.exports = {
79
79
  if (alwaysSpace && !hasWhitespace) {
80
80
  context.report({
81
81
  node,
82
- loc: {
83
- line: operator.loc.end.line,
84
- column: operator.loc.end.column
85
- },
82
+ loc: operator.loc,
86
83
  messageId: "expectedWhitespace",
87
84
  data: {
88
85
  type
@@ -95,8 +92,8 @@ module.exports = {
95
92
  context.report({
96
93
  node,
97
94
  loc: {
98
- line: operator.loc.end.line,
99
- column: operator.loc.end.column
95
+ start: operator.loc.end,
96
+ end: nextToken.loc.start
100
97
  },
101
98
  messageId: "unexpectedWhitespace",
102
99
  data: {
@@ -117,6 +117,18 @@ module.exports = {
117
117
  }
118
118
 
119
119
  /**
120
+ * Report location example :
121
+ *
122
+ * for unexpected space `before`
123
+ *
124
+ * var a = 'b' ;
125
+ * ^^^
126
+ *
127
+ * for unexpected space `after`
128
+ *
129
+ * var a = 'b'; c = 10;
130
+ * ^^
131
+ *
120
132
  * Reports if the given token has invalid spacing.
121
133
  * @param {Token} token The semicolon token to check.
122
134
  * @param {ASTNode} node The corresponding node of the token.
@@ -124,16 +136,19 @@ module.exports = {
124
136
  */
125
137
  function checkSemicolonSpacing(token, node) {
126
138
  if (astUtils.isSemicolonToken(token)) {
127
- const location = token.loc.start;
128
-
129
139
  if (hasLeadingSpace(token)) {
130
140
  if (!requireSpaceBefore) {
141
+ const tokenBefore = sourceCode.getTokenBefore(token);
142
+ const loc = {
143
+ start: tokenBefore.loc.end,
144
+ end: token.loc.start
145
+ };
146
+
131
147
  context.report({
132
148
  node,
133
- loc: location,
149
+ loc,
134
150
  messageId: "unexpectedWhitespaceBefore",
135
151
  fix(fixer) {
136
- const tokenBefore = sourceCode.getTokenBefore(token);
137
152
 
138
153
  return fixer.removeRange([tokenBefore.range[1], token.range[0]]);
139
154
  }
@@ -141,9 +156,11 @@ module.exports = {
141
156
  }
142
157
  } else {
143
158
  if (requireSpaceBefore) {
159
+ const loc = token.loc;
160
+
144
161
  context.report({
145
162
  node,
146
- loc: location,
163
+ loc,
147
164
  messageId: "missingWhitespaceBefore",
148
165
  fix(fixer) {
149
166
  return fixer.insertTextBefore(token, " ");
@@ -155,12 +172,17 @@ module.exports = {
155
172
  if (!isFirstTokenInCurrentLine(token) && !isLastTokenInCurrentLine(token) && !isBeforeClosingParen(token)) {
156
173
  if (hasTrailingSpace(token)) {
157
174
  if (!requireSpaceAfter) {
175
+ const tokenAfter = sourceCode.getTokenAfter(token);
176
+ const loc = {
177
+ start: token.loc.end,
178
+ end: tokenAfter.loc.start
179
+ };
180
+
158
181
  context.report({
159
182
  node,
160
- loc: location,
183
+ loc,
161
184
  messageId: "unexpectedWhitespaceAfter",
162
185
  fix(fixer) {
163
- const tokenAfter = sourceCode.getTokenAfter(token);
164
186
 
165
187
  return fixer.removeRange([token.range[1], tokenAfter.range[0]]);
166
188
  }
@@ -168,9 +190,11 @@ module.exports = {
168
190
  }
169
191
  } else {
170
192
  if (requireSpaceAfter) {
193
+ const loc = token.loc;
194
+
171
195
  context.report({
172
196
  node,
173
- loc: location,
197
+ loc,
174
198
  messageId: "missingWhitespaceAfter",
175
199
  fix(fixer) {
176
200
  return fixer.insertTextAfter(token, " ");
@@ -127,7 +127,10 @@ module.exports = {
127
127
  if (hasSpacing && functionConfig === "never") {
128
128
  context.report({
129
129
  node,
130
- loc: leftToken.loc.end,
130
+ loc: {
131
+ start: leftToken.loc.end,
132
+ end: rightToken.loc.start
133
+ },
131
134
  messageId: "unexpectedSpace",
132
135
  fix(fixer) {
133
136
  const comments = sourceCode.getCommentsBefore(rightToken);
@@ -145,7 +148,7 @@ module.exports = {
145
148
  } else if (!hasSpacing && functionConfig === "always") {
146
149
  context.report({
147
150
  node,
148
- loc: leftToken.loc.end,
151
+ loc: rightToken.loc,
149
152
  messageId: "missingSpace",
150
153
  fix: fixer => fixer.insertTextAfter(leftToken, " ")
151
154
  });
@@ -11,13 +11,6 @@
11
11
 
12
12
  const astUtils = require("./utils/ast-utils");
13
13
 
14
- //------------------------------------------------------------------------------
15
- // Helpers
16
- //------------------------------------------------------------------------------
17
-
18
- const OPEN_PAREN = /\$\{$/u;
19
- const CLOSE_PAREN = /^\}/u;
20
-
21
14
  //------------------------------------------------------------------------------
22
15
  // Rule Definition
23
16
  //------------------------------------------------------------------------------
@@ -49,7 +42,6 @@ module.exports = {
49
42
  create(context) {
50
43
  const sourceCode = context.getSourceCode();
51
44
  const always = context.options[0] === "always";
52
- const prefix = always ? "expected" : "unexpected";
53
45
 
54
46
  /**
55
47
  * Checks spacing before `}` of a given token.
@@ -57,25 +49,39 @@ module.exports = {
57
49
  * @returns {void}
58
50
  */
59
51
  function checkSpacingBefore(token) {
60
- const prevToken = sourceCode.getTokenBefore(token, { includeComments: true });
52
+ if (!token.value.startsWith("}")) {
53
+ return; // starts with a backtick, this is the first template element in the template literal
54
+ }
55
+
56
+ const prevToken = sourceCode.getTokenBefore(token, { includeComments: true }),
57
+ hasSpace = sourceCode.isSpaceBetween(prevToken, token);
58
+
59
+ if (!astUtils.isTokenOnSameLine(prevToken, token)) {
60
+ return;
61
+ }
61
62
 
62
- if (prevToken &&
63
- CLOSE_PAREN.test(token.value) &&
64
- astUtils.isTokenOnSameLine(prevToken, token) &&
65
- sourceCode.isSpaceBetweenTokens(prevToken, token) !== always
66
- ) {
63
+ if (always && !hasSpace) {
67
64
  context.report({
68
- loc: token.loc.start,
69
- messageId: `${prefix}Before`,
70
- fix(fixer) {
71
- if (always) {
72
- return fixer.insertTextBefore(token, " ");
65
+ loc: {
66
+ start: token.loc.start,
67
+ end: {
68
+ line: token.loc.start.line,
69
+ column: token.loc.start.column + 1
73
70
  }
74
- return fixer.removeRange([
75
- prevToken.range[1],
76
- token.range[0]
77
- ]);
78
- }
71
+ },
72
+ messageId: "expectedBefore",
73
+ fix: fixer => fixer.insertTextBefore(token, " ")
74
+ });
75
+ }
76
+
77
+ if (!always && hasSpace) {
78
+ context.report({
79
+ loc: {
80
+ start: prevToken.loc.end,
81
+ end: token.loc.start
82
+ },
83
+ messageId: "unexpectedBefore",
84
+ fix: fixer => fixer.removeRange([prevToken.range[1], token.range[0]])
79
85
  });
80
86
  }
81
87
  }
@@ -86,28 +92,39 @@ module.exports = {
86
92
  * @returns {void}
87
93
  */
88
94
  function checkSpacingAfter(token) {
89
- const nextToken = sourceCode.getTokenAfter(token, { includeComments: true });
95
+ if (!token.value.endsWith("${")) {
96
+ return; // ends with a backtick, this is the last template element in the template literal
97
+ }
98
+
99
+ const nextToken = sourceCode.getTokenAfter(token, { includeComments: true }),
100
+ hasSpace = sourceCode.isSpaceBetween(token, nextToken);
90
101
 
91
- if (nextToken &&
92
- OPEN_PAREN.test(token.value) &&
93
- astUtils.isTokenOnSameLine(token, nextToken) &&
94
- sourceCode.isSpaceBetweenTokens(token, nextToken) !== always
95
- ) {
102
+ if (!astUtils.isTokenOnSameLine(token, nextToken)) {
103
+ return;
104
+ }
105
+
106
+ if (always && !hasSpace) {
96
107
  context.report({
97
108
  loc: {
98
- line: token.loc.end.line,
99
- column: token.loc.end.column - 2
109
+ start: {
110
+ line: token.loc.end.line,
111
+ column: token.loc.end.column - 2
112
+ },
113
+ end: token.loc.end
100
114
  },
101
- messageId: `${prefix}After`,
102
- fix(fixer) {
103
- if (always) {
104
- return fixer.insertTextAfter(token, " ");
105
- }
106
- return fixer.removeRange([
107
- token.range[1],
108
- nextToken.range[0]
109
- ]);
110
- }
115
+ messageId: "expectedAfter",
116
+ fix: fixer => fixer.insertTextAfter(token, " ")
117
+ });
118
+ }
119
+
120
+ if (!always && hasSpace) {
121
+ context.report({
122
+ loc: {
123
+ start: token.loc.end,
124
+ end: nextToken.loc.start
125
+ },
126
+ messageId: "unexpectedAfter",
127
+ fix: fixer => fixer.removeRange([token.range[1], nextToken.range[0]])
111
128
  });
112
129
  }
113
130
  }
@@ -1243,19 +1243,64 @@ module.exports = {
1243
1243
 
1244
1244
  /**
1245
1245
  * Gets next location when the result is not out of bound, otherwise returns null.
1246
+ *
1247
+ * Assumptions:
1248
+ *
1249
+ * - The given location represents a valid location in the given source code.
1250
+ * - Columns are 0-based.
1251
+ * - Lines are 1-based.
1252
+ * - Column immediately after the last character in a line (not incl. linebreaks) is considered to be a valid location.
1253
+ * - If the source code ends with a linebreak, `sourceCode.lines` array will have an extra element (empty string) at the end.
1254
+ * The start (column 0) of that extra line is considered to be a valid location.
1255
+ *
1256
+ * Examples of successive locations (line, column):
1257
+ *
1258
+ * code: foo
1259
+ * locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> null
1260
+ *
1261
+ * code: foo<LF>
1262
+ * locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null
1263
+ *
1264
+ * code: foo<CR><LF>
1265
+ * locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null
1266
+ *
1267
+ * code: a<LF>b
1268
+ * locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> null
1269
+ *
1270
+ * code: a<LF>b<LF>
1271
+ * locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null
1272
+ *
1273
+ * code: a<CR><LF>b<CR><LF>
1274
+ * locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null
1275
+ *
1276
+ * code: a<LF><LF>
1277
+ * locations: (1, 0) -> (1, 1) -> (2, 0) -> (3, 0) -> null
1278
+ *
1279
+ * code: <LF>
1280
+ * locations: (1, 0) -> (2, 0) -> null
1281
+ *
1282
+ * code:
1283
+ * locations: (1, 0) -> null
1246
1284
  * @param {SourceCode} sourceCode The sourceCode
1247
1285
  * @param {{line: number, column: number}} location The location
1248
1286
  * @returns {{line: number, column: number} | null} Next location
1249
1287
  */
1250
- getNextLocation(sourceCode, location) {
1251
- const index = sourceCode.getIndexFromLoc(location);
1288
+ getNextLocation(sourceCode, { line, column }) {
1289
+ if (column < sourceCode.lines[line - 1].length) {
1290
+ return {
1291
+ line,
1292
+ column: column + 1
1293
+ };
1294
+ }
1252
1295
 
1253
- // Avoid out of bound location
1254
- if (index + 1 > sourceCode.text.length) {
1255
- return null;
1296
+ if (line < sourceCode.lines.length) {
1297
+ return {
1298
+ line: line + 1,
1299
+ column: 0
1300
+ };
1256
1301
  }
1257
1302
 
1258
- return sourceCode.getLocFromIndex(index + 1);
1303
+ return null;
1259
1304
  },
1260
1305
 
1261
1306
  /**
@@ -1357,17 +1402,65 @@ module.exports = {
1357
1402
  * next to each other, behavior is undefined (although it should return `true` in most cases).
1358
1403
  */
1359
1404
  canTokensBeAdjacent(leftValue, rightValue) {
1405
+ const espreeOptions = {
1406
+ ecmaVersion: espree.latestEcmaVersion,
1407
+ comment: true,
1408
+ range: true
1409
+ };
1410
+
1360
1411
  let leftToken;
1361
1412
 
1362
1413
  if (typeof leftValue === "string") {
1363
- const leftTokens = espree.tokenize(leftValue, { ecmaVersion: 2015 });
1414
+ let tokens;
1364
1415
 
1365
- leftToken = leftTokens[leftTokens.length - 1];
1416
+ try {
1417
+ tokens = espree.tokenize(leftValue, espreeOptions);
1418
+ } catch (e) {
1419
+ return false;
1420
+ }
1421
+
1422
+ const comments = tokens.comments;
1423
+
1424
+ leftToken = tokens[tokens.length - 1];
1425
+ if (comments.length) {
1426
+ const lastComment = comments[comments.length - 1];
1427
+
1428
+ if (lastComment.range[0] > leftToken.range[0]) {
1429
+ leftToken = lastComment;
1430
+ }
1431
+ }
1366
1432
  } else {
1367
1433
  leftToken = leftValue;
1368
1434
  }
1369
1435
 
1370
- const rightToken = typeof rightValue === "string" ? espree.tokenize(rightValue, { ecmaVersion: 2015 })[0] : rightValue;
1436
+ if (leftToken.type === "Shebang") {
1437
+ return false;
1438
+ }
1439
+
1440
+ let rightToken;
1441
+
1442
+ if (typeof rightValue === "string") {
1443
+ let tokens;
1444
+
1445
+ try {
1446
+ tokens = espree.tokenize(rightValue, espreeOptions);
1447
+ } catch (e) {
1448
+ return false;
1449
+ }
1450
+
1451
+ const comments = tokens.comments;
1452
+
1453
+ rightToken = tokens[0];
1454
+ if (comments.length) {
1455
+ const firstComment = comments[0];
1456
+
1457
+ if (firstComment.range[0] < rightToken.range[0]) {
1458
+ rightToken = firstComment;
1459
+ }
1460
+ }
1461
+ } else {
1462
+ rightToken = rightValue;
1463
+ }
1371
1464
 
1372
1465
  if (leftToken.type === "Punctuator" || rightToken.type === "Punctuator") {
1373
1466
  if (leftToken.type === "Punctuator" && rightToken.type === "Punctuator") {
@@ -1379,6 +1472,9 @@ module.exports = {
1379
1472
  MINUS_TOKENS.has(leftToken.value) && MINUS_TOKENS.has(rightToken.value)
1380
1473
  );
1381
1474
  }
1475
+ if (leftToken.type === "Punctuator" && leftToken.value === "/") {
1476
+ return !["Block", "Line", "RegularExpression"].includes(rightToken.type);
1477
+ }
1382
1478
  return true;
1383
1479
  }
1384
1480
 
@@ -1393,6 +1489,10 @@ module.exports = {
1393
1489
  return true;
1394
1490
  }
1395
1491
 
1492
+ if (leftToken.type === "Block" || rightToken.type === "Block" || rightToken.type === "Line") {
1493
+ return true;
1494
+ }
1495
+
1396
1496
  return false;
1397
1497
  },
1398
1498
 
@@ -1413,11 +1513,17 @@ module.exports = {
1413
1513
  const match = namePattern.exec(comment.value);
1414
1514
 
1415
1515
  // Convert the index to loc.
1416
- return sourceCode.getLocFromIndex(
1516
+ const start = sourceCode.getLocFromIndex(
1417
1517
  comment.range[0] +
1418
1518
  "/*".length +
1419
1519
  (match ? match.index + 1 : 0)
1420
1520
  );
1521
+ const end = {
1522
+ line: start.line,
1523
+ column: start.column + (match ? name.length : 1)
1524
+ };
1525
+
1526
+ return { start, end };
1421
1527
  },
1422
1528
 
1423
1529
  /**