eslint 5.10.0 → 5.11.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 +15 -0
- package/conf/eslint-recommended.js +1 -0
- package/lib/rules/camelcase.js +14 -5
- package/lib/rules/implicit-arrow-linebreak.js +143 -1
- package/lib/rules/indent.js +24 -22
- package/lib/rules/no-irregular-whitespace.js +1 -1
- package/lib/rules/no-useless-catch.js +51 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
v5.11.0 - December 22, 2018
|
2
|
+
|
3
|
+
* [`b4395f6`](https://github.com/eslint/eslint/commit/b4395f671442a7e0be956382c24cce38025a6df6) New: add option `first` for VariableDeclarator in indent (fixes #8976) (#11193) (Pig Fang)
|
4
|
+
* [`2b5a602`](https://github.com/eslint/eslint/commit/2b5a60284670a3ab1281b206941ed38faf2ea10c) New: no-useless-catch rule (fixes #11174) (#11198) (Alexander Grasley)
|
5
|
+
* [`06b3b5b`](https://github.com/eslint/eslint/commit/06b3b5bfcf0429c5078d4f4af3c03bb777e4f022) Fix: Account for comments in implicit-arrow-linebreak (#10545) (Mark de Dios)
|
6
|
+
* [`4242314`](https://github.com/eslint/eslint/commit/4242314215a6f35e432860433906f47af1a29724) Update: handle computed properties in camelcase (fixes #11084) (#11113) (Bence Dányi)
|
7
|
+
* [`1009304`](https://github.com/eslint/eslint/commit/100930493d9ab802a94dac5c761515b12241ddd2) Docs: add a note for no-unused-expressions (fixes #11169) (#11192) (Pig Fang)
|
8
|
+
* [`88f99d3`](https://github.com/eslint/eslint/commit/88f99d31b88a4cde4563bc4a6f4c41f0cc557885) Docs: clarify how to use configs in plugins (#11199) (Kai Cataldo)
|
9
|
+
* [`bcf558b`](https://github.com/eslint/eslint/commit/bcf558b2f7036f487af2bdb2b2d34b6cdf7fc174) Docs: Clarify the no-unused-vars docs (#11195) (Jed Fox)
|
10
|
+
* [`a470eb7`](https://github.com/eslint/eslint/commit/a470eb73d52fae0f0bc48de5a487e23cf78fcfa9) Docs: Fix no-irregular-whitespace description (#11196) (Jed Fox)
|
11
|
+
* [`8abc8af`](https://github.com/eslint/eslint/commit/8abc8afe71691b747cbd1819a13d896e8aa5b92a) Docs: Remove a misleading example (#11204) (Bogdan Gradinariu)
|
12
|
+
* [`733d936`](https://github.com/eslint/eslint/commit/733d93618a99758a05453ab94505a9f1330950e0) Docs: link to JSDoc EOL blogpost in valid-jsdoc and require-jsdoc (#11191) (Nathan Diddle)
|
13
|
+
* [`d5eb108`](https://github.com/eslint/eslint/commit/d5eb108e17f676d0e4fcddeb1211b4bdfac760c1) Docs: Ensure `triage` label is added to new issues (#11182) (Teddy Katz)
|
14
|
+
* [`617a287`](https://github.com/eslint/eslint/commit/617a2874ed085bca36ca289aac55e3b7f7ce937e) Docs: add missing deprecation notices for jsdoc rules (#11171) (Teddy Katz)
|
15
|
+
|
1
16
|
v5.10.0 - December 8, 2018
|
2
17
|
|
3
18
|
* [`4b0f517`](https://github.com/eslint/eslint/commit/4b0f517cd317e5f1b99a1e8a0392332bd8a2e231) Upgrade: single- and multiline const, let, var statements (fixes #10721) (#10919) (Tom Panier)
|
package/lib/rules/camelcase.js
CHANGED
@@ -100,14 +100,20 @@ module.exports = {
|
|
100
100
|
* @private
|
101
101
|
*/
|
102
102
|
function isInsideObjectPattern(node) {
|
103
|
-
let
|
103
|
+
let current = node;
|
104
104
|
|
105
|
-
while (
|
106
|
-
|
105
|
+
while (current) {
|
106
|
+
const parent = current.parent;
|
107
|
+
|
108
|
+
if (parent && parent.type === "Property" && parent.computed && parent.key === current) {
|
109
|
+
return false;
|
110
|
+
}
|
111
|
+
|
112
|
+
if (current.type === "ObjectPattern") {
|
107
113
|
return true;
|
108
114
|
}
|
109
115
|
|
110
|
-
|
116
|
+
current = parent;
|
111
117
|
}
|
112
118
|
|
113
119
|
return false;
|
@@ -169,12 +175,15 @@ module.exports = {
|
|
169
175
|
|
170
176
|
if (node.parent.parent && node.parent.parent.type === "ObjectPattern") {
|
171
177
|
if (node.parent.shorthand && node.parent.value.left && nameIsUnderscored) {
|
172
|
-
|
173
178
|
report(node);
|
174
179
|
}
|
175
180
|
|
176
181
|
const assignmentKeyEqualsValue = node.parent.key.name === node.parent.value.name;
|
177
182
|
|
183
|
+
if (isUnderscored(name) && node.parent.computed) {
|
184
|
+
report(node);
|
185
|
+
}
|
186
|
+
|
178
187
|
// prevent checking righthand side of destructured object
|
179
188
|
if (node.parent.key === node && node.parent.value !== node) {
|
180
189
|
return;
|
@@ -4,6 +4,12 @@
|
|
4
4
|
*/
|
5
5
|
"use strict";
|
6
6
|
|
7
|
+
const {
|
8
|
+
isArrowToken,
|
9
|
+
isParenthesised,
|
10
|
+
isOpeningParenToken
|
11
|
+
} = require("../util/ast-utils");
|
12
|
+
|
7
13
|
//------------------------------------------------------------------------------
|
8
14
|
// Rule Definition
|
9
15
|
//------------------------------------------------------------------------------
|
@@ -41,6 +47,142 @@ module.exports = {
|
|
41
47
|
return context.options[0] || "beside";
|
42
48
|
}
|
43
49
|
|
50
|
+
/**
|
51
|
+
* Formats the comments depending on whether it's a line or block comment.
|
52
|
+
* @param {Comment[]} comments The array of comments between the arrow and body
|
53
|
+
* @param {Integer} column The column number of the first token
|
54
|
+
* @returns {string} A string of comment text joined by line breaks
|
55
|
+
*/
|
56
|
+
function formatComments(comments, column) {
|
57
|
+
const whiteSpaces = " ".repeat(column);
|
58
|
+
|
59
|
+
return `${comments.map(comment => {
|
60
|
+
|
61
|
+
if (comment.type === "Line") {
|
62
|
+
return `//${comment.value}`;
|
63
|
+
}
|
64
|
+
|
65
|
+
return `/*${comment.value}*/`;
|
66
|
+
}).join(`\n${whiteSpaces}`)}\n${whiteSpaces}`;
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Finds the first token to prepend comments to depending on the parent type
|
71
|
+
* @param {Node} node The validated node
|
72
|
+
* @returns {Token|Node} The node to prepend comments to
|
73
|
+
*/
|
74
|
+
function findFirstToken(node) {
|
75
|
+
switch (node.parent.type) {
|
76
|
+
case "VariableDeclarator":
|
77
|
+
|
78
|
+
// If the parent is first or only declarator, return the declaration, else, declarator
|
79
|
+
return sourceCode.getFirstToken(
|
80
|
+
node.parent.parent.declarations.length === 1 ||
|
81
|
+
node.parent.parent.declarations[0].id.name === node.parent.id.name
|
82
|
+
? node.parent.parent : node.parent
|
83
|
+
);
|
84
|
+
case "CallExpression":
|
85
|
+
case "Property":
|
86
|
+
|
87
|
+
// find the object key
|
88
|
+
return sourceCode.getFirstToken(node.parent);
|
89
|
+
default:
|
90
|
+
return node;
|
91
|
+
}
|
92
|
+
}
|
93
|
+
|
94
|
+
/**
|
95
|
+
* Helper function for adding parentheses fixes for nodes containing nested arrow functions
|
96
|
+
* @param {Fixer} fixer Fixer
|
97
|
+
* @param {Token} arrow - The arrow token
|
98
|
+
* @param {ASTNode} arrowBody - The arrow function body
|
99
|
+
* @returns {Function[]} autofixer -- wraps function bodies with parentheses
|
100
|
+
*/
|
101
|
+
function addParentheses(fixer, arrow, arrowBody) {
|
102
|
+
const parenthesesFixes = [];
|
103
|
+
let closingParentheses = "";
|
104
|
+
|
105
|
+
let followingBody = arrowBody;
|
106
|
+
let currentArrow = arrow;
|
107
|
+
|
108
|
+
while (currentArrow) {
|
109
|
+
if (!isParenthesised(sourceCode, followingBody)) {
|
110
|
+
parenthesesFixes.push(
|
111
|
+
fixer.insertTextAfter(currentArrow, " (")
|
112
|
+
);
|
113
|
+
|
114
|
+
const paramsToken = sourceCode.getTokenBefore(currentArrow, token =>
|
115
|
+
isOpeningParenToken(token) || token.type === "Identifier");
|
116
|
+
|
117
|
+
const whiteSpaces = " ".repeat(paramsToken.loc.start.column);
|
118
|
+
|
119
|
+
closingParentheses = `\n${whiteSpaces})${closingParentheses}`;
|
120
|
+
}
|
121
|
+
|
122
|
+
currentArrow = sourceCode.getTokenAfter(currentArrow, isArrowToken);
|
123
|
+
|
124
|
+
if (currentArrow) {
|
125
|
+
followingBody = sourceCode.getTokenAfter(currentArrow, token => !isOpeningParenToken(token));
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
return [...parenthesesFixes,
|
130
|
+
fixer.insertTextAfter(arrowBody, closingParentheses)
|
131
|
+
];
|
132
|
+
}
|
133
|
+
|
134
|
+
/**
|
135
|
+
* Autofixes the function body to collapse onto the same line as the arrow.
|
136
|
+
* If comments exist, prepends the comments before the arrow function.
|
137
|
+
* If the function body contains arrow functions, appends the function bodies with parentheses.
|
138
|
+
* @param {Token} arrowToken The arrow token.
|
139
|
+
* @param {ASTNode} arrowBody the function body
|
140
|
+
* @param {ASTNode} node The evaluated node
|
141
|
+
* @returns {Function} autofixer -- validates the node to adhere to besides
|
142
|
+
*/
|
143
|
+
function autoFixBesides(arrowToken, arrowBody, node) {
|
144
|
+
return fixer => {
|
145
|
+
const placeBesides = fixer.replaceTextRange([arrowToken.range[1], arrowBody.range[0]], " ");
|
146
|
+
|
147
|
+
const comments = sourceCode.getCommentsInside(node).filter(comment =>
|
148
|
+
comment.loc.start.line < arrowBody.loc.start.line);
|
149
|
+
|
150
|
+
if (comments.length) {
|
151
|
+
|
152
|
+
// If the grandparent is not a variable declarator
|
153
|
+
if (
|
154
|
+
arrowBody.parent &&
|
155
|
+
arrowBody.parent.parent &&
|
156
|
+
arrowBody.parent.parent.type !== "VariableDeclarator"
|
157
|
+
) {
|
158
|
+
|
159
|
+
// If any arrow functions follow, return the necessary parens fixes.
|
160
|
+
if (sourceCode.getTokenAfter(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") {
|
161
|
+
return addParentheses(fixer, arrowToken, arrowBody);
|
162
|
+
}
|
163
|
+
|
164
|
+
// If any arrow functions precede, the necessary fixes have already been returned, so return null.
|
165
|
+
if (sourceCode.getTokenBefore(arrowToken, isArrowToken) && arrowBody.parent.parent.type !== "VariableDeclarator") {
|
166
|
+
return null;
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|
170
|
+
const firstToken = findFirstToken(node);
|
171
|
+
|
172
|
+
const commentText = formatComments(comments, firstToken.loc.start.column);
|
173
|
+
|
174
|
+
const commentBeforeExpression = fixer.insertTextBeforeRange(
|
175
|
+
firstToken.range,
|
176
|
+
commentText
|
177
|
+
);
|
178
|
+
|
179
|
+
return [placeBesides, commentBeforeExpression];
|
180
|
+
}
|
181
|
+
|
182
|
+
return placeBesides;
|
183
|
+
};
|
184
|
+
}
|
185
|
+
|
44
186
|
/**
|
45
187
|
* Validates the location of an arrow function body
|
46
188
|
* @param {ASTNode} node The arrow function body
|
@@ -75,7 +217,7 @@ module.exports = {
|
|
75
217
|
context.report({
|
76
218
|
node: fixerTarget,
|
77
219
|
message: "Expected no linebreak before this expression.",
|
78
|
-
fix:
|
220
|
+
fix: autoFixBesides(tokenBefore, fixerTarget, node)
|
79
221
|
});
|
80
222
|
}
|
81
223
|
}
|
package/lib/rules/indent.js
CHANGED
@@ -522,25 +522,13 @@ module.exports = {
|
|
522
522
|
},
|
523
523
|
VariableDeclarator: {
|
524
524
|
oneOf: [
|
525
|
-
|
526
|
-
type: "integer",
|
527
|
-
minimum: 0
|
528
|
-
},
|
525
|
+
ELEMENT_LIST_SCHEMA,
|
529
526
|
{
|
530
527
|
type: "object",
|
531
528
|
properties: {
|
532
|
-
var:
|
533
|
-
|
534
|
-
|
535
|
-
},
|
536
|
-
let: {
|
537
|
-
type: "integer",
|
538
|
-
minimum: 0
|
539
|
-
},
|
540
|
-
const: {
|
541
|
-
type: "integer",
|
542
|
-
minimum: 0
|
543
|
-
}
|
529
|
+
var: ELEMENT_LIST_SCHEMA,
|
530
|
+
let: ELEMENT_LIST_SCHEMA,
|
531
|
+
const: ELEMENT_LIST_SCHEMA
|
544
532
|
},
|
545
533
|
additionalProperties: false
|
546
534
|
}
|
@@ -661,7 +649,7 @@ module.exports = {
|
|
661
649
|
if (context.options[1]) {
|
662
650
|
lodash.merge(options, context.options[1]);
|
663
651
|
|
664
|
-
if (typeof options.VariableDeclarator === "number") {
|
652
|
+
if (typeof options.VariableDeclarator === "number" || options.VariableDeclarator === "first") {
|
665
653
|
options.VariableDeclarator = {
|
666
654
|
var: options.VariableDeclarator,
|
667
655
|
let: options.VariableDeclarator,
|
@@ -1349,10 +1337,27 @@ module.exports = {
|
|
1349
1337
|
},
|
1350
1338
|
|
1351
1339
|
VariableDeclaration(node) {
|
1352
|
-
|
1340
|
+
let variableIndent = Object.prototype.hasOwnProperty.call(options.VariableDeclarator, node.kind)
|
1353
1341
|
? options.VariableDeclarator[node.kind]
|
1354
1342
|
: DEFAULT_VARIABLE_INDENT;
|
1355
1343
|
|
1344
|
+
const firstToken = sourceCode.getFirstToken(node),
|
1345
|
+
lastToken = sourceCode.getLastToken(node);
|
1346
|
+
|
1347
|
+
if (options.VariableDeclarator[node.kind] === "first") {
|
1348
|
+
if (node.declarations.length > 1) {
|
1349
|
+
addElementListIndent(
|
1350
|
+
node.declarations,
|
1351
|
+
firstToken,
|
1352
|
+
lastToken,
|
1353
|
+
"first"
|
1354
|
+
);
|
1355
|
+
return;
|
1356
|
+
}
|
1357
|
+
|
1358
|
+
variableIndent = DEFAULT_VARIABLE_INDENT;
|
1359
|
+
}
|
1360
|
+
|
1356
1361
|
if (node.declarations[node.declarations.length - 1].loc.start.line > node.loc.start.line) {
|
1357
1362
|
|
1358
1363
|
/*
|
@@ -1374,13 +1379,10 @@ module.exports = {
|
|
1374
1379
|
* on the same line as the start of the declaration, provided that there are declarators that
|
1375
1380
|
* follow this one.
|
1376
1381
|
*/
|
1377
|
-
const firstToken = sourceCode.getFirstToken(node);
|
1378
|
-
|
1379
1382
|
offsets.setDesiredOffsets(node.range, firstToken, variableIndent, true);
|
1380
1383
|
} else {
|
1381
|
-
offsets.setDesiredOffsets(node.range,
|
1384
|
+
offsets.setDesiredOffsets(node.range, firstToken, variableIndent);
|
1382
1385
|
}
|
1383
|
-
const lastToken = sourceCode.getLastToken(node);
|
1384
1386
|
|
1385
1387
|
if (astUtils.isSemicolonToken(lastToken)) {
|
1386
1388
|
offsets.ignoreToken(lastToken);
|
@@ -30,7 +30,7 @@ module.exports = {
|
|
30
30
|
type: "problem",
|
31
31
|
|
32
32
|
docs: {
|
33
|
-
description: "disallow irregular whitespace
|
33
|
+
description: "disallow irregular whitespace",
|
34
34
|
category: "Possible Errors",
|
35
35
|
recommended: true,
|
36
36
|
url: "https://eslint.org/docs/rules/no-irregular-whitespace"
|
@@ -0,0 +1,51 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Reports useless `catch` clauses that just rethrow their error.
|
3
|
+
* @author Teddy Katz
|
4
|
+
*/
|
5
|
+
|
6
|
+
"use strict";
|
7
|
+
|
8
|
+
//------------------------------------------------------------------------------
|
9
|
+
// Rule Definition
|
10
|
+
//------------------------------------------------------------------------------
|
11
|
+
|
12
|
+
module.exports = {
|
13
|
+
meta: {
|
14
|
+
type: "suggestion",
|
15
|
+
|
16
|
+
docs: {
|
17
|
+
description: "disallow unnecessary `catch` clauses",
|
18
|
+
category: "Best Practices",
|
19
|
+
recommended: false,
|
20
|
+
url: "https://eslint.org/docs/rules/no-useless-catch"
|
21
|
+
},
|
22
|
+
|
23
|
+
schema: []
|
24
|
+
},
|
25
|
+
|
26
|
+
create(context) {
|
27
|
+
return {
|
28
|
+
CatchClause(node) {
|
29
|
+
if (
|
30
|
+
node.param.type === "Identifier" &&
|
31
|
+
node.body.body.length &&
|
32
|
+
node.body.body[0].type === "ThrowStatement" &&
|
33
|
+
node.body.body[0].argument.type === "Identifier" &&
|
34
|
+
node.body.body[0].argument.name === node.param.name
|
35
|
+
) {
|
36
|
+
if (node.parent.finalizer) {
|
37
|
+
context.report({
|
38
|
+
node,
|
39
|
+
message: "Unnecessary catch clause."
|
40
|
+
});
|
41
|
+
} else {
|
42
|
+
context.report({
|
43
|
+
node: node.parent,
|
44
|
+
message: "Unnecessary try/catch wrapper."
|
45
|
+
});
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
};
|
50
|
+
}
|
51
|
+
};
|