eslint-plugin-ts-data-forge 0.10.4 → 0.10.6
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/rules/ast-utils.d.mts +5 -5
- package/dist/rules/ast-utils.d.mts.map +1 -1
- package/dist/rules/ast-utils.mjs +3 -3
- package/dist/rules/ast-utils.mjs.map +1 -1
- package/dist/rules/import-binding.d.mts +38 -0
- package/dist/rules/import-binding.d.mts.map +1 -0
- package/dist/rules/import-binding.mjs +53 -0
- package/dist/rules/import-binding.mjs.map +1 -0
- package/dist/rules/mutable-result.mjs +37 -37
- package/dist/rules/mutable-result.mjs.map +1 -1
- package/dist/rules/no-unnecessary-type-guard.d.mts.map +1 -1
- package/dist/rules/no-unnecessary-type-guard.mjs +146 -143
- package/dist/rules/no-unnecessary-type-guard.mjs.map +1 -1
- package/dist/rules/prefer-arr-generate.d.mts.map +1 -1
- package/dist/rules/prefer-arr-generate.mjs +129 -131
- package/dist/rules/prefer-arr-generate.mjs.map +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 +14 -16
- package/dist/rules/prefer-arr-is-bounded-length-array.mjs.map +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 +15 -17
- package/dist/rules/prefer-arr-is-fixed-length-array.mjs.map +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 +14 -16
- package/dist/rules/prefer-arr-is-max-length-array.mjs.map +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 +14 -16
- 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 +14 -16
- package/dist/rules/prefer-arr-is-non-empty.mjs.map +1 -1
- package/dist/rules/prefer-arr-scan.d.mts.map +1 -1
- package/dist/rules/prefer-arr-scan.mjs +9 -18
- 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 +16 -21
- 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 +38 -43
- 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 +19 -26
- 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 +49 -15
- package/dist/rules/prefer-canonical-array-slicing.mjs.map +1 -1
- package/dist/rules/prefer-canonical-length-cast.mjs +15 -15
- package/dist/rules/prefer-canonical-length-cast.mjs.map +1 -1
- package/dist/rules/prefer-obj-over-entries-round-trip.d.mts.map +1 -1
- package/dist/rules/prefer-obj-over-entries-round-trip.mjs +100 -99
- package/dist/rules/prefer-obj-over-entries-round-trip.mjs.map +1 -1
- package/dist/rules/prefer-pipe-map-nullable.d.mts.map +1 -1
- package/dist/rules/prefer-pipe-map-nullable.mjs +2 -4
- package/dist/rules/prefer-pipe-map-nullable.mjs.map +1 -1
- package/dist/rules/prefer-range-for-loop.d.mts.map +1 -1
- package/dist/rules/prefer-range-for-loop.mjs +18 -24
- package/dist/rules/prefer-range-for-loop.mjs.map +1 -1
- package/package.json +5 -5
- package/src/rules/ast-utils.mts +11 -11
- package/src/rules/import-binding.mts +94 -0
- package/src/rules/mutable-result.mts +56 -56
- package/src/rules/no-unnecessary-type-guard.mts +199 -203
- package/src/rules/no-unnecessary-type-guard.test.mts +62 -2
- package/src/rules/prefer-arr-generate.mts +184 -194
- package/src/rules/prefer-arr-generate.test.mts +262 -134
- package/src/rules/prefer-arr-is-array.test.mts +87 -5
- package/src/rules/prefer-arr-is-bounded-length-array.mts +22 -33
- package/src/rules/prefer-arr-is-fixed-length-array.mts +24 -36
- package/src/rules/prefer-arr-is-fixed-length-array.test.mts +16 -7
- package/src/rules/prefer-arr-is-max-length-array.mts +21 -34
- package/src/rules/prefer-arr-is-max-length-array.test.mts +16 -7
- package/src/rules/prefer-arr-is-min-length-array.mts +21 -34
- package/src/rules/prefer-arr-is-min-length-array.test.mts +16 -7
- package/src/rules/prefer-arr-is-non-empty.mts +17 -34
- package/src/rules/prefer-arr-is-non-empty.test.mts +110 -0
- package/src/rules/prefer-arr-scan.mts +11 -36
- package/src/rules/prefer-arr-scan.test.mts +55 -0
- package/src/rules/prefer-arr-sum.mts +19 -33
- package/src/rules/prefer-arr-uniq.mts +49 -60
- package/src/rules/prefer-arr-uniq.test.mts +46 -20
- package/src/rules/prefer-as-int.mts +27 -52
- package/src/rules/prefer-as-int.test.mts +79 -29
- package/src/rules/prefer-canonical-array-slicing.mts +86 -24
- package/src/rules/prefer-canonical-array-slicing.test.mts +133 -34
- package/src/rules/prefer-canonical-length-cast.mts +18 -18
- package/src/rules/prefer-is-non-null-object.test.mts +62 -37
- package/src/rules/prefer-is-record-and-has-key.test.mts +32 -17
- package/src/rules/prefer-num-safe-parse-float.test.mts +45 -21
- package/src/rules/prefer-num-safe-parse-int.test.mts +29 -14
- package/src/rules/prefer-obj-over-entries-round-trip.mts +152 -170
- package/src/rules/prefer-obj-over-entries-round-trip.test.mts +48 -6
- package/src/rules/prefer-pipe-map-nullable.mts +6 -8
- package/src/rules/prefer-range-for-loop.mts +31 -55
|
@@ -202,25 +202,40 @@ describe('prefer-arr-generate', () => {
|
|
|
202
202
|
const ys = xs.flatMap((x) => (x === undefined ? [] : [x]));
|
|
203
203
|
const zs = xs.flatMap((x) => (skip ? [] : [x]));
|
|
204
204
|
`,
|
|
205
|
-
output:
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
205
|
+
output: [
|
|
206
|
+
dedent`
|
|
207
|
+
import { Arr } from 'ts-data-forge';
|
|
208
|
+
declare const xs: readonly (number | undefined)[];
|
|
209
|
+
declare const skip: boolean;
|
|
210
|
+
const ys = Arr.generate(function* () {
|
|
211
|
+
for (const x of xs) {
|
|
212
|
+
if (x !== undefined) {
|
|
213
|
+
yield x;
|
|
214
|
+
}
|
|
213
215
|
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
216
|
+
});
|
|
217
|
+
const zs = xs.flatMap((x) => (skip ? [] : [x]));
|
|
218
|
+
`,
|
|
219
|
+
dedent`
|
|
220
|
+
import { Arr } from 'ts-data-forge';
|
|
221
|
+
declare const xs: readonly (number | undefined)[];
|
|
222
|
+
declare const skip: boolean;
|
|
223
|
+
const ys = Arr.generate(function* () {
|
|
224
|
+
for (const x of xs) {
|
|
225
|
+
if (x !== undefined) {
|
|
226
|
+
yield x;
|
|
227
|
+
}
|
|
220
228
|
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
|
|
229
|
+
});
|
|
230
|
+
const zs = Arr.generate(function* () {
|
|
231
|
+
for (const x of xs) {
|
|
232
|
+
if (!skip) {
|
|
233
|
+
yield x;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
`,
|
|
238
|
+
],
|
|
224
239
|
errors: [
|
|
225
240
|
{ messageId: 'useArrGenerate' },
|
|
226
241
|
{ messageId: 'useArrGenerate' },
|
|
@@ -237,40 +252,58 @@ describe('prefer-arr-generate', () => {
|
|
|
237
252
|
const c = xs.flatMap((x) => (n < 0 ? [] : [x]));
|
|
238
253
|
const d = xs.flatMap((x) => (!ok(x) ? [] : [x]));
|
|
239
254
|
`,
|
|
240
|
-
output:
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
255
|
+
output: [
|
|
256
|
+
dedent`
|
|
257
|
+
import { Arr } from 'ts-data-forge';
|
|
258
|
+
declare const xs: readonly (string | undefined)[];
|
|
259
|
+
declare const ok: (x: string | undefined) => boolean;
|
|
260
|
+
declare const n: number;
|
|
261
|
+
const a = Arr.generate(function* () {
|
|
262
|
+
for (const x of xs) {
|
|
263
|
+
if (x !== undefined && x !== '') {
|
|
264
|
+
yield x;
|
|
265
|
+
}
|
|
249
266
|
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
267
|
+
});
|
|
268
|
+
const b = xs.flatMap((x) => (ok(x) ? [] : [x]));
|
|
269
|
+
const c = xs.flatMap((x) => (n < 0 ? [] : [x]));
|
|
270
|
+
const d = xs.flatMap((x) => (!ok(x) ? [] : [x]));
|
|
271
|
+
`,
|
|
272
|
+
dedent`
|
|
273
|
+
import { Arr } from 'ts-data-forge';
|
|
274
|
+
declare const xs: readonly (string | undefined)[];
|
|
275
|
+
declare const ok: (x: string | undefined) => boolean;
|
|
276
|
+
declare const n: number;
|
|
277
|
+
const a = Arr.generate(function* () {
|
|
278
|
+
for (const x of xs) {
|
|
279
|
+
if (x !== undefined && x !== '') {
|
|
280
|
+
yield x;
|
|
281
|
+
}
|
|
256
282
|
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
283
|
+
});
|
|
284
|
+
const b = Arr.generate(function* () {
|
|
285
|
+
for (const x of xs) {
|
|
286
|
+
if (!ok(x)) {
|
|
287
|
+
yield x;
|
|
288
|
+
}
|
|
263
289
|
}
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
290
|
+
});
|
|
291
|
+
const c = Arr.generate(function* () {
|
|
292
|
+
for (const x of xs) {
|
|
293
|
+
if (!(n < 0)) {
|
|
294
|
+
yield x;
|
|
295
|
+
}
|
|
270
296
|
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
|
|
297
|
+
});
|
|
298
|
+
const d = Arr.generate(function* () {
|
|
299
|
+
for (const x of xs) {
|
|
300
|
+
if (ok(x)) {
|
|
301
|
+
yield x;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
`,
|
|
306
|
+
],
|
|
274
307
|
errors: [
|
|
275
308
|
{ messageId: 'useArrGenerate' },
|
|
276
309
|
{ messageId: 'useArrGenerate' },
|
|
@@ -435,6 +468,25 @@ describe('prefer-arr-generate', () => {
|
|
|
435
468
|
`,
|
|
436
469
|
errors: [{ messageId: 'useArrGenerate' }],
|
|
437
470
|
},
|
|
471
|
+
{
|
|
472
|
+
name: 'no fix when an import type binds Arr',
|
|
473
|
+
code: dedent`
|
|
474
|
+
import type { Arr } from 'ts-data-forge';
|
|
475
|
+
declare const xs: readonly number[];
|
|
476
|
+
const ys = xs.flatMap((x) => (x > 0 ? [x] : []));
|
|
477
|
+
`,
|
|
478
|
+
output: null,
|
|
479
|
+
errors: [{ messageId: 'useArrGenerate' }],
|
|
480
|
+
},
|
|
481
|
+
{
|
|
482
|
+
name: 'no fix where a local binding takes Arr',
|
|
483
|
+
code: dedent`
|
|
484
|
+
declare const xs: readonly number[];
|
|
485
|
+
export const f = (Arr: unknown) => xs.flatMap((x) => (x > 0 ? [x] : []));
|
|
486
|
+
`,
|
|
487
|
+
output: null,
|
|
488
|
+
errors: [{ messageId: 'useArrGenerate' }],
|
|
489
|
+
},
|
|
438
490
|
{
|
|
439
491
|
name: 'indents from the line the call starts on, and accepts a mutable array, a tuple or a type parameter',
|
|
440
492
|
code: dedent`
|
|
@@ -446,34 +498,52 @@ describe('prefer-arr-generate', () => {
|
|
|
446
498
|
const c = xs.flatMap((x) => (x > 0 ? [x] : []));
|
|
447
499
|
};
|
|
448
500
|
`,
|
|
449
|
-
output:
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
const
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
501
|
+
output: [
|
|
502
|
+
dedent`
|
|
503
|
+
import { Arr } from 'ts-data-forge';
|
|
504
|
+
declare const ms: number[];
|
|
505
|
+
declare const ts: readonly [number, number];
|
|
506
|
+
export const f = <T extends readonly number[]>(xs: T): void => {
|
|
507
|
+
const a = Arr.generate(function* () {
|
|
508
|
+
for (const x of ms) {
|
|
509
|
+
if (x > 0) {
|
|
510
|
+
yield x;
|
|
511
|
+
}
|
|
458
512
|
}
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
513
|
+
});
|
|
514
|
+
const b = ts.flatMap((x) => (x > 0 ? [x] : []));
|
|
515
|
+
const c = xs.flatMap((x) => (x > 0 ? [x] : []));
|
|
516
|
+
};
|
|
517
|
+
`,
|
|
518
|
+
dedent`
|
|
519
|
+
import { Arr } from 'ts-data-forge';
|
|
520
|
+
declare const ms: number[];
|
|
521
|
+
declare const ts: readonly [number, number];
|
|
522
|
+
export const f = <T extends readonly number[]>(xs: T): void => {
|
|
523
|
+
const a = Arr.generate(function* () {
|
|
524
|
+
for (const x of ms) {
|
|
525
|
+
if (x > 0) {
|
|
526
|
+
yield x;
|
|
527
|
+
}
|
|
465
528
|
}
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
529
|
+
});
|
|
530
|
+
const b = Arr.generate(function* () {
|
|
531
|
+
for (const x of ts) {
|
|
532
|
+
if (x > 0) {
|
|
533
|
+
yield x;
|
|
534
|
+
}
|
|
472
535
|
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
536
|
+
});
|
|
537
|
+
const c = Arr.generate(function* () {
|
|
538
|
+
for (const x of xs) {
|
|
539
|
+
if (x > 0) {
|
|
540
|
+
yield x;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
});
|
|
544
|
+
};
|
|
545
|
+
`,
|
|
546
|
+
],
|
|
477
547
|
errors: [
|
|
478
548
|
{ messageId: 'useArrGenerate' },
|
|
479
549
|
{ messageId: 'useArrGenerate' },
|
|
@@ -691,30 +761,50 @@ describe('prefer-arr-generate', () => {
|
|
|
691
761
|
return [...a, ...b];
|
|
692
762
|
};
|
|
693
763
|
`,
|
|
694
|
-
output:
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
const a = Arr.generate(function* () {
|
|
702
|
-
for (const x of c) {
|
|
703
|
-
if (x > 0) {
|
|
704
|
-
yield x;
|
|
705
|
-
}
|
|
764
|
+
output: [
|
|
765
|
+
dedent`
|
|
766
|
+
import { Arr } from 'ts-data-forge';
|
|
767
|
+
declare const c: readonly number[] | undefined;
|
|
768
|
+
export const f = (p: readonly number[] | undefined): readonly number[] => {
|
|
769
|
+
if (c === undefined || p === undefined) {
|
|
770
|
+
return [];
|
|
706
771
|
}
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
772
|
+
const a = Arr.generate(function* () {
|
|
773
|
+
for (const x of c) {
|
|
774
|
+
if (x > 0) {
|
|
775
|
+
yield x;
|
|
776
|
+
}
|
|
712
777
|
}
|
|
778
|
+
});
|
|
779
|
+
const b = p.flatMap((x) => (x > 0 ? [x] : []));
|
|
780
|
+
return [...a, ...b];
|
|
781
|
+
};
|
|
782
|
+
`,
|
|
783
|
+
dedent`
|
|
784
|
+
import { Arr } from 'ts-data-forge';
|
|
785
|
+
declare const c: readonly number[] | undefined;
|
|
786
|
+
export const f = (p: readonly number[] | undefined): readonly number[] => {
|
|
787
|
+
if (c === undefined || p === undefined) {
|
|
788
|
+
return [];
|
|
713
789
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
790
|
+
const a = Arr.generate(function* () {
|
|
791
|
+
for (const x of c) {
|
|
792
|
+
if (x > 0) {
|
|
793
|
+
yield x;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
});
|
|
797
|
+
const b = Arr.generate(function* () {
|
|
798
|
+
for (const x of p) {
|
|
799
|
+
if (x > 0) {
|
|
800
|
+
yield x;
|
|
801
|
+
}
|
|
802
|
+
}
|
|
803
|
+
});
|
|
804
|
+
return [...a, ...b];
|
|
805
|
+
};
|
|
806
|
+
`,
|
|
807
|
+
],
|
|
718
808
|
errors: [
|
|
719
809
|
{ messageId: 'useArrGenerate' },
|
|
720
810
|
{ messageId: 'useArrGenerate' },
|
|
@@ -737,34 +827,58 @@ describe('prefer-arr-generate', () => {
|
|
|
737
827
|
return [...a, ...b];
|
|
738
828
|
};
|
|
739
829
|
`,
|
|
740
|
-
output:
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
const a = Arr.generate(function* () {
|
|
752
|
-
for (const x of o.names) {
|
|
753
|
-
if (x !== '') {
|
|
754
|
-
yield x;
|
|
755
|
-
}
|
|
830
|
+
output: [
|
|
831
|
+
dedent`
|
|
832
|
+
import { Arr } from 'ts-data-forge';
|
|
833
|
+
declare const isNonEmpty: <T,>(
|
|
834
|
+
xs: readonly T[],
|
|
835
|
+
) => xs is readonly [T, ...T[]];
|
|
836
|
+
declare const o: Readonly<{ names: readonly string[] }>;
|
|
837
|
+
declare const nested: readonly (readonly string[])[];
|
|
838
|
+
export const f = (): readonly string[] => {
|
|
839
|
+
if (!isNonEmpty(o.names)) {
|
|
840
|
+
return [];
|
|
756
841
|
}
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
842
|
+
const a = Arr.generate(function* () {
|
|
843
|
+
for (const x of o.names) {
|
|
844
|
+
if (x !== '') {
|
|
845
|
+
yield x;
|
|
846
|
+
}
|
|
762
847
|
}
|
|
848
|
+
});
|
|
849
|
+
const b = nested.flat().flatMap((x) => (x !== '' ? [x] : []));
|
|
850
|
+
return [...a, ...b];
|
|
851
|
+
};
|
|
852
|
+
`,
|
|
853
|
+
dedent`
|
|
854
|
+
import { Arr } from 'ts-data-forge';
|
|
855
|
+
declare const isNonEmpty: <T,>(
|
|
856
|
+
xs: readonly T[],
|
|
857
|
+
) => xs is readonly [T, ...T[]];
|
|
858
|
+
declare const o: Readonly<{ names: readonly string[] }>;
|
|
859
|
+
declare const nested: readonly (readonly string[])[];
|
|
860
|
+
export const f = (): readonly string[] => {
|
|
861
|
+
if (!isNonEmpty(o.names)) {
|
|
862
|
+
return [];
|
|
763
863
|
}
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
864
|
+
const a = Arr.generate(function* () {
|
|
865
|
+
for (const x of o.names) {
|
|
866
|
+
if (x !== '') {
|
|
867
|
+
yield x;
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
});
|
|
871
|
+
const b = Arr.generate(function* () {
|
|
872
|
+
for (const x of nested.flat()) {
|
|
873
|
+
if (x !== '') {
|
|
874
|
+
yield x;
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
});
|
|
878
|
+
return [...a, ...b];
|
|
879
|
+
};
|
|
880
|
+
`,
|
|
881
|
+
],
|
|
768
882
|
errors: [
|
|
769
883
|
{ messageId: 'useArrGenerate' },
|
|
770
884
|
{ messageId: 'useArrGenerate' },
|
|
@@ -867,24 +981,38 @@ describe('prefer-arr-generate through type wrappers', () => {
|
|
|
867
981
|
);
|
|
868
982
|
const b = xs.flatMap!((x) => (x > 0 ? [x] : []));
|
|
869
983
|
`,
|
|
870
|
-
output:
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
984
|
+
output: [
|
|
985
|
+
dedent`
|
|
986
|
+
import { Arr } from 'ts-data-forge';
|
|
987
|
+
declare const xs: readonly number[];
|
|
988
|
+
const a = Arr.generate(function* () {
|
|
989
|
+
for (const x of xs satisfies readonly number[]) {
|
|
990
|
+
if (x > 0) {
|
|
991
|
+
yield x;
|
|
992
|
+
}
|
|
877
993
|
}
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
994
|
+
});
|
|
995
|
+
const b = xs.flatMap!((x) => (x > 0 ? [x] : []));
|
|
996
|
+
`,
|
|
997
|
+
dedent`
|
|
998
|
+
import { Arr } from 'ts-data-forge';
|
|
999
|
+
declare const xs: readonly number[];
|
|
1000
|
+
const a = Arr.generate(function* () {
|
|
1001
|
+
for (const x of xs satisfies readonly number[]) {
|
|
1002
|
+
if (x > 0) {
|
|
1003
|
+
yield x;
|
|
1004
|
+
}
|
|
884
1005
|
}
|
|
885
|
-
}
|
|
886
|
-
|
|
887
|
-
|
|
1006
|
+
});
|
|
1007
|
+
const b = Arr.generate(function* () {
|
|
1008
|
+
for (const x of xs) {
|
|
1009
|
+
if (x > 0) {
|
|
1010
|
+
yield x;
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
});
|
|
1014
|
+
`,
|
|
1015
|
+
],
|
|
888
1016
|
errors: [
|
|
889
1017
|
{ messageId: 'useArrGenerate' },
|
|
890
1018
|
{ messageId: 'useArrGenerate' },
|
|
@@ -72,11 +72,18 @@ ruleTester.run('prefer-arr-is-array', preferArrIsArray, {
|
|
|
72
72
|
const result1 = Array.isArray(value1);
|
|
73
73
|
const result2 = Array.isArray(value2);
|
|
74
74
|
`,
|
|
75
|
-
output:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
output: [
|
|
76
|
+
dedent`
|
|
77
|
+
import { Arr } from 'ts-data-forge';
|
|
78
|
+
const result1 = Arr.isArray(value1);
|
|
79
|
+
const result2 = Array.isArray(value2);
|
|
80
|
+
`,
|
|
81
|
+
dedent`
|
|
82
|
+
import { Arr } from 'ts-data-forge';
|
|
83
|
+
const result1 = Arr.isArray(value1);
|
|
84
|
+
const result2 = Arr.isArray(value2);
|
|
85
|
+
`,
|
|
86
|
+
],
|
|
80
87
|
errors: [{ messageId: 'useIsArray' }, { messageId: 'useIsArray' }],
|
|
81
88
|
},
|
|
82
89
|
],
|
|
@@ -157,3 +164,78 @@ describe('prefer-arr-is-array with parenthesized operands', () => {
|
|
|
157
164
|
],
|
|
158
165
|
});
|
|
159
166
|
});
|
|
167
|
+
|
|
168
|
+
describe('prefer-arr-is-array brings Arr into scope', () => {
|
|
169
|
+
ruleTester.run('prefer-arr-is-array', preferArrIsArray, {
|
|
170
|
+
valid: [],
|
|
171
|
+
invalid: [
|
|
172
|
+
{
|
|
173
|
+
name: 'after a leading directive',
|
|
174
|
+
code: dedent`
|
|
175
|
+
'use client';
|
|
176
|
+
const result = Array.isArray(value);
|
|
177
|
+
`,
|
|
178
|
+
output: dedent`
|
|
179
|
+
'use client';
|
|
180
|
+
import { Arr } from 'ts-data-forge';
|
|
181
|
+
const result = Arr.isArray(value);
|
|
182
|
+
`,
|
|
183
|
+
errors: [{ messageId: 'useIsArray' }],
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: 'in the existing named import',
|
|
187
|
+
code: dedent`
|
|
188
|
+
import { Num } from 'ts-data-forge';
|
|
189
|
+
const result = Array.isArray(value);
|
|
190
|
+
`,
|
|
191
|
+
output: dedent`
|
|
192
|
+
import { Num, Arr } from 'ts-data-forge';
|
|
193
|
+
const result = Arr.isArray(value);
|
|
194
|
+
`,
|
|
195
|
+
errors: [{ messageId: 'useIsArray' }],
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: 'an inline type import becomes a value import',
|
|
199
|
+
code: dedent`
|
|
200
|
+
import { type Arr } from 'ts-data-forge';
|
|
201
|
+
const result = Array.isArray(value);
|
|
202
|
+
`,
|
|
203
|
+
output: dedent`
|
|
204
|
+
import { Arr } from 'ts-data-forge';
|
|
205
|
+
const result = Arr.isArray(value);
|
|
206
|
+
`,
|
|
207
|
+
errors: [{ messageId: 'useIsArray' }],
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
name: 'no fix when a type-only declaration imports it',
|
|
211
|
+
code: dedent`
|
|
212
|
+
import type { Arr } from 'ts-data-forge';
|
|
213
|
+
const result = Array.isArray(value);
|
|
214
|
+
`,
|
|
215
|
+
output: null,
|
|
216
|
+
errors: [{ messageId: 'useIsArray' }],
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
name: 'the local name of an aliased import',
|
|
220
|
+
code: dedent`
|
|
221
|
+
import { Arr as A } from 'ts-data-forge';
|
|
222
|
+
const result = Array.isArray(value);
|
|
223
|
+
`,
|
|
224
|
+
output: dedent`
|
|
225
|
+
import { Arr as A } from 'ts-data-forge';
|
|
226
|
+
const result = A.isArray(value);
|
|
227
|
+
`,
|
|
228
|
+
errors: [{ messageId: 'useIsArray' }],
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: 'no fix when something else is named Arr where the call is',
|
|
232
|
+
code: dedent`
|
|
233
|
+
const Arr = 1;
|
|
234
|
+
const result = Array.isArray(value);
|
|
235
|
+
`,
|
|
236
|
+
output: null,
|
|
237
|
+
errors: [{ messageId: 'useIsArray' }],
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
});
|
|
241
|
+
});
|
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import type { TSESLint, TSESTree } from '@typescript-eslint/utils';
|
|
2
|
-
import {
|
|
3
|
-
buildNamedImportFix,
|
|
4
|
-
getArgumentText,
|
|
5
|
-
getImportDeclarations,
|
|
6
|
-
getNamedImports,
|
|
7
|
-
} from 'eslint-rule-forge';
|
|
2
|
+
import { getArgumentText } from 'eslint-rule-forge';
|
|
8
3
|
import {
|
|
9
4
|
isArrayOrTupleExpression,
|
|
10
5
|
isSameArrayText,
|
|
11
6
|
parseLengthComparison,
|
|
12
7
|
} from './ast-utils.mjs';
|
|
13
|
-
import {
|
|
8
|
+
import { tsDataForgeValueAt } from './import-binding.mjs';
|
|
14
9
|
|
|
15
10
|
type Options = readonly [];
|
|
16
11
|
|
|
@@ -38,13 +33,6 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
|
|
|
38
33
|
create: (context) => {
|
|
39
34
|
const sourceCode = context.sourceCode;
|
|
40
35
|
|
|
41
|
-
const program = sourceCode.ast;
|
|
42
|
-
|
|
43
|
-
const tsDataForgeImports = getImportDeclarations(
|
|
44
|
-
program,
|
|
45
|
-
TS_DATA_FORGE_MODULE,
|
|
46
|
-
);
|
|
47
|
-
|
|
48
36
|
const services = context.sourceCode.parserServices;
|
|
49
37
|
|
|
50
38
|
const mut_nodesToFix: {
|
|
@@ -100,14 +88,14 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
|
|
|
100
88
|
});
|
|
101
89
|
},
|
|
102
90
|
'Program:exit': () => {
|
|
103
|
-
const
|
|
91
|
+
const arrAt = tsDataForgeValueAt(sourceCode, 'Arr');
|
|
104
92
|
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
93
|
+
for (const {
|
|
94
|
+
node,
|
|
95
|
+
arrayExpression,
|
|
96
|
+
minExpression,
|
|
97
|
+
maxExpression,
|
|
98
|
+
} of mut_nodesToFix) {
|
|
111
99
|
const arrayText = getArgumentText(sourceCode, arrayExpression);
|
|
112
100
|
|
|
113
101
|
const minText = sourceCode.getText(minExpression);
|
|
@@ -116,6 +104,8 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
|
|
|
116
104
|
|
|
117
105
|
const originalText = sourceCode.getText(node);
|
|
118
106
|
|
|
107
|
+
const arr = arrAt(node);
|
|
108
|
+
|
|
119
109
|
context.report({
|
|
120
110
|
node,
|
|
121
111
|
messageId: 'useIsBoundedLengthArray',
|
|
@@ -125,18 +115,17 @@ export const preferArrIsBoundedLengthArray: TSESLint.RuleModule<
|
|
|
125
115
|
min: minText,
|
|
126
116
|
max: maxText,
|
|
127
117
|
},
|
|
128
|
-
fix:
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
},
|
|
118
|
+
fix:
|
|
119
|
+
arr === undefined
|
|
120
|
+
? null
|
|
121
|
+
: (fixer) => {
|
|
122
|
+
const replacement = `${arr.localName}.isBoundedLengthArray(${minText}, ${maxText}, ${arrayText})`;
|
|
123
|
+
|
|
124
|
+
return [
|
|
125
|
+
...arr.edits(fixer),
|
|
126
|
+
fixer.replaceText(node, replacement),
|
|
127
|
+
];
|
|
128
|
+
},
|
|
140
129
|
});
|
|
141
130
|
}
|
|
142
131
|
},
|