eslint 4.2.0 → 4.5.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 +80 -0
- package/bin/eslint.js +5 -4
- package/conf/category-list.json +2 -2
- package/conf/config-schema.js +3 -1
- package/conf/eslint-recommended.js +11 -14
- package/lib/config/config-file.js +5 -5
- package/lib/config/config-initializer.js +123 -14
- package/lib/config/config-validator.js +25 -1
- package/lib/config/plugins.js +13 -1
- package/lib/formatters/junit.js +2 -8
- package/lib/formatters/stylish.js +2 -1
- package/lib/linter.js +21 -13
- package/lib/rule-context.js +53 -41
- package/lib/rules/arrow-parens.js +1 -1
- package/lib/rules/curly.js +1 -1
- package/lib/rules/getter-return.js +34 -9
- package/lib/rules/id-blacklist.js +7 -3
- package/lib/rules/id-match.js +8 -4
- package/lib/rules/indent-legacy.js +2 -2
- package/lib/rules/indent.js +451 -380
- package/lib/rules/key-spacing.js +2 -2
- package/lib/rules/no-cond-assign.js +7 -3
- package/lib/rules/no-constant-condition.js +62 -6
- package/lib/rules/no-else-return.js +1 -1
- package/lib/rules/no-extra-parens.js +3 -1
- package/lib/rules/no-inner-declarations.js +8 -4
- package/lib/rules/no-multi-spaces.js +53 -115
- package/lib/rules/no-regex-spaces.js +2 -2
- package/lib/rules/no-restricted-globals.js +50 -9
- package/lib/rules/no-restricted-properties.js +19 -11
- package/lib/rules/no-tabs.js +8 -4
- package/lib/rules/no-underscore-dangle.js +28 -1
- package/lib/rules/object-curly-newline.js +18 -0
- package/lib/rules/object-curly-spacing.js +1 -1
- package/lib/rules/padded-blocks.js +2 -2
- package/lib/rules/padding-line-between-statements.js +1 -1
- package/lib/rules/prefer-destructuring.js +70 -32
- package/lib/rules/prefer-numeric-literals.js +36 -7
- package/lib/rules/prefer-reflect.js +8 -4
- package/lib/rules/prefer-template.js +2 -2
- package/lib/rules/space-infix-ops.js +1 -1
- package/lib/rules/spaced-comment.js +2 -2
- package/lib/rules/valid-jsdoc.js +15 -7
- package/lib/testers/rule-tester.js +13 -21
- package/lib/testers/test-parser.js +48 -0
- package/lib/util/npm-util.js +9 -8
- package/package.json +11 -6
package/lib/rule-context.js
CHANGED
@@ -20,6 +20,7 @@ const PASSTHROUGHS = [
|
|
20
20
|
"getDeclaredVariables",
|
21
21
|
"getFilename",
|
22
22
|
"getScope",
|
23
|
+
"getSourceCode",
|
23
24
|
"markVariableAsUsed",
|
24
25
|
|
25
26
|
// DEPRECATED
|
@@ -58,7 +59,7 @@ const PASSTHROUGHS = [
|
|
58
59
|
*/
|
59
60
|
|
60
61
|
//------------------------------------------------------------------------------
|
61
|
-
//
|
62
|
+
// Module Definition
|
62
63
|
//------------------------------------------------------------------------------
|
63
64
|
|
64
65
|
/**
|
@@ -132,13 +133,13 @@ function getFix(descriptor, sourceCode) {
|
|
132
133
|
|
133
134
|
/**
|
134
135
|
* Rule context class
|
135
|
-
* Acts as an abstraction layer between rules and the main
|
136
|
+
* Acts as an abstraction layer between rules and the main linter object.
|
136
137
|
*/
|
137
138
|
class RuleContext {
|
138
139
|
|
139
140
|
/**
|
140
141
|
* @param {string} ruleId The ID of the rule using this object.
|
141
|
-
* @param {
|
142
|
+
* @param {Linter} linter The linter object.
|
142
143
|
* @param {number} severity The configured severity level of the rule.
|
143
144
|
* @param {Array} options The configuration information to be added to the rule.
|
144
145
|
* @param {Object} settings The configuration settings passed from the config file.
|
@@ -147,7 +148,7 @@ class RuleContext {
|
|
147
148
|
* @param {Object} meta The metadata of the rule
|
148
149
|
* @param {Object} parserServices The parser services for the rule.
|
149
150
|
*/
|
150
|
-
constructor(ruleId,
|
151
|
+
constructor(ruleId, linter, severity, options, settings, parserOptions, parserPath, meta, parserServices) {
|
151
152
|
|
152
153
|
// public.
|
153
154
|
this.id = ruleId;
|
@@ -161,22 +162,14 @@ class RuleContext {
|
|
161
162
|
this.parserServices = Object.freeze(Object.assign({}, parserServices));
|
162
163
|
|
163
164
|
// private.
|
164
|
-
this.
|
165
|
-
this.
|
165
|
+
this._linter = linter;
|
166
|
+
this._severity = severity;
|
166
167
|
|
167
168
|
Object.freeze(this);
|
168
169
|
}
|
169
170
|
|
170
171
|
/**
|
171
|
-
* Passthrough to
|
172
|
-
* @returns {SourceCode} The SourceCode object for the code.
|
173
|
-
*/
|
174
|
-
getSourceCode() {
|
175
|
-
return this.eslint.getSourceCode();
|
176
|
-
}
|
177
|
-
|
178
|
-
/**
|
179
|
-
* Passthrough to eslint.report() that automatically assigns the rule ID and severity.
|
172
|
+
* Passthrough to Linter#report() that automatically assigns the rule ID and severity.
|
180
173
|
* @param {ASTNode|MessageDescriptor} nodeOrDescriptor The AST node related to the message or a message
|
181
174
|
* descriptor.
|
182
175
|
* @param {Object=} location The location of the error.
|
@@ -192,38 +185,57 @@ class RuleContext {
|
|
192
185
|
const descriptor = nodeOrDescriptor;
|
193
186
|
const fix = getFix(descriptor, this.getSourceCode());
|
194
187
|
|
195
|
-
|
188
|
+
if (descriptor.loc) {
|
189
|
+
this._linter.report(
|
190
|
+
this.id,
|
191
|
+
this._severity,
|
192
|
+
descriptor.node,
|
193
|
+
descriptor.loc,
|
194
|
+
descriptor.message,
|
195
|
+
descriptor.data,
|
196
|
+
fix,
|
197
|
+
this.meta
|
198
|
+
);
|
199
|
+
} else {
|
200
|
+
this._linter.report(
|
201
|
+
this.id,
|
202
|
+
this._severity,
|
203
|
+
descriptor.node,
|
204
|
+
|
205
|
+
/* loc not provided */
|
206
|
+
descriptor.message,
|
207
|
+
descriptor.data,
|
208
|
+
fix,
|
209
|
+
this.meta
|
210
|
+
);
|
211
|
+
}
|
212
|
+
|
213
|
+
} else {
|
214
|
+
|
215
|
+
// old style call
|
216
|
+
this._linter.report(
|
196
217
|
this.id,
|
197
|
-
this.
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
fix,
|
218
|
+
this._severity,
|
219
|
+
nodeOrDescriptor,
|
220
|
+
location,
|
221
|
+
message,
|
222
|
+
opts,
|
203
223
|
this.meta
|
204
224
|
);
|
205
|
-
|
206
|
-
return;
|
207
225
|
}
|
208
|
-
|
209
|
-
// old style call
|
210
|
-
this.eslint.report(
|
211
|
-
this.id,
|
212
|
-
this.severity,
|
213
|
-
nodeOrDescriptor,
|
214
|
-
location,
|
215
|
-
message,
|
216
|
-
opts,
|
217
|
-
this.meta
|
218
|
-
);
|
219
226
|
}
|
220
227
|
}
|
221
228
|
|
222
|
-
// Copy over passthrough methods.
|
223
|
-
PASSTHROUGHS.forEach(
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
},
|
229
|
+
// Copy over passthrough methods.
|
230
|
+
PASSTHROUGHS.forEach(name => {
|
231
|
+
Object.defineProperty(RuleContext.prototype, name, {
|
232
|
+
value() {
|
233
|
+
return this._linter[name].apply(this._linter, arguments);
|
234
|
+
},
|
235
|
+
configurable: true,
|
236
|
+
writable: true,
|
237
|
+
enumerable: false
|
238
|
+
});
|
239
|
+
});
|
228
240
|
|
229
241
|
module.exports = RuleContext;
|
@@ -71,7 +71,7 @@ module.exports = {
|
|
71
71
|
// https://github.com/eslint/eslint/issues/8834
|
72
72
|
const closingParenToken = sourceCode.getTokenAfter(paramToken, astUtils.isClosingParenToken);
|
73
73
|
const asyncToken = isAsync ? sourceCode.getTokenBefore(firstTokenOfParam) : null;
|
74
|
-
const shouldAddSpaceForAsync = asyncToken && (asyncToken.
|
74
|
+
const shouldAddSpaceForAsync = asyncToken && (asyncToken.range[1] === firstTokenOfParam.range[0]);
|
75
75
|
|
76
76
|
return fixer.replaceTextRange([
|
77
77
|
firstTokenOfParam.range[0],
|
package/lib/rules/curly.js
CHANGED
@@ -238,7 +238,7 @@ module.exports = {
|
|
238
238
|
// `do while` expressions sometimes need a space to be inserted after `do`.
|
239
239
|
// e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)`
|
240
240
|
const needsPrecedingSpace = node.type === "DoWhileStatement" &&
|
241
|
-
sourceCode.getTokenBefore(bodyNode).
|
241
|
+
sourceCode.getTokenBefore(bodyNode).range[1] === bodyNode.range[0] &&
|
242
242
|
!astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(bodyNode, { skip: 1 }));
|
243
243
|
|
244
244
|
const openingBracket = sourceCode.getFirstToken(bodyNode);
|
@@ -14,6 +14,7 @@ const astUtils = require("../ast-utils");
|
|
14
14
|
//------------------------------------------------------------------------------
|
15
15
|
// Helpers
|
16
16
|
//------------------------------------------------------------------------------
|
17
|
+
const TARGET_NODE_TYPE = /^(?:Arrow)?FunctionExpression$/;
|
17
18
|
|
18
19
|
/**
|
19
20
|
* Checks a given code path segment is reachable.
|
@@ -101,22 +102,45 @@ module.exports = {
|
|
101
102
|
}
|
102
103
|
}
|
103
104
|
|
105
|
+
/** Checks whether a node means a getter function.
|
106
|
+
* @param {ASTNode} node - a node to check.
|
107
|
+
* @returns {boolean} if node means a getter, return true; else return false.
|
108
|
+
*/
|
109
|
+
function isGetter(node) {
|
110
|
+
const parent = node.parent;
|
111
|
+
|
112
|
+
if (TARGET_NODE_TYPE.test(node.type) && node.body.type === "BlockStatement") {
|
113
|
+
if (parent.kind === "get") {
|
114
|
+
return true;
|
115
|
+
}
|
116
|
+
if (parent.type === "Property" && astUtils.getStaticPropertyName(parent) === "get" && parent.parent.type === "ObjectExpression") {
|
117
|
+
|
118
|
+
// Object.defineProperty()
|
119
|
+
if (parent.parent.parent.type === "CallExpression" &&
|
120
|
+
astUtils.getStaticPropertyName(parent.parent.parent.callee) === "defineProperty") {
|
121
|
+
return true;
|
122
|
+
}
|
123
|
+
|
124
|
+
// Object.defineProperties()
|
125
|
+
if (parent.parent.parent.type === "Property" &&
|
126
|
+
parent.parent.parent.parent.type === "ObjectExpression" &&
|
127
|
+
parent.parent.parent.parent.parent.type === "CallExpression" &&
|
128
|
+
astUtils.getStaticPropertyName(parent.parent.parent.parent.parent.callee) === "defineProperties") {
|
129
|
+
return true;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
}
|
133
|
+
return false;
|
134
|
+
}
|
104
135
|
return {
|
105
136
|
|
106
137
|
// Stacks this function's information.
|
107
138
|
onCodePathStart(codePath, node) {
|
108
|
-
const parent = node.parent;
|
109
|
-
|
110
139
|
funcInfo = {
|
111
140
|
upper: funcInfo,
|
112
141
|
codePath,
|
113
142
|
hasReturn: false,
|
114
|
-
shouldCheck:
|
115
|
-
node.type === "FunctionExpression" &&
|
116
|
-
node.body.type === "BlockStatement" &&
|
117
|
-
|
118
|
-
// check if it is a "getter", or a method named "get".
|
119
|
-
(parent.kind === "get" || astUtils.getStaticPropertyName(parent) === "get"),
|
143
|
+
shouldCheck: isGetter(node),
|
120
144
|
node
|
121
145
|
};
|
122
146
|
},
|
@@ -145,7 +169,8 @@ module.exports = {
|
|
145
169
|
},
|
146
170
|
|
147
171
|
// Reports a given function if the last path is reachable.
|
148
|
-
"FunctionExpression:exit": checkLastSegment
|
172
|
+
"FunctionExpression:exit": checkLastSegment,
|
173
|
+
"ArrowFunctionExpression:exit": checkLastSegment
|
149
174
|
};
|
150
175
|
}
|
151
176
|
};
|
@@ -67,9 +67,13 @@ module.exports = {
|
|
67
67
|
* @private
|
68
68
|
*/
|
69
69
|
function report(node) {
|
70
|
-
context.report({
|
71
|
-
|
72
|
-
|
70
|
+
context.report({
|
71
|
+
node,
|
72
|
+
message: "Identifier '{{name}}' is blacklisted.",
|
73
|
+
data: {
|
74
|
+
name: node.name
|
75
|
+
}
|
76
|
+
});
|
73
77
|
}
|
74
78
|
|
75
79
|
return {
|
package/lib/rules/id-match.js
CHANGED
@@ -75,10 +75,14 @@ module.exports = {
|
|
75
75
|
* @private
|
76
76
|
*/
|
77
77
|
function report(node) {
|
78
|
-
context.report({
|
79
|
-
|
80
|
-
pattern
|
81
|
-
|
78
|
+
context.report({
|
79
|
+
node,
|
80
|
+
message: "Identifier '{{name}}' does not match the pattern '{{pattern}}'.",
|
81
|
+
data: {
|
82
|
+
name: node.name,
|
83
|
+
pattern
|
84
|
+
}
|
85
|
+
});
|
82
86
|
}
|
83
87
|
|
84
88
|
return {
|
@@ -729,7 +729,7 @@ module.exports = {
|
|
729
729
|
if (!parentVarNode || parentVarNode.loc.start.line !== node.loc.start.line) {
|
730
730
|
if (parent.type !== "VariableDeclarator" || parentVarNode === parentVarNode.parent.declarations[0]) {
|
731
731
|
if (parent.type === "VariableDeclarator" && parentVarNode.loc.start.line === parent.loc.start.line) {
|
732
|
-
nodeIndent
|
732
|
+
nodeIndent += (indentSize * options.VariableDeclarator[parentVarNode.parent.kind]);
|
733
733
|
} else if (parent.type === "ObjectExpression" || parent.type === "ArrayExpression") {
|
734
734
|
const parentElements = node.parent.type === "ObjectExpression" ? node.parent.properties : node.parent.elements;
|
735
735
|
|
@@ -765,7 +765,7 @@ module.exports = {
|
|
765
765
|
}
|
766
766
|
}
|
767
767
|
} else if (!parentVarNode && !isFirstArrayElementOnSameLine(parent) && parent.type !== "MemberExpression" && parent.type !== "ExpressionStatement" && parent.type !== "AssignmentExpression" && parent.type !== "Property") {
|
768
|
-
nodeIndent
|
768
|
+
nodeIndent += indentSize;
|
769
769
|
}
|
770
770
|
|
771
771
|
checkFirstNodeLineIndent(node, nodeIndent);
|