eslint 6.5.1 → 6.7.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.
- package/CHANGELOG.md +118 -0
- package/README.md +10 -9
- package/conf/config-schema.js +1 -0
- package/conf/default-cli-options.js +1 -1
- package/lib/cli-engine/cascading-config-array-factory.js +40 -14
- package/lib/cli-engine/cli-engine.js +49 -21
- package/lib/cli-engine/config-array/config-array.js +13 -4
- package/lib/cli-engine/config-array/config-dependency.js +2 -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/override-tester.js +2 -0
- package/lib/cli-engine/config-array-factory.js +120 -2
- package/lib/cli-engine/file-enumerator.js +65 -34
- package/lib/cli-engine/formatters/html.js +1 -0
- package/lib/init/autoconfig.js +1 -11
- package/lib/init/config-file.js +0 -1
- package/lib/init/config-initializer.js +4 -4
- package/lib/init/config-rule.js +1 -5
- package/lib/init/npm-utils.js +0 -5
- package/lib/linter/code-path-analysis/code-path-analyzer.js +24 -38
- package/lib/linter/code-path-analysis/code-path-segment.js +17 -25
- package/lib/linter/code-path-analysis/code-path-state.js +40 -81
- package/lib/linter/code-path-analysis/code-path.js +10 -11
- package/lib/linter/code-path-analysis/debug-helpers.js +8 -12
- package/lib/linter/code-path-analysis/fork-context.js +23 -34
- package/lib/linter/code-path-analysis/id-generator.js +2 -2
- package/lib/linter/linter.js +121 -95
- package/lib/linter/node-event-generator.js +3 -2
- package/lib/linter/report-translator.js +73 -7
- package/lib/rule-tester/rule-tester.js +46 -14
- package/lib/rules/accessor-pairs.js +8 -8
- package/lib/rules/array-bracket-newline.js +12 -15
- package/lib/rules/array-bracket-spacing.js +12 -12
- package/lib/rules/array-callback-return.js +6 -11
- package/lib/rules/array-element-newline.js +5 -8
- package/lib/rules/arrow-parens.js +0 -1
- package/lib/rules/block-scoped-var.js +3 -3
- package/lib/rules/block-spacing.js +4 -4
- package/lib/rules/camelcase.js +19 -6
- package/lib/rules/capitalized-comments.js +0 -7
- package/lib/rules/class-methods-use-this.js +3 -3
- package/lib/rules/comma-dangle.js +20 -25
- package/lib/rules/comma-spacing.js +1 -1
- package/lib/rules/computed-property-spacing.js +14 -14
- package/lib/rules/consistent-return.js +4 -5
- package/lib/rules/consistent-this.js +5 -5
- package/lib/rules/constructor-super.js +14 -16
- package/lib/rules/curly.js +12 -9
- package/lib/rules/default-param-last.js +1 -0
- package/lib/rules/dot-location.js +11 -12
- package/lib/rules/func-names.js +6 -6
- package/lib/rules/function-call-argument-newline.js +8 -6
- package/lib/rules/generator-star-spacing.js +4 -9
- package/lib/rules/getter-return.js +4 -7
- package/lib/rules/grouped-accessor-pairs.js +224 -0
- package/lib/rules/indent.js +13 -2
- package/lib/rules/index.js +5 -0
- package/lib/rules/init-declarations.js +2 -2
- package/lib/rules/jsx-quotes.js +1 -1
- package/lib/rules/keyword-spacing.js +32 -56
- package/lib/rules/lines-around-directive.js +1 -1
- package/lib/rules/max-len.js +0 -5
- package/lib/rules/max-statements-per-line.js +3 -7
- package/lib/rules/multiline-comment-style.js +237 -106
- package/lib/rules/multiline-ternary.js +3 -3
- package/lib/rules/newline-after-var.js +6 -7
- package/lib/rules/newline-before-return.js +8 -9
- package/lib/rules/newline-per-chained-call.js +2 -4
- package/lib/rules/no-class-assign.js +2 -2
- package/lib/rules/no-compare-neg-zero.js +1 -2
- package/lib/rules/no-cond-assign.js +14 -4
- package/lib/rules/no-confusing-arrow.js +2 -2
- package/lib/rules/no-console.js +4 -8
- package/lib/rules/no-const-assign.js +1 -1
- package/lib/rules/no-constructor-return.js +62 -0
- package/lib/rules/no-dupe-args.js +1 -1
- package/lib/rules/no-dupe-class-members.js +3 -4
- package/lib/rules/no-dupe-else-if.js +122 -0
- package/lib/rules/no-dupe-keys.js +6 -5
- package/lib/rules/no-duplicate-imports.js +14 -18
- package/lib/rules/no-else-return.js +0 -8
- package/lib/rules/no-empty-function.js +2 -4
- package/lib/rules/no-eval.js +10 -18
- package/lib/rules/no-ex-assign.js +1 -1
- package/lib/rules/no-extra-bind.js +5 -12
- package/lib/rules/no-extra-boolean-cast.js +0 -2
- package/lib/rules/no-extra-label.js +4 -9
- package/lib/rules/no-extra-parens.js +17 -15
- package/lib/rules/no-extra-semi.js +5 -6
- package/lib/rules/no-fallthrough.js +6 -6
- package/lib/rules/no-func-assign.js +3 -3
- package/lib/rules/no-global-assign.js +4 -4
- package/lib/rules/no-implicit-coercion.js +10 -10
- package/lib/rules/no-implicit-globals.js +90 -8
- package/lib/rules/no-implied-eval.js +0 -1
- package/lib/rules/no-inline-comments.js +25 -11
- package/lib/rules/no-invalid-this.js +17 -5
- package/lib/rules/no-labels.js +3 -6
- package/lib/rules/no-lone-blocks.js +1 -1
- package/lib/rules/no-loop-func.js +6 -11
- package/lib/rules/no-magic-numbers.js +6 -6
- package/lib/rules/no-misleading-character-class.js +14 -7
- package/lib/rules/no-mixed-operators.js +13 -22
- package/lib/rules/no-mixed-requires.js +0 -1
- package/lib/rules/no-multi-spaces.js +1 -1
- package/lib/rules/no-native-reassign.js +4 -4
- package/lib/rules/no-octal-escape.js +1 -1
- package/lib/rules/no-param-reassign.js +28 -7
- package/lib/rules/no-redeclare.js +1 -1
- package/lib/rules/no-regex-spaces.js +0 -1
- package/lib/rules/no-restricted-imports.js +11 -11
- package/lib/rules/no-self-assign.js +12 -13
- package/lib/rules/no-sequences.js +3 -3
- package/lib/rules/no-setter-return.js +227 -0
- package/lib/rules/no-shadow.js +1 -4
- package/lib/rules/no-tabs.js +8 -2
- package/lib/rules/no-this-before-super.js +12 -13
- package/lib/rules/no-trailing-spaces.js +19 -7
- package/lib/rules/no-underscore-dangle.js +23 -4
- package/lib/rules/no-unexpected-multiline.js +8 -0
- package/lib/rules/no-unmodified-loop-condition.js +16 -29
- package/lib/rules/no-unneeded-ternary.js +3 -3
- package/lib/rules/no-unreachable.js +7 -7
- package/lib/rules/no-unsafe-finally.js +4 -7
- package/lib/rules/no-unsafe-negation.js +32 -9
- package/lib/rules/no-unused-expressions.js +11 -7
- package/lib/rules/no-unused-labels.js +3 -6
- package/lib/rules/no-unused-vars.js +22 -29
- package/lib/rules/no-use-before-define.js +10 -15
- package/lib/rules/no-useless-call.js +4 -4
- package/lib/rules/no-useless-computed-key.js +60 -33
- package/lib/rules/no-useless-concat.js +4 -4
- package/lib/rules/no-useless-constructor.js +14 -22
- package/lib/rules/no-useless-escape.js +29 -8
- package/lib/rules/no-useless-rename.js +7 -7
- package/lib/rules/no-useless-return.js +8 -15
- package/lib/rules/no-var.js +12 -25
- package/lib/rules/no-warning-comments.js +0 -1
- package/lib/rules/no-whitespace-before-property.js +3 -3
- package/lib/rules/object-curly-newline.js +7 -10
- package/lib/rules/object-curly-spacing.js +21 -22
- package/lib/rules/object-shorthand.js +1 -1
- package/lib/rules/one-var-declaration-per-line.js +2 -2
- package/lib/rules/operator-assignment.js +33 -3
- package/lib/rules/padded-blocks.js +1 -1
- package/lib/rules/padding-line-between-statements.js +0 -16
- package/lib/rules/prefer-arrow-callback.js +6 -6
- package/lib/rules/prefer-const.js +27 -28
- package/lib/rules/prefer-destructuring.js +1 -7
- package/lib/rules/prefer-exponentiation-operator.js +189 -0
- package/lib/rules/prefer-named-capture-group.js +0 -1
- package/lib/rules/prefer-numeric-literals.js +32 -4
- package/lib/rules/prefer-object-spread.js +7 -7
- package/lib/rules/prefer-rest-params.js +3 -6
- package/lib/rules/prefer-spread.js +4 -4
- package/lib/rules/prefer-template.js +5 -6
- package/lib/rules/quote-props.js +1 -1
- package/lib/rules/quotes.js +5 -6
- package/lib/rules/radix.js +5 -10
- package/lib/rules/require-await.js +10 -5
- package/lib/rules/require-yield.js +2 -2
- package/lib/rules/rest-spread-spacing.js +1 -1
- package/lib/rules/semi.js +6 -3
- package/lib/rules/sort-imports.js +3 -4
- package/lib/rules/sort-keys.js +1 -3
- package/lib/rules/space-before-blocks.js +1 -2
- package/lib/rules/space-in-parens.js +4 -4
- package/lib/rules/space-infix-ops.js +6 -6
- package/lib/rules/spaced-comment.js +20 -22
- package/lib/rules/strict.js +2 -4
- package/lib/rules/symbol-description.js +1 -2
- package/lib/rules/template-curly-spacing.js +2 -2
- package/lib/rules/use-isnan.js +40 -3
- package/lib/rules/utils/ast-utils.js +84 -85
- package/lib/rules/utils/fix-tracker.js +0 -6
- package/lib/rules/utils/lazy-loading-rule-map.js +0 -1
- package/lib/rules/vars-on-top.js +11 -11
- package/lib/shared/config-ops.js +2 -2
- package/lib/shared/runtime-info.js +8 -8
- package/lib/shared/traverser.js +2 -0
- package/lib/shared/types.js +9 -0
- package/lib/source-code/source-code.js +94 -17
- package/lib/source-code/token-store/backward-token-comment-cursor.js +5 -5
- package/lib/source-code/token-store/backward-token-cursor.js +5 -5
- package/lib/source-code/token-store/cursors.js +17 -19
- package/lib/source-code/token-store/decorative-cursor.js +1 -1
- package/lib/source-code/token-store/filter-cursor.js +2 -2
- package/lib/source-code/token-store/forward-token-comment-cursor.js +5 -5
- package/lib/source-code/token-store/forward-token-cursor.js +5 -5
- package/lib/source-code/token-store/index.js +86 -92
- package/lib/source-code/token-store/limit-cursor.js +2 -2
- package/lib/source-code/token-store/padded-token-cursor.js +7 -7
- package/lib/source-code/token-store/skip-cursor.js +2 -2
- package/lib/source-code/token-store/utils.js +9 -13
- package/package.json +9 -7
- package/lib/cli-engine/ignored-paths.js +0 -362
@@ -61,7 +61,6 @@ module.exports = {
|
|
61
61
|
|
62
62
|
/**
|
63
63
|
* Reports with the first extra statement, and clears it.
|
64
|
-
*
|
65
64
|
* @returns {void}
|
66
65
|
*/
|
67
66
|
function reportFirstExtraStatementAndClear() {
|
@@ -81,8 +80,7 @@ module.exports = {
|
|
81
80
|
|
82
81
|
/**
|
83
82
|
* Gets the actual last token of a given node.
|
84
|
-
*
|
85
|
-
* @param {ASTNode} node - A node to get. This is a node except EmptyStatement.
|
83
|
+
* @param {ASTNode} node A node to get. This is a node except EmptyStatement.
|
86
84
|
* @returns {Token} The actual last token.
|
87
85
|
*/
|
88
86
|
function getActualLastToken(node) {
|
@@ -92,8 +90,7 @@ module.exports = {
|
|
92
90
|
/**
|
93
91
|
* Addresses a given node.
|
94
92
|
* It updates the state of this rule, then reports the node if the node violated this rule.
|
95
|
-
*
|
96
|
-
* @param {ASTNode} node - A node to check.
|
93
|
+
* @param {ASTNode} node A node to check.
|
97
94
|
* @returns {void}
|
98
95
|
*/
|
99
96
|
function enterStatement(node) {
|
@@ -127,8 +124,7 @@ module.exports = {
|
|
127
124
|
|
128
125
|
/**
|
129
126
|
* Updates the state of this rule with the end line of leaving node to check with the next statement.
|
130
|
-
*
|
131
|
-
* @param {ASTNode} node - A node to check.
|
127
|
+
* @param {ASTNode} node A node to check.
|
132
128
|
* @returns {void}
|
133
129
|
*/
|
134
130
|
function leaveStatement(node) {
|
@@ -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
|
};
|
@@ -46,9 +46,9 @@ module.exports = {
|
|
46
46
|
|
47
47
|
/**
|
48
48
|
* Tests whether node is preceded by supplied tokens
|
49
|
-
* @param {ASTNode} node
|
50
|
-
* @param {ASTNode} parentNode
|
51
|
-
* @param {boolean} expected
|
49
|
+
* @param {ASTNode} node node to check
|
50
|
+
* @param {ASTNode} parentNode parent of node to report
|
51
|
+
* @param {boolean} expected whether newline was expected or not
|
52
52
|
* @returns {void}
|
53
53
|
* @private
|
54
54
|
*/
|
@@ -72,8 +72,7 @@ module.exports = {
|
|
72
72
|
* var foo = 1
|
73
73
|
*
|
74
74
|
* ;(a || b).doSomething()
|
75
|
-
*
|
76
|
-
* @param {ASTNode} node - The node to get.
|
75
|
+
* @param {ASTNode} node The node to get.
|
77
76
|
* @returns {Token} The token to compare line to the next statement.
|
78
77
|
*/
|
79
78
|
function getLastToken(node) {
|
@@ -93,7 +92,7 @@ module.exports = {
|
|
93
92
|
/**
|
94
93
|
* Determine if provided keyword is a variable declaration
|
95
94
|
* @private
|
96
|
-
* @param {string} keyword
|
95
|
+
* @param {string} keyword keyword to test
|
97
96
|
* @returns {boolean} True if `keyword` is a type of var
|
98
97
|
*/
|
99
98
|
function isVar(keyword) {
|
@@ -103,7 +102,7 @@ module.exports = {
|
|
103
102
|
/**
|
104
103
|
* Determine if provided keyword is a variant of for specifiers
|
105
104
|
* @private
|
106
|
-
* @param {string} keyword
|
105
|
+
* @param {string} keyword keyword to test
|
107
106
|
* @returns {boolean} True if `keyword` is a variant of for specifier
|
108
107
|
*/
|
109
108
|
function isForTypeSpecifier(keyword) {
|
@@ -113,7 +112,7 @@ module.exports = {
|
|
113
112
|
/**
|
114
113
|
* Determine if provided keyword is an export specifiers
|
115
114
|
* @private
|
116
|
-
* @param {string} nodeType
|
115
|
+
* @param {string} nodeType nodeType to test
|
117
116
|
* @returns {boolean} True if `nodeType` is an export specifier
|
118
117
|
*/
|
119
118
|
function isExportSpecifier(nodeType) {
|
@@ -124,7 +123,7 @@ module.exports = {
|
|
124
123
|
/**
|
125
124
|
* Determine if provided node is the last of their parent block.
|
126
125
|
* @private
|
127
|
-
* @param {ASTNode} node
|
126
|
+
* @param {ASTNode} node node to test
|
128
127
|
* @returns {boolean} True if `node` is last of their parent block.
|
129
128
|
*/
|
130
129
|
function isLastNode(node) {
|
@@ -159,7 +158,7 @@ module.exports = {
|
|
159
158
|
* set to "always", or checks that there is no blank line when mode is set
|
160
159
|
* to "never"
|
161
160
|
* @private
|
162
|
-
* @param {ASTNode} node
|
161
|
+
* @param {ASTNode} node `VariableDeclaration` node to test
|
163
162
|
* @returns {void}
|
164
163
|
*/
|
165
164
|
function checkForBlankLine(node) {
|
@@ -39,8 +39,8 @@ module.exports = {
|
|
39
39
|
|
40
40
|
/**
|
41
41
|
* Tests whether node is preceded by supplied tokens
|
42
|
-
* @param {ASTNode} node
|
43
|
-
* @param {Array} testTokens
|
42
|
+
* @param {ASTNode} node node to check
|
43
|
+
* @param {Array} testTokens array of tokens to test against
|
44
44
|
* @returns {boolean} Whether or not the node is preceded by one of the supplied tokens
|
45
45
|
* @private
|
46
46
|
*/
|
@@ -52,7 +52,7 @@ module.exports = {
|
|
52
52
|
|
53
53
|
/**
|
54
54
|
* Checks whether node is the first node after statement or in block
|
55
|
-
* @param {ASTNode} node
|
55
|
+
* @param {ASTNode} node node to check
|
56
56
|
* @returns {boolean} Whether or not the node is the first node after statement or in block
|
57
57
|
* @private
|
58
58
|
*/
|
@@ -80,8 +80,8 @@ module.exports = {
|
|
80
80
|
|
81
81
|
/**
|
82
82
|
* Returns the number of lines of comments that precede the node
|
83
|
-
* @param {ASTNode} node
|
84
|
-
* @param {number} lineNumTokenBefore
|
83
|
+
* @param {ASTNode} node node to check for overlapping comments
|
84
|
+
* @param {number} lineNumTokenBefore line number of previous token, to check for overlapping comments
|
85
85
|
* @returns {number} Number of lines of comments that precede the node
|
86
86
|
* @private
|
87
87
|
*/
|
@@ -115,7 +115,7 @@ module.exports = {
|
|
115
115
|
|
116
116
|
/**
|
117
117
|
* Returns the line number of the token before the node that is passed in as an argument
|
118
|
-
* @param {ASTNode} node
|
118
|
+
* @param {ASTNode} node The node to use as the start of the calculation
|
119
119
|
* @returns {number} Line number of the token before `node`
|
120
120
|
* @private
|
121
121
|
*/
|
@@ -142,7 +142,7 @@ module.exports = {
|
|
142
142
|
|
143
143
|
/**
|
144
144
|
* Checks whether node is preceded by a newline
|
145
|
-
* @param {ASTNode} node
|
145
|
+
* @param {ASTNode} node node to check
|
146
146
|
* @returns {boolean} Whether or not the node is preceded by a newline
|
147
147
|
* @private
|
148
148
|
*/
|
@@ -160,8 +160,7 @@ module.exports = {
|
|
160
160
|
* The fix is not considered safe if the given return statement has leading comments,
|
161
161
|
* as we cannot safely determine if the newline should be added before or after the comments.
|
162
162
|
* For more information, see: https://github.com/eslint/eslint/issues/5958#issuecomment-222767211
|
163
|
-
*
|
164
|
-
* @param {ASTNode} node - The return statement node to check.
|
163
|
+
* @param {ASTNode} node The return statement node to check.
|
165
164
|
* @returns {boolean} `true` if it can fix the node.
|
166
165
|
* @private
|
167
166
|
*/
|
@@ -53,8 +53,7 @@ module.exports = {
|
|
53
53
|
* Get the prefix of a given MemberExpression node.
|
54
54
|
* If the MemberExpression node is a computed value it returns a
|
55
55
|
* left bracket. If not it returns a period.
|
56
|
-
*
|
57
|
-
* @param {ASTNode} node - A MemberExpression node to get
|
56
|
+
* @param {ASTNode} node A MemberExpression node to get
|
58
57
|
* @returns {string} The prefix of the node.
|
59
58
|
*/
|
60
59
|
function getPrefix(node) {
|
@@ -64,8 +63,7 @@ module.exports = {
|
|
64
63
|
/**
|
65
64
|
* Gets the property text of a given MemberExpression node.
|
66
65
|
* If the text is multiline, this returns only the first line.
|
67
|
-
*
|
68
|
-
* @param {ASTNode} node - A MemberExpression node to get.
|
66
|
+
* @param {ASTNode} node A MemberExpression node to get.
|
69
67
|
* @returns {string} The property text of the node.
|
70
68
|
*/
|
71
69
|
function getPropertyText(node) {
|
@@ -33,7 +33,7 @@ module.exports = {
|
|
33
33
|
|
34
34
|
/**
|
35
35
|
* Finds and reports references that are non initializer and writable.
|
36
|
-
* @param {Variable} variable
|
36
|
+
* @param {Variable} variable A variable to check.
|
37
37
|
* @returns {void}
|
38
38
|
*/
|
39
39
|
function checkVariable(variable) {
|
@@ -45,7 +45,7 @@ module.exports = {
|
|
45
45
|
|
46
46
|
/**
|
47
47
|
* Finds and reports references that are non initializer and writable.
|
48
|
-
* @param {ASTNode} node
|
48
|
+
* @param {ASTNode} node A ClassDeclaration/ClassExpression node to check.
|
49
49
|
* @returns {void}
|
50
50
|
*/
|
51
51
|
function checkForClass(node) {
|