eslint 10.0.0-rc.0 → 10.0.0-rc.1
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 +1 -1
- package/lib/rule-tester/rule-tester.js +22 -15
- package/lib/rules/no-shadow.js +89 -24
- package/lib/types/index.d.ts +3 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -342,7 +342,7 @@ to get your logo on our READMEs and [website](https://eslint.org/sponsors).
|
|
|
342
342
|
<h3>Platinum Sponsors</h3>
|
|
343
343
|
<p><a href="https://automattic.com"><img src="https://images.opencollective.com/automattic/d0ef3e1/logo.png" alt="Automattic" height="128"></a></p><h3>Gold Sponsors</h3>
|
|
344
344
|
<p><a href="https://qlty.sh/"><img src="https://images.opencollective.com/qltysh/33d157d/logo.png" alt="Qlty Software" height="96"></a> <a href="https://shopify.engineering/"><img src="https://avatars.githubusercontent.com/u/8085" alt="Shopify" height="96"></a></p><h3>Silver Sponsors</h3>
|
|
345
|
-
<p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/
|
|
345
|
+
<p><a href="https://vite.dev/"><img src="https://images.opencollective.com/vite/d472863/logo.png" alt="Vite" height="64"></a> <a href="https://liftoff.io/"><img src="https://images.opencollective.com/liftoff/2d6c3b6/logo.png" alt="Liftoff" height="64"></a> <a href="https://americanexpress.io"><img src="https://avatars.githubusercontent.com/u/3853301" alt="American Express" height="64"></a> <a href="https://stackblitz.com"><img src="https://avatars.githubusercontent.com/u/28635252" alt="StackBlitz" height="64"></a></p><h3>Bronze Sponsors</h3>
|
|
346
346
|
<p><a href="https://cybozu.co.jp/"><img src="https://images.opencollective.com/cybozu/933e46d/logo.png" alt="Cybozu" height="32"></a> <a href="https://www.crawljobs.com/"><img src="https://images.opencollective.com/crawljobs-poland/fa43a17/logo.png" alt="CrawlJobs" height="32"></a> <a href="https://syntax.fm"><img src="https://github.com/syntaxfm.png" alt="Syntax" height="32"></a> <a href="https://www.n-ix.com/"><img src="https://images.opencollective.com/n-ix-ltd/575a7a5/logo.png" alt="N-iX Ltd" height="32"></a> <a href="https://icons8.com/"><img src="https://images.opencollective.com/icons8/7fa1641/logo.png" alt="Icons8" height="32"></a> <a href="https://discord.com"><img src="https://images.opencollective.com/discordapp/f9645d9/logo.png" alt="Discord" height="32"></a> <a href="https://www.gitbook.com"><img src="https://avatars.githubusercontent.com/u/7111340" alt="GitBook" height="32"></a> <a href="https://nx.dev"><img src="https://avatars.githubusercontent.com/u/23692104" alt="Nx" height="32"></a> <a href="https://herocoders.com"><img src="https://avatars.githubusercontent.com/u/37549774" alt="HeroCoders" height="32"></a> <a href="https://www.lambdatest.com"><img src="https://avatars.githubusercontent.com/u/171592363" alt="LambdaTest" height="32"></a></p>
|
|
347
347
|
<h3>Technology Sponsors</h3>
|
|
348
348
|
Technology sponsors allow us to use their products and services for free as part of a contribution to the open source ecosystem and our work.
|
|
@@ -657,14 +657,25 @@ function assertInvalidTestCase(
|
|
|
657
657
|
/**
|
|
658
658
|
* Gets the invocation location from the stack trace for later use.
|
|
659
659
|
* @param {Function} relative The function before the invocation point.
|
|
660
|
-
* @returns {string} The invocation location.
|
|
660
|
+
* @returns {{ sourceFile: string; sourceLine: number; sourceColumn: number; }} The invocation location.
|
|
661
661
|
*/
|
|
662
662
|
function getInvocationLocation(relative = getInvocationLocation) {
|
|
663
663
|
const dummyObject = {};
|
|
664
|
-
|
|
665
|
-
const {
|
|
666
|
-
|
|
667
|
-
|
|
664
|
+
let location;
|
|
665
|
+
const { prepareStackTrace } = Error;
|
|
666
|
+
Error.prepareStackTrace = (_, [callSite]) => {
|
|
667
|
+
location = {
|
|
668
|
+
sourceFile:
|
|
669
|
+
callSite.getFileName() ??
|
|
670
|
+
`${callSite.getEvalOrigin()}, <anonymous>`,
|
|
671
|
+
sourceLine: callSite.getLineNumber() ?? 1,
|
|
672
|
+
sourceColumn: callSite.getColumnNumber() ?? 1,
|
|
673
|
+
};
|
|
674
|
+
};
|
|
675
|
+
Error.captureStackTrace(dummyObject, relative); // invoke Error.prepareStackTrace in Bun
|
|
676
|
+
void dummyObject.stack; // invoke Error.prepareStackTrace in Node.js
|
|
677
|
+
Error.prepareStackTrace = prepareStackTrace;
|
|
678
|
+
return location;
|
|
668
679
|
}
|
|
669
680
|
|
|
670
681
|
/**
|
|
@@ -677,14 +688,10 @@ function buildLazyTestLocationEstimator(invoker) {
|
|
|
677
688
|
let testLocations = null;
|
|
678
689
|
return key => {
|
|
679
690
|
if (testLocations === null) {
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
sourceFile = sourceFile.replace(/\\\\/u, ":\\");
|
|
685
|
-
sourceLine = Number(sourceLine);
|
|
686
|
-
sourceColumn = Number(sourceColumn);
|
|
687
|
-
testLocations = { root: invocationLocation };
|
|
691
|
+
const { sourceFile, sourceLine, sourceColumn } = invocationLocation;
|
|
692
|
+
testLocations = {
|
|
693
|
+
root: `${sourceFile}:${sourceLine}:${sourceColumn}`,
|
|
694
|
+
};
|
|
688
695
|
|
|
689
696
|
if (existsSync(sourceFile)) {
|
|
690
697
|
let content = readFileSync(sourceFile, "utf8")
|
|
@@ -700,10 +707,10 @@ function buildLazyTestLocationEstimator(invoker) {
|
|
|
700
707
|
|
|
701
708
|
// Roots
|
|
702
709
|
const validStartIndex = content.findIndex(line =>
|
|
703
|
-
/\bvalid
|
|
710
|
+
/\bvalid\s*:/u.test(line),
|
|
704
711
|
);
|
|
705
712
|
const invalidStartIndex = content.findIndex(line =>
|
|
706
|
-
/\binvalid
|
|
713
|
+
/\binvalid\s*:/u.test(line),
|
|
707
714
|
);
|
|
708
715
|
|
|
709
716
|
testLocations.valid = `${sourceFile}:${
|
package/lib/rules/no-shadow.js
CHANGED
|
@@ -346,32 +346,97 @@ module.exports = {
|
|
|
346
346
|
}
|
|
347
347
|
|
|
348
348
|
/**
|
|
349
|
-
*
|
|
349
|
+
* Finds the uppermost expression node that can evaluate to the given one.
|
|
350
350
|
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
351
|
+
* Examples:
|
|
352
|
+
* If given `a` in `a || foo`, it returns the `a || foo` node.
|
|
353
|
+
* If given `a` in `foo ? a : bar`, it returns the `foo ? a : bar` node.
|
|
354
|
+
* If given `a` in `foo ? bar : (baz && a)`, it returns the `foo ? bar : (baz && a)` node.
|
|
355
|
+
* If given `a` in `a ? foo : bar`, it returns the `a` node.
|
|
356
|
+
* If given `a` in `foo(a)`, it returns the `a` node.
|
|
357
|
+
* @param {ASTNode} expression The expression node to unwrap.
|
|
358
|
+
* @returns {ASTNode} The uppermost ancestor that can evaluate to the given node
|
|
359
|
+
* or the given node if there is no such ancestor.
|
|
356
360
|
*/
|
|
357
|
-
function
|
|
358
|
-
const
|
|
359
|
-
const outerDef = scopeVar.defs[0];
|
|
360
|
-
const outer = outerDef && outerDef.parent && outerDef.parent.range;
|
|
361
|
-
const innerScope = variable.scope;
|
|
362
|
-
const innerDef = variable.defs[0];
|
|
363
|
-
const inner = innerDef && innerDef.name.range;
|
|
361
|
+
function unwrapExpression(expression) {
|
|
362
|
+
const { parent } = expression;
|
|
364
363
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
364
|
+
const shouldUnwrap =
|
|
365
|
+
parent.type === "LogicalExpression" ||
|
|
366
|
+
(parent.type === "ConditionalExpression" &&
|
|
367
|
+
parent.test !== expression);
|
|
368
|
+
|
|
369
|
+
return shouldUnwrap ? unwrapExpression(parent) : expression;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Checks if inner variable is the name of a function or class
|
|
374
|
+
* that is assigned to outer variable as its initializer.
|
|
375
|
+
*
|
|
376
|
+
* To avoid reporting at declarations such as:
|
|
377
|
+
* var a = function a() {};
|
|
378
|
+
* var A = class A {};
|
|
379
|
+
* var a = foo || function a() {};
|
|
380
|
+
* var a = foo ? function a() {} : bar;
|
|
381
|
+
* var { a = function a() {} } = foo;
|
|
382
|
+
*
|
|
383
|
+
* But it should report at declarations such as:
|
|
384
|
+
* var a = function(a) {};
|
|
385
|
+
* var a = function() { function a() {} };
|
|
386
|
+
* var a = wrap(function a() {});
|
|
387
|
+
* @param {Object} innerVariable The inner variable to check.
|
|
388
|
+
* @param {Object} outerVariable The outer variable.
|
|
389
|
+
* @returns {boolean} Whether or not inner variable is the name of a
|
|
390
|
+
* function or class that is assigned to outer variable as its initializer.
|
|
391
|
+
*/
|
|
392
|
+
function isFunctionNameInitializerException(
|
|
393
|
+
innerVariable,
|
|
394
|
+
outerVariable,
|
|
395
|
+
) {
|
|
396
|
+
const outerDef = outerVariable.defs[0];
|
|
397
|
+
const innerDef = innerVariable.defs[0];
|
|
398
|
+
|
|
399
|
+
if (!outerDef || !innerDef) {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (
|
|
404
|
+
!(
|
|
405
|
+
(innerDef.type === "FunctionName" &&
|
|
406
|
+
innerDef.node.type === "FunctionExpression") ||
|
|
407
|
+
(innerDef.type === "ClassName" &&
|
|
408
|
+
innerDef.node.type === "ClassExpression")
|
|
409
|
+
)
|
|
410
|
+
) {
|
|
411
|
+
return false;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const outerIdentifier = outerDef.name;
|
|
415
|
+
let initializerNode;
|
|
416
|
+
|
|
417
|
+
if (outerIdentifier.parent.type === "VariableDeclarator") {
|
|
418
|
+
initializerNode = outerIdentifier.parent.init;
|
|
419
|
+
} else if (outerIdentifier.parent.type === "AssignmentPattern") {
|
|
420
|
+
initializerNode = outerIdentifier.parent.right;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if (!initializerNode) {
|
|
424
|
+
return false;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
const nodeToCheck = innerDef.node; // FunctionExpression or ClassExpression node
|
|
428
|
+
|
|
429
|
+
// Exit early if the node to check isn't inside the initializer
|
|
430
|
+
if (
|
|
431
|
+
!(
|
|
432
|
+
initializerNode.range[0] <= nodeToCheck.range[0] &&
|
|
433
|
+
nodeToCheck.range[1] <= initializerNode.range[1]
|
|
434
|
+
)
|
|
435
|
+
) {
|
|
436
|
+
return false;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
return initializerNode === unwrapExpression(nodeToCheck);
|
|
375
440
|
}
|
|
376
441
|
|
|
377
442
|
/**
|
|
@@ -577,7 +642,7 @@ module.exports = {
|
|
|
577
642
|
shadowed &&
|
|
578
643
|
(shadowed.identifiers.length > 0 ||
|
|
579
644
|
(builtinGlobals && "writeable" in shadowed)) &&
|
|
580
|
-
!
|
|
645
|
+
!isFunctionNameInitializerException(variable, shadowed) &&
|
|
581
646
|
!(
|
|
582
647
|
ignoreOnInitialization &&
|
|
583
648
|
isInitPatternNode(variable, shadowed)
|
package/lib/types/index.d.ts
CHANGED
|
@@ -70,6 +70,7 @@ import type {
|
|
|
70
70
|
SuggestedEditBase,
|
|
71
71
|
SuggestedEdit,
|
|
72
72
|
ViolationReport,
|
|
73
|
+
MessagePlaceholderData,
|
|
73
74
|
} from "@eslint/core";
|
|
74
75
|
|
|
75
76
|
//------------------------------------------------------------------------------
|
|
@@ -1458,7 +1459,7 @@ export namespace RuleTester {
|
|
|
1458
1459
|
interface SuggestionOutput {
|
|
1459
1460
|
messageId?: string;
|
|
1460
1461
|
desc?: string;
|
|
1461
|
-
data?:
|
|
1462
|
+
data?: MessagePlaceholderData | undefined;
|
|
1462
1463
|
output: string;
|
|
1463
1464
|
}
|
|
1464
1465
|
|
|
@@ -1470,7 +1471,7 @@ export namespace RuleTester {
|
|
|
1470
1471
|
interface TestCaseError {
|
|
1471
1472
|
message?: string | RegExp;
|
|
1472
1473
|
messageId?: string;
|
|
1473
|
-
data?:
|
|
1474
|
+
data?: MessagePlaceholderData | undefined;
|
|
1474
1475
|
line?: number | undefined;
|
|
1475
1476
|
column?: number | undefined;
|
|
1476
1477
|
endLine?: number | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint",
|
|
3
|
-
"version": "10.0.0-rc.
|
|
3
|
+
"version": "10.0.0-rc.1",
|
|
4
4
|
"author": "Nicholas C. Zakas <nicholas+npm@nczconsulting.com>",
|
|
5
5
|
"description": "An AST-based pattern checker for JavaScript.",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -120,9 +120,9 @@
|
|
|
120
120
|
"cross-spawn": "^7.0.6",
|
|
121
121
|
"debug": "^4.3.2",
|
|
122
122
|
"escape-string-regexp": "^4.0.0",
|
|
123
|
-
"eslint-scope": "^9.
|
|
123
|
+
"eslint-scope": "^9.1.0",
|
|
124
124
|
"eslint-visitor-keys": "^5.0.0",
|
|
125
|
-
"espree": "^11.
|
|
125
|
+
"espree": "^11.1.0",
|
|
126
126
|
"esquery": "^1.5.0",
|
|
127
127
|
"esutils": "^2.0.2",
|
|
128
128
|
"fast-deep-equal": "^3.1.3",
|