eslint 4.15.0 → 4.18.1
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 +56 -0
- package/lib/config/config-validator.js +9 -2
- package/lib/linter.js +38 -19
- package/lib/options.js +7 -7
- package/lib/report-translator.js +28 -37
- package/lib/rules/accessor-pairs.js +7 -3
- package/lib/rules/array-bracket-newline.js +11 -5
- package/lib/rules/array-bracket-spacing.js +11 -5
- package/lib/rules/array-callback-return.js +11 -5
- package/lib/rules/array-element-newline.js +8 -3
- package/lib/rules/arrow-body-style.js +16 -8
- package/lib/rules/arrow-parens.js +13 -9
- package/lib/rules/arrow-spacing.js +13 -5
- package/lib/rules/block-scoped-var.js +6 -2
- package/lib/rules/block-spacing.js +13 -6
- package/lib/rules/brace-style.js +16 -14
- package/lib/rules/callback-return.js +6 -2
- package/lib/rules/camelcase.js +6 -2
- package/lib/rules/capitalized-comments.js +11 -8
- package/lib/rules/class-methods-use-this.js +7 -3
- package/lib/rules/comma-dangle.js +7 -4
- package/lib/rules/comma-spacing.js +13 -10
- package/lib/rules/comma-style.js +16 -5
- package/lib/rules/complexity.js +6 -2
- package/lib/rules/computed-property-spacing.js +13 -5
- package/lib/rules/consistent-return.js +12 -7
- package/lib/rules/consistent-this.js +9 -4
- package/lib/rules/constructor-super.js +17 -8
- package/lib/rules/curly.js +59 -80
- package/lib/rules/default-case.js +6 -2
- package/lib/rules/dot-location.js +8 -3
- package/lib/rules/dot-notation.js +10 -5
- package/lib/rules/eol-last.js +7 -3
- package/lib/rules/eqeqeq.js +6 -2
- package/lib/rules/guard-for-in.js +35 -7
- package/lib/rules/indent.js +4 -4
- package/lib/rules/key-spacing.js +3 -2
- package/lib/rules/keyword-spacing.js +6 -1
- package/lib/rules/no-alert.js +19 -18
- package/lib/rules/no-array-constructor.js +6 -2
- package/lib/rules/no-await-in-loop.js +75 -57
- package/lib/rules/no-bitwise.js +6 -2
- package/lib/rules/no-buffer-constructor.js +6 -3
- package/lib/rules/no-caller.js +6 -2
- package/lib/rules/no-case-declarations.js +6 -2
- package/lib/rules/no-catch-shadow.js +6 -2
- package/lib/rules/no-class-assign.js +6 -2
- package/lib/rules/no-compare-neg-zero.js +5 -2
- package/lib/rules/no-cond-assign.js +10 -4
- package/lib/rules/no-confusing-arrow.js +6 -2
- package/lib/rules/no-console.js +6 -2
- package/lib/rules/no-const-assign.js +6 -2
- package/lib/rules/no-constant-condition.js +6 -3
- package/lib/rules/no-continue.js +6 -2
- package/lib/rules/no-control-regex.js +7 -3
- package/lib/rules/no-debugger.js +5 -2
- package/lib/rules/no-delete-var.js +6 -2
- package/lib/rules/no-div-regex.js +6 -2
- package/lib/rules/no-dupe-args.js +6 -2
- package/lib/rules/no-dupe-class-members.js +6 -2
- package/lib/rules/no-dupe-keys.js +6 -2
- package/lib/rules/no-duplicate-case.js +6 -2
- package/lib/rules/no-else-return.js +7 -2
- package/lib/rules/no-empty-character-class.js +6 -2
- package/lib/rules/no-empty-function.js +6 -2
- package/lib/rules/no-empty-pattern.js +7 -3
- package/lib/rules/no-empty.js +7 -3
- package/lib/rules/no-eq-null.js +6 -2
- package/lib/rules/no-eval.js +6 -2
- package/lib/rules/no-ex-assign.js +6 -2
- package/lib/rules/no-extend-native.js +6 -2
- package/lib/rules/no-extra-bind.js +6 -2
- package/lib/rules/no-extra-boolean-cast.js +8 -3
- package/lib/rules/no-extra-label.js +6 -2
- package/lib/rules/no-extra-parens.js +5 -1
- package/lib/rules/no-extra-semi.js +6 -2
- package/lib/rules/no-self-assign.js +3 -1
- package/lib/rules/no-unused-vars.js +1 -1
- package/lib/rules/object-curly-newline.js +67 -19
- package/lib/rules/object-property-newline.js +8 -2
- package/lib/rules/object-shorthand.js +9 -7
- package/lib/rules/padding-line-between-statements.js +6 -0
- package/lib/rules/prefer-destructuring.js +4 -2
- package/lib/rules/require-await.js +5 -0
- package/lib/rules/rest-spread-spacing.js +6 -0
- package/lib/rules/space-unary-ops.js +1 -10
- package/lib/rules/valid-jsdoc.js +89 -28
- package/lib/util/glob-util.js +17 -4
- package/lib/util/npm-util.js +1 -1
- package/package.json +2 -2
package/lib/rules/valid-jsdoc.js
CHANGED
@@ -57,7 +57,9 @@ module.exports = {
|
|
57
57
|
},
|
58
58
|
additionalProperties: false
|
59
59
|
}
|
60
|
-
]
|
60
|
+
],
|
61
|
+
|
62
|
+
fixable: "code"
|
61
63
|
},
|
62
64
|
|
63
65
|
create(context) {
|
@@ -145,23 +147,35 @@ module.exports = {
|
|
145
147
|
/**
|
146
148
|
* Extract the current and expected type based on the input type object
|
147
149
|
* @param {Object} type JSDoc tag
|
148
|
-
* @returns {
|
150
|
+
* @returns {{currentType: Doctrine.Type, expectedTypeName: string}} The current type annotation and
|
151
|
+
* the expected name of the annotation
|
149
152
|
* @private
|
150
153
|
*/
|
151
154
|
function getCurrentExpectedTypes(type) {
|
152
155
|
let currentType;
|
153
156
|
|
154
157
|
if (type.name) {
|
155
|
-
currentType = type
|
158
|
+
currentType = type;
|
156
159
|
} else if (type.expression) {
|
157
|
-
currentType = type.expression
|
160
|
+
currentType = type.expression;
|
158
161
|
}
|
159
162
|
|
160
|
-
const expectedType = currentType && preferType[currentType];
|
161
|
-
|
162
163
|
return {
|
163
164
|
currentType,
|
164
|
-
|
165
|
+
expectedTypeName: currentType && preferType[currentType.name]
|
166
|
+
};
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Gets the location of a JSDoc node in a file
|
171
|
+
* @param {Token} jsdocComment The comment that this node is parsed from
|
172
|
+
* @param {{range: number[]}} parsedJsdocNode A tag or other node which was parsed from this comment
|
173
|
+
* @returns {{start: SourceLocation, end: SourceLocation}} The 0-based source location for the tag
|
174
|
+
*/
|
175
|
+
function getAbsoluteRange(jsdocComment, parsedJsdocNode) {
|
176
|
+
return {
|
177
|
+
start: sourceCode.getLocFromIndex(jsdocComment.range[0] + 2 + parsedJsdocNode.range[0]),
|
178
|
+
end: sourceCode.getLocFromIndex(jsdocComment.range[0] + 2 + parsedJsdocNode.range[1])
|
165
179
|
};
|
166
180
|
}
|
167
181
|
|
@@ -204,14 +218,21 @@ module.exports = {
|
|
204
218
|
elements.forEach(validateType.bind(null, jsdocNode));
|
205
219
|
|
206
220
|
typesToCheck.forEach(typeToCheck => {
|
207
|
-
if (typeToCheck.
|
208
|
-
typeToCheck.
|
221
|
+
if (typeToCheck.expectedTypeName &&
|
222
|
+
typeToCheck.expectedTypeName !== typeToCheck.currentType.name) {
|
209
223
|
context.report({
|
210
224
|
node: jsdocNode,
|
211
|
-
message: "Use '{{
|
225
|
+
message: "Use '{{expectedTypeName}}' instead of '{{currentTypeName}}'.",
|
226
|
+
loc: getAbsoluteRange(jsdocNode, typeToCheck.currentType),
|
212
227
|
data: {
|
213
|
-
|
214
|
-
|
228
|
+
currentTypeName: typeToCheck.currentType.name,
|
229
|
+
expectedTypeName: typeToCheck.expectedTypeName
|
230
|
+
},
|
231
|
+
fix(fixer) {
|
232
|
+
return fixer.replaceTextRange(
|
233
|
+
typeToCheck.currentType.range.map(indexInComment => jsdocNode.range[0] + 2 + indexInComment),
|
234
|
+
typeToCheck.expectedTypeName
|
235
|
+
);
|
215
236
|
}
|
216
237
|
});
|
217
238
|
}
|
@@ -227,8 +248,8 @@ module.exports = {
|
|
227
248
|
function checkJSDoc(node) {
|
228
249
|
const jsdocNode = sourceCode.getJSDocComment(node),
|
229
250
|
functionData = fns.pop(),
|
230
|
-
|
231
|
-
|
251
|
+
paramTagsByName = Object.create(null),
|
252
|
+
paramTags = [];
|
232
253
|
let hasReturns = false,
|
233
254
|
returnsTag,
|
234
255
|
hasConstructor = false,
|
@@ -244,7 +265,8 @@ module.exports = {
|
|
244
265
|
jsdoc = doctrine.parse(jsdocNode.value, {
|
245
266
|
strict: true,
|
246
267
|
unwrap: true,
|
247
|
-
sloppy: true
|
268
|
+
sloppy: true,
|
269
|
+
range: true
|
248
270
|
});
|
249
271
|
} catch (ex) {
|
250
272
|
|
@@ -264,7 +286,7 @@ module.exports = {
|
|
264
286
|
case "param":
|
265
287
|
case "arg":
|
266
288
|
case "argument":
|
267
|
-
|
289
|
+
paramTags.push(tag);
|
268
290
|
break;
|
269
291
|
|
270
292
|
case "return":
|
@@ -297,7 +319,29 @@ module.exports = {
|
|
297
319
|
|
298
320
|
// check tag preferences
|
299
321
|
if (prefer.hasOwnProperty(tag.title) && tag.title !== prefer[tag.title]) {
|
300
|
-
|
322
|
+
const entireTagRange = getAbsoluteRange(jsdocNode, tag);
|
323
|
+
|
324
|
+
context.report({
|
325
|
+
node: jsdocNode,
|
326
|
+
message: "Use @{{name}} instead.",
|
327
|
+
loc: {
|
328
|
+
start: entireTagRange.start,
|
329
|
+
end: {
|
330
|
+
line: entireTagRange.start.line,
|
331
|
+
column: entireTagRange.start.column + `@${tag.title}`.length
|
332
|
+
}
|
333
|
+
},
|
334
|
+
data: { name: prefer[tag.title] },
|
335
|
+
fix(fixer) {
|
336
|
+
return fixer.replaceTextRange(
|
337
|
+
[
|
338
|
+
jsdocNode.range[0] + tag.range[0] + 3,
|
339
|
+
jsdocNode.range[0] + tag.range[0] + tag.title.length + 3
|
340
|
+
],
|
341
|
+
prefer[tag.title]
|
342
|
+
);
|
343
|
+
}
|
344
|
+
});
|
301
345
|
}
|
302
346
|
|
303
347
|
// validate the types
|
@@ -306,17 +350,32 @@ module.exports = {
|
|
306
350
|
}
|
307
351
|
});
|
308
352
|
|
309
|
-
|
353
|
+
paramTags.forEach(param => {
|
310
354
|
if (!param.type) {
|
311
|
-
context.report({
|
355
|
+
context.report({
|
356
|
+
node: jsdocNode,
|
357
|
+
message: "Missing JSDoc parameter type for '{{name}}'.",
|
358
|
+
loc: getAbsoluteRange(jsdocNode, param),
|
359
|
+
data: { name: param.name }
|
360
|
+
});
|
312
361
|
}
|
313
362
|
if (!param.description && requireParamDescription) {
|
314
|
-
context.report({
|
363
|
+
context.report({
|
364
|
+
node: jsdocNode,
|
365
|
+
message: "Missing JSDoc parameter description for '{{name}}'.",
|
366
|
+
loc: getAbsoluteRange(jsdocNode, param),
|
367
|
+
data: { name: param.name }
|
368
|
+
});
|
315
369
|
}
|
316
|
-
if (
|
317
|
-
context.report({
|
370
|
+
if (paramTagsByName[param.name]) {
|
371
|
+
context.report({
|
372
|
+
node: jsdocNode,
|
373
|
+
message: "Duplicate JSDoc parameter '{{name}}'.",
|
374
|
+
loc: getAbsoluteRange(jsdocNode, param),
|
375
|
+
data: { name: param.name }
|
376
|
+
});
|
318
377
|
} else if (param.name.indexOf(".") === -1) {
|
319
|
-
|
378
|
+
paramTagsByName[param.name] = param;
|
320
379
|
}
|
321
380
|
});
|
322
381
|
|
@@ -325,6 +384,7 @@ module.exports = {
|
|
325
384
|
context.report({
|
326
385
|
node: jsdocNode,
|
327
386
|
message: "Unexpected @{{title}} tag; function has no return statement.",
|
387
|
+
loc: getAbsoluteRange(jsdocNode, returnsTag),
|
328
388
|
data: {
|
329
389
|
title: returnsTag.title
|
330
390
|
}
|
@@ -356,10 +416,10 @@ module.exports = {
|
|
356
416
|
}
|
357
417
|
|
358
418
|
// check the parameters
|
359
|
-
const
|
419
|
+
const jsdocParamNames = Object.keys(paramTagsByName);
|
360
420
|
|
361
421
|
if (node.params) {
|
362
|
-
node.params.forEach((param,
|
422
|
+
node.params.forEach((param, paramsIndex) => {
|
363
423
|
if (param.type === "AssignmentPattern") {
|
364
424
|
param = param.left;
|
365
425
|
}
|
@@ -368,16 +428,17 @@ module.exports = {
|
|
368
428
|
|
369
429
|
// TODO(nzakas): Figure out logical things to do with destructured, default, rest params
|
370
430
|
if (param.type === "Identifier") {
|
371
|
-
if (
|
431
|
+
if (jsdocParamNames[paramsIndex] && (name !== jsdocParamNames[paramsIndex])) {
|
372
432
|
context.report({
|
373
433
|
node: jsdocNode,
|
374
434
|
message: "Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.",
|
435
|
+
loc: getAbsoluteRange(jsdocNode, paramTagsByName[jsdocParamNames[paramsIndex]]),
|
375
436
|
data: {
|
376
437
|
name,
|
377
|
-
jsdocName:
|
438
|
+
jsdocName: jsdocParamNames[paramsIndex]
|
378
439
|
}
|
379
440
|
});
|
380
|
-
} else if (!
|
441
|
+
} else if (!paramTagsByName[name] && !isOverride) {
|
381
442
|
context.report({
|
382
443
|
node: jsdocNode,
|
383
444
|
message: "Missing JSDoc for parameter '{{name}}'.",
|
package/lib/util/glob-util.js
CHANGED
@@ -8,7 +8,8 @@
|
|
8
8
|
// Requirements
|
9
9
|
//------------------------------------------------------------------------------
|
10
10
|
|
11
|
-
const
|
11
|
+
const lodash = require("lodash"),
|
12
|
+
fs = require("fs"),
|
12
13
|
path = require("path"),
|
13
14
|
GlobSync = require("./glob"),
|
14
15
|
|
@@ -88,6 +89,8 @@ function resolveFileGlobPatterns(patterns, options) {
|
|
88
89
|
return patterns.filter(p => p.length).map(processPathExtensions);
|
89
90
|
}
|
90
91
|
|
92
|
+
const dotfilesPattern = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/;
|
93
|
+
|
91
94
|
/**
|
92
95
|
* Build a list of absolute filesnames on which ESLint will act.
|
93
96
|
* Ignored files are excluded from the results, as are duplicates.
|
@@ -107,6 +110,11 @@ function listFilesToProcess(globPatterns, options) {
|
|
107
110
|
|
108
111
|
const cwd = (options && options.cwd) || process.cwd();
|
109
112
|
|
113
|
+
const getIgnorePaths = lodash.memoize(
|
114
|
+
optionsObj =>
|
115
|
+
new IgnoredPaths(optionsObj)
|
116
|
+
);
|
117
|
+
|
110
118
|
/**
|
111
119
|
* Executes the linter on a file defined by the `filename`. Skips
|
112
120
|
* unsupported file extensions and any files that are already linted.
|
@@ -151,15 +159,20 @@ function listFilesToProcess(globPatterns, options) {
|
|
151
159
|
const file = path.resolve(cwd, pattern);
|
152
160
|
|
153
161
|
if (fs.existsSync(file) && fs.statSync(file).isFile()) {
|
154
|
-
const ignoredPaths =
|
162
|
+
const ignoredPaths = getIgnorePaths(options);
|
155
163
|
|
156
164
|
addFile(fs.realpathSync(file), true, ignoredPaths);
|
157
165
|
} else {
|
158
166
|
|
159
167
|
// regex to find .hidden or /.hidden patterns, but not ./relative or ../relative
|
160
|
-
const globIncludesDotfiles =
|
168
|
+
const globIncludesDotfiles = dotfilesPattern.test(pattern);
|
169
|
+
let newOptions = options;
|
170
|
+
|
171
|
+
if (!options.dotfiles) {
|
172
|
+
newOptions = Object.assign({}, options, { dotfiles: globIncludesDotfiles });
|
173
|
+
}
|
161
174
|
|
162
|
-
const ignoredPaths =
|
175
|
+
const ignoredPaths = getIgnorePaths(newOptions);
|
163
176
|
const shouldIgnore = ignoredPaths.getIgnoredFoldersGlobChecker();
|
164
177
|
const globOptions = {
|
165
178
|
nodir: true,
|
package/lib/util/npm-util.js
CHANGED
@@ -60,7 +60,7 @@ function installSyncSaveDev(packages) {
|
|
60
60
|
if (error && error.code === "ENOENT") {
|
61
61
|
const pluralS = packages.length > 1 ? "s" : "";
|
62
62
|
|
63
|
-
log.error(`Could not execute npm. Please install the following package${pluralS} with
|
63
|
+
log.error(`Could not execute npm. Please install the following package${pluralS} with a package manager of your choice: ${packages.join(", ")}`);
|
64
64
|
}
|
65
65
|
}
|
66
66
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "4.
|
3
|
+
"version": "4.18.1",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -40,7 +40,7 @@
|
|
40
40
|
"concat-stream": "^1.6.0",
|
41
41
|
"cross-spawn": "^5.1.0",
|
42
42
|
"debug": "^3.1.0",
|
43
|
-
"doctrine": "^2.0
|
43
|
+
"doctrine": "^2.1.0",
|
44
44
|
"eslint-scope": "^3.7.1",
|
45
45
|
"eslint-visitor-keys": "^1.0.0",
|
46
46
|
"espree": "^3.5.2",
|