Skip to content

Commit 87bd2ce

Browse files
authored
fix: avoid redeclared let when no-var and one-var fix together (#21389)
* fix: avoid redeclared `let` when `no-var` and `one-var` fix together - `no-var` now retains the whole declaration's range when it replaces `var` with `let`, so other fixes that touch the same declaration wait for the next pass. `one-var` could otherwise join a later declaration that redeclares a parameter in the same pass, and the fixed code did not parse. - Add `verifyAndFix` tests running both rules: a redeclared parameter stays `var`, and declarations without a conflict still end as one `let`. * test: move `no-var` and `one-var` fix tests to the `no-var` rule tests - The cases enable `one-var` with an inline `/*eslint one-var:error*/` comment in the `no-var` rule tests, so the single-pass output shows `one-var`'s join waiting for the next pass while `no-var` replaces only the `var` it can fix. - Remove the two `verifyAndFix` cases from the linter tests, which do not test rule behavior.
1 parent 47b7063 commit 87bd2ce

2 files changed

Lines changed: 25 additions & 3 deletions

File tree

‎lib/rules/no-var.js‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//------------------------------------------------------------------------------
1111

1212
const astUtils = require("./utils/ast-utils");
13+
const FixTracker = require("./utils/fix-tracker");
1314

1415
//------------------------------------------------------------------------------
1516
// Types
@@ -460,9 +461,18 @@ module.exports = {
460461
filter: t => t.value === "var",
461462
});
462463

463-
return canFix(node)
464-
? fixer.replaceText(varToken, "let")
465-
: null;
464+
if (!canFix(node)) {
465+
return null;
466+
}
467+
468+
/**
469+
* Extend the replacement range to the whole declaration,
470+
* so other fixes in the same declaration wait for the next pass
471+
* and `canFix` judges the declaration they produce.
472+
*/
473+
return new FixTracker(fixer, sourceCode)
474+
.retainRange(node.range)
475+
.replaceTextRange(varToken.range, "let");
466476
},
467477
});
468478
}

‎tests/lib/rules/no-var.js‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,18 @@ ruleTester.run("no-var", rule, {
588588
output: "function wrap() { function foo() {} foo(); if (bar) { let a = 1; function foo() { console.log(a); } foo (); } }",
589589
errors: [{ messageId: "unexpectedVar" }],
590590
},
591+
592+
// https://github.com/eslint/eslint/issues/21387
593+
{
594+
code: "/*eslint one-var:error*/ function f(a) { var b = 1; var a; }",
595+
output: "/*eslint one-var:error*/ function f(a) { let b = 1; var a; }",
596+
errors: 3,
597+
},
598+
{
599+
code: "/*eslint one-var:error*/ function f() { var b = 1; var c = 2; }",
600+
output: "/*eslint one-var:error*/ function f() { let b = 1; let c = 2; }",
601+
errors: 3,
602+
},
591603
],
592604
});
593605

0 commit comments

Comments
 (0)