eslint 8.7.0 → 8.10.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/README.md +6 -6
- package/lib/cli-engine/cli-engine.js +8 -2
- package/lib/cli-engine/file-enumerator.js +2 -2
- package/lib/config/flat-config-array.js +12 -3
- package/lib/config/flat-config-helpers.js +37 -1
- package/lib/config/rule-validator.js +5 -35
- package/lib/eslint/eslint.js +5 -0
- package/lib/linter/apply-disable-directives.js +35 -44
- package/lib/linter/linter.js +91 -23
- package/lib/rule-tester/flat-rule-tester.js +1039 -0
- package/lib/rules/camelcase.js +2 -2
- package/lib/rules/function-paren-newline.js +5 -1
- package/lib/rules/no-confusing-arrow.js +6 -2
- package/lib/rules/no-shadow.js +127 -16
- package/lib/shared/types.js +15 -0
- package/package.json +6 -5
package/lib/rules/camelcase.js
CHANGED
@@ -146,7 +146,7 @@ module.exports = {
|
|
146
146
|
|
147
147
|
/**
|
148
148
|
* Checks if a given binding identifier uses the original name as-is.
|
149
|
-
* - If it's in object destructuring, the original name is its property name.
|
149
|
+
* - If it's in object destructuring or object expression, the original name is its property name.
|
150
150
|
* - If it's in import declaration, the original name is its exported name.
|
151
151
|
* @param {ASTNode} node The `Identifier` node to check.
|
152
152
|
* @returns {boolean} `true` if the identifier uses the original name as-is.
|
@@ -161,7 +161,7 @@ module.exports = {
|
|
161
161
|
switch (parent.type) {
|
162
162
|
case "Property":
|
163
163
|
return (
|
164
|
-
parent.parent.type === "ObjectPattern" &&
|
164
|
+
(parent.parent.type === "ObjectPattern" || parent.parent.type === "ObjectExpression") &&
|
165
165
|
parent.value === valueNode &&
|
166
166
|
!parent.computed &&
|
167
167
|
parent.key.type === "Identifier" &&
|
@@ -227,9 +227,13 @@ module.exports = {
|
|
227
227
|
return null;
|
228
228
|
}
|
229
229
|
|
230
|
+
const rightParen = node.params.length
|
231
|
+
? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken)
|
232
|
+
: sourceCode.getTokenAfter(firstToken);
|
233
|
+
|
230
234
|
return {
|
231
235
|
leftParen: firstToken,
|
232
|
-
rightParen
|
236
|
+
rightParen
|
233
237
|
};
|
234
238
|
}
|
235
239
|
|
@@ -41,7 +41,8 @@ module.exports = {
|
|
41
41
|
schema: [{
|
42
42
|
type: "object",
|
43
43
|
properties: {
|
44
|
-
allowParens: { type: "boolean", default: true }
|
44
|
+
allowParens: { type: "boolean", default: true },
|
45
|
+
onlyOneSimpleParam: { type: "boolean", default: false }
|
45
46
|
},
|
46
47
|
additionalProperties: false
|
47
48
|
}],
|
@@ -54,6 +55,7 @@ module.exports = {
|
|
54
55
|
create(context) {
|
55
56
|
const config = context.options[0] || {};
|
56
57
|
const allowParens = config.allowParens || (config.allowParens === void 0);
|
58
|
+
const onlyOneSimpleParam = config.onlyOneSimpleParam;
|
57
59
|
const sourceCode = context.getSourceCode();
|
58
60
|
|
59
61
|
|
@@ -65,7 +67,9 @@ module.exports = {
|
|
65
67
|
function checkArrowFunc(node) {
|
66
68
|
const body = node.body;
|
67
69
|
|
68
|
-
if (isConditional(body) &&
|
70
|
+
if (isConditional(body) &&
|
71
|
+
!(allowParens && astUtils.isParenthesised(sourceCode, body)) &&
|
72
|
+
!(onlyOneSimpleParam && !(node.params.length === 1 && node.params[0].type === "Identifier"))) {
|
69
73
|
context.report({
|
70
74
|
node,
|
71
75
|
messageId: "confusing",
|
package/lib/rules/no-shadow.js
CHANGED
@@ -11,6 +11,15 @@
|
|
11
11
|
|
12
12
|
const astUtils = require("./utils/ast-utils");
|
13
13
|
|
14
|
+
//------------------------------------------------------------------------------
|
15
|
+
// Helpers
|
16
|
+
//------------------------------------------------------------------------------
|
17
|
+
|
18
|
+
const FUNC_EXPR_NODE_TYPES = ["ArrowFunctionExpression", "FunctionExpression"];
|
19
|
+
const CALL_EXPR_NODE_TYPE = ["CallExpression"];
|
20
|
+
const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/u;
|
21
|
+
const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u;
|
22
|
+
|
14
23
|
//------------------------------------------------------------------------------
|
15
24
|
// Rule Definition
|
16
25
|
//------------------------------------------------------------------------------
|
@@ -37,7 +46,8 @@ module.exports = {
|
|
37
46
|
items: {
|
38
47
|
type: "string"
|
39
48
|
}
|
40
|
-
}
|
49
|
+
},
|
50
|
+
ignoreOnInitialization: { type: "boolean", default: false }
|
41
51
|
},
|
42
52
|
additionalProperties: false
|
43
53
|
}
|
@@ -54,9 +64,109 @@ module.exports = {
|
|
54
64
|
const options = {
|
55
65
|
builtinGlobals: context.options[0] && context.options[0].builtinGlobals,
|
56
66
|
hoist: (context.options[0] && context.options[0].hoist) || "functions",
|
57
|
-
allow: (context.options[0] && context.options[0].allow) || []
|
67
|
+
allow: (context.options[0] && context.options[0].allow) || [],
|
68
|
+
ignoreOnInitialization: context.options[0] && context.options[0].ignoreOnInitialization
|
58
69
|
};
|
59
70
|
|
71
|
+
/**
|
72
|
+
* Checks whether or not a given location is inside of the range of a given node.
|
73
|
+
* @param {ASTNode} node An node to check.
|
74
|
+
* @param {number} location A location to check.
|
75
|
+
* @returns {boolean} `true` if the location is inside of the range of the node.
|
76
|
+
*/
|
77
|
+
function isInRange(node, location) {
|
78
|
+
return node && node.range[0] <= location && location <= node.range[1];
|
79
|
+
}
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Searches from the current node through its ancestry to find a matching node.
|
83
|
+
* @param {ASTNode} node a node to get.
|
84
|
+
* @param {(node: ASTNode) => boolean} match a callback that checks whether or not the node verifies its condition or not.
|
85
|
+
* @returns {ASTNode|null} the matching node.
|
86
|
+
*/
|
87
|
+
function findSelfOrAncestor(node, match) {
|
88
|
+
let currentNode = node;
|
89
|
+
|
90
|
+
while (currentNode && !match(currentNode)) {
|
91
|
+
currentNode = currentNode.parent;
|
92
|
+
}
|
93
|
+
return currentNode;
|
94
|
+
}
|
95
|
+
|
96
|
+
/**
|
97
|
+
* Finds function's outer scope.
|
98
|
+
* @param {Scope} scope Function's own scope.
|
99
|
+
* @returns {Scope} Function's outer scope.
|
100
|
+
*/
|
101
|
+
function getOuterScope(scope) {
|
102
|
+
const upper = scope.upper;
|
103
|
+
|
104
|
+
if (upper.type === "function-expression-name") {
|
105
|
+
return upper.upper;
|
106
|
+
}
|
107
|
+
return upper;
|
108
|
+
}
|
109
|
+
|
110
|
+
/**
|
111
|
+
* Checks if a variable and a shadowedVariable have the same init pattern ancestor.
|
112
|
+
* @param {Object} variable a variable to check.
|
113
|
+
* @param {Object} shadowedVariable a shadowedVariable to check.
|
114
|
+
* @returns {boolean} Whether or not the variable and the shadowedVariable have the same init pattern ancestor.
|
115
|
+
*/
|
116
|
+
function isInitPatternNode(variable, shadowedVariable) {
|
117
|
+
const outerDef = shadowedVariable.defs[0];
|
118
|
+
|
119
|
+
if (!outerDef) {
|
120
|
+
return false;
|
121
|
+
}
|
122
|
+
|
123
|
+
const { variableScope } = variable.scope;
|
124
|
+
|
125
|
+
|
126
|
+
if (!(FUNC_EXPR_NODE_TYPES.includes(variableScope.block.type) && getOuterScope(variableScope) === shadowedVariable.scope)) {
|
127
|
+
return false;
|
128
|
+
}
|
129
|
+
|
130
|
+
const fun = variableScope.block;
|
131
|
+
const { parent } = fun;
|
132
|
+
|
133
|
+
const callExpression = findSelfOrAncestor(
|
134
|
+
parent,
|
135
|
+
node => CALL_EXPR_NODE_TYPE.includes(node.type)
|
136
|
+
);
|
137
|
+
|
138
|
+
if (!callExpression) {
|
139
|
+
return false;
|
140
|
+
}
|
141
|
+
|
142
|
+
let node = outerDef.name;
|
143
|
+
const location = callExpression.range[1];
|
144
|
+
|
145
|
+
while (node) {
|
146
|
+
if (node.type === "VariableDeclarator") {
|
147
|
+
if (isInRange(node.init, location)) {
|
148
|
+
return true;
|
149
|
+
}
|
150
|
+
if (FOR_IN_OF_TYPE.test(node.parent.parent.type) &&
|
151
|
+
isInRange(node.parent.parent.right, location)
|
152
|
+
) {
|
153
|
+
return true;
|
154
|
+
}
|
155
|
+
break;
|
156
|
+
} else if (node.type === "AssignmentPattern") {
|
157
|
+
if (isInRange(node.right, location)) {
|
158
|
+
return true;
|
159
|
+
}
|
160
|
+
} else if (SENTINEL_TYPE.test(node.type)) {
|
161
|
+
break;
|
162
|
+
}
|
163
|
+
|
164
|
+
node = node.parent;
|
165
|
+
}
|
166
|
+
|
167
|
+
return false;
|
168
|
+
}
|
169
|
+
|
60
170
|
/**
|
61
171
|
* Check if variable name is allowed.
|
62
172
|
* @param {ASTNode} variable The variable to check.
|
@@ -99,11 +209,11 @@ module.exports = {
|
|
99
209
|
|
100
210
|
return (
|
101
211
|
outer &&
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
212
|
+
inner &&
|
213
|
+
outer[0] < inner[0] &&
|
214
|
+
inner[1] < outer[1] &&
|
215
|
+
((innerDef.type === "FunctionName" && innerDef.node.type === "FunctionExpression") || innerDef.node.type === "ClassExpression") &&
|
216
|
+
outerScope === innerScope.upper
|
107
217
|
);
|
108
218
|
}
|
109
219
|
|
@@ -154,11 +264,11 @@ module.exports = {
|
|
154
264
|
|
155
265
|
return (
|
156
266
|
inner &&
|
157
|
-
|
158
|
-
|
267
|
+
outer &&
|
268
|
+
inner[1] < outer[0] &&
|
159
269
|
|
160
|
-
|
161
|
-
|
270
|
+
// Excepts FunctionDeclaration if is {"hoist":"function"}.
|
271
|
+
(options.hoist !== "functions" || !outerDef || outerDef.node.type !== "FunctionDeclaration")
|
162
272
|
);
|
163
273
|
}
|
164
274
|
|
@@ -175,8 +285,8 @@ module.exports = {
|
|
175
285
|
|
176
286
|
// Skips "arguments" or variables of a class name in the class scope of ClassDeclaration.
|
177
287
|
if (variable.identifiers.length === 0 ||
|
178
|
-
|
179
|
-
|
288
|
+
isDuplicatedClassNameVariable(variable) ||
|
289
|
+
isAllowed(variable)
|
180
290
|
) {
|
181
291
|
continue;
|
182
292
|
}
|
@@ -185,9 +295,10 @@ module.exports = {
|
|
185
295
|
const shadowed = astUtils.getVariableByName(scope.upper, variable.name);
|
186
296
|
|
187
297
|
if (shadowed &&
|
188
|
-
|
189
|
-
|
190
|
-
|
298
|
+
(shadowed.identifiers.length > 0 || (options.builtinGlobals && "writeable" in shadowed)) &&
|
299
|
+
!isOnInitializer(variable, shadowed) &&
|
300
|
+
!(options.ignoreOnInitialization && isInitPatternNode(variable, shadowed)) &&
|
301
|
+
!(options.hoist !== "all" && isInTdz(variable, shadowed))
|
191
302
|
) {
|
192
303
|
const location = getDeclaredLocation(shadowed);
|
193
304
|
const messageId = location.global ? "noShadowGlobal" : "noShadow";
|
package/lib/shared/types.js
CHANGED
@@ -105,6 +105,21 @@ module.exports = {};
|
|
105
105
|
* @property {Array<{desc?: string, messageId?: string, fix: {range: [number, number], text: string}}>} [suggestions] Information for suggestions.
|
106
106
|
*/
|
107
107
|
|
108
|
+
/**
|
109
|
+
* @typedef {Object} SuppressedLintMessage
|
110
|
+
* @property {number|undefined} column The 1-based column number.
|
111
|
+
* @property {number} [endColumn] The 1-based column number of the end location.
|
112
|
+
* @property {number} [endLine] The 1-based line number of the end location.
|
113
|
+
* @property {boolean} fatal If `true` then this is a fatal error.
|
114
|
+
* @property {{range:[number,number], text:string}} [fix] Information for autofix.
|
115
|
+
* @property {number|undefined} line The 1-based line number.
|
116
|
+
* @property {string} message The error message.
|
117
|
+
* @property {string|null} ruleId The ID of the rule which makes this message.
|
118
|
+
* @property {0|1|2} severity The severity of this message.
|
119
|
+
* @property {Array<{kind: string, justification: string}>} suppressions The suppression info.
|
120
|
+
* @property {Array<{desc?: string, messageId?: string, fix: {range: [number, number], text: string}}>} [suggestions] Information for suggestions.
|
121
|
+
*/
|
122
|
+
|
108
123
|
/**
|
109
124
|
* @typedef {Object} SuggestionResult
|
110
125
|
* @property {string} desc A short description.
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "eslint",
|
3
|
-
"version": "8.
|
3
|
+
"version": "8.10.0",
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
6
6
|
"bin": {
|
@@ -47,7 +47,7 @@
|
|
47
47
|
"homepage": "https://eslint.org",
|
48
48
|
"bugs": "https://github.com/eslint/eslint/issues/",
|
49
49
|
"dependencies": {
|
50
|
-
"@eslint/eslintrc": "^1.0
|
50
|
+
"@eslint/eslintrc": "^1.2.0",
|
51
51
|
"@humanwhocodes/config-array": "^0.9.2",
|
52
52
|
"ajv": "^6.10.0",
|
53
53
|
"chalk": "^4.0.0",
|
@@ -55,10 +55,10 @@
|
|
55
55
|
"debug": "^4.3.2",
|
56
56
|
"doctrine": "^3.0.0",
|
57
57
|
"escape-string-regexp": "^4.0.0",
|
58
|
-
"eslint-scope": "^7.1.
|
58
|
+
"eslint-scope": "^7.1.1",
|
59
59
|
"eslint-utils": "^3.0.0",
|
60
|
-
"eslint-visitor-keys": "^3.
|
61
|
-
"espree": "^9.3.
|
60
|
+
"eslint-visitor-keys": "^3.3.0",
|
61
|
+
"espree": "^9.3.1",
|
62
62
|
"esquery": "^1.4.0",
|
63
63
|
"esutils": "^2.0.2",
|
64
64
|
"fast-deep-equal": "^3.1.3",
|
@@ -122,6 +122,7 @@
|
|
122
122
|
"node-polyfill-webpack-plugin": "^1.0.3",
|
123
123
|
"npm-license": "^0.3.3",
|
124
124
|
"nyc": "^15.0.1",
|
125
|
+
"pirates": "^4.0.5",
|
125
126
|
"progress": "^2.0.3",
|
126
127
|
"proxyquire": "^2.0.1",
|
127
128
|
"puppeteer": "^9.1.1",
|