Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Commit

Permalink
Rewrite prefer-const (#2219)
Browse files Browse the repository at this point in the history
[enhancement] show warnings for `var`
[bugfix] correctly handle variables shadowed by parameters and catched exceptions
[bugfix] don't warn if a variable in a for loop initializer can be const
[bugfix] handle more cases in destructuring
[bugfix] only fix initialized variables
[new-rule-option] `{destructuring: "all"}` to only warn if all variables in a destructuring can be const
  • Loading branch information
ajafff authored and nchen63 committed Mar 10, 2017
1 parent e2b0ff8 commit 6b913e3
Show file tree
Hide file tree
Showing 9 changed files with 455 additions and 182 deletions.
418 changes: 240 additions & 178 deletions src/rules/preferConstRule.ts

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions test/rules/prefer-const/default/global.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// this is not an external module
// variables in the global scope are ignored by prefer-const
let var1 = 0;
let var2 = 0;
{
let var2 = 1;
{
var2 = 2;
}
var var3 = 0;
{
let var3 = 1;
var3 = 2;
let var4 = 0;
~~~~ [Identifier 'var4' is never reassigned; use 'const' instead of 'let'.]
}
}
25 changes: 25 additions & 0 deletions test/rules/prefer-const/default/spread.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[typescript]: >= 2.1.0
{
let d1 = 0;
let d2 = 0;
let d3 = 0;
let d4 = 0;
[(d1), ([d2]), ...[d3 = 1, ...(d4)]] = [];
}

{
let d1 = 0;
let d2 = 0;
let d3 = 0;
let d4 = 0;
let d5 = 0;
({
d1 = 2,
foo: d2,
bar: {
...d3
},
baz: {d4} = {},
...(d5),
} = {});
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ for (let i1 = 0; i1 < 4; i1++) {
}
for (const i2 = 0;;) { // failure
}
for (const i2 = 0;;) { // failure
for (const i2 = 0;;) {
}

// scope
Expand Down Expand Up @@ -109,8 +109,11 @@ const nest = () => {
};

const nest2 = () => {
const error = false;
try {
} catch(error) {
// variable error is block scoped
error = true;
}
}

Expand Down Expand Up @@ -141,4 +144,46 @@ switch (1) {
case 2:
const y = 1;
break;
}
}

var someVariable = 0;
function funcxion(someVariable, someParameter) {
someVariable = 1;
{
var var1 = 0;
var var2 = 0;
}
{
var1 = 1;
}
{
let var2 = 1;
var2 = 2;
}
}

const shadowed1 = 0;
const shadowed2 = 0;
const shadowed3 = 0;
function shadowVariables({shadowed1, ...shadowed2}, shadowed3) {
shadowed1 = 1;
shadowed2 = 1;
shadowed3 = 1;
}

// no error in for loop initializer
for (let i = 1, l = arr.length; i < l; ++i) {
}

{
const var1 = 0;
let var2 = 0;
function foo(var1 = var2 = 1, var2 = var1 = 1) {}
function foo2(p1 = var2 = 1) {
const var2 = 0;
}
}

// cannot fix, because of uninitialized variables
let uninitialized;
let initialized1 = 0, uninitialized2;
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ for (let i1 = 0; i1 < 4; i1++) {
for (let i2 = 0;;) { // failure
~~ [Identifier 'i2' is never reassigned; use 'const' instead of 'let'.]
}
for (const i2 = 0;;) { // failure
for (const i2 = 0;;) {
}

// scope
Expand Down Expand Up @@ -130,8 +130,12 @@ let nest = () => {

let nest2 = () => {
~~~~~ [Identifier 'nest2' is never reassigned; use 'const' instead of 'let'.]
let error = false;
~~~~~ [Identifier 'error' is never reassigned; use 'const' instead of 'let'.]
try {
} catch(error) {
// variable error is block scoped
error = true;
}
}

Expand Down Expand Up @@ -166,4 +170,56 @@ switch (1) {
let y = 1;
~ [Identifier 'y' is never reassigned; use 'const' instead of 'let'.]
break;
}
}

var someVariable = 0;
~~~~~~~~~~~~ [Identifier 'someVariable' is never reassigned; use 'const' instead of 'var'.]
function funcxion(someVariable, someParameter) {
someVariable = 1;
{
var var1 = 0;
var var2 = 0;
~~~~ [Identifier 'var2' is never reassigned; use 'const' instead of 'var'.]
}
{
var1 = 1;
}
{
let var2 = 1;
var2 = 2;
}
}

let shadowed1 = 0;
~~~~~~~~~ [Identifier 'shadowed1' is never reassigned; use 'const' instead of 'let'.]
let shadowed2 = 0;
~~~~~~~~~ [Identifier 'shadowed2' is never reassigned; use 'const' instead of 'let'.]
let shadowed3 = 0;
~~~~~~~~~ [Identifier 'shadowed3' is never reassigned; use 'const' instead of 'let'.]
function shadowVariables({shadowed1, ...shadowed2}, shadowed3) {
shadowed1 = 1;
shadowed2 = 1;
shadowed3 = 1;
}

// no error in for loop initializer
for (let i = 1, l = arr.length; i < l; ++i) {
}

{
let var1 = 0;
~~~~ [Identifier 'var1' is never reassigned; use 'const' instead of 'let'.]
let var2 = 0;
function foo(var1 = var2 = 1, var2 = var1 = 1) {}
function foo2(p1 = var2 = 1) {
let var2 = 0;
~~~~ [Identifier 'var2' is never reassigned; use 'const' instead of 'let'.]
}
}

// cannot fix, because of uninitialized variables
let uninitialized;
~~~~~~~~~~~~~ [Identifier 'uninitialized' is never reassigned; use 'const' instead of 'let'.]
let initialized1 = 0, uninitialized2;
~~~~~~~~~~~~ [Identifier 'initialized1' is never reassigned; use 'const' instead of 'let'.]
~~~~~~~~~~~~~~ [Identifier 'uninitialized2' is never reassigned; use 'const' instead of 'let'.]
28 changes: 28 additions & 0 deletions test/rules/prefer-const/destructuring-all/test.ts.fix
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export let foo = 1;
// destructuring
{
let destructLater = 4;
[destructLater] = 5;
let a: number;
let b: number;
let c: any;
({ eh: a, b, ...c } = { eh: 0, b: 1 });
}

let {h, i} = {h: 1, i: 1}; // 'h' can be const
let [j, k] = [1, 1]; // 'j' can be const
let [x1, x3] = [1, 2], [x2] = [3]; // failure for x1, x3
let {a: {b: {q}, c: {r}}} = { a: { b: { q: 3 }, c: { r: 2 } } }; // 'r' can be const
i = 2;
k = 2;
q = 4;
x2 = 5;

for (let {o, p} of [{1, 1}, {1, 1}]) { // 'o' can be const
console.log(o);
p = 2;
}

{
const [d1, d2] = [];
}
32 changes: 32 additions & 0 deletions test/rules/prefer-const/destructuring-all/test.ts.lint
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export let foo = 1;
// destructuring
{
let destructLater = 4;
[destructLater] = 5;
let a: number;
let b: number;
let c: any;
({ eh: a, b, ...c } = { eh: 0, b: 1 });
}

let {h, i} = {h: 1, i: 1}; // 'h' can be const
let [j, k] = [1, 1]; // 'j' can be const
let [x1, x3] = [1, 2], [x2] = [3]; // failure for x1, x3
~~ [Identifier 'x1' is never reassigned; use 'const' instead of 'let'.]
~~ [Identifier 'x3' is never reassigned; use 'const' instead of 'let'.]
let {a: {b: {q}, c: {r}}} = { a: { b: { q: 3 }, c: { r: 2 } } }; // 'r' can be const
i = 2;
k = 2;
q = 4;
x2 = 5;

for (let {o, p} of [{1, 1}, {1, 1}]) { // 'o' can be const
console.log(o);
p = 2;
}

{
let [d1, d2] = [];
~~ [Identifier 'd1' is never reassigned; use 'const' instead of 'let'.]
~~ [Identifier 'd2' is never reassigned; use 'const' instead of 'let'.]
}
8 changes: 8 additions & 0 deletions test/rules/prefer-const/destructuring-all/tslint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"rules": {
"prefer-const": [
true,
{"destructuring": "all"}
]
}
}

0 comments on commit 6b913e3

Please sign in to comment.