@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,215 @@
|
|
|
1
|
+
import rule from "./globalAssignments.js";
|
|
2
|
+
import { ruleTester } from "./ruleTester.js";
|
|
3
|
+
ruleTester.describe(rule, {
|
|
4
|
+
invalid: [
|
|
5
|
+
{
|
|
6
|
+
code: `
|
|
7
|
+
undefined = 1;
|
|
8
|
+
`,
|
|
9
|
+
snapshot: `
|
|
10
|
+
undefined = 1;
|
|
11
|
+
~~~~~~~~~
|
|
12
|
+
Read-only global variables should not be reassigned or modified.
|
|
13
|
+
`,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
code: `
|
|
17
|
+
NaN = 42;
|
|
18
|
+
`,
|
|
19
|
+
snapshot: `
|
|
20
|
+
NaN = 42;
|
|
21
|
+
~~~
|
|
22
|
+
Read-only global variables should not be reassigned or modified.
|
|
23
|
+
`,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
code: `
|
|
27
|
+
Infinity = 100;
|
|
28
|
+
`,
|
|
29
|
+
snapshot: `
|
|
30
|
+
Infinity = 100;
|
|
31
|
+
~~~~~~~~
|
|
32
|
+
Read-only global variables should not be reassigned or modified.
|
|
33
|
+
`,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
code: `
|
|
37
|
+
Object = null;
|
|
38
|
+
`,
|
|
39
|
+
snapshot: `
|
|
40
|
+
Object = null;
|
|
41
|
+
~~~~~~
|
|
42
|
+
Read-only global variables should not be reassigned or modified.
|
|
43
|
+
`,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
code: `
|
|
47
|
+
Array = function() {};
|
|
48
|
+
`,
|
|
49
|
+
snapshot: `
|
|
50
|
+
Array = function() {};
|
|
51
|
+
~~~~~
|
|
52
|
+
Read-only global variables should not be reassigned or modified.
|
|
53
|
+
`,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
code: `
|
|
57
|
+
String = "test";
|
|
58
|
+
`,
|
|
59
|
+
snapshot: `
|
|
60
|
+
String = "test";
|
|
61
|
+
~~~~~~
|
|
62
|
+
Read-only global variables should not be reassigned or modified.
|
|
63
|
+
`,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
code: `
|
|
67
|
+
Number = 123;
|
|
68
|
+
`,
|
|
69
|
+
snapshot: `
|
|
70
|
+
Number = 123;
|
|
71
|
+
~~~~~~
|
|
72
|
+
Read-only global variables should not be reassigned or modified.
|
|
73
|
+
`,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
code: `
|
|
77
|
+
Boolean = true;
|
|
78
|
+
`,
|
|
79
|
+
snapshot: `
|
|
80
|
+
Boolean = true;
|
|
81
|
+
~~~~~~~
|
|
82
|
+
Read-only global variables should not be reassigned or modified.
|
|
83
|
+
`,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
code: `
|
|
87
|
+
Math = {};
|
|
88
|
+
`,
|
|
89
|
+
snapshot: `
|
|
90
|
+
Math = {};
|
|
91
|
+
~~~~
|
|
92
|
+
Read-only global variables should not be reassigned or modified.
|
|
93
|
+
`,
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
code: `
|
|
97
|
+
JSON = null;
|
|
98
|
+
`,
|
|
99
|
+
snapshot: `
|
|
100
|
+
JSON = null;
|
|
101
|
+
~~~~
|
|
102
|
+
Read-only global variables should not be reassigned or modified.
|
|
103
|
+
`,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
code: `
|
|
107
|
+
window = {};
|
|
108
|
+
`,
|
|
109
|
+
snapshot: `
|
|
110
|
+
window = {};
|
|
111
|
+
~~~~~~
|
|
112
|
+
Read-only global variables should not be reassigned or modified.
|
|
113
|
+
`,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
code: `
|
|
117
|
+
undefined += 1;
|
|
118
|
+
`,
|
|
119
|
+
snapshot: `
|
|
120
|
+
undefined += 1;
|
|
121
|
+
~~~~~~~~~
|
|
122
|
+
Read-only global variables should not be reassigned or modified.
|
|
123
|
+
`,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
code: `
|
|
127
|
+
NaN *= 2;
|
|
128
|
+
`,
|
|
129
|
+
snapshot: `
|
|
130
|
+
NaN *= 2;
|
|
131
|
+
~~~
|
|
132
|
+
Read-only global variables should not be reassigned or modified.
|
|
133
|
+
`,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
code: `
|
|
137
|
+
++undefined;
|
|
138
|
+
`,
|
|
139
|
+
snapshot: `
|
|
140
|
+
++undefined;
|
|
141
|
+
~~~~~~~~~
|
|
142
|
+
Read-only global variables should not be reassigned or modified.
|
|
143
|
+
`,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
code: `
|
|
147
|
+
NaN++;
|
|
148
|
+
`,
|
|
149
|
+
snapshot: `
|
|
150
|
+
NaN++;
|
|
151
|
+
~~~
|
|
152
|
+
Read-only global variables should not be reassigned or modified.
|
|
153
|
+
`,
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
code: `
|
|
157
|
+
--Infinity;
|
|
158
|
+
`,
|
|
159
|
+
snapshot: `
|
|
160
|
+
--Infinity;
|
|
161
|
+
~~~~~~~~
|
|
162
|
+
Read-only global variables should not be reassigned or modified.
|
|
163
|
+
`,
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
code: `
|
|
167
|
+
Object--;
|
|
168
|
+
`,
|
|
169
|
+
snapshot: `
|
|
170
|
+
Object--;
|
|
171
|
+
~~~~~~
|
|
172
|
+
Read-only global variables should not be reassigned or modified.
|
|
173
|
+
`,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
valid: [
|
|
177
|
+
`let undefined = 1;`,
|
|
178
|
+
`const NaN = 42;`,
|
|
179
|
+
`var Infinity = 100;`,
|
|
180
|
+
`function Object() {}`,
|
|
181
|
+
`let value = undefined;`,
|
|
182
|
+
`const result = NaN;`,
|
|
183
|
+
`if (value === undefined) {}`,
|
|
184
|
+
`const obj = { undefined: 1 };`,
|
|
185
|
+
`obj.undefined = 2;`,
|
|
186
|
+
`const custom = { NaN: 42 }; custom.NaN = 100;`,
|
|
187
|
+
`let myVar = 5; myVar = 10;`,
|
|
188
|
+
`const data = { value: 1 }; data.value = 2;`,
|
|
189
|
+
`let counter = 0; counter++;`,
|
|
190
|
+
`let index = 10; --index;`,
|
|
191
|
+
`
|
|
192
|
+
function test() {
|
|
193
|
+
let undefined = 5;
|
|
194
|
+
undefined = 10;
|
|
195
|
+
}
|
|
196
|
+
`,
|
|
197
|
+
`
|
|
198
|
+
const obj = {
|
|
199
|
+
undefined: 1,
|
|
200
|
+
NaN: 2,
|
|
201
|
+
};
|
|
202
|
+
obj.undefined = 5;
|
|
203
|
+
`,
|
|
204
|
+
`
|
|
205
|
+
const fn = (undefined: number) => {
|
|
206
|
+
undefined = 10;
|
|
207
|
+
};
|
|
208
|
+
`,
|
|
209
|
+
`
|
|
210
|
+
function test(NaN: string) {
|
|
211
|
+
NaN = "updated";
|
|
212
|
+
}
|
|
213
|
+
`,
|
|
214
|
+
],
|
|
215
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports calling global objects like Math, JSON, or Reflect as functions.";
|
|
3
|
+
readonly id: "globalObjectCalls";
|
|
4
|
+
readonly preset: "untyped";
|
|
5
|
+
}, import("../nodes.js").TSNodesByName, import("../language.js").TypeScriptServices, "noGlobalObjectCall", undefined>;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import { getTSNodeRange } from "../getTSNodeRange.js";
|
|
3
|
+
import { typescriptLanguage } from "../language.js";
|
|
4
|
+
const globalObjects = new Set(["Atomics", "JSON", "Math", "Reflect"]);
|
|
5
|
+
export default typescriptLanguage.createRule({
|
|
6
|
+
about: {
|
|
7
|
+
description: "Reports calling global objects like Math, JSON, or Reflect as functions.",
|
|
8
|
+
id: "globalObjectCalls",
|
|
9
|
+
preset: "untyped",
|
|
10
|
+
},
|
|
11
|
+
messages: {
|
|
12
|
+
noGlobalObjectCall: {
|
|
13
|
+
primary: "{{ name }} is not a function and cannot be called directly.",
|
|
14
|
+
secondary: [
|
|
15
|
+
"{{ name }} is a built-in global object that provides utility methods and properties.",
|
|
16
|
+
"It is not a constructor or function and cannot be called or instantiated.",
|
|
17
|
+
],
|
|
18
|
+
suggestions: [
|
|
19
|
+
"Use the static methods available on {{ name }} instead (e.g., {{ name }}.methodName()).",
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
setup(context) {
|
|
24
|
+
function reportGlobalObjectCall(expression, name) {
|
|
25
|
+
context.report({
|
|
26
|
+
data: { name },
|
|
27
|
+
message: "noGlobalObjectCall",
|
|
28
|
+
range: getTSNodeRange(expression, context.sourceFile),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function checkNode({ expression }) {
|
|
32
|
+
if (ts.isIdentifier(expression) && globalObjects.has(expression.text)) {
|
|
33
|
+
reportGlobalObjectCall(expression, expression.text);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
visitors: {
|
|
38
|
+
CallExpression: checkNode,
|
|
39
|
+
NewExpression: checkNode,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
},
|
|
43
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import rule from "./globalObjectCalls.js";
|
|
2
|
+
import { ruleTester } from "./ruleTester.js";
|
|
3
|
+
ruleTester.describe(rule, {
|
|
4
|
+
invalid: [
|
|
5
|
+
{
|
|
6
|
+
code: `
|
|
7
|
+
const result = Math();
|
|
8
|
+
`,
|
|
9
|
+
snapshot: `
|
|
10
|
+
const result = Math();
|
|
11
|
+
~~~~
|
|
12
|
+
Math is not a function and cannot be called directly.
|
|
13
|
+
`,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
code: `
|
|
17
|
+
const data = JSON();
|
|
18
|
+
`,
|
|
19
|
+
snapshot: `
|
|
20
|
+
const data = JSON();
|
|
21
|
+
~~~~
|
|
22
|
+
JSON is not a function and cannot be called directly.
|
|
23
|
+
`,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
code: `
|
|
27
|
+
const reflected = Reflect();
|
|
28
|
+
`,
|
|
29
|
+
snapshot: `
|
|
30
|
+
const reflected = Reflect();
|
|
31
|
+
~~~~~~~
|
|
32
|
+
Reflect is not a function and cannot be called directly.
|
|
33
|
+
`,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
code: `
|
|
37
|
+
const atomic = Atomics();
|
|
38
|
+
`,
|
|
39
|
+
snapshot: `
|
|
40
|
+
const atomic = Atomics();
|
|
41
|
+
~~~~~~~
|
|
42
|
+
Atomics is not a function and cannot be called directly.
|
|
43
|
+
`,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
code: `
|
|
47
|
+
const instance = new Math();
|
|
48
|
+
`,
|
|
49
|
+
snapshot: `
|
|
50
|
+
const instance = new Math();
|
|
51
|
+
~~~~
|
|
52
|
+
Math is not a function and cannot be called directly.
|
|
53
|
+
`,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
code: `
|
|
57
|
+
const instance = new JSON();
|
|
58
|
+
`,
|
|
59
|
+
snapshot: `
|
|
60
|
+
const instance = new JSON();
|
|
61
|
+
~~~~
|
|
62
|
+
JSON is not a function and cannot be called directly.
|
|
63
|
+
`,
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
code: `
|
|
67
|
+
const instance = new Reflect();
|
|
68
|
+
`,
|
|
69
|
+
snapshot: `
|
|
70
|
+
const instance = new Reflect();
|
|
71
|
+
~~~~~~~
|
|
72
|
+
Reflect is not a function and cannot be called directly.
|
|
73
|
+
`,
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
code: `
|
|
77
|
+
const instance = new Atomics();
|
|
78
|
+
`,
|
|
79
|
+
snapshot: `
|
|
80
|
+
const instance = new Atomics();
|
|
81
|
+
~~~~~~~
|
|
82
|
+
Atomics is not a function and cannot be called directly.
|
|
83
|
+
`,
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
valid: [
|
|
87
|
+
`const value = Math.abs(-5);`,
|
|
88
|
+
`const parsed = JSON.parse("{}");`,
|
|
89
|
+
`const stringified = JSON.stringify({});`,
|
|
90
|
+
`const keys = Reflect.ownKeys({});`,
|
|
91
|
+
`const result = Atomics.add(buffer, 0, 1);`,
|
|
92
|
+
],
|
|
93
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports comparisons with -0 that may not behave as expected.";
|
|
3
|
+
readonly id: "negativeZeroComparisons";
|
|
4
|
+
readonly preset: "logical";
|
|
5
|
+
}, import("../nodes.js").TSNodesByName, import("../language.js").TypeScriptServices, "unexpectedNegativeZeroComparison", undefined>;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import { typescriptLanguage } from "../language.js";
|
|
3
|
+
import { isComparisonOperator, isEqualityOperator, isNegatedEqualityOperator, } from "./utils/operators.js";
|
|
4
|
+
function isNegativeZero(node) {
|
|
5
|
+
return (ts.isPrefixUnaryExpression(node) &&
|
|
6
|
+
node.operator === ts.SyntaxKind.MinusToken &&
|
|
7
|
+
ts.isNumericLiteral(node.operand) &&
|
|
8
|
+
node.operand.text === "0");
|
|
9
|
+
}
|
|
10
|
+
export default typescriptLanguage.createRule({
|
|
11
|
+
about: {
|
|
12
|
+
description: "Reports comparisons with -0 that may not behave as expected.",
|
|
13
|
+
id: "negativeZeroComparisons",
|
|
14
|
+
preset: "logical",
|
|
15
|
+
},
|
|
16
|
+
messages: {
|
|
17
|
+
unexpectedNegativeZeroComparison: {
|
|
18
|
+
primary: "Comparisons with -0 using {{ operator }} do not distinguish between -0 and +0.",
|
|
19
|
+
secondary: [
|
|
20
|
+
"In JavaScript, -0 and +0 are considered equal when using comparison operators like === or ==, even though they are distinct values.",
|
|
21
|
+
"To properly check for -0, use `Object.is(value, -0)` which correctly distinguishes between -0 and +0.",
|
|
22
|
+
],
|
|
23
|
+
suggestions: ["Use `Object.is()` to reliably check if a value is -0."],
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
setup(context) {
|
|
27
|
+
function generateObjectIsText(node, isNegated) {
|
|
28
|
+
const leftText = node.left.getText(context.sourceFile);
|
|
29
|
+
const rightText = node.right.getText(context.sourceFile);
|
|
30
|
+
const objectIsCall = `Object.is(${leftText}, ${rightText})`;
|
|
31
|
+
return isNegated ? `!${objectIsCall}` : objectIsCall;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
visitors: {
|
|
35
|
+
BinaryExpression: (node) => {
|
|
36
|
+
if (!isComparisonOperator(node.operatorToken) ||
|
|
37
|
+
(!isNegativeZero(node.left) && !isNegativeZero(node.right))) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const operator = node.operatorToken.getText(context.sourceFile);
|
|
41
|
+
const range = {
|
|
42
|
+
begin: node.getStart(context.sourceFile),
|
|
43
|
+
end: node.getEnd(),
|
|
44
|
+
};
|
|
45
|
+
context.report({
|
|
46
|
+
data: {
|
|
47
|
+
operator,
|
|
48
|
+
},
|
|
49
|
+
message: "unexpectedNegativeZeroComparison",
|
|
50
|
+
range,
|
|
51
|
+
suggestions: isEqualityOperator(node.operatorToken)
|
|
52
|
+
? [
|
|
53
|
+
{
|
|
54
|
+
id: "useObjectIs",
|
|
55
|
+
range,
|
|
56
|
+
text: generateObjectIsText(node, isNegatedEqualityOperator(node.operatorToken)),
|
|
57
|
+
},
|
|
58
|
+
]
|
|
59
|
+
: undefined,
|
|
60
|
+
});
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
},
|
|
65
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import rule from "./negativeZeroComparisons.js";
|
|
2
|
+
import { ruleTester } from "./ruleTester.js";
|
|
3
|
+
ruleTester.describe(rule, {
|
|
4
|
+
invalid: [
|
|
5
|
+
{
|
|
6
|
+
code: `
|
|
7
|
+
if (value === -0) {}
|
|
8
|
+
`,
|
|
9
|
+
snapshot: `
|
|
10
|
+
if (value === -0) {}
|
|
11
|
+
~~~~~~~~~~~~
|
|
12
|
+
Comparisons with -0 using === do not distinguish between -0 and +0.
|
|
13
|
+
`,
|
|
14
|
+
suggestions: [
|
|
15
|
+
{
|
|
16
|
+
id: "useObjectIs",
|
|
17
|
+
updated: `
|
|
18
|
+
if (Object.is(value, -0)) {}
|
|
19
|
+
`,
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
code: `
|
|
25
|
+
if (-0 === value) {}
|
|
26
|
+
`,
|
|
27
|
+
snapshot: `
|
|
28
|
+
if (-0 === value) {}
|
|
29
|
+
~~~~~~~~~~~~
|
|
30
|
+
Comparisons with -0 using === do not distinguish between -0 and +0.
|
|
31
|
+
`,
|
|
32
|
+
suggestions: [
|
|
33
|
+
{
|
|
34
|
+
id: "useObjectIs",
|
|
35
|
+
updated: `
|
|
36
|
+
if (Object.is(-0, value)) {}
|
|
37
|
+
`,
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
code: `
|
|
43
|
+
if (value == -0) {}
|
|
44
|
+
`,
|
|
45
|
+
snapshot: `
|
|
46
|
+
if (value == -0) {}
|
|
47
|
+
~~~~~~~~~~~
|
|
48
|
+
Comparisons with -0 using == do not distinguish between -0 and +0.
|
|
49
|
+
`,
|
|
50
|
+
suggestions: [
|
|
51
|
+
{
|
|
52
|
+
id: "useObjectIs",
|
|
53
|
+
updated: `
|
|
54
|
+
if (Object.is(value, -0)) {}
|
|
55
|
+
`,
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
code: `
|
|
61
|
+
if (value !== -0) {}
|
|
62
|
+
`,
|
|
63
|
+
snapshot: `
|
|
64
|
+
if (value !== -0) {}
|
|
65
|
+
~~~~~~~~~~~~
|
|
66
|
+
Comparisons with -0 using !== do not distinguish between -0 and +0.
|
|
67
|
+
`,
|
|
68
|
+
suggestions: [
|
|
69
|
+
{
|
|
70
|
+
id: "useObjectIs",
|
|
71
|
+
updated: `
|
|
72
|
+
if (!Object.is(value, -0)) {}
|
|
73
|
+
`,
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
code: `
|
|
79
|
+
if (value != -0) {}
|
|
80
|
+
`,
|
|
81
|
+
snapshot: `
|
|
82
|
+
if (value != -0) {}
|
|
83
|
+
~~~~~~~~~~~
|
|
84
|
+
Comparisons with -0 using != do not distinguish between -0 and +0.
|
|
85
|
+
`,
|
|
86
|
+
suggestions: [
|
|
87
|
+
{
|
|
88
|
+
id: "useObjectIs",
|
|
89
|
+
updated: `
|
|
90
|
+
if (!Object.is(value, -0)) {}
|
|
91
|
+
`,
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
code: `
|
|
97
|
+
if (value < -0) {}
|
|
98
|
+
`,
|
|
99
|
+
snapshot: `
|
|
100
|
+
if (value < -0) {}
|
|
101
|
+
~~~~~~~~~~
|
|
102
|
+
Comparisons with -0 using < do not distinguish between -0 and +0.
|
|
103
|
+
`,
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
code: `
|
|
107
|
+
if (value <= -0) {}
|
|
108
|
+
`,
|
|
109
|
+
snapshot: `
|
|
110
|
+
if (value <= -0) {}
|
|
111
|
+
~~~~~~~~~~~
|
|
112
|
+
Comparisons with -0 using <= do not distinguish between -0 and +0.
|
|
113
|
+
`,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
code: `
|
|
117
|
+
if (value > -0) {}
|
|
118
|
+
`,
|
|
119
|
+
snapshot: `
|
|
120
|
+
if (value > -0) {}
|
|
121
|
+
~~~~~~~~~~
|
|
122
|
+
Comparisons with -0 using > do not distinguish between -0 and +0.
|
|
123
|
+
`,
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
code: `
|
|
127
|
+
if (value >= -0) {}
|
|
128
|
+
`,
|
|
129
|
+
snapshot: `
|
|
130
|
+
if (value >= -0) {}
|
|
131
|
+
~~~~~~~~~~~
|
|
132
|
+
Comparisons with -0 using >= do not distinguish between -0 and +0.
|
|
133
|
+
`,
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
code: `
|
|
137
|
+
const result = value === -0 ? "negative zero" : "other";
|
|
138
|
+
`,
|
|
139
|
+
snapshot: `
|
|
140
|
+
const result = value === -0 ? "negative zero" : "other";
|
|
141
|
+
~~~~~~~~~~~~
|
|
142
|
+
Comparisons with -0 using === do not distinguish between -0 and +0.
|
|
143
|
+
`,
|
|
144
|
+
suggestions: [
|
|
145
|
+
{
|
|
146
|
+
id: "useObjectIs",
|
|
147
|
+
updated: `
|
|
148
|
+
const result = Object.is(value, -0) ? "negative zero" : "other";
|
|
149
|
+
`,
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
code: `
|
|
155
|
+
while (value !== -0) {
|
|
156
|
+
value++;
|
|
157
|
+
}
|
|
158
|
+
`,
|
|
159
|
+
snapshot: `
|
|
160
|
+
while (value !== -0) {
|
|
161
|
+
~~~~~~~~~~~~
|
|
162
|
+
Comparisons with -0 using !== do not distinguish between -0 and +0.
|
|
163
|
+
value++;
|
|
164
|
+
}
|
|
165
|
+
`,
|
|
166
|
+
suggestions: [
|
|
167
|
+
{
|
|
168
|
+
id: "useObjectIs",
|
|
169
|
+
updated: `
|
|
170
|
+
while (!Object.is(value, -0)) {
|
|
171
|
+
value++;
|
|
172
|
+
}
|
|
173
|
+
`,
|
|
174
|
+
},
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
code: `
|
|
179
|
+
const isNegativeZero = value === -0;
|
|
180
|
+
`,
|
|
181
|
+
snapshot: `
|
|
182
|
+
const isNegativeZero = value === -0;
|
|
183
|
+
~~~~~~~~~~~~
|
|
184
|
+
Comparisons with -0 using === do not distinguish between -0 and +0.
|
|
185
|
+
`,
|
|
186
|
+
suggestions: [
|
|
187
|
+
{
|
|
188
|
+
id: "useObjectIs",
|
|
189
|
+
updated: `
|
|
190
|
+
const isNegativeZero = Object.is(value, -0);
|
|
191
|
+
`,
|
|
192
|
+
},
|
|
193
|
+
],
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
valid: [
|
|
197
|
+
`if (value === 0) {}`,
|
|
198
|
+
`if (value === -1) {}`,
|
|
199
|
+
`if (value === 1) {}`,
|
|
200
|
+
`if (Object.is(value, -0)) {}`,
|
|
201
|
+
`if (Object.is(-0, value)) {}`,
|
|
202
|
+
`const result = -0;`,
|
|
203
|
+
`const value = -0 + 1;`,
|
|
204
|
+
`const value = -0 * 2;`,
|
|
205
|
+
`const value = Math.abs(-0);`,
|
|
206
|
+
`const value = [-0, 0, 1];`,
|
|
207
|
+
`function test() { return -0; }`,
|
|
208
|
+
],
|
|
209
|
+
});
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
declare const _default: import("@flint.fyi/core").Rule<{
|
|
2
|
+
readonly description: "Reports standalone new expressions that don't use the constructed object.";
|
|
3
|
+
readonly id: "newExpressions";
|
|
4
|
+
readonly preset: "logical";
|
|
5
|
+
}, import("../nodes.js").TSNodesByName, import("../language.js").TypeScriptServices, "noStandaloneNew", undefined>;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import { getTSNodeRange } from "../getTSNodeRange.js";
|
|
3
|
+
import { typescriptLanguage } from "../language.js";
|
|
4
|
+
export default typescriptLanguage.createRule({
|
|
5
|
+
about: {
|
|
6
|
+
description: "Reports standalone new expressions that don't use the constructed object.",
|
|
7
|
+
id: "newExpressions",
|
|
8
|
+
preset: "logical",
|
|
9
|
+
},
|
|
10
|
+
messages: {
|
|
11
|
+
noStandaloneNew: {
|
|
12
|
+
primary: "Constructors should only be called when their return value is used.",
|
|
13
|
+
secondary: [
|
|
14
|
+
"Using `new` to construct an object but not storing or using the result is often a mistake or indicates unclear code intent.",
|
|
15
|
+
"If the constructor has side effects you want to trigger, it's better to make that explicit by calling a separate method rather than relying on constructor side effects.",
|
|
16
|
+
],
|
|
17
|
+
suggestions: [
|
|
18
|
+
"If you need to use the constructed object, assign it to a variable or return it.",
|
|
19
|
+
"If you only need the constructor's side effects, consider refactoring to a function that makes the side effects explicit.",
|
|
20
|
+
],
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
setup(context) {
|
|
24
|
+
function isStandaloneExpression(node) {
|
|
25
|
+
const parent = node.parent;
|
|
26
|
+
// If parent is an ExpressionStatement, it's standalone
|
|
27
|
+
if (parent.kind === ts.SyntaxKind.ExpressionStatement) {
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
// If parent is a comma expression, check recursively
|
|
31
|
+
if (ts.isBinaryExpression(parent) &&
|
|
32
|
+
parent.operatorToken.kind === ts.SyntaxKind.CommaToken) {
|
|
33
|
+
// If this is the last expression in the comma sequence, check if the parent is standalone
|
|
34
|
+
if (parent.right === node) {
|
|
35
|
+
return isStandaloneExpression(parent);
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
visitors: {
|
|
43
|
+
NewExpression: (node) => {
|
|
44
|
+
if (isStandaloneExpression(node)) {
|
|
45
|
+
context.report({
|
|
46
|
+
message: "noStandaloneNew",
|
|
47
|
+
range: getTSNodeRange(node.getChildAt(0, context.sourceFile), context.sourceFile),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
});
|