@flint.fyi/ts 0.14.2 → 0.14.4
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 +17 -0
- package/lib/createTypeScriptFileFromProgram.js +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/language.d.ts +1 -0
- package/lib/nodes.d.ts +1 -0
- package/lib/plugin.d.ts +165 -1
- package/lib/plugin.js +82 -0
- package/lib/rules/anyReturns.d.ts +6 -0
- package/lib/rules/anyReturns.js +187 -0
- package/lib/rules/anyReturns.test.d.ts +1 -0
- package/lib/rules/anyReturns.test.js +647 -0
- package/lib/rules/asyncPromiseExecutors.d.ts +6 -0
- package/lib/rules/asyncPromiseExecutors.js +51 -0
- package/lib/rules/asyncPromiseExecutors.test.d.ts +1 -0
- package/lib/rules/asyncPromiseExecutors.test.js +71 -0
- package/lib/rules/caseDeclarations.d.ts +6 -0
- package/lib/rules/caseDeclarations.js +53 -0
- package/lib/rules/caseDeclarations.test.d.ts +1 -0
- package/lib/rules/caseDeclarations.test.js +227 -0
- package/lib/rules/caseDuplicates.d.ts +6 -0
- package/lib/rules/caseDuplicates.js +49 -0
- package/lib/rules/caseDuplicates.test.d.ts +1 -0
- package/lib/rules/caseDuplicates.test.js +307 -0
- package/lib/rules/chainedAssignments.d.ts +6 -0
- package/lib/rules/chainedAssignments.js +48 -0
- package/lib/rules/chainedAssignments.test.d.ts +1 -0
- package/lib/rules/chainedAssignments.test.js +238 -0
- package/lib/rules/classAssignments.d.ts +6 -0
- package/lib/rules/classAssignments.js +42 -0
- package/lib/rules/classAssignments.test.d.ts +1 -0
- package/lib/rules/classAssignments.test.js +156 -0
- package/lib/rules/constantAssignments.d.ts +6 -0
- package/lib/rules/constantAssignments.js +61 -0
- package/lib/rules/constantAssignments.test.d.ts +1 -0
- package/lib/rules/constantAssignments.test.js +221 -0
- package/lib/rules/constructorReturns.d.ts +6 -0
- package/lib/rules/constructorReturns.js +52 -0
- package/lib/rules/constructorReturns.test.d.ts +1 -0
- package/lib/rules/constructorReturns.test.js +96 -0
- package/lib/rules/defaultCaseLast.d.ts +6 -0
- package/lib/rules/defaultCaseLast.js +43 -0
- package/lib/rules/defaultCaseLast.test.d.ts +1 -0
- package/lib/rules/defaultCaseLast.test.js +195 -0
- package/lib/rules/duplicateArguments.d.ts +6 -0
- package/lib/rules/duplicateArguments.js +51 -0
- package/lib/rules/duplicateArguments.test.d.ts +1 -0
- package/lib/rules/duplicateArguments.test.js +139 -0
- package/lib/rules/elseIfDuplicates.d.ts +6 -0
- package/lib/rules/elseIfDuplicates.js +53 -0
- package/lib/rules/elseIfDuplicates.test.d.ts +1 -0
- package/lib/rules/elseIfDuplicates.test.js +176 -0
- package/lib/rules/emptyDestructures.d.ts +6 -0
- package/lib/rules/emptyDestructures.js +40 -0
- package/lib/rules/emptyDestructures.test.d.ts +1 -0
- package/lib/rules/emptyDestructures.test.js +186 -0
- package/lib/rules/emptyStaticBlocks.d.ts +6 -0
- package/lib/rules/emptyStaticBlocks.js +54 -0
- package/lib/rules/emptyStaticBlocks.test.d.ts +1 -0
- package/lib/rules/emptyStaticBlocks.test.js +167 -0
- package/lib/rules/exceptionAssignments.d.ts +6 -0
- package/lib/rules/exceptionAssignments.js +61 -0
- package/lib/rules/exceptionAssignments.test.d.ts +1 -0
- package/lib/rules/exceptionAssignments.test.js +264 -0
- package/lib/rules/forDirections.d.ts +6 -0
- package/lib/rules/forDirections.js +124 -0
- package/lib/rules/forDirections.test.d.ts +1 -0
- package/lib/rules/forDirections.test.js +99 -0
- package/lib/rules/functionAssignments.d.ts +6 -0
- package/lib/rules/functionAssignments.js +42 -0
- package/lib/rules/functionAssignments.test.d.ts +1 -0
- package/lib/rules/functionAssignments.test.js +209 -0
- package/lib/rules/functionNewCalls.d.ts +6 -0
- package/lib/rules/functionNewCalls.js +60 -0
- package/lib/rules/functionNewCalls.test.d.ts +1 -0
- package/lib/rules/functionNewCalls.test.js +115 -0
- package/lib/rules/generatorFunctionYields.d.ts +6 -0
- package/lib/rules/generatorFunctionYields.js +57 -0
- package/lib/rules/generatorFunctionYields.test.d.ts +1 -0
- package/lib/rules/generatorFunctionYields.test.js +151 -0
- package/lib/rules/globalAssignments.d.ts +6 -0
- package/lib/rules/globalAssignments.js +59 -0
- package/lib/rules/globalAssignments.test.d.ts +1 -0
- package/lib/rules/globalAssignments.test.js +215 -0
- package/lib/rules/globalObjectCalls.d.ts +6 -0
- package/lib/rules/globalObjectCalls.js +43 -0
- package/lib/rules/globalObjectCalls.test.d.ts +1 -0
- package/lib/rules/globalObjectCalls.test.js +93 -0
- package/lib/rules/negativeZeroComparisons.d.ts +6 -0
- package/lib/rules/negativeZeroComparisons.js +65 -0
- package/lib/rules/negativeZeroComparisons.test.d.ts +1 -0
- package/lib/rules/negativeZeroComparisons.test.js +209 -0
- package/lib/rules/newExpressions.d.ts +6 -0
- package/lib/rules/newExpressions.js +54 -0
- package/lib/rules/newExpressions.test.d.ts +1 -0
- package/lib/rules/newExpressions.test.js +79 -0
- package/lib/rules/newNativeNonConstructors.d.ts +6 -0
- package/lib/rules/newNativeNonConstructors.js +49 -0
- package/lib/rules/newNativeNonConstructors.test.d.ts +1 -0
- package/lib/rules/newNativeNonConstructors.test.js +94 -0
- package/lib/rules/nonOctalDecimalEscapes.d.ts +6 -0
- package/lib/rules/nonOctalDecimalEscapes.js +57 -0
- package/lib/rules/nonOctalDecimalEscapes.test.d.ts +1 -0
- package/lib/rules/nonOctalDecimalEscapes.test.js +69 -0
- package/lib/rules/numericLiteralParsing.d.ts +6 -0
- package/lib/rules/numericLiteralParsing.js +97 -0
- package/lib/rules/numericLiteralParsing.test.d.ts +1 -0
- package/lib/rules/numericLiteralParsing.test.js +99 -0
- package/lib/rules/objectProto.d.ts +6 -0
- package/lib/rules/objectProto.js +54 -0
- package/lib/rules/objectProto.test.d.ts +1 -0
- package/lib/rules/objectProto.test.js +96 -0
- package/lib/rules/octalNumbers.d.ts +6 -0
- package/lib/rules/octalNumbers.js +68 -0
- package/lib/rules/octalNumbers.test.d.ts +1 -0
- package/lib/rules/octalNumbers.test.js +245 -0
- package/lib/rules/returnAssignments.d.ts +6 -0
- package/lib/rules/returnAssignments.js +50 -0
- package/lib/rules/returnAssignments.test.d.ts +1 -0
- package/lib/rules/returnAssignments.test.js +185 -0
- package/lib/rules/selfAssignments.d.ts +6 -0
- package/lib/rules/selfAssignments.js +44 -0
- package/lib/rules/selfAssignments.test.d.ts +1 -0
- package/lib/rules/selfAssignments.test.js +66 -0
- package/lib/rules/selfComparisons.d.ts +6 -0
- package/lib/rules/selfComparisons.js +41 -0
- package/lib/rules/selfComparisons.test.d.ts +1 -0
- package/lib/rules/selfComparisons.test.js +297 -0
- package/lib/rules/sequences.d.ts +6 -0
- package/lib/rules/sequences.js +34 -0
- package/lib/rules/sequences.test.d.ts +1 -0
- package/lib/rules/sequences.test.js +48 -0
- package/lib/rules/sparseArrays.d.ts +6 -0
- package/lib/rules/sparseArrays.js +54 -0
- package/lib/rules/sparseArrays.test.d.ts +1 -0
- package/lib/rules/sparseArrays.test.js +110 -0
- package/lib/rules/symbolDescriptions.d.ts +6 -0
- package/lib/rules/symbolDescriptions.js +41 -0
- package/lib/rules/symbolDescriptions.test.d.ts +1 -0
- package/lib/rules/symbolDescriptions.test.js +89 -0
- package/lib/rules/typeofComparisons.d.ts +6 -0
- package/lib/rules/typeofComparisons.js +78 -0
- package/lib/rules/typeofComparisons.test.d.ts +1 -0
- package/lib/rules/typeofComparisons.test.js +85 -0
- package/lib/rules/unassignedVariables.d.ts +6 -0
- package/lib/rules/unassignedVariables.js +55 -0
- package/lib/rules/unassignedVariables.test.d.ts +1 -0
- package/lib/rules/unassignedVariables.test.js +72 -0
- package/lib/rules/undefinedVariables.d.ts +6 -0
- package/lib/rules/undefinedVariables.js +76 -0
- package/lib/rules/undefinedVariables.test.d.ts +1 -0
- package/lib/rules/undefinedVariables.test.js +80 -0
- package/lib/rules/unicodeBOMs.d.ts +6 -0
- package/lib/rules/unicodeBOMs.js +41 -0
- package/lib/rules/unicodeBOMs.test.d.ts +1 -0
- package/lib/rules/unicodeBOMs.test.js +65 -0
- package/lib/rules/unnecessaryCatches.d.ts +6 -0
- package/lib/rules/unnecessaryCatches.js +68 -0
- package/lib/rules/unnecessaryCatches.test.d.ts +1 -0
- package/lib/rules/unnecessaryCatches.test.js +210 -0
- package/lib/rules/unsafeNegations.d.ts +6 -0
- package/lib/rules/unsafeNegations.js +50 -0
- package/lib/rules/unsafeNegations.test.d.ts +1 -0
- package/lib/rules/unsafeNegations.test.js +63 -0
- package/lib/rules/utils/discriminateAnyType.d.ts +12 -0
- package/lib/rules/utils/discriminateAnyType.js +41 -0
- package/lib/rules/utils/getThisExpression.d.ts +2 -0
- package/lib/rules/utils/getThisExpression.js +23 -0
- package/lib/rules/utils/isUnsafeAssignment.d.ts +13 -0
- package/lib/rules/utils/isUnsafeAssignment.js +76 -0
- package/lib/rules/utils/operators.d.ts +4 -0
- package/lib/rules/utils/operators.js +36 -0
- package/lib/rules/variableDeletions.d.ts +6 -0
- package/lib/rules/variableDeletions.js +39 -0
- package/lib/rules/variableDeletions.test.d.ts +1 -0
- package/lib/rules/variableDeletions.test.js +75 -0
- package/lib/rules/voidOperator.d.ts +6 -0
- package/lib/rules/voidOperator.js +36 -0
- package/lib/rules/voidOperator.test.d.ts +1 -0
- package/lib/rules/voidOperator.test.js +98 -0
- package/lib/utils/declarationIncludesGlobal.d.ts +2 -0
- package/lib/utils/declarationIncludesGlobal.js +5 -0
- package/lib/utils/declarationsIncludeGlobal.d.ts +2 -0
- package/lib/utils/declarationsIncludeGlobal.js +4 -0
- package/lib/utils/getModifyingReferences.d.ts +8 -0
- package/lib/utils/getModifyingReferences.js +42 -0
- package/lib/utils/hasSameTokens.d.ts +2 -0
- package/lib/utils/hasSameTokens.js +30 -0
- package/lib/utils/isGlobalDeclaration.d.ts +2 -0
- package/lib/utils/isGlobalDeclaration.js +5 -0
- package/lib/utils/isGlobalDeclarationOfName.d.ts +5 -0
- package/lib/utils/isGlobalDeclarationOfName.js +31 -0
- package/lib/utils/isGlobalVariable.d.ts +8 -0
- package/lib/utils/isGlobalVariable.js +21 -0
- package/lib/utils/unwrapParentParenthesizedExpressions.d.ts +2 -0
- package/lib/utils/unwrapParentParenthesizedExpressions.js +6 -0
- package/lib/utils/unwrapParenthesizedExpression.d.ts +2 -0
- package/lib/utils/unwrapParenthesizedExpression.js +6 -0
- package/package.json +1 -1
- package/src/createTypeScriptFileFromProgram.ts +1 -0
- package/src/index.ts +1 -0
- package/src/language.ts +1 -0
- package/src/nodes.ts +1 -0
- package/src/plugin.ts +82 -0
- package/src/rules/anyReturns.test.ts +649 -0
- package/src/rules/anyReturns.ts +263 -0
- package/src/rules/asyncPromiseExecutors.test.ts +72 -0
- package/src/rules/asyncPromiseExecutors.ts +61 -0
- package/src/rules/caseDeclarations.test.ts +228 -0
- package/src/rules/caseDeclarations.ts +70 -0
- package/src/rules/caseDuplicates.test.ts +308 -0
- package/src/rules/caseDuplicates.ts +57 -0
- package/src/rules/chainedAssignments.test.ts +239 -0
- package/src/rules/chainedAssignments.ts +55 -0
- package/src/rules/classAssignments.test.ts +157 -0
- package/src/rules/classAssignments.ts +50 -0
- package/src/rules/constantAssignments.test.ts +222 -0
- package/src/rules/constantAssignments.ts +78 -0
- package/src/rules/constructorReturns.test.ts +97 -0
- package/src/rules/constructorReturns.ts +59 -0
- package/src/rules/defaultCaseLast.test.ts +196 -0
- package/src/rules/defaultCaseLast.ts +54 -0
- package/src/rules/duplicateArguments.test.ts +140 -0
- package/src/rules/duplicateArguments.ts +58 -0
- package/src/rules/elseIfDuplicates.test.ts +177 -0
- package/src/rules/elseIfDuplicates.ts +69 -0
- package/src/rules/emptyDestructures.test.ts +187 -0
- package/src/rules/emptyDestructures.ts +48 -0
- package/src/rules/emptyStaticBlocks.test.ts +168 -0
- package/src/rules/emptyStaticBlocks.ts +60 -0
- package/src/rules/exceptionAssignments.test.ts +265 -0
- package/src/rules/exceptionAssignments.ts +77 -0
- package/src/rules/forDirections.test.ts +100 -0
- package/src/rules/forDirections.ts +163 -0
- package/src/rules/functionAssignments.test.ts +210 -0
- package/src/rules/functionAssignments.ts +51 -0
- package/src/rules/functionNewCalls.test.ts +116 -0
- package/src/rules/functionNewCalls.ts +75 -0
- package/src/rules/generatorFunctionYields.test.ts +152 -0
- package/src/rules/generatorFunctionYields.ts +71 -0
- package/src/rules/globalAssignments.test.ts +216 -0
- package/src/rules/globalAssignments.ts +67 -0
- package/src/rules/globalObjectCalls.test.ts +94 -0
- package/src/rules/globalObjectCalls.ts +52 -0
- package/src/rules/negativeZeroComparisons.test.ts +210 -0
- package/src/rules/negativeZeroComparisons.ts +87 -0
- package/src/rules/newExpressions.test.ts +80 -0
- package/src/rules/newExpressions.ts +67 -0
- package/src/rules/newNativeNonConstructors.test.ts +95 -0
- package/src/rules/newNativeNonConstructors.ts +59 -0
- package/src/rules/nonOctalDecimalEscapes.test.ts +70 -0
- package/src/rules/nonOctalDecimalEscapes.ts +70 -0
- package/src/rules/numericLiteralParsing.test.ts +100 -0
- package/src/rules/numericLiteralParsing.ts +116 -0
- package/src/rules/objectProto.test.ts +97 -0
- package/src/rules/objectProto.ts +62 -0
- package/src/rules/octalNumbers.test.ts +246 -0
- package/src/rules/octalNumbers.ts +75 -0
- package/src/rules/returnAssignments.test.ts +186 -0
- package/src/rules/returnAssignments.ts +57 -0
- package/src/rules/selfAssignments.test.ts +67 -0
- package/src/rules/selfAssignments.ts +50 -0
- package/src/rules/selfComparisons.test.ts +298 -0
- package/src/rules/selfComparisons.ts +45 -0
- package/src/rules/sequences.test.ts +49 -0
- package/src/rules/sequences.ts +37 -0
- package/src/rules/sparseArrays.test.ts +111 -0
- package/src/rules/sparseArrays.ts +61 -0
- package/src/rules/symbolDescriptions.test.ts +90 -0
- package/src/rules/symbolDescriptions.ts +47 -0
- package/src/rules/typeofComparisons.test.ts +86 -0
- package/src/rules/typeofComparisons.ts +88 -0
- package/src/rules/unassignedVariables.test.ts +73 -0
- package/src/rules/unassignedVariables.ts +69 -0
- package/src/rules/undefinedVariables.test.ts +81 -0
- package/src/rules/undefinedVariables.ts +97 -0
- package/src/rules/unicodeBOMs.test.ts +66 -0
- package/src/rules/unicodeBOMs.ts +44 -0
- package/src/rules/unnecessaryCatches.test.ts +211 -0
- package/src/rules/unnecessaryCatches.ts +84 -0
- package/src/rules/unsafeNegations.test.ts +64 -0
- package/src/rules/unsafeNegations.ts +59 -0
- package/src/rules/utils/discriminateAnyType.ts +66 -0
- package/src/rules/utils/getThisExpression.ts +24 -0
- package/src/rules/utils/isUnsafeAssignment.ts +113 -0
- package/src/rules/utils/operators.ts +39 -0
- package/src/rules/variableDeletions.test.ts +76 -0
- package/src/rules/variableDeletions.ts +43 -0
- package/src/rules/voidOperator.test.ts +99 -0
- package/src/rules/voidOperator.ts +38 -0
- package/src/utils/declarationIncludesGlobal.ts +9 -0
- package/src/utils/declarationsIncludeGlobal.ts +7 -0
- package/src/utils/getModifyingReferences.ts +58 -0
- package/src/utils/hasSameTokens.ts +45 -0
- package/src/utils/isGlobalDeclaration.ts +12 -0
- package/src/utils/isGlobalDeclarationOfName.ts +51 -0
- package/src/utils/isGlobalVariable.ts +30 -0
- package/src/utils/unwrapParentParenthesizedExpressions.ts +7 -0
- package/src/utils/unwrapParenthesizedExpression.ts +9 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import rule from "./exceptionAssignments.js";
|
|
2
|
+
import { ruleTester } from "./ruleTester.js";
|
|
3
|
+
ruleTester.describe(rule, {
|
|
4
|
+
invalid: [
|
|
5
|
+
{
|
|
6
|
+
code: `
|
|
7
|
+
try {
|
|
8
|
+
doSomething();
|
|
9
|
+
} catch (error) {
|
|
10
|
+
error = new Error("Different error");
|
|
11
|
+
}
|
|
12
|
+
`,
|
|
13
|
+
snapshot: `
|
|
14
|
+
try {
|
|
15
|
+
doSomething();
|
|
16
|
+
} catch (error) {
|
|
17
|
+
error = new Error("Different error");
|
|
18
|
+
~~~~~
|
|
19
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
20
|
+
}
|
|
21
|
+
`,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
code: `
|
|
25
|
+
try {
|
|
26
|
+
doSomething();
|
|
27
|
+
} catch (exception) {
|
|
28
|
+
exception = null;
|
|
29
|
+
}
|
|
30
|
+
`,
|
|
31
|
+
snapshot: `
|
|
32
|
+
try {
|
|
33
|
+
doSomething();
|
|
34
|
+
} catch (exception) {
|
|
35
|
+
exception = null;
|
|
36
|
+
~~~~~~~~~
|
|
37
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
38
|
+
}
|
|
39
|
+
`,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
code: `
|
|
43
|
+
try {
|
|
44
|
+
doSomething();
|
|
45
|
+
} catch (error) {
|
|
46
|
+
error++;
|
|
47
|
+
}
|
|
48
|
+
`,
|
|
49
|
+
snapshot: `
|
|
50
|
+
try {
|
|
51
|
+
doSomething();
|
|
52
|
+
} catch (error) {
|
|
53
|
+
error++;
|
|
54
|
+
~~~~~
|
|
55
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
56
|
+
}
|
|
57
|
+
`,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
code: `
|
|
61
|
+
try {
|
|
62
|
+
doSomething();
|
|
63
|
+
} catch (error) {
|
|
64
|
+
++error;
|
|
65
|
+
}
|
|
66
|
+
`,
|
|
67
|
+
snapshot: `
|
|
68
|
+
try {
|
|
69
|
+
doSomething();
|
|
70
|
+
} catch (error) {
|
|
71
|
+
++error;
|
|
72
|
+
~~~~~
|
|
73
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
74
|
+
}
|
|
75
|
+
`,
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
code: `
|
|
79
|
+
try {
|
|
80
|
+
doSomething();
|
|
81
|
+
} catch (error) {
|
|
82
|
+
error += "additional info";
|
|
83
|
+
}
|
|
84
|
+
`,
|
|
85
|
+
snapshot: `
|
|
86
|
+
try {
|
|
87
|
+
doSomething();
|
|
88
|
+
} catch (error) {
|
|
89
|
+
error += "additional info";
|
|
90
|
+
~~~~~
|
|
91
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
92
|
+
}
|
|
93
|
+
`,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
code: `
|
|
97
|
+
try {
|
|
98
|
+
doSomething();
|
|
99
|
+
} catch (error) {
|
|
100
|
+
error ??= new Error("default error");
|
|
101
|
+
}
|
|
102
|
+
`,
|
|
103
|
+
snapshot: `
|
|
104
|
+
try {
|
|
105
|
+
doSomething();
|
|
106
|
+
} catch (error) {
|
|
107
|
+
error ??= new Error("default error");
|
|
108
|
+
~~~~~
|
|
109
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
110
|
+
}
|
|
111
|
+
`,
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
code: `
|
|
115
|
+
try {
|
|
116
|
+
doSomething();
|
|
117
|
+
} catch (error) {
|
|
118
|
+
error &&= false;
|
|
119
|
+
}
|
|
120
|
+
`,
|
|
121
|
+
snapshot: `
|
|
122
|
+
try {
|
|
123
|
+
doSomething();
|
|
124
|
+
} catch (error) {
|
|
125
|
+
error &&= false;
|
|
126
|
+
~~~~~
|
|
127
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
128
|
+
}
|
|
129
|
+
`,
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
code: `
|
|
133
|
+
try {
|
|
134
|
+
doSomething();
|
|
135
|
+
} catch (error) {
|
|
136
|
+
error ||= new Error("fallback");
|
|
137
|
+
}
|
|
138
|
+
`,
|
|
139
|
+
snapshot: `
|
|
140
|
+
try {
|
|
141
|
+
doSomething();
|
|
142
|
+
} catch (error) {
|
|
143
|
+
error ||= new Error("fallback");
|
|
144
|
+
~~~~~
|
|
145
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
146
|
+
}
|
|
147
|
+
`,
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
code: `
|
|
151
|
+
try {
|
|
152
|
+
doSomething();
|
|
153
|
+
} catch (error) {
|
|
154
|
+
function inner() {
|
|
155
|
+
error = "reassigned in nested function";
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
`,
|
|
159
|
+
snapshot: `
|
|
160
|
+
try {
|
|
161
|
+
doSomething();
|
|
162
|
+
} catch (error) {
|
|
163
|
+
function inner() {
|
|
164
|
+
error = "reassigned in nested function";
|
|
165
|
+
~~~~~
|
|
166
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
`,
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
code: `
|
|
173
|
+
try {
|
|
174
|
+
doSomething();
|
|
175
|
+
} catch ({ message }) {
|
|
176
|
+
message = "reassigned destructured parameter";
|
|
177
|
+
}
|
|
178
|
+
`,
|
|
179
|
+
snapshot: `
|
|
180
|
+
try {
|
|
181
|
+
doSomething();
|
|
182
|
+
} catch ({ message }) {
|
|
183
|
+
message = "reassigned destructured parameter";
|
|
184
|
+
~~~~~~~
|
|
185
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
186
|
+
}
|
|
187
|
+
`,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
code: `
|
|
191
|
+
try {
|
|
192
|
+
doSomething();
|
|
193
|
+
} catch ({ message, code }) {
|
|
194
|
+
code = 500;
|
|
195
|
+
}
|
|
196
|
+
`,
|
|
197
|
+
snapshot: `
|
|
198
|
+
try {
|
|
199
|
+
doSomething();
|
|
200
|
+
} catch ({ message, code }) {
|
|
201
|
+
code = 500;
|
|
202
|
+
~~~~
|
|
203
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
204
|
+
}
|
|
205
|
+
`,
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
code: `
|
|
209
|
+
try {
|
|
210
|
+
doSomething();
|
|
211
|
+
} catch ([first, second]) {
|
|
212
|
+
first = "reassigned array destructured parameter";
|
|
213
|
+
}
|
|
214
|
+
`,
|
|
215
|
+
snapshot: `
|
|
216
|
+
try {
|
|
217
|
+
doSomething();
|
|
218
|
+
} catch ([first, second]) {
|
|
219
|
+
first = "reassigned array destructured parameter";
|
|
220
|
+
~~~~~
|
|
221
|
+
Exception parameters in catch clauses should not be reassigned.
|
|
222
|
+
}
|
|
223
|
+
`,
|
|
224
|
+
},
|
|
225
|
+
],
|
|
226
|
+
valid: [
|
|
227
|
+
`try { doSomething(); } catch (error) { console.log(error); }`,
|
|
228
|
+
`try { doSomething(); } catch (error) { throw error; }`,
|
|
229
|
+
`try { doSomething(); } catch (error) { const message = error.message; }`,
|
|
230
|
+
`try { doSomething(); } catch (error) { if (error instanceof TypeError) { handle(); } }`,
|
|
231
|
+
`try { doSomething(); } catch { handleError(); }`,
|
|
232
|
+
`const error = new Error("test");`,
|
|
233
|
+
`
|
|
234
|
+
try {
|
|
235
|
+
doSomething();
|
|
236
|
+
} catch (error) {
|
|
237
|
+
const error = "shadowed variable";
|
|
238
|
+
console.log(error);
|
|
239
|
+
}
|
|
240
|
+
`,
|
|
241
|
+
`
|
|
242
|
+
try {
|
|
243
|
+
doSomething();
|
|
244
|
+
} catch (error) {
|
|
245
|
+
function inner() {
|
|
246
|
+
const error = "shadowed in function";
|
|
247
|
+
error = "reassigning shadowed variable is ok";
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
`,
|
|
251
|
+
`
|
|
252
|
+
let error = "outer";
|
|
253
|
+
try {
|
|
254
|
+
doSomething();
|
|
255
|
+
} catch (error) {
|
|
256
|
+
console.log(error);
|
|
257
|
+
}
|
|
258
|
+
error = "reassigning outer is ok";
|
|
259
|
+
`,
|
|
260
|
+
`try { doSomething(); } catch ({ message }) { console.log(message); }`,
|
|
261
|
+
`try { doSomething(); } catch ({ message, code }) { if (code === 404) { handle(); } }`,
|
|
262
|
+
`try { doSomething(); } catch ([first]) { console.log(first); }`,
|
|
263
|
+
],
|
|
264
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports for loops with counter variables that move in the wrong direction.";
|
|
3
|
+
readonly id: "forDirections";
|
|
4
|
+
readonly preset: "stylistic";
|
|
5
|
+
}, import("../nodes.js").TSNodesByName, import("../language.js").TypeScriptServices, "wrongDirection", undefined>;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import { getTSNodeRange } from "../getTSNodeRange.js";
|
|
3
|
+
import { typescriptLanguage } from "../language.js";
|
|
4
|
+
function getConditionDirection(condition, counterName) {
|
|
5
|
+
if (!ts.isBinaryExpression(condition)) {
|
|
6
|
+
return undefined;
|
|
7
|
+
}
|
|
8
|
+
const leftName = getCounterName(condition.left);
|
|
9
|
+
const rightName = getCounterName(condition.right);
|
|
10
|
+
const isCounterLeft = leftName === counterName;
|
|
11
|
+
const isCounterRight = rightName === counterName;
|
|
12
|
+
if (!isCounterLeft && !isCounterRight) {
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
const { operatorToken } = condition;
|
|
16
|
+
if (isCounterLeft) {
|
|
17
|
+
if (operatorToken.kind === ts.SyntaxKind.LessThanToken ||
|
|
18
|
+
operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken) {
|
|
19
|
+
return 1;
|
|
20
|
+
}
|
|
21
|
+
if (operatorToken.kind === ts.SyntaxKind.GreaterThanToken ||
|
|
22
|
+
operatorToken.kind === ts.SyntaxKind.GreaterThanEqualsToken) {
|
|
23
|
+
return -1;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
if (operatorToken.kind === ts.SyntaxKind.LessThanToken ||
|
|
28
|
+
operatorToken.kind === ts.SyntaxKind.LessThanEqualsToken) {
|
|
29
|
+
return -1;
|
|
30
|
+
}
|
|
31
|
+
if (operatorToken.kind === ts.SyntaxKind.GreaterThanToken ||
|
|
32
|
+
operatorToken.kind === ts.SyntaxKind.GreaterThanEqualsToken) {
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
function getCounterName(node) {
|
|
39
|
+
return ts.isIdentifier(node) ? node.text : undefined;
|
|
40
|
+
}
|
|
41
|
+
function getUpdateDirection(update) {
|
|
42
|
+
if (ts.isPostfixUnaryExpression(update) ||
|
|
43
|
+
ts.isPrefixUnaryExpression(update)) {
|
|
44
|
+
switch (update.operator) {
|
|
45
|
+
case ts.SyntaxKind.MinusMinusToken:
|
|
46
|
+
return -1;
|
|
47
|
+
case ts.SyntaxKind.PlusPlusToken:
|
|
48
|
+
return 1;
|
|
49
|
+
default:
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (ts.isBinaryExpression(update)) {
|
|
54
|
+
const { operatorToken, right } = update;
|
|
55
|
+
if (operatorToken.kind === ts.SyntaxKind.PlusEqualsToken ||
|
|
56
|
+
operatorToken.kind === ts.SyntaxKind.MinusEqualsToken) {
|
|
57
|
+
if (ts.isNumericLiteral(right)) {
|
|
58
|
+
const value = Number(right.text);
|
|
59
|
+
if (operatorToken.kind === ts.SyntaxKind.PlusEqualsToken) {
|
|
60
|
+
return value > 0 ? 1 : value < 0 ? -1 : 0;
|
|
61
|
+
}
|
|
62
|
+
return value > 0 ? -1 : value < 0 ? 1 : 0;
|
|
63
|
+
}
|
|
64
|
+
if (ts.isPrefixUnaryExpression(right) &&
|
|
65
|
+
right.operator === ts.SyntaxKind.MinusToken &&
|
|
66
|
+
ts.isNumericLiteral(right.operand)) {
|
|
67
|
+
const value = Number(right.operand.text);
|
|
68
|
+
if (operatorToken.kind === ts.SyntaxKind.PlusEqualsToken) {
|
|
69
|
+
return value > 0 ? -1 : 1;
|
|
70
|
+
}
|
|
71
|
+
return value > 0 ? 1 : -1;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
export default typescriptLanguage.createRule({
|
|
78
|
+
about: {
|
|
79
|
+
description: "Reports for loops with counter variables that move in the wrong direction.",
|
|
80
|
+
id: "forDirections",
|
|
81
|
+
preset: "stylistic",
|
|
82
|
+
},
|
|
83
|
+
messages: {
|
|
84
|
+
wrongDirection: {
|
|
85
|
+
primary: "The update moves the counter in the wrong direction for this loop condition.",
|
|
86
|
+
secondary: [
|
|
87
|
+
"A for loop with a counter that moves in the wrong direction relative to its stop condition will run infinitely or never execute.",
|
|
88
|
+
"When the counter increases but the condition expects it to decrease (or vice versa), the loop logic is incorrect.",
|
|
89
|
+
],
|
|
90
|
+
suggestions: [
|
|
91
|
+
"Verify the loop counter update direction matches the condition.",
|
|
92
|
+
],
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
setup(context) {
|
|
96
|
+
return {
|
|
97
|
+
visitors: {
|
|
98
|
+
ForStatement: (node) => {
|
|
99
|
+
if (!node.condition ||
|
|
100
|
+
!node.incrementor ||
|
|
101
|
+
!node.initializer ||
|
|
102
|
+
!ts.isVariableDeclarationList(node.initializer)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const declaration = node.initializer.declarations.at(0);
|
|
106
|
+
if (!declaration || !ts.isIdentifier(declaration.name)) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const updateDirection = getUpdateDirection(node.incrementor);
|
|
110
|
+
if (!updateDirection) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const conditionDirection = getConditionDirection(node.condition, declaration.name.text);
|
|
114
|
+
if (updateDirection !== conditionDirection) {
|
|
115
|
+
context.report({
|
|
116
|
+
message: "wrongDirection",
|
|
117
|
+
range: getTSNodeRange(node.incrementor, context.sourceFile),
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import rule from "./forDirections.js";
|
|
2
|
+
import { ruleTester } from "./ruleTester.js";
|
|
3
|
+
ruleTester.describe(rule, {
|
|
4
|
+
invalid: [
|
|
5
|
+
{
|
|
6
|
+
code: `
|
|
7
|
+
for (let i = 0; i < 10; i--) {}
|
|
8
|
+
`,
|
|
9
|
+
snapshot: `
|
|
10
|
+
for (let i = 0; i < 10; i--) {}
|
|
11
|
+
~~~
|
|
12
|
+
The update moves the counter in the wrong direction for this loop condition.
|
|
13
|
+
`,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
code: `
|
|
17
|
+
for (let index = 0; index < 10; index--) {}
|
|
18
|
+
`,
|
|
19
|
+
snapshot: `
|
|
20
|
+
for (let index = 0; index < 10; index--) {}
|
|
21
|
+
~~~~~~~
|
|
22
|
+
The update moves the counter in the wrong direction for this loop condition.
|
|
23
|
+
`,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
code: `
|
|
27
|
+
for (let index = 10; index >= 0; index++) {}
|
|
28
|
+
`,
|
|
29
|
+
snapshot: `
|
|
30
|
+
for (let index = 10; index >= 0; index++) {}
|
|
31
|
+
~~~~~~~
|
|
32
|
+
The update moves the counter in the wrong direction for this loop condition.
|
|
33
|
+
`,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
code: `
|
|
37
|
+
for (let index = 0; index > 10; index++) {}
|
|
38
|
+
`,
|
|
39
|
+
snapshot: `
|
|
40
|
+
for (let index = 0; index > 10; index++) {}
|
|
41
|
+
~~~~~~~
|
|
42
|
+
The update moves the counter in the wrong direction for this loop condition.
|
|
43
|
+
`,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
code: `
|
|
47
|
+
for (let index = 0; 10 > index; index--) {}
|
|
48
|
+
`,
|
|
49
|
+
snapshot: `
|
|
50
|
+
for (let index = 0; 10 > index; index--) {}
|
|
51
|
+
~~~~~~~
|
|
52
|
+
The update moves the counter in the wrong direction for this loop condition.
|
|
53
|
+
`,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
code: `
|
|
57
|
+
for (let index = 0; index < 10; index -= 1) {}
|
|
58
|
+
`,
|
|
59
|
+
snapshot: `
|
|
60
|
+
for (let index = 0; index < 10; index -= 1) {}
|
|
61
|
+
~~~~~~~~~~
|
|
62
|
+
The update moves the counter in the wrong direction for this loop condition.
|
|
63
|
+
`,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
code: `
|
|
67
|
+
for (let index = 10; index > 0; index += 1) {}
|
|
68
|
+
`,
|
|
69
|
+
snapshot: `
|
|
70
|
+
for (let index = 10; index > 0; index += 1) {}
|
|
71
|
+
~~~~~~~~~~
|
|
72
|
+
The update moves the counter in the wrong direction for this loop condition.
|
|
73
|
+
`,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
code: `
|
|
77
|
+
for (let index = 0; index < 10; index += -1) {}
|
|
78
|
+
`,
|
|
79
|
+
snapshot: `
|
|
80
|
+
for (let index = 0; index < 10; index += -1) {}
|
|
81
|
+
~~~~~~~~~~~
|
|
82
|
+
The update moves the counter in the wrong direction for this loop condition.
|
|
83
|
+
`,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
valid: [
|
|
87
|
+
`for (let i = 0; i < 10; i++) { }`,
|
|
88
|
+
`for (let index = 0; index < 10; index++) { }`,
|
|
89
|
+
`for (let index = 10; index >= 0; index--) { }`,
|
|
90
|
+
`for (let index = 0; 10 > index; index++) { }`,
|
|
91
|
+
`for (let index = 10; 0 < index; index--) { }`,
|
|
92
|
+
`for (let index = 10; index >= 0; index += step) { }`,
|
|
93
|
+
`for (let index = 0; index <= 10; index -= 0) { }`,
|
|
94
|
+
`for (let index = 0; index < 10; index += 1) { }`,
|
|
95
|
+
`for (let index = 10; index > 0; index -= 1) { }`,
|
|
96
|
+
`for (let index = 0; index < 10; index += 2) { }`,
|
|
97
|
+
`for (let index = 10; index > 0; index -= 2) { }`,
|
|
98
|
+
],
|
|
99
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports reassigning variables declared with function declarations.";
|
|
3
|
+
readonly id: "functionAssignments";
|
|
4
|
+
readonly preset: "untyped";
|
|
5
|
+
}, import("../nodes.js").TSNodesByName, import("../language.js").TypeScriptServices, "noFunctionAssignment", undefined>;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { typescriptLanguage } from "../language.js";
|
|
2
|
+
import { getModifyingReferences } from "../utils/getModifyingReferences.js";
|
|
3
|
+
export default typescriptLanguage.createRule({
|
|
4
|
+
about: {
|
|
5
|
+
description: "Reports reassigning variables declared with function declarations.",
|
|
6
|
+
id: "functionAssignments",
|
|
7
|
+
preset: "untyped",
|
|
8
|
+
},
|
|
9
|
+
messages: {
|
|
10
|
+
noFunctionAssignment: {
|
|
11
|
+
primary: "Variables declared with function declarations should not be reassigned.",
|
|
12
|
+
secondary: [
|
|
13
|
+
"Reassigning a function declaration can make code harder to understand and maintain.",
|
|
14
|
+
"Function declarations are hoisted to the top of their scope, and reassigning them can lead to unexpected behavior.",
|
|
15
|
+
],
|
|
16
|
+
suggestions: [
|
|
17
|
+
"Use a function expression or const variable instead if you need to reassign the function.",
|
|
18
|
+
],
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
setup(context) {
|
|
22
|
+
return {
|
|
23
|
+
visitors: {
|
|
24
|
+
FunctionDeclaration: (node) => {
|
|
25
|
+
if (!node.name) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const modifyingReferences = getModifyingReferences(node.name, context.sourceFile, context.typeChecker);
|
|
29
|
+
for (const reference of modifyingReferences) {
|
|
30
|
+
context.report({
|
|
31
|
+
message: "noFunctionAssignment",
|
|
32
|
+
range: {
|
|
33
|
+
begin: reference.getStart(context.sourceFile),
|
|
34
|
+
end: reference.getEnd(),
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
},
|
|
42
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|