eslint 4.16.0 → 4.18.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 +46 -0
- package/conf/environments.js +3 -1
- package/conf/eslint-recommended.js +0 -0
- package/lib/linter.js +368 -366
- 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 +9 -4
- 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/indent.js +0 -1
- package/lib/rules/key-spacing.js +3 -2
- package/lib/rules/keyword-spacing.js +6 -1
- package/lib/rules/max-len.js +2 -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-shorthand.js +9 -7
- package/lib/rules/padding-line-between-statements.js +6 -0
- 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/template-tag-spacing.js +0 -0
- package/lib/util/glob-util.js +17 -4
- package/lib/util/interpolate.js +5 -1
- package/lib/util/npm-util.js +1 -1
- package/package.json +2 -2
- package/conf/default-config-options.js +0 -29
@@ -10,6 +10,7 @@
|
|
10
10
|
//------------------------------------------------------------------------------
|
11
11
|
|
12
12
|
const astUtils = require("../ast-utils");
|
13
|
+
const lodash = require("lodash");
|
13
14
|
|
14
15
|
//------------------------------------------------------------------------------
|
15
16
|
// Helpers
|
@@ -73,19 +74,57 @@ function normalizeOptionValue(value) {
|
|
73
74
|
* Normalizes a given option value.
|
74
75
|
*
|
75
76
|
* @param {string|Object|undefined} options - An option value to parse.
|
76
|
-
* @returns {{
|
77
|
+
* @returns {{
|
78
|
+
* ObjectExpression: {multiline: boolean, minProperties: number, consistent: boolean},
|
79
|
+
* ObjectPattern: {multiline: boolean, minProperties: number, consistent: boolean},
|
80
|
+
* ImportDeclaration: {multiline: boolean, minProperties: number, consistent: boolean},
|
81
|
+
* ExportNamedDeclaration : {multiline: boolean, minProperties: number, consistent: boolean}
|
82
|
+
* }} Normalized option object.
|
77
83
|
*/
|
78
84
|
function normalizeOptions(options) {
|
79
|
-
|
85
|
+
const isNodeSpecificOption = lodash.overSome([lodash.isPlainObject, lodash.isString]);
|
86
|
+
|
87
|
+
if (lodash.isPlainObject(options) && lodash.some(options, isNodeSpecificOption)) {
|
80
88
|
return {
|
81
89
|
ObjectExpression: normalizeOptionValue(options.ObjectExpression),
|
82
|
-
ObjectPattern: normalizeOptionValue(options.ObjectPattern)
|
90
|
+
ObjectPattern: normalizeOptionValue(options.ObjectPattern),
|
91
|
+
ImportDeclaration: normalizeOptionValue(options.ImportDeclaration),
|
92
|
+
ExportNamedDeclaration: normalizeOptionValue(options.ExportDeclaration)
|
83
93
|
};
|
84
94
|
}
|
85
95
|
|
86
96
|
const value = normalizeOptionValue(options);
|
87
97
|
|
88
|
-
return { ObjectExpression: value, ObjectPattern: value };
|
98
|
+
return { ObjectExpression: value, ObjectPattern: value, ImportDeclaration: value, ExportNamedDeclaration: value };
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Determines if ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration
|
103
|
+
* node needs to be checked for missing line breaks
|
104
|
+
*
|
105
|
+
* @param {ASTNode} node - Node under inspection
|
106
|
+
* @param {Object} options - option specific to node type
|
107
|
+
* @param {Token} first - First object property
|
108
|
+
* @param {Token} last - Last object property
|
109
|
+
* @returns {boolean} `true` if node needs to be checked for missing line breaks
|
110
|
+
*/
|
111
|
+
function areLineBreaksRequired(node, options, first, last) {
|
112
|
+
let objectProperties;
|
113
|
+
|
114
|
+
if (node.type === "ObjectExpression" || node.type === "ObjectPattern") {
|
115
|
+
objectProperties = node.properties;
|
116
|
+
} else {
|
117
|
+
|
118
|
+
// is ImportDeclaration or ExportNamedDeclaration
|
119
|
+
objectProperties = node.specifiers;
|
120
|
+
}
|
121
|
+
|
122
|
+
return objectProperties.length >= options.minProperties ||
|
123
|
+
(
|
124
|
+
options.multiline &&
|
125
|
+
objectProperties.length > 0 &&
|
126
|
+
first.loc.start.line !== last.loc.end.line
|
127
|
+
);
|
89
128
|
}
|
90
129
|
|
91
130
|
//------------------------------------------------------------------------------
|
@@ -109,7 +148,9 @@ module.exports = {
|
|
109
148
|
type: "object",
|
110
149
|
properties: {
|
111
150
|
ObjectExpression: OPTION_VALUE,
|
112
|
-
ObjectPattern: OPTION_VALUE
|
151
|
+
ObjectPattern: OPTION_VALUE,
|
152
|
+
ImportDeclaration: OPTION_VALUE,
|
153
|
+
ExportDeclaration: OPTION_VALUE
|
113
154
|
},
|
114
155
|
additionalProperties: false,
|
115
156
|
minProperties: 1
|
@@ -125,32 +166,37 @@ module.exports = {
|
|
125
166
|
|
126
167
|
/**
|
127
168
|
* Reports a given node if it violated this rule.
|
128
|
-
*
|
129
|
-
* @param {
|
130
|
-
* @param {{multiline: boolean, minProperties: number}} options - An option object.
|
169
|
+
* @param {ASTNode} node - A node to check. This is an ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration node.
|
170
|
+
* @param {{multiline: boolean, minProperties: number, consistent: boolean}} options - An option object.
|
131
171
|
* @returns {void}
|
132
172
|
*/
|
133
173
|
function check(node) {
|
134
174
|
const options = normalizedOptions[node.type];
|
175
|
+
|
176
|
+
if (
|
177
|
+
(node.type === "ImportDeclaration" &&
|
178
|
+
!node.specifiers.some(specifier => specifier.type === "ImportSpecifier")) ||
|
179
|
+
(node.type === "ExportNamedDeclaration" &&
|
180
|
+
!node.specifiers.some(specifier => specifier.type === "ExportSpecifier"))
|
181
|
+
) {
|
182
|
+
return;
|
183
|
+
}
|
184
|
+
|
135
185
|
const openBrace = sourceCode.getFirstToken(node, token => token.value === "{");
|
186
|
+
|
136
187
|
let closeBrace;
|
137
188
|
|
138
189
|
if (node.typeAnnotation) {
|
139
190
|
closeBrace = sourceCode.getTokenBefore(node.typeAnnotation);
|
140
191
|
} else {
|
141
|
-
closeBrace = sourceCode.getLastToken(node);
|
192
|
+
closeBrace = sourceCode.getLastToken(node, token => token.value === "}");
|
142
193
|
}
|
143
194
|
|
144
195
|
let first = sourceCode.getTokenAfter(openBrace, { includeComments: true });
|
145
196
|
let last = sourceCode.getTokenBefore(closeBrace, { includeComments: true });
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
options.multiline &&
|
150
|
-
node.properties.length > 0 &&
|
151
|
-
first.loc.start.line !== last.loc.end.line
|
152
|
-
)
|
153
|
-
);
|
197
|
+
|
198
|
+
const needsLineBreaks = areLineBreaksRequired(node, options, first, last);
|
199
|
+
|
154
200
|
const hasCommentsFirstToken = astUtils.isCommentToken(first);
|
155
201
|
const hasCommentsLastToken = astUtils.isCommentToken(last);
|
156
202
|
|
@@ -165,7 +211,7 @@ module.exports = {
|
|
165
211
|
first = sourceCode.getTokenAfter(openBrace);
|
166
212
|
last = sourceCode.getTokenBefore(closeBrace);
|
167
213
|
|
168
|
-
if (
|
214
|
+
if (needsLineBreaks) {
|
169
215
|
if (astUtils.isTokenOnSameLine(openBrace, first)) {
|
170
216
|
context.report({
|
171
217
|
message: "Expected a line break after this opening brace.",
|
@@ -244,7 +290,9 @@ module.exports = {
|
|
244
290
|
|
245
291
|
return {
|
246
292
|
ObjectExpression: check,
|
247
|
-
ObjectPattern: check
|
293
|
+
ObjectPattern: check,
|
294
|
+
ImportDeclaration: check,
|
295
|
+
ExportNamedDeclaration: check
|
248
296
|
};
|
249
297
|
}
|
250
298
|
};
|
@@ -131,7 +131,7 @@ module.exports = {
|
|
131
131
|
*
|
132
132
|
*/
|
133
133
|
function canHaveShorthand(property) {
|
134
|
-
return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty");
|
134
|
+
return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadElement" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty");
|
135
135
|
}
|
136
136
|
|
137
137
|
/**
|
@@ -233,10 +233,11 @@ module.exports = {
|
|
233
233
|
const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]);
|
234
234
|
let keyPrefix = "";
|
235
235
|
|
236
|
+
if (node.value.async) {
|
237
|
+
keyPrefix += "async ";
|
238
|
+
}
|
236
239
|
if (node.value.generator) {
|
237
|
-
keyPrefix
|
238
|
-
} else if (node.value.async) {
|
239
|
-
keyPrefix = "async ";
|
240
|
+
keyPrefix += "*";
|
240
241
|
}
|
241
242
|
|
242
243
|
if (node.value.type === "FunctionExpression") {
|
@@ -273,10 +274,11 @@ module.exports = {
|
|
273
274
|
const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]);
|
274
275
|
let functionHeader = "function";
|
275
276
|
|
277
|
+
if (node.value.async) {
|
278
|
+
functionHeader = `async ${functionHeader}`;
|
279
|
+
}
|
276
280
|
if (node.value.generator) {
|
277
|
-
functionHeader =
|
278
|
-
} else if (node.value.async) {
|
279
|
-
functionHeader = "async function";
|
281
|
+
functionHeader = `${functionHeader}*`;
|
280
282
|
}
|
281
283
|
|
282
284
|
return fixer.replaceTextRange([node.range[0], lastKeyToken.range[1]], `${keyText}: ${functionHeader}`);
|
@@ -358,6 +358,12 @@ const StatementTypes = {
|
|
358
358
|
node.loc.start.line !== node.loc.end.line &&
|
359
359
|
isBlockLikeStatement(sourceCode, node)
|
360
360
|
},
|
361
|
+
"multiline-expression": {
|
362
|
+
test: (node, sourceCode) =>
|
363
|
+
node.loc.start.line !== node.loc.end.line &&
|
364
|
+
node.type === "ExpressionStatement" &&
|
365
|
+
!isDirectivePrologue(node, sourceCode)
|
366
|
+
},
|
361
367
|
|
362
368
|
block: newNodeTypeTester("BlockStatement"),
|
363
369
|
empty: newNodeTypeTester("EmptyStatement"),
|
@@ -47,9 +47,15 @@ module.exports = {
|
|
47
47
|
switch (node.type) {
|
48
48
|
case "SpreadElement":
|
49
49
|
type = "spread";
|
50
|
+
if (node.parent.type === "ObjectExpression") {
|
51
|
+
type += " property";
|
52
|
+
}
|
50
53
|
break;
|
51
54
|
case "RestElement":
|
52
55
|
type = "rest";
|
56
|
+
if (node.parent.type === "ObjectPattern") {
|
57
|
+
type += " property";
|
58
|
+
}
|
53
59
|
break;
|
54
60
|
case "ExperimentalSpreadProperty":
|
55
61
|
type = "spread property";
|
@@ -66,15 +66,6 @@ module.exports = {
|
|
66
66
|
node.argument && node.argument.type === "UnaryExpression" && node.argument.operator === "!";
|
67
67
|
}
|
68
68
|
|
69
|
-
/**
|
70
|
-
* Check if the node's child argument is an "ObjectExpression"
|
71
|
-
* @param {ASTnode} node AST node
|
72
|
-
* @returns {boolean} Whether or not the argument's type is "ObjectExpression"
|
73
|
-
*/
|
74
|
-
function isArgumentObjectExpression(node) {
|
75
|
-
return node.argument && node.argument.type && node.argument.type === "ObjectExpression";
|
76
|
-
}
|
77
|
-
|
78
69
|
/**
|
79
70
|
* Checks if an override exists for a given operator.
|
80
71
|
* @param {string} operator Operator
|
@@ -125,7 +116,7 @@ module.exports = {
|
|
125
116
|
* @returns {void}
|
126
117
|
*/
|
127
118
|
function verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word) {
|
128
|
-
if (
|
119
|
+
if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) {
|
129
120
|
if (secondToken.range[0] > firstToken.range[1]) {
|
130
121
|
context.report({
|
131
122
|
node,
|
File without changes
|
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/interpolate.js
CHANGED
@@ -13,7 +13,11 @@ module.exports = (text, data) => {
|
|
13
13
|
if (!data) {
|
14
14
|
return text;
|
15
15
|
}
|
16
|
-
|
16
|
+
|
17
|
+
// Substitution content for any {{ }} markers.
|
18
|
+
return text.replace(/\{\{([^{}]+?)\}\}/g, (fullMatch, termWithWhitespace) => {
|
19
|
+
const term = termWithWhitespace.trim();
|
20
|
+
|
17
21
|
if (term in data) {
|
18
22
|
return data[term];
|
19
23
|
}
|
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.2",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -69,7 +69,7 @@
|
|
69
69
|
"semver": "^5.3.0",
|
70
70
|
"strip-ansi": "^4.0.0",
|
71
71
|
"strip-json-comments": "~2.0.1",
|
72
|
-
"table": "
|
72
|
+
"table": "4.0.2",
|
73
73
|
"text-table": "~0.2.0"
|
74
74
|
},
|
75
75
|
"devDependencies": {
|
@@ -1,29 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* @fileoverview Default config options
|
3
|
-
* @author Teddy Katz
|
4
|
-
*/
|
5
|
-
|
6
|
-
"use strict";
|
7
|
-
|
8
|
-
/**
|
9
|
-
* Freezes an object and all its nested properties
|
10
|
-
* @param {Object} obj The object to deeply freeze
|
11
|
-
* @returns {Object} `obj` after freezing it
|
12
|
-
*/
|
13
|
-
function deepFreeze(obj) {
|
14
|
-
if (obj === null || typeof obj !== "object") {
|
15
|
-
return obj;
|
16
|
-
}
|
17
|
-
|
18
|
-
Object.keys(obj).map(key => obj[key]).forEach(deepFreeze);
|
19
|
-
return Object.freeze(obj);
|
20
|
-
}
|
21
|
-
|
22
|
-
module.exports = deepFreeze({
|
23
|
-
env: {},
|
24
|
-
globals: {},
|
25
|
-
rules: {},
|
26
|
-
settings: {},
|
27
|
-
parser: "espree",
|
28
|
-
parserOptions: {}
|
29
|
-
});
|