eslint 6.6.0 → 6.8.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.
- package/CHANGELOG.md +94 -0
- package/README.md +7 -8
- package/conf/config-schema.js +2 -0
- package/conf/default-cli-options.js +1 -1
- package/conf/eslint-recommended.js +0 -1
- package/lib/cli-engine/cascading-config-array-factory.js +38 -13
- package/lib/cli-engine/cli-engine.js +41 -14
- package/lib/cli-engine/config-array/config-array.js +13 -0
- package/lib/cli-engine/config-array/extracted-config.js +27 -0
- package/lib/cli-engine/config-array/ignore-pattern.js +231 -0
- package/lib/cli-engine/config-array/index.js +2 -0
- package/lib/cli-engine/config-array-factory.js +115 -1
- package/lib/cli-engine/file-enumerator.js +73 -40
- package/lib/cli-engine/lint-result-cache.js +2 -1
- package/lib/cli.js +2 -1
- package/lib/init/config-initializer.js +4 -3
- package/lib/linter/config-comment-parser.js +1 -1
- package/lib/linter/report-translator.js +73 -7
- package/lib/options.js +6 -0
- package/lib/rule-tester/rule-tester.js +42 -6
- package/lib/rules/array-bracket-spacing.js +8 -8
- package/lib/rules/camelcase.js +19 -6
- package/lib/rules/comma-dangle.js +5 -2
- package/lib/rules/computed-property-spacing.js +4 -4
- package/lib/rules/curly.js +9 -4
- package/lib/rules/function-call-argument-newline.js +3 -1
- package/lib/rules/grouped-accessor-pairs.js +224 -0
- package/lib/rules/indent.js +11 -0
- package/lib/rules/index.js +5 -0
- package/lib/rules/key-spacing.js +34 -15
- package/lib/rules/lines-between-class-members.js +42 -53
- package/lib/rules/multiline-comment-style.js +237 -106
- package/lib/rules/no-cond-assign.js +14 -4
- package/lib/rules/no-constructor-return.js +62 -0
- package/lib/rules/no-dupe-else-if.js +122 -0
- package/lib/rules/no-implicit-globals.js +90 -8
- package/lib/rules/no-inline-comments.js +25 -11
- package/lib/rules/no-invalid-this.js +16 -2
- package/lib/rules/no-multiple-empty-lines.js +1 -1
- package/lib/rules/no-octal-escape.js +1 -1
- package/lib/rules/no-restricted-imports.js +2 -2
- package/lib/rules/no-setter-return.js +227 -0
- package/lib/rules/no-underscore-dangle.js +23 -4
- package/lib/rules/no-unexpected-multiline.js +8 -0
- package/lib/rules/no-unsafe-negation.js +30 -5
- package/lib/rules/no-useless-computed-key.js +60 -33
- package/lib/rules/no-useless-escape.js +26 -3
- package/lib/rules/object-curly-spacing.js +8 -8
- package/lib/rules/operator-assignment.js +11 -2
- package/lib/rules/prefer-const.js +14 -7
- package/lib/rules/prefer-exponentiation-operator.js +189 -0
- package/lib/rules/prefer-numeric-literals.js +29 -28
- package/lib/rules/require-atomic-updates.js +1 -1
- package/lib/rules/require-await.js +8 -0
- package/lib/rules/semi.js +6 -3
- package/lib/rules/space-infix-ops.js +1 -1
- package/lib/rules/spaced-comment.js +5 -4
- package/lib/rules/utils/ast-utils.js +31 -4
- package/lib/shared/types.js +9 -0
- package/lib/source-code/source-code.js +87 -10
- package/package.json +4 -3
- package/lib/cli-engine/ignored-paths.js +0 -363
@@ -43,17 +43,150 @@ module.exports = {
|
|
43
43
|
//----------------------------------------------------------------------
|
44
44
|
|
45
45
|
/**
|
46
|
-
*
|
47
|
-
* @param {
|
48
|
-
* @returns {
|
46
|
+
* Checks if a comment line is starred.
|
47
|
+
* @param {string} line A string representing a comment line.
|
48
|
+
* @returns {boolean} Whether or not the comment line is starred.
|
49
|
+
*/
|
50
|
+
function isStarredCommentLine(line) {
|
51
|
+
return /^\s*\*/u.test(line);
|
52
|
+
}
|
53
|
+
|
54
|
+
/**
|
55
|
+
* Checks if a comment group is in starred-block form.
|
56
|
+
* @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment.
|
57
|
+
* @returns {boolean} Whether or not the comment group is in starred block form.
|
58
|
+
*/
|
59
|
+
function isStarredBlockComment([firstComment]) {
|
60
|
+
if (firstComment.type !== "Block") {
|
61
|
+
return false;
|
62
|
+
}
|
63
|
+
|
64
|
+
const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER);
|
65
|
+
|
66
|
+
// The first and last lines can only contain whitespace.
|
67
|
+
return lines.length > 0 && lines.every((line, i) => (i === 0 || i === lines.length - 1 ? /^\s*$/u : /^\s*\*/u).test(line));
|
68
|
+
}
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Checks if a comment group is in JSDoc form.
|
72
|
+
* @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment.
|
73
|
+
* @returns {boolean} Whether or not the comment group is in JSDoc form.
|
74
|
+
*/
|
75
|
+
function isJSDocComment([firstComment]) {
|
76
|
+
if (firstComment.type !== "Block") {
|
77
|
+
return false;
|
78
|
+
}
|
79
|
+
|
80
|
+
const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER);
|
81
|
+
|
82
|
+
return /^\*\s*$/u.test(lines[0]) &&
|
83
|
+
lines.slice(1, -1).every(line => /^\s* /u.test(line)) &&
|
84
|
+
/^\s*$/u.test(lines[lines.length - 1]);
|
85
|
+
}
|
86
|
+
|
87
|
+
/**
|
88
|
+
* Processes a comment group that is currently in separate-line form, calculating the offset for each line.
|
89
|
+
* @param {Token[]} commentGroup A group of comments containing multiple line comments.
|
90
|
+
* @returns {string[]} An array of the processed lines.
|
91
|
+
*/
|
92
|
+
function processSeparateLineComments(commentGroup) {
|
93
|
+
const allLinesHaveLeadingSpace = commentGroup
|
94
|
+
.map(({ value }) => value)
|
95
|
+
.filter(line => line.trim().length)
|
96
|
+
.every(line => line.startsWith(" "));
|
97
|
+
|
98
|
+
return commentGroup.map(({ value }) => (allLinesHaveLeadingSpace ? value.replace(/^ /u, "") : value));
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Processes a comment group that is currently in starred-block form, calculating the offset for each line.
|
103
|
+
* @param {Token} comment A single block comment token in starred-block form.
|
104
|
+
* @returns {string[]} An array of the processed lines.
|
105
|
+
*/
|
106
|
+
function processStarredBlockComment(comment) {
|
107
|
+
const lines = comment.value.split(astUtils.LINEBREAK_MATCHER)
|
108
|
+
.filter((line, i, linesArr) => !(i === 0 || i === linesArr.length - 1))
|
109
|
+
.map(line => line.replace(/^\s*$/u, ""));
|
110
|
+
const allLinesHaveLeadingSpace = lines
|
111
|
+
.map(line => line.replace(/\s*\*/u, ""))
|
112
|
+
.filter(line => line.trim().length)
|
113
|
+
.every(line => line.startsWith(" "));
|
114
|
+
|
115
|
+
return lines.map(line => line.replace(allLinesHaveLeadingSpace ? /\s*\* ?/u : /\s*\*/u, ""));
|
116
|
+
}
|
117
|
+
|
118
|
+
/**
|
119
|
+
* Processes a comment group that is currently in bare-block form, calculating the offset for each line.
|
120
|
+
* @param {Token} comment A single block comment token in bare-block form.
|
121
|
+
* @returns {string[]} An array of the processed lines.
|
122
|
+
*/
|
123
|
+
function processBareBlockComment(comment) {
|
124
|
+
const lines = comment.value.split(astUtils.LINEBREAK_MATCHER).map(line => line.replace(/^\s*$/u, ""));
|
125
|
+
const leadingWhitespace = `${sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0])} `;
|
126
|
+
let offset = "";
|
127
|
+
|
128
|
+
/*
|
129
|
+
* Calculate the offset of the least indented line and use that as the basis for offsetting all the lines.
|
130
|
+
* The first line should not be checked because it is inline with the opening block comment delimiter.
|
131
|
+
*/
|
132
|
+
for (const [i, line] of lines.entries()) {
|
133
|
+
if (!line.trim().length || i === 0) {
|
134
|
+
continue;
|
135
|
+
}
|
136
|
+
|
137
|
+
const [, lineOffset] = line.match(/^(\s*\*?\s*)/u);
|
138
|
+
|
139
|
+
if (lineOffset.length < leadingWhitespace.length) {
|
140
|
+
const newOffset = leadingWhitespace.slice(lineOffset.length - leadingWhitespace.length);
|
141
|
+
|
142
|
+
if (newOffset.length > offset.length) {
|
143
|
+
offset = newOffset;
|
144
|
+
}
|
145
|
+
}
|
146
|
+
}
|
147
|
+
|
148
|
+
return lines.map(line => {
|
149
|
+
const match = line.match(/^(\s*\*?\s*)(.*)/u);
|
150
|
+
const [, lineOffset, lineContents] = match;
|
151
|
+
|
152
|
+
if (lineOffset.length > leadingWhitespace.length) {
|
153
|
+
return `${lineOffset.slice(leadingWhitespace.length - (offset.length + lineOffset.length))}${lineContents}`;
|
154
|
+
}
|
155
|
+
|
156
|
+
if (lineOffset.length < leadingWhitespace.length) {
|
157
|
+
return `${lineOffset.slice(leadingWhitespace.length)}${lineContents}`;
|
158
|
+
}
|
159
|
+
|
160
|
+
return lineContents;
|
161
|
+
});
|
162
|
+
}
|
163
|
+
|
164
|
+
/**
|
165
|
+
* Gets a list of comment lines in a group, formatting leading whitespace as necessary.
|
166
|
+
* @param {Token[]} commentGroup A group of comments containing either multiple line comments or a single block comment.
|
167
|
+
* @returns {string[]} A list of comment lines.
|
49
168
|
*/
|
50
169
|
function getCommentLines(commentGroup) {
|
51
|
-
|
52
|
-
|
170
|
+
const [firstComment] = commentGroup;
|
171
|
+
|
172
|
+
if (firstComment.type === "Line") {
|
173
|
+
return processSeparateLineComments(commentGroup);
|
53
174
|
}
|
54
|
-
|
55
|
-
|
56
|
-
|
175
|
+
|
176
|
+
if (isStarredBlockComment(commentGroup)) {
|
177
|
+
return processStarredBlockComment(firstComment);
|
178
|
+
}
|
179
|
+
|
180
|
+
return processBareBlockComment(firstComment);
|
181
|
+
}
|
182
|
+
|
183
|
+
/**
|
184
|
+
* Gets the initial offset (whitespace) from the beginning of a line to a given comment token.
|
185
|
+
* @param {Token} comment The token to check.
|
186
|
+
* @returns {string} The offset from the beginning of a line to the token.
|
187
|
+
*/
|
188
|
+
function getInitialOffset(comment) {
|
189
|
+
return sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0]);
|
57
190
|
}
|
58
191
|
|
59
192
|
/**
|
@@ -63,10 +196,9 @@ module.exports = {
|
|
63
196
|
* @returns {string} A representation of the comment value in starred-block form, excluding start and end markers
|
64
197
|
*/
|
65
198
|
function convertToStarredBlock(firstComment, commentLinesList) {
|
66
|
-
const initialOffset =
|
67
|
-
const starredLines = commentLinesList.map(line => `${initialOffset} *${line}`);
|
199
|
+
const initialOffset = getInitialOffset(firstComment);
|
68
200
|
|
69
|
-
return
|
201
|
+
return `/*\n${commentLinesList.map(line => `${initialOffset} * ${line}`).join("\n")}\n${initialOffset} */`;
|
70
202
|
}
|
71
203
|
|
72
204
|
/**
|
@@ -76,10 +208,7 @@ module.exports = {
|
|
76
208
|
* @returns {string} A representation of the comment value in separate-line form
|
77
209
|
*/
|
78
210
|
function convertToSeparateLines(firstComment, commentLinesList) {
|
79
|
-
|
80
|
-
const separateLines = commentLinesList.map(line => `// ${line.trim()}`);
|
81
|
-
|
82
|
-
return separateLines.join(`\n${initialOffset}`);
|
211
|
+
return commentLinesList.map(line => `// ${line}`).join(`\n${getInitialOffset(firstComment)}`);
|
83
212
|
}
|
84
213
|
|
85
214
|
/**
|
@@ -89,24 +218,7 @@ module.exports = {
|
|
89
218
|
* @returns {string} A representation of the comment value in bare-block form
|
90
219
|
*/
|
91
220
|
function convertToBlock(firstComment, commentLinesList) {
|
92
|
-
|
93
|
-
const blockLines = commentLinesList.map(line => line.trim());
|
94
|
-
|
95
|
-
return `/* ${blockLines.join(`\n${initialOffset} `)} */`;
|
96
|
-
}
|
97
|
-
|
98
|
-
/**
|
99
|
-
* Check a comment is JSDoc form
|
100
|
-
* @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment
|
101
|
-
* @returns {boolean} if commentGroup is JSDoc form, return true
|
102
|
-
*/
|
103
|
-
function isJSDoc(commentGroup) {
|
104
|
-
const lines = commentGroup[0].value.split(astUtils.LINEBREAK_MATCHER);
|
105
|
-
|
106
|
-
return commentGroup[0].type === "Block" &&
|
107
|
-
/^\*\s*$/u.test(lines[0]) &&
|
108
|
-
lines.slice(1, -1).every(line => /^\s* /u.test(line)) &&
|
109
|
-
/^\s*$/u.test(lines[lines.length - 1]);
|
221
|
+
return `/* ${commentLinesList.join(`\n${getInitialOffset(firstComment)} `)} */`;
|
110
222
|
}
|
111
223
|
|
112
224
|
/**
|
@@ -117,6 +229,7 @@ module.exports = {
|
|
117
229
|
*/
|
118
230
|
const commentGroupCheckers = {
|
119
231
|
"starred-block"(commentGroup) {
|
232
|
+
const [firstComment] = commentGroup;
|
120
233
|
const commentLines = getCommentLines(commentGroup);
|
121
234
|
|
122
235
|
if (commentLines.some(value => value.includes("*/"))) {
|
@@ -126,31 +239,30 @@ module.exports = {
|
|
126
239
|
if (commentGroup.length > 1) {
|
127
240
|
context.report({
|
128
241
|
loc: {
|
129
|
-
start:
|
242
|
+
start: firstComment.loc.start,
|
130
243
|
end: commentGroup[commentGroup.length - 1].loc.end
|
131
244
|
},
|
132
245
|
messageId: "expectedBlock",
|
133
246
|
fix(fixer) {
|
134
|
-
const range = [
|
135
|
-
const starredBlock = `/*${convertToStarredBlock(commentGroup[0], commentLines)}*/`;
|
247
|
+
const range = [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]];
|
136
248
|
|
137
249
|
return commentLines.some(value => value.startsWith("/"))
|
138
250
|
? null
|
139
|
-
: fixer.replaceTextRange(range,
|
251
|
+
: fixer.replaceTextRange(range, convertToStarredBlock(firstComment, commentLines));
|
140
252
|
}
|
141
253
|
});
|
142
254
|
} else {
|
143
|
-
const
|
144
|
-
const
|
145
|
-
const expectedLinePrefix = `${
|
255
|
+
const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER);
|
256
|
+
const expectedLeadingWhitespace = getInitialOffset(firstComment);
|
257
|
+
const expectedLinePrefix = `${expectedLeadingWhitespace} *`;
|
146
258
|
|
147
259
|
if (!/^\*?\s*$/u.test(lines[0])) {
|
148
|
-
const start =
|
260
|
+
const start = firstComment.value.startsWith("*") ? firstComment.range[0] + 1 : firstComment.range[0];
|
149
261
|
|
150
262
|
context.report({
|
151
263
|
loc: {
|
152
|
-
start:
|
153
|
-
end: { line:
|
264
|
+
start: firstComment.loc.start,
|
265
|
+
end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 }
|
154
266
|
},
|
155
267
|
messageId: "startNewline",
|
156
268
|
fix: fixer => fixer.insertTextAfterRange([start, start + 2], `\n${expectedLinePrefix}`)
|
@@ -160,36 +272,54 @@ module.exports = {
|
|
160
272
|
if (!/^\s*$/u.test(lines[lines.length - 1])) {
|
161
273
|
context.report({
|
162
274
|
loc: {
|
163
|
-
start: { line:
|
164
|
-
end:
|
275
|
+
start: { line: firstComment.loc.end.line, column: firstComment.loc.end.column - 2 },
|
276
|
+
end: firstComment.loc.end
|
165
277
|
},
|
166
278
|
messageId: "endNewline",
|
167
|
-
fix: fixer => fixer.replaceTextRange([
|
279
|
+
fix: fixer => fixer.replaceTextRange([firstComment.range[1] - 2, firstComment.range[1]], `\n${expectedLinePrefix}/`)
|
168
280
|
});
|
169
281
|
}
|
170
282
|
|
171
|
-
for (let lineNumber =
|
283
|
+
for (let lineNumber = firstComment.loc.start.line + 1; lineNumber <= firstComment.loc.end.line; lineNumber++) {
|
172
284
|
const lineText = sourceCode.lines[lineNumber - 1];
|
285
|
+
const errorType = isStarredCommentLine(lineText)
|
286
|
+
? "alignment"
|
287
|
+
: "missingStar";
|
173
288
|
|
174
289
|
if (!lineText.startsWith(expectedLinePrefix)) {
|
175
290
|
context.report({
|
176
291
|
loc: {
|
177
292
|
start: { line: lineNumber, column: 0 },
|
178
|
-
end: { line: lineNumber, column:
|
293
|
+
end: { line: lineNumber, column: lineText.length }
|
179
294
|
},
|
180
|
-
messageId:
|
181
|
-
? "alignment"
|
182
|
-
: "missingStar",
|
295
|
+
messageId: errorType,
|
183
296
|
fix(fixer) {
|
184
297
|
const lineStartIndex = sourceCode.getIndexFromLoc({ line: lineNumber, column: 0 });
|
185
|
-
const linePrefixLength = lineText.match(/^\s*\*? ?/u)[0].length;
|
186
|
-
const commentStartIndex = lineStartIndex + linePrefixLength;
|
187
298
|
|
188
|
-
|
189
|
-
|
190
|
-
|
299
|
+
if (errorType === "alignment") {
|
300
|
+
const [, commentTextPrefix = ""] = lineText.match(/^(\s*\*)/u) || [];
|
301
|
+
const commentTextStartIndex = lineStartIndex + commentTextPrefix.length;
|
302
|
+
|
303
|
+
return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], expectedLinePrefix);
|
304
|
+
}
|
305
|
+
|
306
|
+
const [, commentTextPrefix = ""] = lineText.match(/^(\s*)/u) || [];
|
307
|
+
const commentTextStartIndex = lineStartIndex + commentTextPrefix.length;
|
308
|
+
let offset;
|
309
|
+
|
310
|
+
for (const [idx, line] of lines.entries()) {
|
311
|
+
if (!/\S+/u.test(line)) {
|
312
|
+
continue;
|
313
|
+
}
|
314
|
+
|
315
|
+
const lineTextToAlignWith = sourceCode.lines[firstComment.loc.start.line - 1 + idx];
|
316
|
+
const [, prefix = "", initialOffset = ""] = lineTextToAlignWith.match(/^(\s*(?:\/?\*)?(\s*))/u) || [];
|
191
317
|
|
192
|
-
|
318
|
+
offset = `${commentTextPrefix.slice(prefix.length)}${initialOffset}`;
|
319
|
+
break;
|
320
|
+
}
|
321
|
+
|
322
|
+
return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], `${expectedLinePrefix}${offset}`);
|
193
323
|
}
|
194
324
|
});
|
195
325
|
}
|
@@ -197,67 +327,68 @@ module.exports = {
|
|
197
327
|
}
|
198
328
|
},
|
199
329
|
"separate-lines"(commentGroup) {
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
330
|
+
const [firstComment] = commentGroup;
|
331
|
+
|
332
|
+
if (firstComment.type !== "Block" || isJSDocComment(commentGroup)) {
|
333
|
+
return;
|
334
|
+
}
|
204
335
|
|
205
|
-
|
206
|
-
|
336
|
+
const commentLines = getCommentLines(commentGroup);
|
337
|
+
const tokenAfter = sourceCode.getTokenAfter(firstComment, { includeComments: true });
|
338
|
+
|
339
|
+
if (tokenAfter && firstComment.loc.end.line === tokenAfter.loc.start.line) {
|
340
|
+
return;
|
341
|
+
}
|
342
|
+
|
343
|
+
context.report({
|
344
|
+
loc: {
|
345
|
+
start: firstComment.loc.start,
|
346
|
+
end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 }
|
347
|
+
},
|
348
|
+
messageId: "expectedLines",
|
349
|
+
fix(fixer) {
|
350
|
+
return fixer.replaceText(firstComment, convertToSeparateLines(firstComment, commentLines));
|
207
351
|
}
|
352
|
+
});
|
353
|
+
},
|
354
|
+
"bare-block"(commentGroup) {
|
355
|
+
if (isJSDocComment(commentGroup)) {
|
356
|
+
return;
|
357
|
+
}
|
208
358
|
|
359
|
+
const [firstComment] = commentGroup;
|
360
|
+
const commentLines = getCommentLines(commentGroup);
|
361
|
+
|
362
|
+
// Disallows consecutive line comments in favor of using a block comment.
|
363
|
+
if (firstComment.type === "Line" && commentLines.length > 1 &&
|
364
|
+
!commentLines.some(value => value.includes("*/"))) {
|
209
365
|
context.report({
|
210
366
|
loc: {
|
211
|
-
start:
|
212
|
-
end:
|
367
|
+
start: firstComment.loc.start,
|
368
|
+
end: commentGroup[commentGroup.length - 1].loc.end
|
213
369
|
},
|
214
|
-
messageId: "
|
370
|
+
messageId: "expectedBlock",
|
215
371
|
fix(fixer) {
|
216
|
-
return fixer.
|
372
|
+
return fixer.replaceTextRange(
|
373
|
+
[firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]],
|
374
|
+
convertToBlock(firstComment, commentLines)
|
375
|
+
);
|
217
376
|
}
|
218
377
|
});
|
219
378
|
}
|
220
|
-
},
|
221
|
-
"bare-block"(commentGroup) {
|
222
|
-
if (!isJSDoc(commentGroup)) {
|
223
|
-
const commentLines = getCommentLines(commentGroup);
|
224
|
-
|
225
|
-
// disallows consecutive line comments in favor of using a block comment.
|
226
|
-
if (commentGroup[0].type === "Line" && commentLines.length > 1 &&
|
227
|
-
!commentLines.some(value => value.includes("*/"))) {
|
228
|
-
context.report({
|
229
|
-
loc: {
|
230
|
-
start: commentGroup[0].loc.start,
|
231
|
-
end: commentGroup[commentGroup.length - 1].loc.end
|
232
|
-
},
|
233
|
-
messageId: "expectedBlock",
|
234
|
-
fix(fixer) {
|
235
|
-
const range = [commentGroup[0].range[0], commentGroup[commentGroup.length - 1].range[1]];
|
236
|
-
const block = convertToBlock(commentGroup[0], commentLines.filter(line => line));
|
237
|
-
|
238
|
-
return fixer.replaceTextRange(range, block);
|
239
|
-
}
|
240
|
-
});
|
241
|
-
}
|
242
379
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
},
|
254
|
-
messageId: "expectedBareBlock",
|
255
|
-
fix(fixer) {
|
256
|
-
return fixer.replaceText(block, convertToBlock(block, commentLines.filter(line => line)));
|
257
|
-
}
|
258
|
-
});
|
380
|
+
// Prohibits block comments from having a * at the beginning of each line.
|
381
|
+
if (isStarredBlockComment(commentGroup)) {
|
382
|
+
context.report({
|
383
|
+
loc: {
|
384
|
+
start: firstComment.loc.start,
|
385
|
+
end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 }
|
386
|
+
},
|
387
|
+
messageId: "expectedBareBlock",
|
388
|
+
fix(fixer) {
|
389
|
+
return fixer.replaceText(firstComment, convertToBlock(firstComment, commentLines));
|
259
390
|
}
|
260
|
-
}
|
391
|
+
});
|
261
392
|
}
|
262
393
|
}
|
263
394
|
};
|
@@ -2,10 +2,21 @@
|
|
2
2
|
* @fileoverview Rule to flag assignment in a conditional statement's test expression
|
3
3
|
* @author Stephen Murray <spmurrayzzz>
|
4
4
|
*/
|
5
|
+
|
5
6
|
"use strict";
|
6
7
|
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Requirements
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
7
12
|
const astUtils = require("./utils/ast-utils");
|
8
13
|
|
14
|
+
//------------------------------------------------------------------------------
|
15
|
+
// Helpers
|
16
|
+
//------------------------------------------------------------------------------
|
17
|
+
|
18
|
+
const TEST_CONDITION_PARENT_TYPES = new Set(["IfStatement", "WhileStatement", "DoWhileStatement", "ForStatement", "ConditionalExpression"]);
|
19
|
+
|
9
20
|
const NODE_DESCRIPTIONS = {
|
10
21
|
DoWhileStatement: "a 'do...while' statement",
|
11
22
|
ForStatement: "a 'for' statement",
|
@@ -55,7 +66,7 @@ module.exports = {
|
|
55
66
|
*/
|
56
67
|
function isConditionalTestExpression(node) {
|
57
68
|
return node.parent &&
|
58
|
-
node.parent.
|
69
|
+
TEST_CONDITION_PARENT_TYPES.has(node.parent.type) &&
|
59
70
|
node === node.parent.test;
|
60
71
|
}
|
61
72
|
|
@@ -105,8 +116,7 @@ module.exports = {
|
|
105
116
|
) {
|
106
117
|
|
107
118
|
context.report({
|
108
|
-
node,
|
109
|
-
loc: node.test.loc.start,
|
119
|
+
node: node.test,
|
110
120
|
messageId: "missing"
|
111
121
|
});
|
112
122
|
}
|
@@ -122,7 +132,7 @@ module.exports = {
|
|
122
132
|
|
123
133
|
if (ancestor) {
|
124
134
|
context.report({
|
125
|
-
node
|
135
|
+
node,
|
126
136
|
messageId: "unexpected",
|
127
137
|
data: {
|
128
138
|
type: NODE_DESCRIPTIONS[ancestor.type] || ancestor.type
|
@@ -0,0 +1,62 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Rule to disallow returning value from constructor.
|
3
|
+
* @author Pig Fang <https://github.com/g-plane>
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Rule Definition
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
module.exports = {
|
13
|
+
meta: {
|
14
|
+
type: "problem",
|
15
|
+
|
16
|
+
docs: {
|
17
|
+
description: "disallow returning value from constructor",
|
18
|
+
category: "Best Practices",
|
19
|
+
recommended: false,
|
20
|
+
url: "https://eslint.org/docs/rules/no-constructor-return"
|
21
|
+
},
|
22
|
+
|
23
|
+
schema: {},
|
24
|
+
|
25
|
+
fixable: null,
|
26
|
+
|
27
|
+
messages: {
|
28
|
+
unexpected: "Unexpected return statement in constructor."
|
29
|
+
}
|
30
|
+
},
|
31
|
+
|
32
|
+
create(context) {
|
33
|
+
const stack = [];
|
34
|
+
|
35
|
+
return {
|
36
|
+
onCodePathStart(_, node) {
|
37
|
+
stack.push(node);
|
38
|
+
},
|
39
|
+
onCodePathEnd() {
|
40
|
+
stack.pop();
|
41
|
+
},
|
42
|
+
ReturnStatement(node) {
|
43
|
+
const last = stack[stack.length - 1];
|
44
|
+
|
45
|
+
if (!last.parent) {
|
46
|
+
return;
|
47
|
+
}
|
48
|
+
|
49
|
+
if (
|
50
|
+
last.parent.type === "MethodDefinition" &&
|
51
|
+
last.parent.kind === "constructor" &&
|
52
|
+
(node.parent.parent === last || node.argument)
|
53
|
+
) {
|
54
|
+
context.report({
|
55
|
+
node,
|
56
|
+
messageId: "unexpected"
|
57
|
+
});
|
58
|
+
}
|
59
|
+
}
|
60
|
+
};
|
61
|
+
}
|
62
|
+
};
|