-
Notifications
You must be signed in to change notification settings - Fork 711
/
Copy pathlinter_rules.json
3613 lines (3613 loc) · 254 KB
/
linter_rules.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
[
{
"name": "always_declare_return_types",
"description": "Declare method return types.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** declare method return types.\n\nWhen declaring a method or function *always* specify a return type.\nDeclaring return types for functions helps improve your codebase by allowing the\nanalyzer to more adequately check your code for errors that could occur during\nruntime.\n\n**BAD:**\n```dart\nmain() { }\n\n_bar() => _Foo();\n\nclass _Foo {\n _foo() => 42;\n}\n```\n\n**GOOD:**\n```dart\nvoid main() { }\n\n_Foo _bar() => _Foo();\n\nclass _Foo {\n int _foo() => 42;\n}\n\ntypedef predicate = bool Function(Object o);\n```",
"sinceDartSdk": "2.0"
},
{
"name": "always_put_control_body_on_new_line",
"description": "Separate the control structure expression from its statement.",
"categories": [
"errorProne",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "From the [style guide for the flutter repo](https://flutter.dev/style-guide/):\n\n**DO** separate the control structure expression from its statement.\n\nDon't put the statement part of an `if`, `for`, `while`, `do` on the same line\nas the expression, even if it is short. Doing so makes it unclear that there\nis relevant code there. This is especially important for early returns.\n\n**BAD:**\n```dart\nif (notReady) return;\n\nif (notReady)\n return;\nelse print('ok')\n\nwhile (condition) i += 1;\n```\n\n**GOOD:**\n```dart\nif (notReady)\n return;\n\nif (notReady)\n return;\nelse\n print('ok')\n\nwhile (condition)\n i += 1;\n```\n\nNote that this rule can conflict with the\n[Dart formatter](https://dart.dev/tools/dart-format), and should not be enabled\nwhen the Dart formatter is used.",
"sinceDartSdk": "2.0"
},
{
"name": "always_put_required_named_parameters_first",
"description": "Put required named parameters first.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** specify `required` on named parameter before other named parameters.\n\n**BAD:**\n```dart\nm({b, c, required a}) ;\n```\n\n**GOOD:**\n```dart\nm({required a, b, c}) ;\n```\n\n**BAD:**\n```dart\nm({b, c, @required a}) ;\n```\n\n**GOOD:**\n```dart\nm({@required a, b, c}) ;\n```",
"sinceDartSdk": "2.0"
},
{
"name": "always_require_non_null_named_parameters",
"description": "Specify `@required` on named parameters without defaults.",
"categories": [],
"state": "removed",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "NOTE: This rule is removed in Dart 3.3.0; it is no longer functional.\n\n**DO** specify `@required` on named parameters without a default value on which\nan `assert(param != null)` is done.\n\n**BAD:**\n```dart\nm1({a}) {\n assert(a != null);\n}\n```\n\n**GOOD:**\n```dart\nm1({@required a}) {\n assert(a != null);\n}\n\nm2({a: 1}) {\n assert(a != null);\n}\n```\n\nNOTE: Only asserts at the start of the bodies will be taken into account.",
"sinceDartSdk": "2.0"
},
{
"name": "always_specify_types",
"description": "Specify type annotations.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [
"avoid_types_on_closure_parameters",
"omit_local_variable_types",
"omit_obvious_local_variable_types",
"omit_obvious_property_types"
],
"sets": [],
"fixStatus": "hasFix",
"details": "From the [style guide for the flutter repo](https://flutter.dev/style-guide/):\n\n**DO** specify type annotations.\n\nAvoid `var` when specifying that a type is unknown and short-hands that elide\ntype annotations. Use `dynamic` if you are being explicit that the type is\nunknown. Use `Object` if you are being explicit that you want an object that\nimplements `==` and `hashCode`.\n\n**BAD:**\n```dart\nvar foo = 10;\nfinal bar = Bar();\nconst quux = 20;\n```\n\n**GOOD:**\n```dart\nint foo = 10;\nfinal Bar bar = Bar();\nString baz = 'hello';\nconst int quux = 20;\n```\n\nNOTE: Using the `@optionalTypeArgs` annotation in the `meta` package, API\nauthors can special-case type parameters whose type needs to be dynamic but whose\ndeclaration should be treated as optional. For example, suppose you have a\n`Key` object whose type parameter you'd like to treat as optional. Using the\n`@optionalTypeArgs` would look like this:\n\n```dart\nimport 'package:meta/meta.dart';\n\n@optionalTypeArgs\nclass Key<T> {\n ...\n}\n\nvoid main() {\n Key s = Key(); // OK!\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "always_use_package_imports",
"description": "Avoid relative imports for files in `lib/`.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [
"prefer_relative_imports"
],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** avoid relative imports for files in `lib/`.\n\nWhen mixing relative and absolute imports it's possible to create confusion\nwhere the same member gets imported in two different ways. One way to avoid\nthat is to ensure you consistently use absolute imports for files within the\n`lib/` directory.\n\nThis is the opposite of 'prefer_relative_imports'.\n\nYou can also use 'avoid_relative_lib_imports' to disallow relative imports of\nfiles within `lib/` directory outside of it (for example `test/`).\n\n**BAD:**\n```dart\nimport 'baz.dart';\n\nimport 'src/bag.dart'\n\nimport '../lib/baz.dart';\n\n...\n```\n\n**GOOD:**\n```dart\nimport 'package:foo/bar.dart';\n\nimport 'package:foo/baz.dart';\n\nimport 'package:foo/src/baz.dart';\n...\n```",
"sinceDartSdk": "2.10"
},
{
"name": "annotate_overrides",
"description": "Annotate overridden members.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**DO** annotate overridden methods and fields.\n\nThis practice improves code readability and helps protect against\nunintentionally overriding superclass members.\n\n**BAD:**\n```dart\nclass Cat {\n int get lives => 9;\n}\n\nclass Lucky extends Cat {\n final int lives = 14;\n}\n```\n\n**GOOD:**\n```dart\nabstract class Dog {\n String get breed;\n void bark() {}\n}\n\nclass Husky extends Dog {\n @override\n final String breed = 'Husky';\n @override\n void bark() {}\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "annotate_redeclares",
"description": "Annotate redeclared members.",
"categories": [
"style"
],
"state": "experimental",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** annotate redeclared members.\n\nThis practice improves code readability and helps protect against\nunintentionally redeclaring members or being surprised when a member ceases to\nredeclare (due for example to a rename refactoring).\n\n**BAD:**\n```dart\nclass C {\n void f() { }\n}\n\nextension type E(C c) implements C {\n void f() {\n ...\n }\n}\n```\n\n**GOOD:**\n```dart\nimport 'package:meta/meta.dart';\n\nclass C {\n void f() { }\n}\n\nextension type E(C c) implements C {\n @redeclare\n void f() {\n ...\n }\n}\n```",
"sinceDartSdk": "3.2"
},
{
"name": "avoid_annotating_with_dynamic",
"description": "Avoid annotating with `dynamic` when not required.",
"categories": [
"brevity",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**AVOID** annotating with `dynamic` when not required.\n\nAs `dynamic` is the assumed return value of a function or method, it is usually\nnot necessary to annotate it.\n\n**BAD:**\n```dart\ndynamic lookUpOrDefault(String name, Map map, dynamic defaultValue) {\n var value = map[name];\n if (value != null) return value;\n return defaultValue;\n}\n```\n\n**GOOD:**\n```dart\nlookUpOrDefault(String name, Map map, defaultValue) {\n var value = map[name];\n if (value != null) return value;\n return defaultValue;\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_as",
"description": "Avoid using `as`.",
"categories": [],
"state": "removed",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "NOTE: This rule was removed from the SDK in Dart 3; it is no longer functional.\nIts advice is compiler-specific and mostly obsolete with null safety.\n\n**AVOID** using `as`.\n\nIf you know the type is correct, use an assertion or assign to a more\nnarrowly-typed variable (this avoids the type check in release mode; `as` is not\ncompiled out in release mode). If you don't know whether the type is\ncorrect, check using `is` (this avoids the exception that `as` raises).\n\n**BAD:**\n```dart\n(pm as Person).firstName = 'Seth';\n```\n\n**GOOD:**\n```dart\nif (pm is Person)\n pm.firstName = 'Seth';\n```\n\nbut certainly not\n\n**BAD:**\n```dart\ntry {\n (pm as Person).firstName = 'Seth';\n} on CastError { }\n```\n\nNote that an exception is made in the case of `dynamic` since the cast has no\nperformance impact.\n\n**OK:**\n```dart\nHasScrollDirection scrollable = renderObject as dynamic;\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_bool_literals_in_conditional_expressions",
"description": "Avoid `bool` literals in conditional expressions.",
"categories": [
"brevity"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "**AVOID** `bool` literals in conditional expressions.\n\n**BAD:**\n```dart\ncondition ? true : boolExpression\ncondition ? false : boolExpression\ncondition ? boolExpression : true\ncondition ? boolExpression : false\n```\n\n**GOOD:**\n```dart\ncondition || boolExpression\n!condition && boolExpression\n!condition || boolExpression\ncondition && boolExpression\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_catches_without_on_clauses",
"description": "Avoid catches without on clauses.",
"categories": [
"effectiveDart",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/usage#avoid-catches-without-on-clauses):\n\n**AVOID** catches without on clauses.\n\nUsing catch clauses without on clauses make your code prone to encountering\nunexpected errors that won't be thrown (and thus will go unnoticed).\n\n**BAD:**\n```dart\ntry {\n somethingRisky()\n} catch(e) {\n doSomething(e);\n}\n```\n\n**GOOD:**\n```dart\ntry {\n somethingRisky()\n} on Exception catch(e) {\n doSomething(e);\n}\n```\n\nA few exceptional cases are allowed:\n\n* If the body of the catch rethrows the exception.\n* If the caught exception is \"directly used\" in an argument to `Future.error`,\n `Completer.completeError`, or `FlutterError.reportError`, or any function with\n a return type of `Never`.\n* If the caught exception is \"directly used\" in a new throw-expression.\n\nIn these cases, \"directly used\" means that the exception is referenced within\nthe relevant code (like within an argument). If the exception variable is\nreferenced _before_ the relevant code, for example to instantiate a wrapper\nexception, the variable is not \"directly used.\"",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_catching_errors",
"description": "Don't explicitly catch `Error` or types that implement it.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DON'T** explicitly catch `Error` or types that implement it.\n\nErrors differ from Exceptions in that Errors can be analyzed and prevented prior\nto runtime. It should almost never be necessary to catch an error at runtime.\n\n**BAD:**\n```dart\ntry {\n somethingRisky();\n} on Error catch(e) {\n doSomething(e);\n}\n```\n\n**GOOD:**\n```dart\ntry {\n somethingRisky();\n} on Exception catch(e) {\n doSomething(e);\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_classes_with_only_static_members",
"description": "Avoid defining a class that contains only static members.",
"categories": [
"effectiveDart",
"languageFeatureUsage",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/design#avoid-defining-a-class-that-contains-only-static-members):\n\n**AVOID** defining a class that contains only static members.\n\nCreating classes with the sole purpose of providing utility or otherwise static\nmethods is discouraged. Dart allows functions to exist outside of classes for\nthis very reason.\n\n**BAD:**\n```dart\nclass DateUtils {\n static DateTime mostRecent(List<DateTime> dates) {\n return dates.reduce((a, b) => a.isAfter(b) ? a : b);\n }\n}\n\nclass _Favorites {\n static const mammal = 'weasel';\n}\n```\n\n**GOOD:**\n```dart\nDateTime mostRecent(List<DateTime> dates) {\n return dates.reduce((a, b) => a.isAfter(b) ? a : b);\n}\n\nconst _favoriteMammal = 'weasel';\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_double_and_int_checks",
"description": "Avoid `double` and `int` checks.",
"categories": [
"errorProne",
"web"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "**AVOID** to check if type is `double` or `int`.\n\nWhen compiled to JS, integer values are represented as floats. That can lead to\nsome unexpected behavior when using either `is` or `is!` where the type is\neither `int` or `double`.\n\n**BAD:**\n```dart\nf(num x) {\n if (x is double) {\n ...\n } else if (x is int) {\n ...\n }\n}\n```\n\n**GOOD:**\n```dart\nf(dynamic x) {\n if (x is num) {\n ...\n } else {\n ...\n }\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_dynamic_calls",
"description": "Avoid method calls or property accesses on a `dynamic` target.",
"categories": [
"binarySize",
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DO** avoid method calls or accessing properties on an object that is either\nexplicitly or implicitly statically typed `dynamic`. Dynamic calls are treated\nslightly different in every runtime environment and compiler, but most\nproduction modes (and even some development modes) have both compile size and\nruntime performance penalties associated with dynamic calls.\n\nAdditionally, targets typed `dynamic` disables most static analysis, meaning it\nis easier to lead to a runtime `NoSuchMethodError` or `TypeError` than properly\nstatically typed Dart code.\n\nThere is an exception to methods and properties that exist on `Object?`:\n- `a.hashCode`\n- `a.runtimeType`\n- `a.noSuchMethod(someInvocation)`\n- `a.toString()`\n\n... these members are dynamically dispatched in the web-based runtimes, but not\nin the VM-based ones. Additionally, they are so common that it would be very\npunishing to disallow `any.toString()` or `any == true`, for example.\n\nNote that despite `Function` being a type, the semantics are close to identical\nto `dynamic`, and calls to an object that is typed `Function` will also trigger\nthis lint.\n\nDynamic calls are allowed on cast expressions (`as dynamic` or `as Function`).\n\n**BAD:**\n```dart\nvoid explicitDynamicType(dynamic object) {\n print(object.foo());\n}\n\nvoid implicitDynamicType(object) {\n print(object.foo());\n}\n\nabstract class SomeWrapper {\n T doSomething<T>();\n}\n\nvoid inferredDynamicType(SomeWrapper wrapper) {\n var object = wrapper.doSomething();\n print(object.foo());\n}\n\nvoid callDynamic(dynamic function) {\n function();\n}\n\nvoid functionType(Function function) {\n function();\n}\n```\n\n**GOOD:**\n```dart\nvoid explicitType(Fooable object) {\n object.foo();\n}\n\nvoid castedType(dynamic object) {\n (object as Fooable).foo();\n}\n\nabstract class SomeWrapper {\n T doSomething<T>();\n}\n\nvoid inferredType(SomeWrapper wrapper) {\n var object = wrapper.doSomething<Fooable>();\n object.foo();\n}\n\nvoid functionTypeWithParameters(Function() function) {\n function();\n}\n```",
"sinceDartSdk": "2.12"
},
{
"name": "avoid_empty_else",
"description": "Avoid empty statements in else clauses.",
"categories": [
"brevity",
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** empty statements in the `else` clause of `if` statements.\n\n**BAD:**\n```dart\nif (x > y)\n print('1');\nelse ;\n print('2');\n```\n\nIf you want a statement that follows the empty clause to _conditionally_ run,\nremove the dangling semicolon to include it in the `else` clause.\nOptionally, also enclose the else's statement in a block.\n\n**GOOD:**\n```dart\nif (x > y)\n print('1');\nelse\n print('2');\n```\n\n**GOOD:**\n```dart\nif (x > y) {\n print('1');\n} else {\n print('2');\n}\n```\n\nIf you want a statement that follows the empty clause to _unconditionally_ run,\nremove the `else` clause.\n\n**GOOD:**\n```dart\nif (x > y) print('1');\n\nprint('2');\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_equals_and_hash_code_on_mutable_classes",
"description": "Avoid overloading operator == and hashCode on classes not marked `@immutable`.",
"categories": [
"effectiveDart",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/design#avoid-defining-custom-equality-for-mutable-classes):\n\n**AVOID** overloading operator == and hashCode on classes not marked `@immutable`.\n\nIf a class is not immutable, overloading `operator ==` and `hashCode` can\nlead to unpredictable and undesirable behavior when used in collections.\n\n**BAD:**\n```dart\nclass B {\n String key;\n const B(this.key);\n @override\n operator ==(other) => other is B && other.key == key;\n @override\n int get hashCode => key.hashCode;\n}\n```\n\n**GOOD:**\n```dart\n@immutable\nclass A {\n final String key;\n const A(this.key);\n @override\n operator ==(other) => other is A && other.key == key;\n @override\n int get hashCode => key.hashCode;\n}\n```\n\nNOTE: The lint checks the use of the `@immutable` annotation, and will trigger\neven if the class is otherwise not mutable. Thus:\n\n**BAD:**\n```dart\nclass C {\n final String key;\n const C(this.key);\n @override\n operator ==(other) => other is C && other.key == key;\n @override\n int get hashCode => key.hashCode;\n}\n```",
"sinceDartSdk": "2.6"
},
{
"name": "avoid_escaping_inner_quotes",
"description": "Avoid escaping inner quotes by converting surrounding quotes.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "Avoid escaping inner quotes by converting surrounding quotes.\n\n**BAD:**\n```dart\nvar s = 'It\\'s not fun';\n```\n\n**GOOD:**\n```dart\nvar s = \"It's not fun\";\n```",
"sinceDartSdk": "2.8"
},
{
"name": "avoid_field_initializers_in_const_classes",
"description": "Avoid field initializers in const classes.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**AVOID** field initializers in const classes.\n\nInstead of `final x = const expr;`, you should write `get x => const expr;` and\nnot allocate a useless field. As of April 2018 this is true for the VM, but not\nfor code that will be compiled to JS.\n\n**BAD:**\n```dart\nclass A {\n final a = const [];\n const A();\n}\n```\n\n**GOOD:**\n```dart\nclass A {\n get a => const [];\n const A();\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_final_parameters",
"description": "Avoid `final` for parameter declarations.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [
"prefer_final_parameters"
],
"sets": [],
"fixStatus": "needsFix",
"details": "**AVOID** declaring parameters as `final`.\n\nDeclaring parameters as `final` can lead to unnecessarily verbose code,\nespecially when using the \"parameter_assignments\" rule.\n\n**BAD:**\n```dart\nvoid goodParameter(final String label) { // LINT\n print(label);\n}\n```\n\n**GOOD:**\n```dart\nvoid badParameter(String label) { // OK\n print(label);\n}\n```\n\n**BAD:**\n```dart\nvoid goodExpression(final int value) => print(value); // LINT\n```\n\n**GOOD:**\n```dart\nvoid badExpression(int value) => print(value); // OK\n```\n\n**BAD:**\n```dart\n[1, 4, 6, 8].forEach((final value) => print(value + 2)); // LINT\n```\n\n**GOOD:**\n```dart\n[1, 4, 6, 8].forEach((value) => print(value + 2)); // OK\n```",
"sinceDartSdk": "2.16"
},
{
"name": "avoid_function_literals_in_foreach_calls",
"description": "Avoid using `forEach` with a function literal.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** using `forEach` with a function literal.\n\nThe `for` loop enables a developer to be clear and explicit as to their intent.\nA return in the body of the `for` loop returns from the body of the function,\nwhere as a return in the body of the `forEach` closure only returns a value\nfor that iteration of the `forEach`. The body of a `for` loop can contain\n`await`s, while the closure body of a `forEach` cannot.\n\n**BAD:**\n```dart\npeople.forEach((person) {\n ...\n});\n```\n\n**GOOD:**\n```dart\nfor (var person in people) {\n ...\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_futureor_void",
"description": "Avoid using 'FutureOr<void>' as the type of a result.",
"categories": [
"errorProne",
"unintentional"
],
"state": "experimental",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**AVOID** using `FutureOr<void>` as the type of a result. This type is\nproblematic because it may appear to encode that a result is either a\n`Future<void>`, or the result should be discarded (when it is `void`).\nHowever, there is no safe way to detect whether we have one or the other\ncase (because an expression of type `void` can evaluate to any object\nwhatsoever, including a future of any type).\n\nIt is also conceptually unsound to have a type whose meaning is something\nlike \"ignore this object; also, take a look because it might be a future\".\n\nAn exception is made for contravariant occurrences of the type\n`FutureOr<void>` (e.g., for the type of a formal parameter), and no\nwarning is emitted for these occurrences. The reason for this exception\nis that the type does not describe a result, it describes a constraint\non a value provided by others. Similarly, an exception is made for type\nalias declarations, because they may well be used in a contravariant\nposition (e.g., as the type of a formal parameter). Hence, in type alias\ndeclarations, only the type parameter bounds are checked.\n\nA replacement for the type `FutureOr<void>` which is often useful is\n`Future<void>?`. This type encodes that the result is either a\n`Future<void>` or it is null, and there is no ambiguity at run time\nsince no object can have both types.\n\nIt may not always be possible to use the type `Future<void>?` as a\nreplacement for the type `FutureOr<void>`, because the latter is a\nsupertype of all types, and the former is not. In this case it may be a\nuseful remedy to replace `FutureOr<void>` by the type `void`.\n\n**BAD:**\n```dart\nFutureOr<void> m() {...}\n```\n\n**GOOD:**\n```dart\nFuture<void>? m() {...}\n```\n\n**This rule is experimental.** It is being evaluated, and it may be changed\nor removed. Feedback on its behavior is welcome! The main issue is here:\nhttps://github.com/dart-lang/linter/issues/4622",
"sinceDartSdk": "3.6"
},
{
"name": "avoid_implementing_value_types",
"description": "Don't implement classes that override `==`.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DON'T** implement classes that override `==`.\n\nThe `==` operator is contractually required to be an equivalence relation;\nthat is, symmetrically for all objects `o1` and `o2`, `o1 == o2` and `o2 == o1`\nmust either both be true, or both be false.\n\n> _NOTE_: Dart does not have true _value types_, so instead we consider a class\n> that implements `==` as a _proxy_ for identifying value types.\n\nWhen using `implements`, you do not inherit the method body of `==`, making it\nnearly impossible to follow the contract of `==`. Classes that override `==`\ntypically are usable directly in tests _without_ creating mocks or fakes as\nwell. For example, for a given class `Size`:\n\n```dart\nclass Size {\n final int inBytes;\n const Size(this.inBytes);\n\n @override\n bool operator ==(Object other) => other is Size && other.inBytes == inBytes;\n\n @override\n int get hashCode => inBytes.hashCode;\n}\n```\n\n**BAD:**\n```dart\nclass CustomSize implements Size {\n final int inBytes;\n const CustomSize(this.inBytes);\n\n int get inKilobytes => inBytes ~/ 1000;\n}\n```\n\n**BAD:**\n```dart\nimport 'package:test/test.dart';\nimport 'size.dart';\n\nclass FakeSize implements Size {\n int inBytes = 0;\n}\n\nvoid main() {\n test('should not throw on a size >1Kb', () {\n expect(() => someFunction(FakeSize()..inBytes = 1001), returnsNormally);\n });\n}\n```\n\n**GOOD:**\n```dart\nclass ExtendedSize extends Size {\n ExtendedSize(int inBytes) : super(inBytes);\n\n int get inKilobytes => inBytes ~/ 1000;\n}\n```\n\n**GOOD:**\n```dart\nimport 'package:test/test.dart';\nimport 'size.dart';\n\nvoid main() {\n test('should not throw on a size >1Kb', () {\n expect(() => someFunction(Size(1001)), returnsNormally);\n });\n}\n```",
"sinceDartSdk": "2.1"
},
{
"name": "avoid_init_to_null",
"description": "Don't explicitly initialize variables to `null`.",
"categories": [
"brevity",
"effectiveDart",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/usage#dont-explicitly-initialize-variables-to-null):\n\n**DON'T** explicitly initialize variables to `null`.\n\nIf a variable has a non-nullable type or is `final`,\nDart reports a compile error if you try to use it\nbefore it has been definitely initialized.\nIf the variable is nullable and not `const` or `final`,\nthen it is implicitly initialized to `null` for you.\nThere's no concept of \"uninitialized memory\" in Dart\nand no need to explicitly initialize a variable to `null` to be \"safe\".\nAdding `= null` is redundant and unneeded.\n\n**BAD:**\n```dart\nItem? bestDeal(List<Item> cart) {\n Item? bestItem = null;\n\n for (final item in cart) {\n if (bestItem == null || item.price < bestItem.price) {\n bestItem = item;\n }\n }\n\n return bestItem;\n}\n```\n\n**GOOD:**\n```dart\nItem? bestDeal(List<Item> cart) {\n Item? bestItem;\n\n for (final item in cart) {\n if (bestItem == null || item.price < bestItem.price) {\n bestItem = item;\n }\n }\n\n return bestItem;\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_js_rounded_ints",
"description": "Avoid JavaScript rounded ints.",
"categories": [
"errorProne",
"web"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**AVOID** integer literals that cannot be represented exactly when compiled to\nJavaScript.\n\nWhen a program is compiled to JavaScript `int` and `double` become JavaScript\nNumbers. Too large integers (`value < Number.MIN_SAFE_INTEGER` or\n`value > Number.MAX_SAFE_INTEGER`) may be rounded to the closest Number value.\n\nFor instance `1000000000000000001` cannot be represented exactly as a JavaScript\nNumber, so `1000000000000000000` will be used instead.\n\n**BAD:**\n```dart\nint value = 9007199254740995;\n```\n\n**GOOD:**\n```dart\nBigInt value = BigInt.parse('9007199254740995');\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_multiple_declarations_per_line",
"description": "Don't declare multiple variables on a single line.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DON'T** declare multiple variables on a single line.\n\n**BAD:**\n```dart\nString? foo, bar, baz;\n```\n\n**GOOD:**\n```dart\nString? foo;\nString? bar;\nString? baz;\n```",
"sinceDartSdk": "2.13"
},
{
"name": "avoid_null_checks_in_equality_operators",
"description": "Don't check for `null` in custom `==` operators.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**NOTE:** This lint has been replaced by the\n`non_nullable_equals_parameter` warning and is deprecated.\nRemove all inclusions of this lint from your analysis options.\n\n**DON'T** check for `null` in custom `==` operators.\n\nAs `null` is a special value, no instance of any class (other than `Null`) can\nbe equivalent to it. Thus, it is redundant to check whether the other instance\nis `null`.\n\n**BAD:**\n```dart\nclass Person {\n final String? name;\n\n @override\n operator ==(Object? other) =>\n other != null && other is Person && name == other.name;\n}\n```\n\n**GOOD:**\n```dart\nclass Person {\n final String? name;\n\n @override\n operator ==(Object? other) => other is Person && name == other.name;\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_positional_boolean_parameters",
"description": "Avoid positional boolean parameters.",
"categories": [
"effectiveDart",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/design#avoid-positional-boolean-parameters):\n\n**AVOID** positional boolean parameters.\n\nPositional boolean parameters are a bad practice because they are very\nambiguous. Using named boolean parameters is much more readable because it\ninherently describes what the boolean value represents.\n\n**BAD:**\n```dart\nTask(true);\nTask(false);\nListBox(false, true, true);\nButton(false);\n```\n\n**GOOD:**\n```dart\nTask.oneShot();\nTask.repeating();\nListBox(scroll: true, showScrollbars: true);\nButton(ButtonState.enabled);\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_print",
"description": "Avoid `print` calls in production code.",
"categories": [
"unintentional"
],
"state": "stable",
"incompatible": [],
"sets": [
"flutter"
],
"fixStatus": "hasFix",
"details": "**DO** avoid `print` calls in production code.\n\nFor production code, consider using a logging framework.\nIf you are using Flutter, you can use `debugPrint`\nor surround `print` calls with a check for `kDebugMode`\n\n**BAD:**\n```dart\nvoid f(int x) {\n print('debug: $x');\n ...\n}\n```\n\n\n**GOOD:**\n```dart\nvoid f(int x) {\n debugPrint('debug: $x');\n ...\n}\n```\n\n\n**GOOD:**\n```dart\nvoid f(int x) {\n log('log: $x');\n ...\n}\n```\n\n\n**GOOD:**\n```dart\nvoid f(int x) {\n if (kDebugMode) {\n print('debug: $x');\n }\n ...\n}\n```",
"sinceDartSdk": "2.5"
},
{
"name": "avoid_private_typedef_functions",
"description": "Avoid private typedef functions.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**AVOID** private typedef functions used only once. Prefer inline function\nsyntax.\n\n**BAD:**\n```dart\ntypedef void _F();\nm(_F f);\n```\n\n**GOOD:**\n```dart\nm(void Function() f);\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_redundant_argument_values",
"description": "Avoid redundant argument values.",
"categories": [
"brevity",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DON'T** pass an argument that matches the corresponding parameter's default\nvalue.\n\nNote that a method override can change the default value of a parameter, so that\nan argument may be equal to one default value, and not the other. Take, for\nexample, two classes, `A` and `B` where `B` is a subclass of `A`, and `B`\noverrides a method declared on `A`, and that method has a parameter with one\ndefault value in `A`'s declaration, and a different default value in `B`'s\ndeclaration. If the static type of the target of the invoked method is `B`, and\n`B`'s default value matches the argument, then the argument can be omitted (and\nif the argument value is different, then a lint is not reported). If, however,\nthe static type of the target of the invoked method is `A`, then a lint may be\nreported, but we cannot know statically which method is invoked, so the reported\nlint may be a false positive. Such cases can be ignored inline with a comment\nlike `// ignore: avoid_redundant_argument_values`.\n\n**BAD:**\n```dart\nvoid f({bool valWithDefault = true, bool? val}) {\n ...\n}\n\nvoid main() {\n f(valWithDefault: true);\n}\n```\n\n**GOOD:**\n```dart\nvoid f({bool valWithDefault = true, bool? val}) {\n ...\n}\n\nvoid main() {\n f(valWithDefault: false);\n f();\n}\n```",
"sinceDartSdk": "2.8"
},
{
"name": "avoid_relative_lib_imports",
"description": "Avoid relative imports for files in `lib/`.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**DO** avoid relative imports for files in `lib/`.\n\nWhen mixing relative and absolute imports it's possible to create confusion\nwhere the same member gets imported in two different ways. An easy way to avoid\nthat is to ensure you have no relative imports that include `lib/` in their\npaths.\n\nYou can also use 'always_use_package_imports' to disallow relative imports\nbetween files within `lib/`.\n\n**BAD:**\n```dart\nimport 'package:foo/bar.dart';\n\nimport '../lib/baz.dart';\n\n...\n```\n\n**GOOD:**\n```dart\nimport 'package:foo/bar.dart';\n\nimport 'baz.dart';\n\n...\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_renaming_method_parameters",
"description": "Don't rename parameters of overridden methods.",
"categories": [
"documentationCommentMaintenance"
],
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**DON'T** rename parameters of overridden methods.\n\nMethods that override another method, but do not have their own documentation\ncomment, will inherit the overridden method's comment when `dart doc` produces\ndocumentation. If the inherited method contains the name of the parameter (in\nsquare brackets), then `dart doc` cannot link it correctly.\n\n**BAD:**\n```dart\nabstract class A {\n m(a);\n}\n\nabstract class B extends A {\n m(b);\n}\n```\n\n**GOOD:**\n```dart\nabstract class A {\n m(a);\n}\n\nabstract class B extends A {\n m(a);\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_return_types_on_setters",
"description": "Avoid return types on setters.",
"categories": [
"brevity",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** return types on setters.\n\nAs setters do not return a value, declaring the return type of one is redundant.\n\n**BAD:**\n```dart\nvoid set speed(int ms);\n```\n\n**GOOD:**\n```dart\nset speed(int ms);\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_returning_null",
"description": "Avoid returning null from members whose return type is bool, double, int, or num.",
"categories": [],
"state": "removed",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "NOTE: This rule is removed in Dart 3.3.0; it is no longer functional.\n\n**AVOID** returning null from members whose return type is bool, double, int,\nor num.\n\nFunctions that return primitive types such as bool, double, int, and num are\ngenerally expected to return non-nullable values. Thus, returning null where a\nprimitive type was expected can lead to runtime exceptions.\n\n**BAD:**\n```dart\nbool getBool() => null;\nnum getNum() => null;\nint getInt() => null;\ndouble getDouble() => null;\n```\n\n**GOOD:**\n```dart\nbool getBool() => false;\nnum getNum() => -1;\nint getInt() => -1;\ndouble getDouble() => -1.0;\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_returning_null_for_future",
"description": "Avoid returning null for Future.",
"categories": [],
"state": "removed",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "NOTE: This rule is removed in Dart 3.3.0; it is no longer functional.\n\n**AVOID** returning null for Future.\n\nIt is almost always wrong to return `null` for a `Future`. Most of the time the\ndeveloper simply forgot to put an `async` keyword on the function.",
"sinceDartSdk": "2.1"
},
{
"name": "avoid_returning_null_for_void",
"description": "Avoid returning `null` for `void`.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** returning `null` for `void`.\n\nIn a large variety of languages `void` as return type is used to indicate that\na function doesn't return anything. Dart allows returning `null` in functions\nwith `void` return type but it also allow using `return;` without specifying any\nvalue. To have a consistent way you should not return `null` and only use an\nempty return.\n\n**BAD:**\n```dart\nvoid f1() {\n return null;\n}\nFuture<void> f2() async {\n return null;\n}\n```\n\n**GOOD:**\n```dart\nvoid f1() {\n return;\n}\nFuture<void> f2() async {\n return;\n}\n```",
"sinceDartSdk": "2.1"
},
{
"name": "avoid_returning_this",
"description": "Avoid returning this from methods just to enable a fluent interface.",
"categories": [
"effectiveDart",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/design#avoid-returning-this-from-methods-just-to-enable-a-fluent-interface):\n\n**AVOID** returning this from methods just to enable a fluent interface.\n\nReturning `this` from a method is redundant; Dart has a cascade operator which\nallows method chaining universally.\n\nReturning `this` is allowed for:\n\n- operators\n- methods with a return type different of the current class\n- methods defined in parent classes / mixins or interfaces\n- methods defined in extensions\n\n**BAD:**\n```dart\nvar buffer = StringBuffer()\n .write('one')\n .write('two')\n .write('three');\n```\n\n**GOOD:**\n```dart\nvar buffer = StringBuffer()\n ..write('one')\n ..write('two')\n ..write('three');\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_setters_without_getters",
"description": "Avoid setters without getters.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "**DON'T** define a setter without a corresponding getter.\n\nDefining a setter without defining a corresponding getter can lead to logical\ninconsistencies. Doing this could allow you to set a property to some value,\nbut then upon observing the property's value, it could easily be different.\n\n**BAD:**\n```dart\nclass Bad {\n int l, r;\n\n set length(int newLength) {\n r = l + newLength;\n }\n}\n```\n\n**GOOD:**\n```dart\nclass Good {\n int l, r;\n\n int get length => r - l;\n\n set length(int newLength) {\n r = l + newLength;\n }\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_shadowing_type_parameters",
"description": "Avoid shadowing type parameters.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "noFix",
"details": "**AVOID** shadowing type parameters.\n\n**BAD:**\n```dart\nclass A<T> {\n void fn<T>() {}\n}\n```\n\n**GOOD:**\n```dart\nclass A<T> {\n void fn<U>() {}\n}\n```",
"sinceDartSdk": "2.1"
},
{
"name": "avoid_single_cascade_in_expression_statements",
"description": "Avoid single cascade in expression statements.",
"categories": [
"brevity",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** single cascade in expression statements.\n\n**BAD:**\n```dart\no..m();\n```\n\n**GOOD:**\n```dart\no.m();\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_slow_async_io",
"description": "Avoid slow asynchronous `dart:io` methods.",
"categories": [
"nonPerformant"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "**AVOID** using the following asynchronous file I/O methods because they are\nmuch slower than their synchronous counterparts.\n\n* `Directory.exists`\n* `Directory.stat`\n* `File.lastModified`\n* `File.exists`\n* `File.stat`\n* `FileSystemEntity.isDirectory`\n* `FileSystemEntity.isFile`\n* `FileSystemEntity.isLink`\n* `FileSystemEntity.type`\n\n**BAD:**\n```dart\nimport 'dart:io';\n\nFuture<Null> someFunction() async {\n var file = File('/path/to/my/file');\n var now = DateTime.now();\n if ((await file.lastModified()).isBefore(now)) print('before'); // LINT\n}\n```\n\n**GOOD:**\n```dart\nimport 'dart:io';\n\nFuture<Null> someFunction() async {\n var file = File('/path/to/my/file');\n var now = DateTime.now();\n if (file.lastModifiedSync().isBefore(now)) print('before'); // OK\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_type_to_string",
"description": "Avoid <Type>.toString() in production code since results may be minified.",
"categories": [
"unintentional"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DO** avoid calls to <Type>.toString() in production code, since it does not\ncontractually return the user-defined name of the Type (or underlying class).\nDevelopment-mode compilers where code size is not a concern use the full name,\nbut release-mode compilers often choose to minify these symbols.\n\n**BAD:**\n```dart\nvoid bar(Object other) {\n if (other.runtimeType.toString() == 'Bar') {\n doThing();\n }\n}\n\nObject baz(Thing myThing) {\n return getThingFromDatabase(key: myThing.runtimeType.toString());\n}\n```\n\n**GOOD:**\n```dart\nvoid bar(Object other) {\n if (other is Bar) {\n doThing();\n }\n}\n\nclass Thing {\n String get thingTypeKey => ...\n}\n\nObject baz(Thing myThing) {\n return getThingFromDatabase(key: myThing.thingTypeKey);\n}\n```",
"sinceDartSdk": "2.12"
},
{
"name": "avoid_types_as_parameter_names",
"description": "Avoid types as parameter names.",
"categories": [
"unintentional"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** using a parameter name that is the same as an existing type.\n\n**BAD:**\n```dart\nm(f(int));\n```\n\n**GOOD:**\n```dart\nm(f(int v));\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_types_on_closure_parameters",
"description": "Avoid annotating types for function expression parameters.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [
"always_specify_types"
],
"sets": [],
"fixStatus": "hasFix",
"details": "**AVOID** annotating types for function expression parameters.\n\nAnnotating types for function expression parameters is usually unnecessary\nbecause the parameter types can almost always be inferred from the context,\nthus making the practice redundant.\n\n**BAD:**\n```dart\nvar names = people.map((Person person) => person.name);\n```\n\n**GOOD:**\n```dart\nvar names = people.map((person) => person.name);\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_unnecessary_containers",
"description": "Avoid unnecessary containers.",
"categories": [
"flutter",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** wrapping widgets in unnecessary containers.\n\nWrapping a widget in `Container` with no other parameters set has no effect\nand makes code needlessly more complex.\n\n**BAD:**\n```dart\nWidget buildRow() {\n return Container(\n child: Row(\n children: <Widget>[\n const MyLogo(),\n const Expanded(\n child: Text('...'),\n ),\n ],\n )\n );\n}\n```\n\n**GOOD:**\n```dart\nWidget buildRow() {\n return Row(\n children: <Widget>[\n const MyLogo(),\n const Expanded(\n child: Text('...'),\n ),\n ],\n );\n}\n```",
"sinceDartSdk": "2.7"
},
{
"name": "avoid_unstable_final_fields",
"description": "Avoid overriding a final field to return different values if called multiple times.",
"categories": [],
"state": "removed",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "This rule has been removed.",
"sinceDartSdk": "3.3"
},
{
"name": "avoid_unused_constructor_parameters",
"description": "Avoid defining unused parameters in constructors.",
"categories": [
"unintentional"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**AVOID** defining unused parameters in constructors.\n\n**BAD:**\n```dart\nclass BadOne {\n BadOne(int unusedParameter, [String unusedPositional]);\n}\n\nclass BadTwo {\n int c;\n\n BadTwo(int a, int b, int x) {\n c = a + b;\n }\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "avoid_void_async",
"description": "Avoid `async` functions that return `void`.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** mark `async` functions as returning `Future<void>`.\n\nWhen declaring an `async` method or function which does not return a value,\ndeclare that it returns `Future<void>` and not just `void`.\n\n**BAD:**\n```dart\nvoid f() async {}\nvoid f2() async => null;\n```\n\n**GOOD:**\n```dart\nFuture<void> f() async {}\nFuture<void> f2() async => null;\n```\n\n**EXCEPTION:**\n\nAn exception is made for top-level `main` functions, where the `Future`\nannotation *can* (and generally should) be dropped in favor of `void`.\n\n**GOOD:**\n```dart\nFuture<void> f() async {}\n\nvoid main() async {\n await f();\n}\n```",
"sinceDartSdk": "2.1"
},
{
"name": "avoid_web_libraries_in_flutter",
"description": "Avoid using web-only libraries outside Flutter web plugin packages.",
"categories": [
"errorProne",
"flutter",
"web"
],
"state": "stable",
"incompatible": [],
"sets": [
"flutter"
],
"fixStatus": "noFix",
"details": "**AVOID** using web libraries, `dart:html`, `dart:js` and\n`dart:js_util` in Flutter packages that are not web plugins. These libraries are\nnot supported outside of a web context; functionality that depends on them will\nfail at runtime in Flutter mobile, and their use is generally discouraged in\nFlutter web.\n\nWeb library access *is* allowed in:\n\n* plugin packages that declare `web` as a supported context\n\notherwise, imports of `dart:html`, `dart:js` and `dart:js_util` are disallowed.",
"sinceDartSdk": "2.6"
},
{
"name": "await_only_futures",
"description": "Await only futures.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** using await on anything which is not a future.\n\nAwait is allowed on the types: `Future<X>`, `FutureOr<X>`, `Future<X>?`,\n`FutureOr<X>?` and `dynamic`.\n\nFurther, using `await null` is specifically allowed as a way to introduce a\nmicrotask delay.\n\n**BAD:**\n```dart\nmain() async {\n print(await 23);\n}\n```\n\n**GOOD:**\n```dart\nmain() async {\n await null; // If a delay is really intended.\n print(23);\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "camel_case_extensions",
"description": "Name extensions using UpperCamelCase.",
"categories": [
"effectiveDart",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "noFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/style#do-name-extensions-using-uppercamelcase):\n\n**DO** name extensions using `UpperCamelCase`.\n\nExtensions should capitalize the first letter of each word (including\nthe first word), and use no separators.\n\n**GOOD:**\n```dart\nextension MyFancyList<T> on List<T> {\n // ...\n}\n\nextension SmartIterable<T> on Iterable<T> {\n // ...\n}\n```",
"sinceDartSdk": "2.6"
},
{
"name": "camel_case_types",
"description": "Name types using UpperCamelCase.",
"categories": [
"effectiveDart",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "noFix",
"details": "From [Effective Dart](https://dart.dev/effective-dart/style#do-name-types-using-uppercamelcase):\n\n**DO** name types using UpperCamelCase.\n\nClasses and typedefs should capitalize the first letter of each word (including\nthe first word), and use no separators.\n\n**GOOD:**\n```dart\nclass SliderMenu {\n // ...\n}\n\nclass HttpRequest {\n // ...\n}\n\ntypedef num Adder(num x, num y);\n```",
"sinceDartSdk": "2.0"
},
{
"name": "cancel_subscriptions",
"description": "Cancel instances of `dart:async` `StreamSubscription`.",
"categories": [
"errorProne",
"memoryLeaks"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DO** invoke `cancel` on instances of `dart:async` `StreamSubscription`.\n\nCancelling instances of StreamSubscription prevents memory leaks and unexpected\nbehavior.\n\n**BAD:**\n```dart\nclass A {\n StreamSubscription _subscriptionA; // LINT\n void init(Stream stream) {\n _subscriptionA = stream.listen((_) {});\n }\n}\n```\n\n**BAD:**\n```dart\nvoid someFunction() {\n StreamSubscription _subscriptionF; // LINT\n}\n```\n\n**GOOD:**\n```dart\nclass B {\n StreamSubscription _subscriptionB; // OK\n void init(Stream stream) {\n _subscriptionB = stream.listen((_) {});\n }\n\n void dispose(filename) {\n _subscriptionB.cancel();\n }\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunctionOK() {\n StreamSubscription _subscriptionB; // OK\n _subscriptionB.cancel();\n}\n```\n\n**Known limitations**\n\nThis rule does not track all patterns of StreamSubscription instantiations and\ncancellations. See [linter#317](https://github.com/dart-lang/linter/issues/317)\nfor more information.",
"sinceDartSdk": "2.0"
},
{
"name": "cascade_invocations",
"description": "Cascade consecutive method invocations on the same reference.",
"categories": [
"brevity",
"languageFeatureUsage",
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** Use the cascading style when successively invoking methods on the same\nreference.\n\n**BAD:**\n```dart\nSomeClass someReference = SomeClass();\nsomeReference.firstMethod();\nsomeReference.secondMethod();\n```\n\n**BAD:**\n```dart\nSomeClass someReference = SomeClass();\n...\nsomeReference.firstMethod();\nsomeReference.aProperty = value;\nsomeReference.secondMethod();\n```\n\n**GOOD:**\n```dart\nSomeClass someReference = SomeClass()\n ..firstMethod()\n ..aProperty = value\n ..secondMethod();\n```\n\n**GOOD:**\n```dart\nSomeClass someReference = SomeClass();\n...\nsomeReference\n ..firstMethod()\n ..aProperty = value\n ..secondMethod();\n```",
"sinceDartSdk": "2.0"
},
{
"name": "cast_nullable_to_non_nullable",
"description": "Don't cast a nullable value to a non nullable type.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DON'T** cast a nullable value to a non nullable type. This hides a null check\nand most of the time it is not what is expected.\n\n**BAD:**\n```dart\nclass A {}\nclass B extends A {}\n\nA? a;\nvar v = a as B;\nvar v = a as A;\n```\n\n**GOOD:**\n```dart\nclass A {}\nclass B extends A {}\n\nA? a;\nvar v = a! as B;\nvar v = a!;\n```",
"sinceDartSdk": "2.12"
},
{
"name": "close_sinks",
"description": "Close instances of `dart:core` `Sink`.",
"categories": [
"errorProne",
"memoryLeaks"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DO** invoke `close` on instances of `dart:core` `Sink`.\n\nClosing instances of Sink prevents memory leaks and unexpected behavior.\n\n**BAD:**\n```dart\nclass A {\n IOSink _sinkA;\n void init(filename) {\n _sinkA = File(filename).openWrite(); // LINT\n }\n}\n```\n\n**BAD:**\n```dart\nvoid someFunction() {\n IOSink _sinkF; // LINT\n}\n```\n\n**GOOD:**\n```dart\nclass B {\n IOSink _sinkB;\n void init(filename) {\n _sinkB = File(filename).openWrite(); // OK\n }\n\n void dispose(filename) {\n _sinkB.close();\n }\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunctionOK() {\n IOSink _sinkFOK; // OK\n _sinkFOK.close();\n}\n```\n\n**Known limitations**\n\nThis rule does not track all patterns of Sink instantiations and\nclosures. See [linter#1381](https://github.com/dart-lang/linter/issues/1381)\nfor more information.",
"sinceDartSdk": "2.0"
},
{
"name": "collection_methods_unrelated_type",
"description": "Invocation of various collection methods with arguments of unrelated types.",
"categories": [
"unintentional"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "noFix",
"details": "**DON'T** invoke certain collection method with an argument with an unrelated\ntype.\n\nDoing this will invoke `==` on the collection's elements and most likely will\nreturn `false`.\n\nAn argument passed to a collection method should relate to the collection type\nas follows:\n\n* an argument to `Iterable<E>.contains` should be related to `E`\n* an argument to `List<E>.remove` should be related to `E`\n* an argument to `Map<K, V>.containsKey` should be related to `K`\n* an argument to `Map<K, V>.containsValue` should be related to `V`\n* an argument to `Map<K, V>.remove` should be related to `K`\n* an argument to `Map<K, V>.[]` should be related to `K`\n* an argument to `Queue<E>.remove` should be related to `E`\n* an argument to `Set<E>.lookup` should be related to `E`\n* an argument to `Set<E>.remove` should be related to `E`\n\n**BAD:**\n```dart\nvoid someFunction() {\n var list = <int>[];\n if (list.contains('1')) print('someFunction'); // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid someFunction() {\n var set = <int>{};\n set.remove('1'); // LINT\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction() {\n var list = <int>[];\n if (list.contains(1)) print('someFunction'); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction() {\n var set = <int>{};\n set.remove(1); // OK\n}\n```",
"sinceDartSdk": "2.19"
},
{
"name": "combinators_ordering",
"description": "Sort combinator names alphabetically.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** sort combinator names alphabetically.\n\n**BAD:**\n```dart\nimport 'a.dart' show B, A hide D, C;\nexport 'a.dart' show B, A hide D, C;\n```\n\n**GOOD:**\n```dart\nimport 'a.dart' show A, B hide C, D;\nexport 'a.dart' show A, B hide C, D;\n```",
"sinceDartSdk": "2.19"
},
{
"name": "comment_references",
"description": "Only reference in-scope identifiers in doc comments.",
"categories": [
"documentationCommentMaintenance"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** reference only in-scope identifiers in doc comments.\n\nIf you surround identifiers like variable, method, or type names in square\nbrackets, then tools like your IDE and\n[`dart doc`](https://dart.dev/tools/dart-doc) can link to them. For this to\nwork, ensure that all identifiers in docs wrapped in brackets are in scope.\n\nFor example, assuming `outOfScopeId` is out of scope:\n\n**BAD:**\n```dart\n/// Returns whether [value] is larger than [outOfScopeId].\nbool isOutOfRange(int value) { ... }\n```\n\n**GOOD:**\n```dart\n/// Returns the larger of [a] or [b].\nint max_int(int a, int b) { ... }\n```\n\nNote that the square bracket comment format is designed to allow comments to\nrefer to declarations using a fairly natural format but does not allow\n*arbitrary expressions*. In particular, code references within square brackets\ncan consist of any of the following:\n\n- A bare identifier which is in-scope for the comment (see the spec for what is\n \"in-scope\" in doc comments). Examples include `[print]` and `[Future]`.\n- Two identifiers separated by a period (a \"prefixed identifier\"), such that the\n first identifier acts as a namespacing identifier, such as a class property\n name or method name prefixed by the containing class's name, or a top-level\n identifier prefixed by an import prefix. Examples include `[Future.new]` (an\n unnamed constructor), `[Future.value]` (a constructor), `[Future.wait]` (a\n static method), `[Future.then]` (an instance method), `[math.max]` (given that\n 'dart:async' is imported with a `max` prefix).\n- A prefixed identifier followed by a pair of parentheses, used to disambiguate\n named constructors from instance members (whose names are allowed to collide).\n Examples include `[Future.value()]`.\n- Three identifiers separated by two periods, such that the first identifier is\n an import prefix name, the second identifier is a top-level element like a\n class or an extension, and the third identifier is a member of that top-level\n element. Examples include `[async.Future.then]` (given that 'dart:async' is\n imported with an `async` prefix).\n\n**Known limitations**\n\nThe `comment_references` lint rule aligns with the Dart analyzer's notion of\ncomment references, which is occasionally distinct from Dartdoc's notion of\ncomment references. The lint rule may report comment references which Dartdoc\ncan resolve, even though the analyzer cannot. See\n[linter#1142](https://github.com/dart-lang/linter/issues/1142) for more\ninformation.",
"sinceDartSdk": "2.0"
},
{
"name": "conditional_uri_does_not_exist",
"description": "Missing conditional import.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DON'T** reference files that do not exist in conditional imports.\n\nCode may fail at runtime if the condition evaluates such that the missing file\nneeds to be imported.\n\n**BAD:**\n```dart\nimport 'file_that_does_exist.dart'\n if (condition) 'file_that_does_not_exist.dart';\n```\n\n**GOOD:**\n```dart\nimport 'file_that_does_exist.dart'\n if (condition) 'file_that_also_does_exist.dart';\n```",
"sinceDartSdk": "2.16"
},
{
"name": "constant_identifier_names",
"description": "Prefer using lowerCamelCase for constant names.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**PREFER** using lowerCamelCase for constant names.\n\nIn new code, use `lowerCamelCase` for constant variables, including enum values.\n\nIn existing code that uses `ALL_CAPS_WITH_UNDERSCORES` for constants, you may\ncontinue to use all caps to stay consistent.\n\n**BAD:**\n```dart\nconst PI = 3.14;\nconst kDefaultTimeout = 1000;\nfinal URL_SCHEME = RegExp('^([a-z]+):');\n\nclass Dice {\n static final NUMBER_GENERATOR = Random();\n}\n```\n\n**GOOD:**\n```dart\nconst pi = 3.14;\nconst defaultTimeout = 1000;\nfinal urlScheme = RegExp('^([a-z]+):');\n\nclass Dice {\n static final numberGenerator = Random();\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "control_flow_in_finally",
"description": "Avoid control flow in `finally` blocks.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "noFix",
"details": "**AVOID** control flow leaving `finally` blocks.\n\nUsing control flow in `finally` blocks will inevitably cause unexpected behavior\nthat is hard to debug.\n\n**BAD:**\n```dart\nclass BadReturn {\n double nonCompliantMethod() {\n try {\n return 1 / 0;\n } catch (e) {\n print(e);\n } finally {\n return 1.0; // LINT\n }\n }\n}\n```\n\n**BAD:**\n```dart\nclass BadContinue {\n double nonCompliantMethod() {\n for (var o in [1, 2]) {\n try {\n print(o / 0);\n } catch (e) {\n print(e);\n } finally {\n continue; // LINT\n }\n }\n return 1.0;\n }\n}\n```\n\n**BAD:**\n```dart\nclass BadBreak {\n double nonCompliantMethod() {\n for (var o in [1, 2]) {\n try {\n print(o / 0);\n } catch (e) {\n print(e);\n } finally {\n break; // LINT\n }\n }\n return 1.0;\n }\n}\n```\n\n**GOOD:**\n```dart\nclass Ok {\n double compliantMethod() {\n var i = 5;\n try {\n i = 1 / 0;\n } catch (e) {\n print(e); // OK\n }\n return i;\n }\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "curly_braces_in_flow_control_structures",
"description": "DO use curly braces for all flow control structures.",
"categories": [
"errorProne"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**DO** use curly braces for all flow control structures.\n\nDoing so avoids the [dangling else](https://en.wikipedia.org/wiki/Dangling_else)\nproblem.\n\n**BAD:**\n```dart\nif (overflowChars != other.overflowChars)\n return overflowChars < other.overflowChars;\n```\n\n**GOOD:**\n```dart\nif (isWeekDay) {\n print('Bike to work!');\n} else {\n print('Go dancing or read a book!');\n}\n```\n\nThere is one exception to this: an `if` statement with no `else` clause where\nthe entire `if` statement (including the condition and the body) fits in one\nline. In that case, you may leave off the braces if you prefer:\n\n**GOOD:**\n```dart\nif (arg == null) return defaultValue;\n```\n\nIf the body wraps to the next line, though, use braces:\n\n**GOOD:**\n```dart\nif (overflowChars != other.overflowChars) {\n return overflowChars < other.overflowChars;\n}\n```",
"sinceDartSdk": "2.0"
},
{
"name": "dangling_library_doc_comments",
"description": "Attach library doc comments to library directives.",
"categories": [
"documentationCommentMaintenance"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "Attach library doc comments (with `///`) to library directives, rather than\nleaving them dangling near the top of a library.\n\n**BAD:**\n```dart\n/// This is a great library.\nimport 'package:math';\n```\n\n```dart\n/// This is a great library.\n\nclass C {}\n```\n\n**GOOD:**\n```dart\n/// This is a great library.\nlibrary;\n\nimport 'package:math';\n\nclass C {}\n```\n\n**NOTE:** An unnamed library, like `library;` above, is only supported in Dart\n2.19 and later. Code which might run in earlier versions of Dart will need to\nprovide a name in the `library` directive.",
"sinceDartSdk": "2.19"
},
{
"name": "depend_on_referenced_packages",
"description": "Depend on referenced packages.",
"categories": [
"pub"
],
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "needsFix",
"details": "**DO** depend on referenced packages.\n\nWhen importing a package, add a dependency on it to your pubspec.\n\nDepending explicitly on packages that you reference ensures they will always\nexist and allows you to put a dependency constraint on them to guard you\nagainst breaking changes.\n\nWhether this should be a regular dependency or dev_dependency depends on if it\nis referenced from a public file (one under either `lib` or `bin`), or some\nother private file.\n\n**BAD:**\n```dart\nimport 'package:a/a.dart';\n```\n\n```yaml\ndependencies:\n```\n\n**GOOD:**\n```dart\nimport 'package:a/a.dart';\n```\n\n```yaml\ndependencies:\n a: ^1.0.0\n```",
"sinceDartSdk": "2.14"
},
{
"name": "deprecated_consistency",
"description": "Missing deprecated annotation.",
"categories": [
"style"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "**DO** apply `@Deprecated()` consistently:\n\n- if a class is deprecated, its constructors should also be deprecated.\n- if a field is deprecated, the constructor parameter pointing to it should also\n be deprecated.\n- if a constructor parameter pointing to a field is deprecated, the field should\n also be deprecated.\n\n**BAD:**\n```dart\n@deprecated\nclass A {\n A();\n}\n\nclass B {\n B({this.field});\n @deprecated\n Object field;\n}\n```\n\n**GOOD:**\n```dart\n@deprecated\nclass A {\n @deprecated\n A();\n}\n\nclass B {\n B({@deprecated this.field});\n @deprecated\n Object field;\n}\n\nclass C extends B {\n C({@deprecated super.field});\n}\n```",
"sinceDartSdk": "2.13"
},
{
"name": "deprecated_member_use_from_same_package",
"description": "Avoid using deprecated elements from within the package in which they are declared.",
"categories": [
"languageFeatureUsage"
],
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",