eslint-plugin-ts-data-forge 0.8.2 → 0.8.3
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/dist/plugin.d.mts +1 -1
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +1 -0
- package/dist/plugin.mjs.map +1 -1
- package/dist/rule-types.d.mts +3 -3
- package/dist/rule-types.d.mts.map +1 -1
- package/dist/rules/ast-utils.d.mts +59 -3
- package/dist/rules/ast-utils.d.mts.map +1 -1
- package/dist/rules/ast-utils.mjs +119 -8
- package/dist/rules/ast-utils.mjs.map +1 -1
- package/dist/rules/import-utils.d.mts +1 -1
- package/dist/rules/import-utils.d.mts.map +1 -1
- package/dist/rules/import-utils.mjs +22 -11
- package/dist/rules/import-utils.mjs.map +1 -1
- package/dist/rules/no-side-effect-import.d.mts +1 -1
- package/dist/rules/no-side-effect-import.d.mts.map +1 -1
- package/dist/rules/no-unnecessary-type-guard.d.mts.map +1 -1
- package/dist/rules/no-unnecessary-type-guard.mjs +125 -79
- package/dist/rules/no-unnecessary-type-guard.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-array.mjs +11 -4
- package/dist/rules/prefer-arr-is-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-bounded-length-array.d.mts +1 -1
- package/dist/rules/prefer-arr-is-bounded-length-array.d.mts.map +1 -1
- package/dist/rules/prefer-arr-is-bounded-length-array.mjs +5 -19
- package/dist/rules/prefer-arr-is-bounded-length-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-fixed-length-array.d.mts +1 -1
- package/dist/rules/prefer-arr-is-fixed-length-array.d.mts.map +1 -1
- package/dist/rules/prefer-arr-is-fixed-length-array.mjs +11 -27
- package/dist/rules/prefer-arr-is-fixed-length-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-max-length-array.d.mts +1 -1
- package/dist/rules/prefer-arr-is-max-length-array.d.mts.map +1 -1
- package/dist/rules/prefer-arr-is-max-length-array.mjs +9 -22
- package/dist/rules/prefer-arr-is-max-length-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-min-length-array.d.mts +1 -1
- package/dist/rules/prefer-arr-is-min-length-array.d.mts.map +1 -1
- package/dist/rules/prefer-arr-is-min-length-array.mjs +9 -22
- package/dist/rules/prefer-arr-is-min-length-array.mjs.map +1 -1
- package/dist/rules/prefer-arr-is-non-empty.d.mts.map +1 -1
- package/dist/rules/prefer-arr-is-non-empty.mjs +7 -22
- package/dist/rules/prefer-arr-is-non-empty.mjs.map +1 -1
- package/dist/rules/prefer-arr-scan.d.mts +6 -5
- package/dist/rules/prefer-arr-scan.d.mts.map +1 -1
- package/dist/rules/prefer-arr-scan.mjs +33 -13
- package/dist/rules/prefer-arr-scan.mjs.map +1 -1
- package/dist/rules/prefer-arr-sum.d.mts.map +1 -1
- package/dist/rules/prefer-arr-sum.mjs +51 -37
- package/dist/rules/prefer-arr-sum.mjs.map +1 -1
- package/dist/rules/prefer-arr-uniq.d.mts.map +1 -1
- package/dist/rules/prefer-arr-uniq.mjs +33 -10
- package/dist/rules/prefer-arr-uniq.mjs.map +1 -1
- package/dist/rules/prefer-as-int.d.mts.map +1 -1
- package/dist/rules/prefer-as-int.mjs +18 -12
- package/dist/rules/prefer-as-int.mjs.map +1 -1
- package/dist/rules/prefer-canonical-array-slicing.d.mts.map +1 -1
- package/dist/rules/prefer-canonical-array-slicing.mjs +29 -14
- package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
- package/dist/rules/prefer-canonical-length-cast.d.mts.map +1 -1
- package/dist/rules/prefer-canonical-length-cast.mjs +34 -13
- package/dist/rules/prefer-canonical-length-cast.mjs.map +1 -1
- package/dist/rules/prefer-canonical-length-guard.d.mts.map +1 -1
- package/dist/rules/prefer-canonical-length-guard.mjs +10 -4
- package/dist/rules/prefer-canonical-length-guard.mjs.map +1 -1
- package/dist/rules/prefer-comparison-over-nullish-guard.d.mts.map +1 -1
- package/dist/rules/prefer-comparison-over-nullish-guard.mjs +25 -3
- package/dist/rules/prefer-comparison-over-nullish-guard.mjs.map +1 -1
- package/dist/rules/prefer-is-non-null-object.mjs +28 -10
- package/dist/rules/prefer-is-non-null-object.mjs.map +1 -1
- package/dist/rules/prefer-is-record-and-has-key.d.mts.map +1 -1
- package/dist/rules/prefer-is-record-and-has-key.mjs +8 -3
- package/dist/rules/prefer-is-record-and-has-key.mjs.map +1 -1
- package/dist/rules/prefer-num-safe-parse-float.d.mts +3 -1
- package/dist/rules/prefer-num-safe-parse-float.d.mts.map +1 -1
- package/dist/rules/prefer-num-safe-parse-float.mjs +18 -7
- package/dist/rules/prefer-num-safe-parse-float.mjs.map +1 -1
- package/dist/rules/prefer-num-safe-parse-int.d.mts.map +1 -1
- package/dist/rules/prefer-num-safe-parse-int.mjs +15 -8
- package/dist/rules/prefer-num-safe-parse-int.mjs.map +1 -1
- package/dist/rules/prefer-range-for-loop.d.mts.map +1 -1
- package/dist/rules/prefer-range-for-loop.mjs +13 -7
- package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
- package/dist/types.d.mts +2 -2
- package/dist/types.d.mts.map +1 -1
- package/package.json +3 -3
- package/src/plugin.mts +5 -4
- package/src/plugin.test.mts +0 -13
- package/src/rule-types.mts +3 -3
- package/src/rules/ast-utils.mts +156 -13
- package/src/rules/import-utils.mts +35 -15
- package/src/rules/no-side-effect-import.mts +1 -1
- package/src/rules/no-unnecessary-type-guard.mts +192 -124
- package/src/rules/no-unnecessary-type-guard.test.mts +100 -0
- package/src/rules/prefer-arr-is-array.mts +11 -6
- package/src/rules/prefer-arr-is-array.test.mts +40 -0
- package/src/rules/prefer-arr-is-bounded-length-array.mts +13 -25
- package/src/rules/prefer-arr-is-bounded-length-array.test.mts +68 -0
- package/src/rules/prefer-arr-is-fixed-length-array.mts +18 -38
- package/src/rules/prefer-arr-is-fixed-length-array.test.mts +63 -0
- package/src/rules/prefer-arr-is-max-length-array.mts +15 -26
- package/src/rules/prefer-arr-is-max-length-array.test.mts +67 -0
- package/src/rules/prefer-arr-is-min-length-array.mts +15 -26
- package/src/rules/prefer-arr-is-min-length-array.test.mts +70 -0
- package/src/rules/prefer-arr-is-non-empty.mts +16 -25
- package/src/rules/prefer-arr-is-non-empty.test.mts +79 -0
- package/src/rules/prefer-arr-scan.mts +55 -19
- package/src/rules/prefer-arr-scan.test.mts +149 -0
- package/src/rules/prefer-arr-sum.mts +78 -47
- package/src/rules/prefer-arr-sum.test.mts +97 -0
- package/src/rules/prefer-arr-uniq.mts +46 -12
- package/src/rules/prefer-arr-uniq.test.mts +71 -0
- package/src/rules/prefer-as-int.mts +24 -16
- package/src/rules/prefer-as-int.test.mts +51 -0
- package/src/rules/prefer-canonical-array-slicing.mts +38 -15
- package/src/rules/prefer-canonical-array-slicing.test.mts +92 -0
- package/src/rules/prefer-canonical-length-cast.mts +45 -15
- package/src/rules/prefer-canonical-length-cast.test.mts +111 -0
- package/src/rules/prefer-canonical-length-guard.mts +13 -7
- package/src/rules/prefer-canonical-length-guard.test.mts +99 -0
- package/src/rules/prefer-comparison-over-nullish-guard.mts +33 -6
- package/src/rules/prefer-comparison-over-nullish-guard.test.mts +136 -0
- package/src/rules/prefer-is-non-null-object.mts +31 -11
- package/src/rules/prefer-is-non-null-object.test.mts +42 -0
- package/src/rules/prefer-is-record-and-has-key.mts +10 -5
- package/src/rules/prefer-is-record-and-has-key.test.mts +34 -0
- package/src/rules/prefer-num-safe-parse-float.mts +24 -11
- package/src/rules/prefer-num-safe-parse-float.test.mts +79 -0
- package/src/rules/prefer-num-safe-parse-int.mts +25 -11
- package/src/rules/prefer-num-safe-parse-int.test.mts +64 -0
- package/src/rules/prefer-obj-over-entries-round-trip.mts +1 -1
- package/src/rules/prefer-range-for-loop.mts +18 -8
- package/src/rules/prefer-range-for-loop.test.mts +75 -0
- package/src/rules/rules.mts +1 -1
- package/src/types.mts +2 -2
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type TSESTree,
|
|
5
5
|
} from '@typescript-eslint/utils';
|
|
6
6
|
import { Arr } from 'ts-data-forge';
|
|
7
|
+
import { skipTypeWrappers, toArgumentText } from './ast-utils.mjs';
|
|
7
8
|
import {
|
|
8
9
|
buildImportFixes,
|
|
9
10
|
getNamedImports,
|
|
@@ -68,12 +69,21 @@ export const preferRangeForLoop: TSESLint.RuleModule<MessageIds, Options> = {
|
|
|
68
69
|
|
|
69
70
|
const beginExpr = declaration.init;
|
|
70
71
|
|
|
71
|
-
// Check test: i < end
|
|
72
|
+
// Check test: i < end. The loop variable and the step are read
|
|
73
|
+
// through type wrappers: `(i satisfies number) < n` tests `i`, and
|
|
74
|
+
// `i += 0 as number` still steps by 0.
|
|
72
75
|
if (
|
|
73
76
|
node.test?.type !== AST_NODE_TYPES.BinaryExpression ||
|
|
74
|
-
node.test.operator !== '<'
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
node.test.operator !== '<'
|
|
78
|
+
) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const testedVariable = skipTypeWrappers(node.test.left);
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
testedVariable.type !== AST_NODE_TYPES.Identifier ||
|
|
86
|
+
testedVariable.name !== varName
|
|
77
87
|
) {
|
|
78
88
|
return;
|
|
79
89
|
}
|
|
@@ -105,7 +115,7 @@ export const preferRangeForLoop: TSESLint.RuleModule<MessageIds, Options> = {
|
|
|
105
115
|
node.update.left.name === varName
|
|
106
116
|
) {
|
|
107
117
|
// i += step
|
|
108
|
-
const stepValue = node.update.right;
|
|
118
|
+
const stepValue = skipTypeWrappers(node.update.right);
|
|
109
119
|
|
|
110
120
|
if (stepValue.type === AST_NODE_TYPES.Literal) {
|
|
111
121
|
const stepNum = stepValue.value;
|
|
@@ -118,15 +128,15 @@ export const preferRangeForLoop: TSESLint.RuleModule<MessageIds, Options> = {
|
|
|
118
128
|
}
|
|
119
129
|
} else {
|
|
120
130
|
// Variable step like i += step
|
|
121
|
-
mut_step = sourceCode
|
|
131
|
+
mut_step = toArgumentText(node.update.right, sourceCode);
|
|
122
132
|
}
|
|
123
133
|
} else {
|
|
124
134
|
return;
|
|
125
135
|
}
|
|
126
136
|
|
|
127
|
-
const beginText =
|
|
137
|
+
const beginText = toArgumentText(beginExpr, sourceCode);
|
|
128
138
|
|
|
129
|
-
const endText =
|
|
139
|
+
const endText = toArgumentText(endExpr, sourceCode);
|
|
130
140
|
|
|
131
141
|
mut_nodesToFix.push({
|
|
132
142
|
node,
|
|
@@ -154,3 +154,78 @@ describe('prefer-range-for-loop', () => {
|
|
|
154
154
|
],
|
|
155
155
|
});
|
|
156
156
|
}, 20000);
|
|
157
|
+
|
|
158
|
+
describe('prefer-range-for-loop through type wrappers', () => {
|
|
159
|
+
tester.run('prefer-range-for-loop', preferRangeForLoop, {
|
|
160
|
+
valid: [
|
|
161
|
+
{
|
|
162
|
+
name: 'a wrapped non-positive step',
|
|
163
|
+
code: dedent`
|
|
164
|
+
declare const n: number;
|
|
165
|
+
for (let i = 0; i < n; i += 0 as number) {
|
|
166
|
+
console.log(i);
|
|
167
|
+
}
|
|
168
|
+
`,
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
invalid: [
|
|
172
|
+
{
|
|
173
|
+
name: 'the loop variable or the step wrapped',
|
|
174
|
+
code: dedent`
|
|
175
|
+
import { range } from 'ts-data-forge';
|
|
176
|
+
declare const n: number;
|
|
177
|
+
for (let i = 0; (i satisfies number) < n; ++i) {
|
|
178
|
+
console.log(i);
|
|
179
|
+
}
|
|
180
|
+
for (let j = 0; j! < n; j += 2 as number) {
|
|
181
|
+
console.log(j);
|
|
182
|
+
}
|
|
183
|
+
`,
|
|
184
|
+
output: dedent`
|
|
185
|
+
import { range } from 'ts-data-forge';
|
|
186
|
+
declare const n: number;
|
|
187
|
+
for (const i of range(0, n)) {
|
|
188
|
+
console.log(i);
|
|
189
|
+
}
|
|
190
|
+
for (const j of range(0, n, 2)) {
|
|
191
|
+
console.log(j);
|
|
192
|
+
}
|
|
193
|
+
`,
|
|
194
|
+
errors: [
|
|
195
|
+
{ messageId: 'useRangeForLoop' },
|
|
196
|
+
{ messageId: 'useRangeForLoop' },
|
|
197
|
+
],
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
});
|
|
201
|
+
}, 20000);
|
|
202
|
+
|
|
203
|
+
describe('prefer-range-for-loop with parenthesized operands', () => {
|
|
204
|
+
tester.run('prefer-range-for-loop', preferRangeForLoop, {
|
|
205
|
+
valid: [],
|
|
206
|
+
invalid: [
|
|
207
|
+
{
|
|
208
|
+
name: 'sequence bounds and step keep their parentheses',
|
|
209
|
+
code: dedent`
|
|
210
|
+
import { range } from 'ts-data-forge';
|
|
211
|
+
declare const n: number;
|
|
212
|
+
declare const step: number;
|
|
213
|
+
declare const log: () => void;
|
|
214
|
+
for (let i = (log(), 0); i < (log(), n); i += (log(), step)) {
|
|
215
|
+
console.log(i);
|
|
216
|
+
}
|
|
217
|
+
`,
|
|
218
|
+
output: dedent`
|
|
219
|
+
import { range } from 'ts-data-forge';
|
|
220
|
+
declare const n: number;
|
|
221
|
+
declare const step: number;
|
|
222
|
+
declare const log: () => void;
|
|
223
|
+
for (const i of range((log(), 0), (log(), n), (log(), step))) {
|
|
224
|
+
console.log(i);
|
|
225
|
+
}
|
|
226
|
+
`,
|
|
227
|
+
errors: [{ messageId: 'useRangeForLoop' }],
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
});
|
|
231
|
+
}, 20000);
|
package/src/rules/rules.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ESLintPlugin } from '../types.mjs';
|
|
2
2
|
import { noSideEffectImport } from './no-side-effect-import.mjs';
|
|
3
3
|
import { noUnnecessaryTypeGuard } from './no-unnecessary-type-guard.mjs';
|
|
4
4
|
import { preferArrIsArray } from './prefer-arr-is-array.mjs';
|
package/src/types.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import type { TSESLint } from '@typescript-eslint/utils';
|
|
2
|
+
import type { DeepReadonly } from 'ts-type-forge';
|
|
3
3
|
|
|
4
4
|
export type ESLintPlugin = DeepReadonly<TSESLint.FlatConfig.Plugin>;
|
|
5
5
|
|