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
@@ -291,6 +291,7 @@ function processAnswers(answers) {
|
|
291
291
|
jsx: true
|
292
292
|
};
|
293
293
|
config.plugins = ["react"];
|
294
|
+
config.extends.push("plugin:react/recommended");
|
294
295
|
} else if (answers.framework === "vue") {
|
295
296
|
config.plugins = ["vue"];
|
296
297
|
config.extends.push("plugin:vue/essential");
|
@@ -522,9 +523,9 @@ function promptUser() {
|
|
522
523
|
name: "styleguide",
|
523
524
|
message: "Which style guide do you want to follow?",
|
524
525
|
choices: [
|
525
|
-
{ name: "Airbnb
|
526
|
-
{ name: "Standard
|
527
|
-
{ name: "Google
|
526
|
+
{ name: "Airbnb: https://github.com/airbnb/javascript", value: "airbnb" },
|
527
|
+
{ name: "Standard: https://github.com/standard/standard", value: "standard" },
|
528
|
+
{ name: "Google: https://github.com/google/eslint-config-google", value: "google" }
|
528
529
|
],
|
529
530
|
when(answers) {
|
530
531
|
answers.packageJsonExists = npmUtils.checkPackageJson();
|
@@ -90,7 +90,7 @@ module.exports = class ConfigCommentParser {
|
|
90
90
|
* But we are supporting that. So this is a fallback for that.
|
91
91
|
*/
|
92
92
|
items = {};
|
93
|
-
const normalizedString = string.replace(/([a-zA-Z0-9
|
93
|
+
const normalizedString = string.replace(/([-a-zA-Z0-9/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,");
|
94
94
|
|
95
95
|
try {
|
96
96
|
items = JSON.parse(`{${normalizedString}}`);
|
@@ -26,6 +26,7 @@ const interpolate = require("./interpolate");
|
|
26
26
|
* @property {Object} [data] Optional data to use to fill in placeholders in the
|
27
27
|
* message.
|
28
28
|
* @property {Function} [fix] The function to call that creates a fix command.
|
29
|
+
* @property {Array<{desc?: string, messageId?: string, fix: Function}>} suggest Suggestion descriptions and functions to create a the associated fixes.
|
29
30
|
*/
|
30
31
|
|
31
32
|
/**
|
@@ -34,14 +35,15 @@ const interpolate = require("./interpolate");
|
|
34
35
|
* @property {string} ruleId
|
35
36
|
* @property {(0|1|2)} severity
|
36
37
|
* @property {(string|undefined)} message
|
37
|
-
* @property {(string|undefined)} messageId
|
38
|
+
* @property {(string|undefined)} [messageId]
|
38
39
|
* @property {number} line
|
39
40
|
* @property {number} column
|
40
|
-
* @property {(number|undefined)} endLine
|
41
|
-
* @property {(number|undefined)} endColumn
|
41
|
+
* @property {(number|undefined)} [endLine]
|
42
|
+
* @property {(number|undefined)} [endColumn]
|
42
43
|
* @property {(string|null)} nodeType
|
43
44
|
* @property {string} source
|
44
|
-
* @property {({text: string, range: (number[]|null)}|null)} fix
|
45
|
+
* @property {({text: string, range: (number[]|null)}|null)} [fix]
|
46
|
+
* @property {Array<{text: string, range: (number[]|null)}|null>} [suggestions]
|
45
47
|
*/
|
46
48
|
|
47
49
|
//------------------------------------------------------------------------------
|
@@ -182,6 +184,29 @@ function normalizeFixes(descriptor, sourceCode) {
|
|
182
184
|
return fix;
|
183
185
|
}
|
184
186
|
|
187
|
+
/**
|
188
|
+
* Gets an array of suggestion objects from the given descriptor.
|
189
|
+
* @param {MessageDescriptor} descriptor The report descriptor.
|
190
|
+
* @param {SourceCode} sourceCode The source code object to get text between fixes.
|
191
|
+
* @param {Object} messages Object of meta messages for the rule.
|
192
|
+
* @returns {Array<SuggestionResult>} The suggestions for the descriptor
|
193
|
+
*/
|
194
|
+
function mapSuggestions(descriptor, sourceCode, messages) {
|
195
|
+
if (!descriptor.suggest || !Array.isArray(descriptor.suggest)) {
|
196
|
+
return [];
|
197
|
+
}
|
198
|
+
|
199
|
+
return descriptor.suggest.map(suggestInfo => {
|
200
|
+
const computedDesc = suggestInfo.desc || messages[suggestInfo.messageId];
|
201
|
+
|
202
|
+
return {
|
203
|
+
...suggestInfo,
|
204
|
+
desc: interpolate(computedDesc, suggestInfo.data),
|
205
|
+
fix: normalizeFixes(suggestInfo, sourceCode)
|
206
|
+
};
|
207
|
+
});
|
208
|
+
}
|
209
|
+
|
185
210
|
/**
|
186
211
|
* Creates information about the report from a descriptor
|
187
212
|
* @param {Object} options Information about the problem
|
@@ -192,6 +217,7 @@ function normalizeFixes(descriptor, sourceCode) {
|
|
192
217
|
* @param {string} [options.messageId] The error message ID.
|
193
218
|
* @param {{start: SourceLocation, end: (SourceLocation|null)}} options.loc Start and end location
|
194
219
|
* @param {{text: string, range: (number[]|null)}} options.fix The fix object
|
220
|
+
* @param {Array<{text: string, range: (number[]|null)}>} options.suggestions The array of suggestions objects
|
195
221
|
* @returns {function(...args): ReportInfo} Function that returns information about the report
|
196
222
|
*/
|
197
223
|
function createProblem(options) {
|
@@ -221,9 +247,47 @@ function createProblem(options) {
|
|
221
247
|
problem.fix = options.fix;
|
222
248
|
}
|
223
249
|
|
250
|
+
if (options.suggestions && options.suggestions.length > 0) {
|
251
|
+
problem.suggestions = options.suggestions;
|
252
|
+
}
|
253
|
+
|
224
254
|
return problem;
|
225
255
|
}
|
226
256
|
|
257
|
+
/**
|
258
|
+
* Validates that suggestions are properly defined. Throws if an error is detected.
|
259
|
+
* @param {Array<{ desc?: string, messageId?: string }>} suggest The incoming suggest data.
|
260
|
+
* @param {Object} messages Object of meta messages for the rule.
|
261
|
+
* @returns {void}
|
262
|
+
*/
|
263
|
+
function validateSuggestions(suggest, messages) {
|
264
|
+
if (suggest && Array.isArray(suggest)) {
|
265
|
+
suggest.forEach(suggestion => {
|
266
|
+
if (suggestion.messageId) {
|
267
|
+
const { messageId } = suggestion;
|
268
|
+
|
269
|
+
if (!messages) {
|
270
|
+
throw new TypeError(`context.report() called with a suggest option with a messageId '${messageId}', but no messages were present in the rule metadata.`);
|
271
|
+
}
|
272
|
+
|
273
|
+
if (!messages[messageId]) {
|
274
|
+
throw new TypeError(`context.report() called with a suggest option with a messageId '${messageId}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`);
|
275
|
+
}
|
276
|
+
|
277
|
+
if (suggestion.desc) {
|
278
|
+
throw new TypeError("context.report() called with a suggest option that defines both a 'messageId' and an 'desc'. Please only pass one.");
|
279
|
+
}
|
280
|
+
} else if (!suggestion.desc) {
|
281
|
+
throw new TypeError("context.report() called with a suggest option that doesn't have either a `desc` or `messageId`");
|
282
|
+
}
|
283
|
+
|
284
|
+
if (typeof suggestion.fix !== "function") {
|
285
|
+
throw new TypeError(`context.report() called with a suggest option without a fix function. See: ${suggestion}`);
|
286
|
+
}
|
287
|
+
});
|
288
|
+
}
|
289
|
+
}
|
290
|
+
|
227
291
|
/**
|
228
292
|
* Returns a function that converts the arguments of a `context.report` call from a rule into a reported
|
229
293
|
* problem for the Node.js API.
|
@@ -242,17 +306,17 @@ module.exports = function createReportTranslator(metadata) {
|
|
242
306
|
*/
|
243
307
|
return (...args) => {
|
244
308
|
const descriptor = normalizeMultiArgReportCall(...args);
|
309
|
+
const messages = metadata.messageIds;
|
245
310
|
|
246
311
|
assertValidNodeInfo(descriptor);
|
247
312
|
|
248
313
|
let computedMessage;
|
249
314
|
|
250
315
|
if (descriptor.messageId) {
|
251
|
-
if (!
|
316
|
+
if (!messages) {
|
252
317
|
throw new TypeError("context.report() called with a messageId, but no messages were present in the rule metadata.");
|
253
318
|
}
|
254
319
|
const id = descriptor.messageId;
|
255
|
-
const messages = metadata.messageIds;
|
256
320
|
|
257
321
|
if (descriptor.message) {
|
258
322
|
throw new TypeError("context.report() called with a message and a messageId. Please only pass one.");
|
@@ -267,6 +331,7 @@ module.exports = function createReportTranslator(metadata) {
|
|
267
331
|
throw new TypeError("Missing `message` property in report() call; add a message that describes the linting problem.");
|
268
332
|
}
|
269
333
|
|
334
|
+
validateSuggestions(descriptor.suggest, messages);
|
270
335
|
|
271
336
|
return createProblem({
|
272
337
|
ruleId: metadata.ruleId,
|
@@ -275,7 +340,8 @@ module.exports = function createReportTranslator(metadata) {
|
|
275
340
|
message: interpolate(computedMessage, descriptor.data),
|
276
341
|
messageId: descriptor.messageId,
|
277
342
|
loc: normalizeReportLoc(descriptor),
|
278
|
-
fix: metadata.disableFixes ? null : normalizeFixes(descriptor, metadata.sourceCode)
|
343
|
+
fix: metadata.disableFixes ? null : normalizeFixes(descriptor, metadata.sourceCode),
|
344
|
+
suggestions: metadata.disableFixes ? [] : mapSuggestions(descriptor, metadata.sourceCode, messages)
|
279
345
|
});
|
280
346
|
};
|
281
347
|
};
|
package/lib/options.js
CHANGED
@@ -230,6 +230,12 @@ module.exports = optionator({
|
|
230
230
|
default: "false",
|
231
231
|
description: "Output execution environment information"
|
232
232
|
},
|
233
|
+
{
|
234
|
+
option: "error-on-unmatched-pattern",
|
235
|
+
type: "Boolean",
|
236
|
+
default: "true",
|
237
|
+
description: "Prevent errors when pattern is unmatched"
|
238
|
+
},
|
233
239
|
{
|
234
240
|
option: "debug",
|
235
241
|
type: "Boolean",
|
@@ -349,7 +349,7 @@ class RuleTester {
|
|
349
349
|
filename = item.filename;
|
350
350
|
}
|
351
351
|
|
352
|
-
if (
|
352
|
+
if (hasOwnProperty(item, "options")) {
|
353
353
|
assert(Array.isArray(item.options), "options must be an array");
|
354
354
|
config.rules[ruleName] = [1].concat(item.options);
|
355
355
|
} else {
|
@@ -577,21 +577,57 @@ class RuleTester {
|
|
577
577
|
assert.strictEqual(message.nodeType, error.type, `Error type should be ${error.type}, found ${message.nodeType}`);
|
578
578
|
}
|
579
579
|
|
580
|
-
if (
|
580
|
+
if (hasOwnProperty(error, "line")) {
|
581
581
|
assert.strictEqual(message.line, error.line, `Error line should be ${error.line}`);
|
582
582
|
}
|
583
583
|
|
584
|
-
if (
|
584
|
+
if (hasOwnProperty(error, "column")) {
|
585
585
|
assert.strictEqual(message.column, error.column, `Error column should be ${error.column}`);
|
586
586
|
}
|
587
587
|
|
588
|
-
if (
|
588
|
+
if (hasOwnProperty(error, "endLine")) {
|
589
589
|
assert.strictEqual(message.endLine, error.endLine, `Error endLine should be ${error.endLine}`);
|
590
590
|
}
|
591
591
|
|
592
|
-
if (
|
592
|
+
if (hasOwnProperty(error, "endColumn")) {
|
593
593
|
assert.strictEqual(message.endColumn, error.endColumn, `Error endColumn should be ${error.endColumn}`);
|
594
594
|
}
|
595
|
+
|
596
|
+
if (hasOwnProperty(error, "suggestions")) {
|
597
|
+
|
598
|
+
// Support asserting there are no suggestions
|
599
|
+
if (!error.suggestions || (Array.isArray(error.suggestions) && error.suggestions.length === 0)) {
|
600
|
+
if (Array.isArray(message.suggestions) && message.suggestions.length > 0) {
|
601
|
+
assert.fail(`Error should have no suggestions on error with message: "${message.message}"`);
|
602
|
+
}
|
603
|
+
} else {
|
604
|
+
assert.strictEqual(Array.isArray(message.suggestions), true, `Error should have an array of suggestions. Instead received "${message.suggestions}" on error with message: "${message.message}"`);
|
605
|
+
assert.strictEqual(message.suggestions.length, error.suggestions.length, `Error should have ${error.suggestions.length} suggestions. Instead found ${message.suggestions.length} suggestions`);
|
606
|
+
|
607
|
+
error.suggestions.forEach((expectedSuggestion, index) => {
|
608
|
+
const actualSuggestion = message.suggestions[index];
|
609
|
+
|
610
|
+
/**
|
611
|
+
* Tests equality of a suggestion key if that key is defined in the expected output.
|
612
|
+
* @param {string} key Key to validate from the suggestion object
|
613
|
+
* @returns {void}
|
614
|
+
*/
|
615
|
+
function assertSuggestionKeyEquals(key) {
|
616
|
+
if (hasOwnProperty(expectedSuggestion, key)) {
|
617
|
+
assert.deepStrictEqual(actualSuggestion[key], expectedSuggestion[key], `Error suggestion at index: ${index} should have desc of: "${actualSuggestion[key]}"`);
|
618
|
+
}
|
619
|
+
}
|
620
|
+
assertSuggestionKeyEquals("desc");
|
621
|
+
assertSuggestionKeyEquals("messageId");
|
622
|
+
|
623
|
+
if (hasOwnProperty(expectedSuggestion, "output")) {
|
624
|
+
const codeWithAppliedSuggestion = SourceCodeFixer.applyFixes(item.code, [actualSuggestion]).output;
|
625
|
+
|
626
|
+
assert.strictEqual(codeWithAppliedSuggestion, expectedSuggestion.output, `Expected the applied suggestion fix to match the test suggestion output for suggestion at index: ${index} on error with message: "${message.message}"`);
|
627
|
+
}
|
628
|
+
});
|
629
|
+
}
|
630
|
+
}
|
595
631
|
} else {
|
596
632
|
|
597
633
|
// Message was an unexpected type
|
@@ -600,7 +636,7 @@ class RuleTester {
|
|
600
636
|
}
|
601
637
|
}
|
602
638
|
|
603
|
-
if (
|
639
|
+
if (hasOwnProperty(item, "output")) {
|
604
640
|
if (item.output === null) {
|
605
641
|
assert.strictEqual(
|
606
642
|
result.output,
|
@@ -84,16 +84,16 @@ module.exports = {
|
|
84
84
|
* @returns {void}
|
85
85
|
*/
|
86
86
|
function reportNoBeginningSpace(node, token) {
|
87
|
+
const nextToken = sourceCode.getTokenAfter(token);
|
88
|
+
|
87
89
|
context.report({
|
88
90
|
node,
|
89
|
-
loc: token.loc.start,
|
91
|
+
loc: { start: token.loc.end, end: nextToken.loc.start },
|
90
92
|
messageId: "unexpectedSpaceAfter",
|
91
93
|
data: {
|
92
94
|
tokenValue: token.value
|
93
95
|
},
|
94
96
|
fix(fixer) {
|
95
|
-
const nextToken = sourceCode.getTokenAfter(token);
|
96
|
-
|
97
97
|
return fixer.removeRange([token.range[1], nextToken.range[0]]);
|
98
98
|
}
|
99
99
|
});
|
@@ -106,16 +106,16 @@ module.exports = {
|
|
106
106
|
* @returns {void}
|
107
107
|
*/
|
108
108
|
function reportNoEndingSpace(node, token) {
|
109
|
+
const previousToken = sourceCode.getTokenBefore(token);
|
110
|
+
|
109
111
|
context.report({
|
110
112
|
node,
|
111
|
-
loc: token.loc.start,
|
113
|
+
loc: { start: previousToken.loc.end, end: token.loc.start },
|
112
114
|
messageId: "unexpectedSpaceBefore",
|
113
115
|
data: {
|
114
116
|
tokenValue: token.value
|
115
117
|
},
|
116
118
|
fix(fixer) {
|
117
|
-
const previousToken = sourceCode.getTokenBefore(token);
|
118
|
-
|
119
119
|
return fixer.removeRange([previousToken.range[1], token.range[0]]);
|
120
120
|
}
|
121
121
|
});
|
@@ -130,7 +130,7 @@ module.exports = {
|
|
130
130
|
function reportRequiredBeginningSpace(node, token) {
|
131
131
|
context.report({
|
132
132
|
node,
|
133
|
-
loc: token.loc
|
133
|
+
loc: token.loc,
|
134
134
|
messageId: "missingSpaceAfter",
|
135
135
|
data: {
|
136
136
|
tokenValue: token.value
|
@@ -150,7 +150,7 @@ module.exports = {
|
|
150
150
|
function reportRequiredEndingSpace(node, token) {
|
151
151
|
context.report({
|
152
152
|
node,
|
153
|
-
loc: token.loc
|
153
|
+
loc: token.loc,
|
154
154
|
messageId: "missingSpaceBefore",
|
155
155
|
data: {
|
156
156
|
tokenValue: token.value
|
package/lib/rules/camelcase.js
CHANGED
@@ -28,6 +28,10 @@ module.exports = {
|
|
28
28
|
type: "boolean",
|
29
29
|
default: false
|
30
30
|
},
|
31
|
+
ignoreImports: {
|
32
|
+
type: "boolean",
|
33
|
+
default: false
|
34
|
+
},
|
31
35
|
properties: {
|
32
36
|
enum: ["always", "never"]
|
33
37
|
},
|
@@ -56,6 +60,7 @@ module.exports = {
|
|
56
60
|
const options = context.options[0] || {};
|
57
61
|
let properties = options.properties || "";
|
58
62
|
const ignoreDestructuring = options.ignoreDestructuring;
|
63
|
+
const ignoreImports = options.ignoreImports;
|
59
64
|
const allow = options.allow || [];
|
60
65
|
|
61
66
|
if (properties !== "always" && properties !== "never") {
|
@@ -79,7 +84,7 @@ module.exports = {
|
|
79
84
|
function isUnderscored(name) {
|
80
85
|
|
81
86
|
// if there's an underscore, it might be A_CONSTANT, which is okay
|
82
|
-
return name.
|
87
|
+
return name.includes("_") && name !== name.toUpperCase();
|
83
88
|
}
|
84
89
|
|
85
90
|
/**
|
@@ -89,9 +94,9 @@ module.exports = {
|
|
89
94
|
* @private
|
90
95
|
*/
|
91
96
|
function isAllowed(name) {
|
92
|
-
return allow.
|
97
|
+
return allow.some(
|
93
98
|
entry => name === entry || name.match(new RegExp(entry, "u"))
|
94
|
-
)
|
99
|
+
);
|
95
100
|
}
|
96
101
|
|
97
102
|
/**
|
@@ -127,7 +132,7 @@ module.exports = {
|
|
127
132
|
* @private
|
128
133
|
*/
|
129
134
|
function report(node) {
|
130
|
-
if (reported.
|
135
|
+
if (!reported.includes(node)) {
|
131
136
|
reported.push(node);
|
132
137
|
context.report({ node, messageId: "notCamelCase", data: { name: node.name } });
|
133
138
|
}
|
@@ -209,10 +214,18 @@ module.exports = {
|
|
209
214
|
}
|
210
215
|
|
211
216
|
// Check if it's an import specifier
|
212
|
-
} else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].
|
217
|
+
} else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].includes(node.parent.type)) {
|
218
|
+
|
219
|
+
if (node.parent.type === "ImportSpecifier" && ignoreImports) {
|
220
|
+
return;
|
221
|
+
}
|
213
222
|
|
214
223
|
// Report only if the local imported identifier is underscored
|
215
|
-
if (
|
224
|
+
if (
|
225
|
+
node.parent.local &&
|
226
|
+
node.parent.local.name === node.name &&
|
227
|
+
nameIsUnderscored
|
228
|
+
) {
|
216
229
|
report(node);
|
217
230
|
}
|
218
231
|
|
@@ -231,7 +231,7 @@ module.exports = {
|
|
231
231
|
if (astUtils.isCommaToken(trailingToken)) {
|
232
232
|
context.report({
|
233
233
|
node: lastItem,
|
234
|
-
loc: trailingToken.loc
|
234
|
+
loc: trailingToken.loc,
|
235
235
|
messageId: "unexpected",
|
236
236
|
fix(fixer) {
|
237
237
|
return fixer.remove(trailingToken);
|
@@ -267,7 +267,10 @@ module.exports = {
|
|
267
267
|
if (trailingToken.value !== ",") {
|
268
268
|
context.report({
|
269
269
|
node: lastItem,
|
270
|
-
loc:
|
270
|
+
loc: {
|
271
|
+
start: trailingToken.loc.end,
|
272
|
+
end: astUtils.getNextLocation(sourceCode, trailingToken.loc.end)
|
273
|
+
},
|
271
274
|
messageId: "missing",
|
272
275
|
fix(fixer) {
|
273
276
|
return fixer.insertTextAfter(trailingToken, ",");
|
@@ -153,10 +153,10 @@ module.exports = {
|
|
153
153
|
|
154
154
|
const property = node[propertyName];
|
155
155
|
|
156
|
-
const before = sourceCode.getTokenBefore(property),
|
157
|
-
first = sourceCode.
|
158
|
-
|
159
|
-
|
156
|
+
const before = sourceCode.getTokenBefore(property, astUtils.isOpeningBracketToken),
|
157
|
+
first = sourceCode.getTokenAfter(before, { includeComments: true }),
|
158
|
+
after = sourceCode.getTokenAfter(property, astUtils.isClosingBracketToken),
|
159
|
+
last = sourceCode.getTokenBefore(after, { includeComments: true });
|
160
160
|
|
161
161
|
if (astUtils.isTokenOnSameLine(before, first)) {
|
162
162
|
if (propertyNameMustBeSpaced) {
|
package/lib/rules/curly.js
CHANGED
@@ -97,10 +97,15 @@ module.exports = {
|
|
97
97
|
* @private
|
98
98
|
*/
|
99
99
|
function isOneLiner(node) {
|
100
|
-
|
101
|
-
|
100
|
+
if (node.type === "EmptyStatement") {
|
101
|
+
return true;
|
102
|
+
}
|
103
|
+
|
104
|
+
const first = sourceCode.getFirstToken(node);
|
105
|
+
const last = sourceCode.getLastToken(node);
|
106
|
+
const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last;
|
102
107
|
|
103
|
-
return first.loc.start.line ===
|
108
|
+
return first.loc.start.line === lastExcludingSemicolon.loc.end.line;
|
104
109
|
}
|
105
110
|
|
106
111
|
/**
|
@@ -240,7 +245,7 @@ module.exports = {
|
|
240
245
|
if (node.type === "IfStatement" && node.consequent === body && requiresBraceOfConsequent(node)) {
|
241
246
|
expected = true;
|
242
247
|
} else if (multiOnly) {
|
243
|
-
if (hasBlock && body.body.length === 1) {
|
248
|
+
if (hasBlock && body.body.length === 1 && !isLexicalDeclaration(body.body[0])) {
|
244
249
|
expected = false;
|
245
250
|
}
|
246
251
|
} else if (multiLine) {
|
@@ -70,6 +70,8 @@ module.exports = {
|
|
70
70
|
{ includeComments: true }
|
71
71
|
);
|
72
72
|
|
73
|
+
const hasLineCommentBefore = tokenBefore.type === "Line";
|
74
|
+
|
73
75
|
context.report({
|
74
76
|
node,
|
75
77
|
loc: {
|
@@ -77,7 +79,7 @@ module.exports = {
|
|
77
79
|
end: currentArgToken.loc.start
|
78
80
|
},
|
79
81
|
messageId: checker.messageId,
|
80
|
-
fix: checker.createFix(currentArgToken, tokenBefore)
|
82
|
+
fix: hasLineCommentBefore ? null : checker.createFix(currentArgToken, tokenBefore)
|
81
83
|
});
|
82
84
|
}
|
83
85
|
}
|