eslint 3.16.1 → 3.19.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 +103 -0
- package/README.md +1 -0
- package/conf/eslint-recommended.js +2 -0
- package/lib/ast-utils.js +3 -67
- package/lib/code-path-analysis/code-path-analyzer.js +2 -7
- package/lib/code-path-analysis/debug-helpers.js +17 -16
- package/lib/config/config-file.js +68 -38
- package/lib/config/config-rule.js +14 -10
- package/lib/config/plugins.js +19 -8
- package/lib/eslint.js +11 -10
- package/lib/formatters/codeframe.js +4 -9
- package/lib/formatters/stylish.js +5 -4
- package/lib/ignored-paths.js +6 -0
- package/lib/internal-rules/internal-no-invalid-meta.js +2 -40
- package/lib/rules/array-callback-return.js +15 -5
- package/lib/rules/arrow-body-style.js +2 -2
- package/lib/rules/arrow-parens.js +9 -3
- package/lib/rules/capitalized-comments.js +2 -1
- package/lib/rules/comma-dangle.js +3 -2
- package/lib/rules/comma-spacing.js +4 -14
- package/lib/rules/comma-style.js +8 -14
- package/lib/rules/complexity.js +14 -8
- package/lib/rules/consistent-return.js +17 -10
- package/lib/rules/curly.js +2 -2
- package/lib/rules/dot-notation.js +12 -6
- package/lib/rules/func-name-matching.js +18 -7
- package/lib/rules/func-names.js +20 -5
- package/lib/rules/keyword-spacing.js +19 -4
- package/lib/rules/line-comment-position.js +15 -5
- package/lib/rules/lines-around-comment.js +19 -0
- package/lib/rules/lines-around-directive.js +1 -1
- package/lib/rules/max-params.js +17 -4
- package/lib/rules/max-statements.js +11 -10
- package/lib/rules/new-parens.js +7 -21
- package/lib/rules/no-compare-neg-zero.js +53 -0
- package/lib/rules/no-cond-assign.js +4 -17
- package/lib/rules/no-else-return.js +19 -4
- package/lib/rules/no-empty-function.js +9 -16
- package/lib/rules/no-extra-parens.js +110 -121
- package/lib/rules/no-extra-semi.js +16 -3
- package/lib/rules/no-global-assign.js +1 -1
- package/lib/rules/no-implicit-coercion.js +21 -8
- package/lib/rules/no-invalid-regexp.js +2 -1
- package/lib/rules/no-multiple-empty-lines.js +2 -4
- package/lib/rules/no-native-reassign.js +1 -1
- package/lib/rules/no-negated-in-lhs.js +1 -1
- package/lib/rules/no-new-func.js +6 -8
- package/lib/rules/no-new.js +2 -6
- package/lib/rules/no-param-reassign.js +37 -7
- package/lib/rules/no-process-exit.js +2 -10
- package/lib/rules/no-restricted-properties.js +2 -0
- package/lib/rules/no-restricted-syntax.js +32 -21
- package/lib/rules/no-return-await.js +1 -1
- package/lib/rules/no-sequences.js +2 -2
- package/lib/rules/no-sync.js +8 -13
- package/lib/rules/no-unsafe-negation.js +1 -1
- package/lib/rules/no-unused-expressions.js +10 -1
- package/lib/rules/no-unused-vars.js +12 -12
- package/lib/rules/no-use-before-define.js +1 -1
- package/lib/rules/no-useless-computed-key.js +12 -1
- package/lib/rules/no-useless-escape.js +8 -2
- package/lib/rules/no-useless-return.js +13 -2
- package/lib/rules/nonblock-statement-body-position.js +114 -0
- package/lib/rules/object-curly-spacing.js +2 -2
- package/lib/rules/object-shorthand.js +10 -3
- package/lib/rules/operator-assignment.js +20 -3
- package/lib/rules/padded-blocks.js +37 -31
- package/lib/rules/prefer-const.js +1 -1
- package/lib/rules/prefer-destructuring.js +1 -1
- package/lib/rules/quotes.js +1 -0
- package/lib/rules/semi-spacing.js +2 -15
- package/lib/rules/semi.js +17 -13
- package/lib/rules/sort-vars.js +3 -5
- package/lib/rules/space-before-function-paren.js +53 -77
- package/lib/rules/space-in-parens.js +4 -8
- package/lib/rules/space-unary-ops.js +19 -1
- package/lib/rules/strict.js +8 -2
- package/lib/rules/yoda.js +2 -2
- package/lib/testers/rule-tester.js +44 -13
- package/lib/util/fix-tracker.js +121 -0
- package/lib/util/glob-util.js +1 -1
- package/lib/util/node-event-generator.js +274 -4
- package/lib/util/source-code-fixer.js +3 -9
- package/lib/util/source-code.js +99 -2
- package/lib/util/traverser.js +16 -25
- package/package.json +34 -34
package/lib/util/source-code.js
CHANGED
@@ -10,7 +10,8 @@
|
|
10
10
|
|
11
11
|
const TokenStore = require("../token-store"),
|
12
12
|
Traverser = require("./traverser"),
|
13
|
-
astUtils = require("../ast-utils")
|
13
|
+
astUtils = require("../ast-utils"),
|
14
|
+
lodash = require("lodash");
|
14
15
|
|
15
16
|
//------------------------------------------------------------------------------
|
16
17
|
// Private
|
@@ -138,7 +139,26 @@ function SourceCode(text, ast) {
|
|
138
139
|
* This is done to avoid each rule needing to do so separately.
|
139
140
|
* @type string[]
|
140
141
|
*/
|
141
|
-
this.lines =
|
142
|
+
this.lines = [];
|
143
|
+
this.lineStartIndices = [0];
|
144
|
+
|
145
|
+
const lineEndingPattern = astUtils.createGlobalLinebreakMatcher();
|
146
|
+
let match;
|
147
|
+
|
148
|
+
/*
|
149
|
+
* Previously, this was implemented using a regex that
|
150
|
+
* matched a sequence of non-linebreak characters followed by a
|
151
|
+
* linebreak, then adding the lengths of the matches. However,
|
152
|
+
* this caused a catastrophic backtracking issue when the end
|
153
|
+
* of a file contained a large number of non-newline characters.
|
154
|
+
* To avoid this, the current implementation just matches newlines
|
155
|
+
* and uses match.index to get the correct line start indices.
|
156
|
+
*/
|
157
|
+
while ((match = lineEndingPattern.exec(this.text))) {
|
158
|
+
this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1], match.index));
|
159
|
+
this.lineStartIndices.push(match.index + match[0].length);
|
160
|
+
}
|
161
|
+
this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1]));
|
142
162
|
|
143
163
|
this.tokensAndComments = sortedMerge(ast.tokens, ast.comments);
|
144
164
|
|
@@ -312,6 +332,83 @@ SourceCode.prototype = {
|
|
312
332
|
const text = this.text.slice(first.range[1], second.range[0]);
|
313
333
|
|
314
334
|
return /\s/.test(text.replace(/\/\*.*?\*\//g, ""));
|
335
|
+
},
|
336
|
+
|
337
|
+
/**
|
338
|
+
* Converts a source text index into a (line, column) pair.
|
339
|
+
* @param {number} index The index of a character in a file
|
340
|
+
* @returns {Object} A {line, column} location object with a 0-indexed column
|
341
|
+
*/
|
342
|
+
getLocFromIndex(index) {
|
343
|
+
if (typeof index !== "number") {
|
344
|
+
throw new TypeError("Expected `index` to be a number.");
|
345
|
+
}
|
346
|
+
|
347
|
+
if (index < 0 || index > this.text.length) {
|
348
|
+
throw new RangeError(`Index out of range (requested index ${index}, but source text has length ${this.text.length}).`);
|
349
|
+
}
|
350
|
+
|
351
|
+
/*
|
352
|
+
* For an argument of this.text.length, return the location one "spot" past the last character
|
353
|
+
* of the file. If the last character is a linebreak, the location will be column 0 of the next
|
354
|
+
* line; otherwise, the location will be in the next column on the same line.
|
355
|
+
*
|
356
|
+
* See getIndexFromLoc for the motivation for this special case.
|
357
|
+
*/
|
358
|
+
if (index === this.text.length) {
|
359
|
+
return { line: this.lines.length, column: this.lines[this.lines.length - 1].length };
|
360
|
+
}
|
361
|
+
|
362
|
+
/*
|
363
|
+
* To figure out which line rangeIndex is on, determine the last index at which rangeIndex could
|
364
|
+
* be inserted into lineIndices to keep the list sorted.
|
365
|
+
*/
|
366
|
+
const lineNumber = lodash.sortedLastIndex(this.lineStartIndices, index);
|
367
|
+
|
368
|
+
return { line: lineNumber, column: index - this.lineStartIndices[lineNumber - 1] };
|
369
|
+
|
370
|
+
},
|
371
|
+
|
372
|
+
/**
|
373
|
+
* Converts a (line, column) pair into a range index.
|
374
|
+
* @param {Object} loc A line/column location
|
375
|
+
* @param {number} loc.line The line number of the location (1-indexed)
|
376
|
+
* @param {number} loc.column The column number of the location (0-indexed)
|
377
|
+
* @returns {number} The range index of the location in the file.
|
378
|
+
*/
|
379
|
+
getIndexFromLoc(loc) {
|
380
|
+
if (typeof loc !== "object" || typeof loc.line !== "number" || typeof loc.column !== "number") {
|
381
|
+
throw new TypeError("Expected `loc` to be an object with numeric `line` and `column` properties.");
|
382
|
+
}
|
383
|
+
|
384
|
+
if (loc.line <= 0) {
|
385
|
+
throw new RangeError(`Line number out of range (line ${loc.line} requested). Line numbers should be 1-based.`);
|
386
|
+
}
|
387
|
+
|
388
|
+
if (loc.line > this.lineStartIndices.length) {
|
389
|
+
throw new RangeError(`Line number out of range (line ${loc.line} requested, but only ${this.lineStartIndices.length} lines present).`);
|
390
|
+
}
|
391
|
+
|
392
|
+
const lineStartIndex = this.lineStartIndices[loc.line - 1];
|
393
|
+
const lineEndIndex = loc.line === this.lineStartIndices.length ? this.text.length : this.lineStartIndices[loc.line];
|
394
|
+
const positionIndex = lineStartIndex + loc.column;
|
395
|
+
|
396
|
+
/*
|
397
|
+
* By design, getIndexFromLoc({ line: lineNum, column: 0 }) should return the start index of
|
398
|
+
* the given line, provided that the line number is valid element of this.lines. Since the
|
399
|
+
* last element of this.lines is an empty string for files with trailing newlines, add a
|
400
|
+
* special case where getting the index for the first location after the end of the file
|
401
|
+
* will return the length of the file, rather than throwing an error. This allows rules to
|
402
|
+
* use getIndexFromLoc consistently without worrying about edge cases at the end of a file.
|
403
|
+
*/
|
404
|
+
if (
|
405
|
+
loc.line === this.lineStartIndices.length && positionIndex > lineEndIndex ||
|
406
|
+
loc.line < this.lineStartIndices.length && positionIndex >= lineEndIndex
|
407
|
+
) {
|
408
|
+
throw new RangeError(`Column number out of range (column ${loc.column} requested, but the length of line ${loc.line} is ${lineEndIndex - lineStartIndex}).`);
|
409
|
+
}
|
410
|
+
|
411
|
+
return positionIndex;
|
315
412
|
}
|
316
413
|
};
|
317
414
|
|
package/lib/util/traverser.js
CHANGED
@@ -14,41 +14,32 @@ const estraverse = require("estraverse");
|
|
14
14
|
// Helpers
|
15
15
|
//------------------------------------------------------------------------------
|
16
16
|
|
17
|
-
const KEY_BLACKLIST = [
|
17
|
+
const KEY_BLACKLIST = new Set([
|
18
18
|
"parent",
|
19
19
|
"leadingComments",
|
20
20
|
"trailingComments"
|
21
|
-
];
|
21
|
+
]);
|
22
22
|
|
23
23
|
/**
|
24
24
|
* Wrapper around an estraverse controller that ensures the correct keys
|
25
25
|
* are visited.
|
26
26
|
* @constructor
|
27
27
|
*/
|
28
|
-
|
29
|
-
|
30
|
-
const controller = Object.create(new estraverse.Controller()),
|
31
|
-
originalTraverse = controller.traverse;
|
32
|
-
|
33
|
-
// intercept call to traverse() and add the fallback key to the visitor
|
34
|
-
controller.traverse = function(node, visitor) {
|
28
|
+
class Traverser extends estraverse.Controller {
|
29
|
+
traverse(node, visitor) {
|
35
30
|
visitor.fallback = Traverser.getKeys;
|
36
|
-
return
|
37
|
-
}
|
38
|
-
|
39
|
-
|
31
|
+
return super.traverse(node, visitor);
|
32
|
+
}
|
33
|
+
|
34
|
+
/**
|
35
|
+
* Calculates the keys to use for traversal.
|
36
|
+
* @param {ASTNode} node The node to read keys from.
|
37
|
+
* @returns {string[]} An array of keys to visit on the node.
|
38
|
+
* @private
|
39
|
+
*/
|
40
|
+
static getKeys(node) {
|
41
|
+
return Object.keys(node).filter(key => !KEY_BLACKLIST.has(key));
|
42
|
+
}
|
40
43
|
}
|
41
44
|
|
42
|
-
/**
|
43
|
-
* Calculates the keys to use for traversal.
|
44
|
-
* @param {ASTNode} node The node to read keys from.
|
45
|
-
* @returns {string[]} An array of keys to visit on the node.
|
46
|
-
* @private
|
47
|
-
*/
|
48
|
-
Traverser.getKeys = function(node) {
|
49
|
-
return Object.keys(node).filter(key => KEY_BLACKLIST.indexOf(key) === -1);
|
50
|
-
};
|
51
|
-
|
52
45
|
module.exports = Traverser;
|
53
|
-
|
54
|
-
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.19.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -36,11 +36,12 @@
|
|
36
36
|
"dependencies": {
|
37
37
|
"babel-code-frame": "^6.16.0",
|
38
38
|
"chalk": "^1.1.3",
|
39
|
-
"concat-stream": "^1.
|
39
|
+
"concat-stream": "^1.5.2",
|
40
40
|
"debug": "^2.1.1",
|
41
|
-
"doctrine": "^
|
41
|
+
"doctrine": "^2.0.0",
|
42
42
|
"escope": "^3.6.0",
|
43
43
|
"espree": "^3.4.0",
|
44
|
+
"esquery": "^1.0.0",
|
44
45
|
"estraverse": "^4.2.0",
|
45
46
|
"esutils": "^2.0.2",
|
46
47
|
"file-entry-cache": "^2.0.0",
|
@@ -70,43 +71,42 @@
|
|
70
71
|
"user-home": "^2.0.0"
|
71
72
|
},
|
72
73
|
"devDependencies": {
|
73
|
-
"babel-polyfill": "^6.
|
74
|
-
"babel-preset-es2015": "^6.
|
74
|
+
"babel-polyfill": "^6.23.0",
|
75
|
+
"babel-preset-es2015": "^6.24.0",
|
75
76
|
"babelify": "^7.3.0",
|
76
|
-
"beefy": "^2.
|
77
|
-
"brfs": "
|
78
|
-
"browserify": "^
|
77
|
+
"beefy": "^2.1.8",
|
78
|
+
"brfs": "1.4.3",
|
79
|
+
"browserify": "^14.1.0",
|
79
80
|
"chai": "^3.5.0",
|
80
|
-
"cheerio": "^0.
|
81
|
-
"coveralls": "2.
|
82
|
-
"dateformat": "^
|
83
|
-
"ejs": "^2.
|
84
|
-
"eslint-plugin-
|
85
|
-
"eslint-
|
86
|
-
"
|
81
|
+
"cheerio": "^0.22.0",
|
82
|
+
"coveralls": "^2.12.0",
|
83
|
+
"dateformat": "^2.0.0",
|
84
|
+
"ejs": "^2.5.6",
|
85
|
+
"eslint-plugin-eslint-plugin": "^0.7.1",
|
86
|
+
"eslint-plugin-node": "^4.2.1",
|
87
|
+
"eslint-release": "^0.10.1",
|
88
|
+
"esprima": "^3.1.3",
|
87
89
|
"esprima-fb": "^15001.1001.0-dev-harmony-fb",
|
88
|
-
"
|
89
|
-
"
|
90
|
-
"
|
91
|
-
"karma": "^0.13.22",
|
90
|
+
"istanbul": "^0.4.5",
|
91
|
+
"jsdoc": "^3.4.3",
|
92
|
+
"karma": "^1.5.0",
|
92
93
|
"karma-babel-preprocessor": "^6.0.1",
|
93
|
-
"karma-mocha": "^1.0
|
94
|
-
"karma-mocha-reporter": "^2.
|
95
|
-
"karma-phantomjs-launcher": "^1.0.
|
96
|
-
"leche": "^2.1.
|
97
|
-
"linefix": "^0.1.1",
|
94
|
+
"karma-mocha": "^1.3.0",
|
95
|
+
"karma-mocha-reporter": "^2.2.2",
|
96
|
+
"karma-phantomjs-launcher": "^1.0.4",
|
97
|
+
"leche": "^2.1.2",
|
98
98
|
"load-perf": "^0.2.0",
|
99
|
-
"markdownlint": "^0.
|
100
|
-
"mocha": "^2.
|
101
|
-
"mock-fs": "^4.
|
102
|
-
"npm-license": "^0.3.
|
103
|
-
"phantomjs-prebuilt": "^2.1.
|
104
|
-
"proxyquire": "^1.7.
|
105
|
-
"semver": "^5.0
|
106
|
-
"shelljs-nodecli": "~0.1.
|
107
|
-
"sinon": "^
|
99
|
+
"markdownlint": "^0.4.0",
|
100
|
+
"mocha": "^3.2.0",
|
101
|
+
"mock-fs": "^4.2.0",
|
102
|
+
"npm-license": "^0.3.3",
|
103
|
+
"phantomjs-prebuilt": "^2.1.14",
|
104
|
+
"proxyquire": "^1.7.11",
|
105
|
+
"semver": "^5.3.0",
|
106
|
+
"shelljs-nodecli": "~0.1.1",
|
107
|
+
"sinon": "^2.0.0",
|
108
108
|
"temp": "^0.8.3",
|
109
|
-
"through": "^2.3.
|
109
|
+
"through": "^2.3.8"
|
110
110
|
},
|
111
111
|
"keywords": [
|
112
112
|
"ast",
|