-
Notifications
You must be signed in to change notification settings - Fork 170
/
rules.json
2831 lines (2831 loc) · 211 KB
/
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_use_package_imports",
"description": "Avoid relative imports for files in `lib/`.",
"group": "errors",
"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```\n\n",
"sinceDartSdk": "2.10.0"
},
{
"name": "avoid_dynamic_calls",
"description": "Avoid method calls or property accesses on a \"dynamic\" target.",
"group": "errors",
"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 \"NullError\" 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\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```\n\n",
"sinceDartSdk": "2.12.0"
},
{
"name": "avoid_empty_else",
"description": "Avoid empty else statements.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** empty else statements.\n\n**BAD:**\n```dart\nif (x > y)\n print(\"1\");\nelse ;\n print(\"2\");\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_print",
"description": "Avoid `print` calls in production code.",
"group": "errors",
"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```\n",
"sinceDartSdk": "2.5.0"
},
{
"name": "avoid_relative_lib_imports",
"description": "Avoid relative imports for files in `lib/`.",
"group": "errors",
"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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_returning_null_for_future",
"description": "Avoid returning null for Future.",
"group": "errors",
"state": "deprecated",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**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.\n\n",
"sinceDartSdk": "2.1.1"
},
{
"name": "avoid_slow_async_io",
"description": "Avoid slow async `dart:io` methods.",
"group": "errors",
"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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_type_to_string",
"description": "Avoid <Type>.toString() in production code since results may be minified.",
"group": "errors",
"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```\n\n",
"sinceDartSdk": "2.12.0"
},
{
"name": "avoid_types_as_parameter_names",
"description": "Avoid types as parameter names.",
"group": "errors",
"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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_web_libraries_in_flutter",
"description": "Avoid using web-only libraries outside Flutter web plugin packages.",
"group": "errors",
"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 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.\n",
"sinceDartSdk": "2.6.0"
},
{
"name": "cancel_subscriptions",
"description": "Cancel instances of dart.async.StreamSubscription.",
"group": "errors",
"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",
"sinceDartSdk": "2.0.0"
},
{
"name": "close_sinks",
"description": "Close instances of `dart.core.Sink`.",
"group": "errors",
"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",
"sinceDartSdk": "2.0.0"
},
{
"name": "collection_methods_unrelated_type",
"description": "Invocation of various collection methods with arguments of unrelated types.",
"group": "errors",
"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```\n\n",
"sinceDartSdk": "2.19.0"
},
{
"name": "comment_references",
"description": "Only reference in scope identifiers in doc comments.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DO** reference only in scope identifiers in doc comments.\n\nIf you surround things like variable, method, or type names in square brackets,\nthen [`dart doc`](https://dart.dev/tools/dart-doc) will look\nup the name and link to its docs. For this all to work, ensure that all\nidentifiers in docs wrapped in brackets are in scope.\n\nFor example, assuming `outOfScopeId` is out of scope:\n\n**BAD:**\n```dart\n/// Return true if [value] is larger than [outOfScopeId].\nbool isOutOfRange(int value) { ... }\n```\n\n**GOOD:**\n```dart\n/// Return 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\ncomments to refer to declarations using a fairly natural format\nbut does not allow *arbitrary expressions*. In particular, code\nreferences within square brackets can consist of either\n\n- a single identifier where the identifier is any identifier in scope for the comment (see the spec for what is in scope in doc comments),\n- two identifiers separated by a period where the first identifier is the name of a class that is in scope and the second is the name of a member declared in the class,\n- a single identifier followed by a pair of parentheses where the identifier is the name of a class that is in scope (used to refer to the unnamed constructor for the class), or\n- two identifiers separated by a period and followed by a pair of parentheses where the first identifier is the name of a class that is in scope and the second is the name of a named constructor (not strictly necessary, but allowed for consistency).\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "control_flow_in_finally",
"description": "Avoid control flow in finally blocks.",
"group": "errors",
"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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "deprecated_member_use_from_same_package",
"description": "Avoid using deprecated elements from within the package in which they are declared.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "Elements that are annotated with `@Deprecated` should not be referenced from\nwithin the package in which they are declared.\n\n**AVOID** using deprecated elements.\n\n...\n\n**BAD:**\n```dart\n// Declared in one library:\nclass Foo {\n @Deprecated(\"Use 'm2' instead\")\n void m1() {}\n\n void m2({\n @Deprecated('This is an old parameter') int? p,\n })\n}\n\n@Deprecated('Do not use')\nint x = 0;\n\n// In the same or another library, but within the same package:\nvoid m(Foo foo) {\n foo.m1();\n foo.m2(p: 7);\n x = 1;\n}\n```\n\nDeprecated elements can be used from within _other_ deprecated elements, in\norder to allow for the deprecation of a collection of APIs together as one unit.\n\n**GOOD:**\n```dart\n// Declared in one library:\nclass Foo {\n @Deprecated(\"Use 'm2' instead\")\n void m1() {}\n\n void m2({\n @Deprecated('This is an old parameter') int? p,\n })\n}\n\n@Deprecated('Do not use')\nint x = 0;\n\n// In the same or another library, but within the same package:\n@Deprecated('Do not use')\nvoid m(Foo foo) {\n foo.m1();\n foo.m2(p: 7);\n x = 1;\n}\n```\n",
"sinceDartSdk": "3.0.0"
},
{
"name": "diagnostic_describe_all_properties",
"description": "DO reference all public properties in debug methods.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DO** reference all public properties in `debug` method implementations.\n\nImplementers of `Diagnosticable` should reference all public properties in\na `debugFillProperties(...)` or `debugDescribeChildren(...)` method\nimplementation to improve debuggability at runtime.\n\nPublic properties are defined as fields and getters that are\n\n* not package-private (e.g., prefixed with `_`)\n* not `static` or overriding\n* not themselves `Widget`s or collections of `Widget`s\n\nIn addition, the \"debug\" prefix is treated specially for properties in Flutter.\nFor the purposes of diagnostics, a property `foo` and a prefixed property\n`debugFoo` are treated as effectively describing the same property and it is\nsufficient to refer to one or the other.\n\n**BAD:**\n```dart\nclass Absorber extends Widget {\n bool get absorbing => _absorbing;\n bool _absorbing;\n bool get ignoringSemantics => _ignoringSemantics;\n bool _ignoringSemantics;\n @override\n void debugFillProperties(DiagnosticPropertiesBuilder properties) {\n super.debugFillProperties(properties);\n properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));\n // Missing reference to ignoringSemantics\n }\n}\n```\n\n**GOOD:**\n```dart\nclass Absorber extends Widget {\n bool get absorbing => _absorbing;\n bool _absorbing;\n bool get ignoringSemantics => _ignoringSemantics;\n bool _ignoringSemantics;\n @override\n void debugFillProperties(DiagnosticPropertiesBuilder properties) {\n super.debugFillProperties(properties);\n properties.add(DiagnosticsProperty<bool>('absorbing', absorbing));\n properties.add(DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics));\n }\n}\n```\n",
"sinceDartSdk": "2.3.0"
},
{
"name": "discarded_futures",
"description": "Don't invoke asynchronous functions in non-async blocks.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "Making asynchronous calls in non-`async` functions is usually the sign of a\nprogramming error. In general these functions should be marked `async` and such\nfutures should likely be awaited (as enforced by `unawaited_futures`).\n\n**DON'T** invoke asynchronous functions in non-`async` blocks.\n\n**BAD:**\n```dart\nvoid recreateDir(String path) {\n deleteDir(path);\n createDir(path);\n}\n\nFuture<void> deleteDir(String path) async {}\n\nFuture<void> createDir(String path) async {}\n```\n\n**GOOD:**\n```dart\nFuture<void> recreateDir(String path) async {\n await deleteDir(path);\n await createDir(path);\n}\n\nFuture<void> deleteDir(String path) async {}\n\nFuture<void> createDir(String path) async {}\n```\n",
"sinceDartSdk": "2.18.0"
},
{
"name": "empty_statements",
"description": "Avoid empty statements.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**AVOID** empty statements.\n\nEmpty statements almost always indicate a bug.\n\nFor example,\n\n**BAD:**\n```dart\nif (complicated.expression.foo());\n bar();\n```\n\nFormatted with `dart format` the bug becomes obvious:\n\n```dart\nif (complicated.expression.foo()) ;\nbar();\n\n```\n\nBetter to avoid the empty statement altogether.\n\n**GOOD:**\n```dart\nif (complicated.expression.foo())\n bar();\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "hash_and_equals",
"description": "Always override `hashCode` if overriding `==`.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**DO** override `hashCode` if overriding `==` and prefer overriding `==` if\noverriding `hashCode`.\n\nEvery object in Dart has a `hashCode`. Both the `==` operator and the\n`hashCode` property of objects must be consistent in order for a common hash\nmap implementation to function properly. Thus, when overriding `==`, the\n`hashCode` should also be overridden to maintain consistency. Similarly, if\n`hashCode` is overridden, `==` should be also.\n\n**BAD:**\n```dart\nclass Bad {\n final int value;\n Bad(this.value);\n\n @override\n bool operator ==(Object other) => other is Bad && other.value == value;\n}\n```\n\n**GOOD:**\n```dart\nclass Better {\n final int value;\n Better(this.value);\n\n @override\n bool operator ==(Object other) =>\n other is Better &&\n other.runtimeType == runtimeType &&\n other.value == value;\n\n @override\n int get hashCode => value.hashCode;\n}\n```\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "implicit_reopen",
"description": "Don't implicitly reopen classes.",
"group": "errors",
"state": "experimental",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "Using an `interface`, `base`, `final`, or `sealed` modifier on a class,\nor a `base` modifier on a mixin,\nauthors can control whether classes and mixins allow being implemented,\nextended, and/or mixed in from outside of the library where they're defined.\nIn some cases, it's possible for an author to inadvertently relax these controls\nand implicitly \"reopen\" a class. (A similar reopening cannot occur with a mixin.)\n\nThis lint guards against unintentionally reopening a class by requiring such\ncases to be made explicit with the \n[`@reopen`](https://pub.dev/documentation/meta/latest/meta/reopen-constant.html)\nannotation in `package:meta`.\n\n**BAD:**\n```dart\ninterface class I {}\n\nclass C extends I {} // LINT\n```\n\n**GOOD:**\n```dart\ninterface class I {}\n\nfinal class C extends I {}\n```\n\n```dart\ninterface class I {}\n\nfinal class C extends I {}\n```\n\n```dart\nimport 'package:meta/meta.dart';\n\ninterface class I {}\n\n@reopen\nclass C extends I {}\n```\n",
"sinceDartSdk": "3.0.0"
},
{
"name": "invalid_case_patterns",
"description": "Use case expressions that are valid in Dart 3.0.",
"group": "errors",
"state": "experimental",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "Some case expressions that are valid in Dart 2.19 and below will become an error\nor have changed semantics when a library is upgraded to 3.0. This lint flags\nthose expressions in order to ease migration to Dart 3.0.\n\nSome valid switch cases in 2.19 will become compile errors in Dart 3.0:\n\n* Set literals\n* Parenthesized expressions\n* Calls to `identical()`.\n* Unary operator expressions `!`, `-`, or `~` (except for `-` before an integer\n literal, which is a valid pattern and is fine)\n* Binary operator expressions `!=`, `==`, `&`, `|`, `^`, `~/`, `>>`, `>>>`,\n `<<`, `+`, `-`, `*`, `/`, `%`, `<`, `<=`, `>`, `>=`, `??`.\n* Conditional operator `?:`\n* `.length` calls on strings\n* `is` and `is!` expressions\n\nExamples of all of them:\n\n```dart\nswitch (obj) {\n case {1}: // Set literal.\n case (1): // Parenthesized expression.\n case identical(1, 2): // `identical()` call.\n case -pi: // Unary operator.\n case 1 + 2: // Binary operator.\n case true ? 1 : 2: // Conditional operator.\n case 'hi'.length: // .length call.\n case i is int: // is expression.\n}\n```\n\nSome valid switch cases in 2.19 are also syntactically valid patterns, but the\npattern matching behavior may be different from the current constant equality\nbehavior. They are:\n\n**List and map literals.** A list or map literal can appear as a constant in a\ncase:\n\n```dart\nswitch (obj) {\n case [1, 2]: ...\n case {'k': 'v'}: ...\n}\n```\n\nCurrently, the case will only match if the incoming value has the same identity\nas the constant. So:\n\n```dart\ntest(List<int> list) {\n switch (list) {\n case [1, 2]: print('Matched'); break;\n default: print('Did not match'); break;\n }\n}\n\nmain() {\n test(const [1, 2]); // Prints \"Matched\".\n test([1, 2]); // Prints \"Did not match\".\n}\n```\n\nWith patterns, a list or map literal becomes a list or map pattern. The pattern\ndestructures the incoming object and matches if the subpatterns all match. In\nother words, list and map pattern match using something more like deep equality.\n\nWith Dart 3.0, the above program prints \"Matched\" twice.\n\n**Constant constructor calls.** Similar to collections, you can construct a\nconstant instance of a class in a case:\n\n```dart\nclass Point {\n final int x;\n final int y;\n const Point({this.x, this.y});\n}\n\ntest(Point p) {\n switch (p) {\n case Point(x: 1, y: 2): print('Matched'); break;\n default: print('Did not match'); break;\n }\n}\n\nmain() {\n test(const Point(1, 2)); // Prints \"Matched\".\n test(Point(1, 2)); // Prints \"Did not match\".\n}\n```\n\nAgain, like collections, the case currently only matches if the incoming value\nhas the same identity. With patterns, the `Point(...)` syntax becomes an object\npattern that destructures the incoming point, calls the `x` and `y` getters on\nit and then matches the results of those against the corresponding subpatterns.\n\nIn this example, it will print \"Matched\" twice.\n\nNote that object patterns only support named fields. So any constant constructor\nin a case today that has positional arguments will become a compile-time error\nwhen parsed as a pattern. A constant constructor call with no arguments is a\nvalid object pattern and only does a type test:\n\n```dart\nclass Thing {\n const Thing();\n}\n\ntest(Thing t) {\n switch (t) {\n case Thing(): print('Matched'); break;\n default: print('Did not match'); break;\n }\n}\n\nmain() {\n test(const Thing()); // Prints \"Matched\".\n test(Thing()); // Prints \"Did not match\".\n}\n```\n\nWhen interpreted as a pattern, this prints \"Matched\" twice.\n\n**Wildcards.** Today, you can have a constant named `_`:\n\n```dart\ntest(int n) {\n const _ = 3;\n switch (n) {\n case _: print('Matched'); break;\n default: print('Did not match'); break;\n }\n}\n\nmain() {\n test(3); // Prints \"Matched\".\n test(5); // Prints \"Did not match\".\n}\n```\n\nWith patterns, the identifier `_` is treated as a pattern that matches all \nvalues, so this prints \"Matched\" twice.\n\n**Logic operators.** The logic operators `&&` and `||` are valid constant\nexpressions and also valid patterns. As a constant expression, they simply\nevaluate the expression to a boolean and match if the incoming value is equal to\nthat boolean value. So:\n\n```dart\ntest(bool b) {\n switch (b) {\n case true && false: print('Matched'); break;\n default: print('Did not match'); break;\n }\n}\n\nmain() {\n test(false); // Prints \"Matched\".\n test(true); // Prints \"Did not match\".\n}\n```\n\nWith Dart 3.0, these become patterns. The above example prints \"Did not match\"\ntwice because no boolean value can be both true and false.\n\nMany of invalid cases can be mechanically changed to something that is valid\nboth in Dart today and valid and means the same in Dart 3.0.\n\n**Parenthesized expressions:** Provided the inner expression is one that's not\nbroken in Dart 3.0, just discard the parentheses.\n\n**List literals, map literals, set literals, and constant constructor calls:**\nPut `const` before the literal or call. This turns it into a constant pattern\nwhich preserves the current behavior:\n\n**BAD:**\n\n```dart\ncase [1, 2]:\ncase {'k': 'v'}:\ncase {1, 2}:\ncase Point(1, 2):\n```\n\n**GOOD:**\n\n```dart\ncase const [1, 2]:\ncase const {'k': 'v'}:\ncase const {1, 2}:\ncase const Point(1, 2):\n```\n\n* **Wildcards:** Rename the constant from `_` to something else. Since the name\nis private, this can be done locally in the library without affecting other\ncode.\n\n* **Everything else:** For any other invalid expression, you have to hoist the\nexpression out into a new named constant. For example, if you have code like\nthis:\n\n\n**BAD:**\n\n```dart\nswitch (n) {\n case 1 + 2: ...\n}\n```\n\nIt can be fixed by changing it to:\n\n**GOOD:**\n\n ```dart\nconst three = 1 + 2;\n\nswitch (n) {\n case three: ...\n}\n```\n",
"sinceDartSdk": "3.0.0"
},
{
"name": "invariant_booleans",
"description": "Conditions should not unconditionally evaluate to `true` or to `false`.",
"group": "errors",
"state": "removed",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DON'T** test for conditions that can be inferred at compile time or test the\nsame condition twice.\n\nConditional statements using a condition which cannot be anything but `false`\nhave the effect of making blocks of code non-functional. If the condition\ncannot evaluate to anything but `true`, the conditional statement is completely\nredundant, and makes the code less readable.\nIt is quite likely that the code does not match the programmer's intent.\nEither the condition should be removed or it should be updated so that it does\nnot always evaluate to `true` or `false` and does not perform redundant tests.\nThis rule will hint to the test conflicting with the linted one.\n\n**BAD:**\n```dart\n// foo can't be both equal and not equal to bar in the same expression\nif(foo == bar && something && foo != bar) {...}\n```\n\n**BAD:**\n```dart\nvoid compute(int foo) {\n if (foo == 4) {\n doSomething();\n // we know foo is equal to 4 at this point, so the next condition is always false\n if (foo > 4) {...}\n ...\n }\n ...\n}\n```\n\n**BAD:**\n```dart\nvoid compute(bool foo) {\n if (foo) {\n return;\n }\n doSomething();\n // foo is always false here\n if (foo){...}\n ...\n}\n```\n\n**GOOD:**\n```dart\nvoid nestedOK() {\n if (foo == bar) {\n foo = baz;\n if (foo != bar) {...}\n }\n}\n```\n\n**GOOD:**\n```dart\nvoid nestedOk2() {\n if (foo == bar) {\n return;\n }\n\n foo = baz;\n if (foo == bar) {...} // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid nestedOk5() {\n if (foo != null) {\n if (bar != null) {\n return;\n }\n }\n\n if (bar != null) {...} // OK\n}\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "iterable_contains_unrelated_type",
"description": "Invocation of Iterable<E>.contains with references of unrelated types.",
"group": "errors",
"state": "deprecated",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DON'T** invoke `contains` on `Iterable` with an instance of different type\nthan the parameter type.\n\nDoing this will invoke `==` on its elements and most likely will return `false`.\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 someFunction3() {\n List<int> list = <int>[];\n if (list.contains('1')) print('someFunction3'); // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid someFunction8() {\n List<DerivedClass2> list = <DerivedClass2>[];\n DerivedClass3 instance;\n if (list.contains(instance)) print('someFunction8'); // LINT\n}\n```\n\n**BAD:**\n```dart\nabstract class SomeIterable<E> implements Iterable<E> {}\n\nabstract class MyClass implements SomeIterable<int> {\n bool badMethod(String thing) => this.contains(thing); // LINT\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction10() {\n var list = [];\n if (list.contains(1)) print('someFunction10'); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction1() {\n var list = <int>[];\n if (list.contains(1)) print('someFunction1'); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction4() {\n List<int> list = <int>[];\n if (list.contains(1)) print('someFunction4'); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction5() {\n List<ClassBase> list = <ClassBase>[];\n DerivedClass1 instance;\n if (list.contains(instance)) print('someFunction5'); // OK\n}\n\nabstract class ClassBase {}\n\nclass DerivedClass1 extends ClassBase {}\n```\n\n**GOOD:**\n```dart\nvoid someFunction6() {\n List<Mixin> list = <Mixin>[];\n DerivedClass2 instance;\n if (list.contains(instance)) print('someFunction6'); // OK\n}\n\nabstract class ClassBase {}\n\nabstract class Mixin {}\n\nclass DerivedClass2 extends ClassBase with Mixin {}\n```\n\n**GOOD:**\n```dart\nvoid someFunction7() {\n List<Mixin> list = <Mixin>[];\n DerivedClass3 instance;\n if (list.contains(instance)) print('someFunction7'); // OK\n}\n\nabstract class ClassBase {}\n\nabstract class Mixin {}\n\nclass DerivedClass3 extends ClassBase implements Mixin {}\n```\n\n**DEPRECATED:** This rule is deprecated in favor of\n`collection_methods_unrelated_type`.\nThe rule will be removed in a future Dart release.\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "list_remove_unrelated_type",
"description": "Invocation of `remove` with references of unrelated types.",
"group": "errors",
"state": "deprecated",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DON'T** invoke `remove` on `List` with an instance of different type than\nthe parameter type.\n\nDoing this will invoke `==` on its elements and most likely will\nreturn `false`.\n\n**BAD:**\n```dart\nvoid someFunction() {\n var list = <int>[];\n if (list.remove('1')) print('someFunction'); // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid someFunction3() {\n List<int> list = <int>[];\n if (list.remove('1')) print('someFunction3'); // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid someFunction8() {\n List<DerivedClass2> list = <DerivedClass2>[];\n DerivedClass3 instance;\n if (list.remove(instance)) print('someFunction8'); // LINT\n}\n```\n\n**BAD:**\n```dart\nabstract class SomeList<E> implements List<E> {}\n\nabstract class MyClass implements SomeList<int> {\n bool badMethod(String thing) => this.remove(thing); // LINT\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction10() {\n var list = [];\n if (list.remove(1)) print('someFunction10'); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction1() {\n var list = <int>[];\n if (list.remove(1)) print('someFunction1'); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction4() {\n List<int> list = <int>[];\n if (list.remove(1)) print('someFunction4'); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction5() {\n List<ClassBase> list = <ClassBase>[];\n DerivedClass1 instance;\n if (list.remove(instance)) print('someFunction5'); // OK\n}\n\nabstract class ClassBase {}\n\nclass DerivedClass1 extends ClassBase {}\n```\n\n**GOOD:**\n```dart\nvoid someFunction6() {\n List<Mixin> list = <Mixin>[];\n DerivedClass2 instance;\n if (list.remove(instance)) print('someFunction6'); // OK\n}\n\nabstract class ClassBase {}\n\nabstract class Mixin {}\n\nclass DerivedClass2 extends ClassBase with Mixin {}\n```\n\n**GOOD:**\n```dart\nvoid someFunction7() {\n List<Mixin> list = <Mixin>[];\n DerivedClass3 instance;\n if (list.remove(instance)) print('someFunction7'); // OK\n}\n\nabstract class ClassBase {}\n\nabstract class Mixin {}\n\nclass DerivedClass3 extends ClassBase implements Mixin {}\n```\n\n**DEPRECATED:** This rule is deprecated in favor of\n`collection_methods_unrelated_type`.\nThe rule will be removed in a future Dart release.\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "literal_only_boolean_expressions",
"description": "Boolean expression composed only with literals.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DON'T** test for conditions composed only by literals, since the value can be\ninferred at compile time.\n\nConditional statements using a condition which cannot be anything but FALSE have\nthe effect of making blocks of code non-functional. If the condition cannot\nevaluate to anything but `true`, the conditional statement is completely\nredundant, and makes the code less readable.\nIt is quite likely that the code does not match the programmer's intent.\nEither the condition should be removed or it should be updated so that it does\nnot always evaluate to `true` or `false`.\n\n**BAD:**\n```dart\nvoid bad() {\n if (true) {} // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid bad() {\n if (true && 1 != 0) {} // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid bad() {\n if (1 != 0 && true) {} // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid bad() {\n if (1 < 0 && true) {} // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid bad() {\n if (true && false) {} // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid bad() {\n if (1 != 0) {} // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid bad() {\n if (true && 1 != 0 || 3 < 4) {} // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid bad() {\n if (1 != 0 || 3 < 4 && true) {} // LINT\n}\n```\n\n**NOTE:** that an exception is made for the common `while (true) { }` idiom,\nwhich is often reasonably preferred to the equivalent `for (;;)`.\n\n**GOOD:**\n```dart\nvoid good() {\n while (true) {\n // Do stuff.\n }\n}\n```\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "no_adjacent_strings_in_list",
"description": "Don't use adjacent strings in list.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "**DON'T** use adjacent strings in a list.\n\nThis can indicate a forgotten comma.\n\n**BAD:**\n```dart\nList<String> list = <String>[\n 'a'\n 'b',\n 'c',\n];\n```\n\n**GOOD:**\n```dart\nList<String> list = <String>[\n 'a' +\n 'b',\n 'c',\n];\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "no_duplicate_case_values",
"description": "Don't use more than one case with same value.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**DON'T** use more than one case with same value.\n\nThis is usually a typo or changed value of constant.\n\n**BAD:**\n```dart\nconst int A = 1;\nswitch (v) {\n case 1:\n case 2:\n case A:\n case 2:\n}\n```\n\n**GOOD:**\n```dart\nconst int A = 1;\nswitch (v) {\n case A:\n case 2:\n}\n```\n\nNOTE: this lint only reports duplicate cases in libraries opted in to Dart 2.19\nand below. In Dart 3.0 and after, duplicate cases are reported as dead code\nby the analyzer.\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "no_logic_in_create_state",
"description": "Don't put any logic in createState.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [
"flutter"
],
"fixStatus": "noFix",
"details": "**DON'T** put any logic in `createState()`.\n\nImplementations of `createState()` should return a new instance\nof a State object and do nothing more. Since state access is preferred \nvia the `widget` field, passing data to `State` objects using custom\nconstructor parameters should also be avoided and so further, the State\nconstructor is required to be passed no arguments.\n\n**BAD:**\n```dart\nMyState global;\n\nclass MyStateful extends StatefulWidget {\n @override\n MyState createState() {\n global = MyState();\n return global;\n } \n}\n```\n\n```dart\nclass MyStateful extends StatefulWidget {\n @override\n MyState createState() => MyState()..field = 42;\n}\n```\n\n```dart\nclass MyStateful extends StatefulWidget {\n @override\n MyState createState() => MyState(42);\n}\n```\n\n\n**GOOD:**\n```dart\nclass MyStateful extends StatefulWidget {\n @override\n MyState createState() {\n return MyState();\n }\n}\n```\n",
"sinceDartSdk": "2.8.1"
},
{
"name": "no_self_assignments",
"description": "Don't assign a variable to itself.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsEvaluation",
"details": "**DON'T** assign a variable to itself. Usually this is a mistake.\n\n**BAD:**\n```dart\nclass C {\n int x;\n\n C(int x) {\n x = x;\n }\n}\n```\n\n**GOOD:**\n```dart\nclass C {\n int x;\n\n C(int x) : x = x;\n}\n```\n\n**GOOD:**\n```dart\nclass C {\n int x;\n\n C(int x) {\n this.x = x;\n }\n}\n```\n\n**BAD:**\n```dart\nclass C {\n int _x = 5;\n\n int get x => _x;\n\n set x(int x) {\n _x = x;\n _customUpdateLogic();\n }\n\n void _customUpdateLogic() {\n print('updated');\n }\n\n void example() {\n x = x;\n }\n}\n```\n\n**GOOD:**\n```dart\nclass C {\n int _x = 5;\n\n int get x => _x;\n\n set x(int x) {\n _x = x;\n _customUpdateLogic();\n }\n\n void _customUpdateLogic() {\n print('updated');\n }\n\n void example() {\n _customUpdateLogic();\n }\n}\n```\n\n**BAD:**\n```dart\nclass C {\n int x = 5;\n\n void update(C other) {\n this.x = this.x;\n }\n}\n```\n\n**GOOD:**\n```dart\nclass C {\n int x = 5;\n\n void update(C other) {\n this.x = other.x;\n }\n}\n```\n\n",
"sinceDartSdk": "3.1.0-wip"
},
{
"name": "no_wildcard_variable_uses",
"description": "Don't use wildcard parameters or variables.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsEvaluation",
"details": "**DON'T** use wildcard parameters or variables.\n\nWildcard parameters and local variables\n(e.g. underscore-only names like `_`, `__`, `___`, etc.) will\nbecome non-binding in a future version of the Dart language.\nAny existing code that uses wildcard parameters or variables will\nbreak. In anticipation of this change, and to make adoption easier,\nthis lint disallows wildcard and variable parameter uses.\n\n\n**BAD:**\n```dart\nvar _ = 1;\nprint(_); // LINT\n```\n\n```dart\nvoid f(int __) {\n print(__); // LINT multiple underscores too\n}\n```\n\n**GOOD:**\n```dart\nfor (var _ in [1, 2, 3]) count++;\n```\n\n```dart\nvar [a, _, b, _] = [1, 2, 3, 4];\n```\n",
"sinceDartSdk": "3.1.0-wip"
},
{
"name": "prefer_relative_imports",
"description": "Prefer relative imports for files in `lib/`.",
"group": "errors",
"state": "stable",
"incompatible": [
"always_use_package_imports"
],
"sets": [],
"fixStatus": "hasFix",
"details": "**PREFER** 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 relative imports for files within the\n`lib/` directory.\n\n**BAD:**\n```dart\nimport 'package:my_package/bar.dart';\n```\n\n**GOOD:**\n```dart\nimport 'bar.dart';\n```\n\n",
"sinceDartSdk": "2.6.0"
},
{
"name": "prefer_void_to_null",
"description": "Don't use the Null type, unless you are positive that you don't want void.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**DON'T** use the type Null where void would work.\n\n**BAD:**\n```dart\nNull f() {}\nFuture<Null> f() {}\nStream<Null> f() {}\nf(Null x) {}\n```\n\n**GOOD:**\n```dart\nvoid f() {}\nFuture<void> f() {}\nStream<void> f() {}\nf(void x) {}\n```\n\nSome exceptions include formulating special function types:\n\n```dart\nNull Function(Null, Null);\n```\n\nand for making empty literals which are safe to pass into read-only locations\nfor any type of map or list:\n\n```dart\n<Null>[];\n<int, Null>{};\n```\n",
"sinceDartSdk": "2.1.0"
},
{
"name": "test_types_in_equals",
"description": "Test type arguments in operator ==(Object other).",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DO** test type arguments in operator ==(Object other).\n\nNot testing types might result in null pointer exceptions which will be\nunexpected for consumers of your class.\n\n**BAD:**\n```dart\nclass Field {\n}\n\nclass Bad {\n final Field someField;\n\n Bad(this.someField);\n\n @override\n bool operator ==(Object other) {\n Bad otherBad = other as Bad; // LINT\n bool areEqual = otherBad != null && otherBad.someField == someField;\n return areEqual;\n }\n\n @override\n int get hashCode {\n return someField.hashCode;\n }\n}\n```\n\n**GOOD:**\n```dart\nclass Field {\n}\n\nclass Good {\n final Field someField;\n\n Good(this.someField);\n\n @override\n bool operator ==(Object other) {\n if (identical(this, other)) {\n return true;\n }\n return other is Good &&\n this.someField == other.someField;\n }\n\n @override\n int get hashCode {\n return someField.hashCode;\n }\n}\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "throw_in_finally",
"description": "Avoid `throw` in finally block.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**AVOID** throwing exceptions in finally blocks.\n\nThrowing exceptions in finally blocks will inevitably cause unexpected behavior\nthat is hard to debug.\n\n**BAD:**\n```dart\nclass BadThrow {\n double nonCompliantMethod() {\n try {\n print('hello world! ${1 / 0}');\n } catch (e) {\n print(e);\n } finally {\n throw 'Find the hidden error :P'; // LINT\n }\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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "unnecessary_statements",
"description": "Avoid using unnecessary statements.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**AVOID** using unnecessary statements.\n\nStatements which have no clear effect are usually unnecessary, or should be\nbroken up.\n\nFor example,\n\n**BAD:**\n```dart\nmyvar;\nlist.clear;\n1 + 2;\nmethodOne() + methodTwo();\nfoo ? bar : baz;\n```\n\nThough the added methods have a clear effect, the addition itself does not\nunless there is some magical overload of the + operator.\n\nUsually code like this indicates an incomplete thought, and is a bug.\n\n**GOOD:**\n```dart\nsome.method();\nconst SomeClass();\nmethodOne();\nmethodTwo();\nfoo ? bar() : baz();\nreturn myvar;\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "unrelated_type_equality_checks",
"description": "Equality operator `==` invocation with references of unrelated types.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "unregistered",
"details": "**DON'T** Compare references of unrelated types for equality.\n\nComparing references of a type where neither is a subtype of the other most\nlikely will return `false` and might not reflect programmer's intent.\n\n`Int64` and `Int32` from `package:fixnum` allow comparing to `int` provided\nthe `int` is on the right hand side. The lint allows this as a special case. \n\n**BAD:**\n```dart\nvoid someFunction() {\n var x = '1';\n if (x == 1) print('someFunction'); // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid someFunction1() {\n String x = '1';\n if (x == 1) print('someFunction1'); // LINT\n}\n```\n\n**BAD:**\n```dart\nvoid someFunction13(DerivedClass2 instance) {\n var other = DerivedClass3();\n\n if (other == instance) print('someFunction13'); // LINT\n}\n\nclass ClassBase {}\n\nclass DerivedClass1 extends ClassBase {}\n\nabstract class Mixin {}\n\nclass DerivedClass2 extends ClassBase with Mixin {}\n\nclass DerivedClass3 extends ClassBase implements Mixin {}\n```\n\n**GOOD:**\n```dart\nvoid someFunction2() {\n var x = '1';\n var y = '2';\n if (x == y) print(someFunction2); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction3() {\n for (var i = 0; i < 10; i++) {\n if (i == 0) print(someFunction3); // OK\n }\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction4() {\n var x = '1';\n if (x == null) print(someFunction4); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction7() {\n List someList;\n\n if (someList.length == 0) print('someFunction7'); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction8(ClassBase instance) {\n DerivedClass1 other;\n\n if (other == instance) print('someFunction8'); // OK\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction10(unknown) {\n var what = unknown - 1;\n for (var index = 0; index < unknown; index++) {\n if (what == index) print('someFunction10'); // OK\n }\n}\n```\n\n**GOOD:**\n```dart\nvoid someFunction11(Mixin instance) {\n var other = DerivedClass2();\n\n if (other == instance) print('someFunction11'); // OK\n if (other != instance) print('!someFunction11'); // OK\n}\n\nclass ClassBase {}\n\nabstract class Mixin {}\n\nclass DerivedClass2 extends ClassBase with Mixin {}\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "unsafe_html",
"description": "Avoid unsafe HTML APIs.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "unregistered",
"details": "**AVOID**\n\n* assigning directly to the `href` field of an AnchorElement\n* assigning directly to the `src` field of an EmbedElement, IFrameElement, or\n ScriptElement\n* assigning directly to the `srcdoc` field of an IFrameElement\n* calling the `createFragment` method of Element\n* calling the `open` method of Window\n* calling the `setInnerHtml` method of Element\n* calling the `Element.html` constructor\n* calling the `DocumentFragment.html` constructor\n\n\n**BAD:**\n```dart\nvar script = ScriptElement()..src = 'foo.js';\n```\n",
"sinceDartSdk": "2.4.0"
},
{
"name": "use_build_context_synchronously",
"description": "Do not use BuildContexts across async gaps.",
"group": "errors",
"state": "experimental",
"incompatible": [],
"sets": [
"flutter"
],
"fixStatus": "noFix",
"details": "**DON'T** use BuildContext across asynchronous gaps.\n\nStoring `BuildContext` for later usage can easily lead to difficult to diagnose\ncrashes. Asynchronous gaps are implicitly storing `BuildContext` and are some of\nthe easiest to overlook when writing code.\n\nWhen a `BuildContext` is used, its `mounted` property must be checked after an\nasynchronous gap.\n\n**BAD:**\n```dart\nvoid onButtonTapped(BuildContext context) async {\n await Future.delayed(const Duration(seconds: 1));\n Navigator.of(context).pop();\n}\n```\n\n**GOOD:**\n```dart\nvoid onButtonTapped(BuildContext context) {\n Navigator.of(context).pop();\n}\n```\n\n**GOOD:**\n```dart\nvoid onButtonTapped() async {\n await Future.delayed(const Duration(seconds: 1));\n\n if (!context.mounted) return;\n Navigator.of(context).pop();\n}\n```\n",
"sinceDartSdk": "2.13.0"
},
{
"name": "use_key_in_widget_constructors",
"description": "Use key in widget constructors.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [
"flutter"
],
"fixStatus": "hasFix",
"details": "**DO** use key in widget constructors.\n\nIt's a good practice to expose the ability to provide a key when creating public\nwidgets.\n\n**BAD:**\n```dart\nclass MyPublicWidget extends StatelessWidget {\n}\n```\n\n**GOOD:**\n```dart\nclass MyPublicWidget extends StatelessWidget {\n MyPublicWidget({super.key});\n}\n```\n",
"sinceDartSdk": "2.8.1"
},
{
"name": "valid_regexps",
"description": "Use valid regular expression syntax.",
"group": "errors",
"state": "stable",
"incompatible": [],
"sets": [
"core",
"recommended",
"flutter"
],
"fixStatus": "noFix",
"details": "**DO** use valid regular expression syntax when creating regular expression\ninstances.\n\nRegular expressions created with invalid syntax will throw a `FormatException`\nat runtime so should be avoided.\n\n**BAD:**\n```dart\nprint(RegExp(r'(').hasMatch('foo()'));\n```\n\n**GOOD:**\n```dart\nprint(RegExp(r'\\(').hasMatch('foo()'));\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "depend_on_referenced_packages",
"description": "Depend on referenced packages.",
"group": "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```\n\n",
"sinceDartSdk": "2.14.0"
},
{
"name": "package_names",
"description": "Use `lowercase_with_underscores` for package names.",
"group": "pub",
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "noFix",
"details": "From the [Pubspec format description](https://dart.dev/tools/pub/pubspec):\n\n**DO** use `lowercase_with_underscores` for package names.\n\nPackage names should be all lowercase, with underscores to separate words,\n`just_like_this`. Use only basic Latin letters and Arabic digits: [a-z0-9_].\nAlso, make sure the name is a valid Dart identifier -- that it doesn't start\nwith digits and isn't a reserved word.\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "secure_pubspec_urls",
"description": "Use secure urls in `pubspec.yaml`.",
"group": "pub",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**DO** Use secure urls in `pubspec.yaml`.\n\nUse `https` instead of `http` or `git:`.\n\n**BAD:**\n```yaml\nrepository: http://github.com/dart-lang/example\n```\n\n```yaml\ngit:\n url: git://github.com/dart-lang/example/example.git\n```\n\n**GOOD:**\n```yaml\nrepository: https://github.com/dart-lang/example\n```\n\n",
"sinceDartSdk": "2.16.0"
},
{
"name": "sort_pub_dependencies",
"description": "Sort pub dependencies alphabetically.",
"group": "pub",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "needsFix",
"details": "**DO** sort pub dependencies alphabetically (A to Z) in `pubspec.yaml`.\n\nSorting list of pub dependencies makes maintenance easier.\n",
"sinceDartSdk": "2.1.0"
},
{
"name": "always_declare_return_types",
"description": "Declare method return types.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "always_put_control_body_on_new_line",
"description": "Separate the control structure expression from its statement.",
"group": "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.\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "always_put_required_named_parameters_first",
"description": "Put required named parameters first.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "always_require_non_null_named_parameters",
"description": "Specify `@required` on named parameters without defaults.",
"group": "style",
"state": "deprecated",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**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.\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "always_specify_types",
"description": "Specify type annotations.",
"group": "style",
"state": "stable",
"incompatible": [
"avoid_types_on_closure_parameters",
"omit_local_variable_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 the `@optionalTypeArgs` annotation in the `meta` package, API\nauthors can special-case type variables whose type needs to by 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\nmain() {\n Key s = Key(); // OK!\n}\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "annotate_overrides",
"description": "Annotate overridden members.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_annotating_with_dynamic",
"description": "Avoid annotating with dynamic when not required.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_as",
"description": "Avoid using `as`.",
"group": "style",
"state": "removed",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**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```\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_bool_literals_in_conditional_expressions",
"description": "Avoid bool literals in conditional expressions.",
"group": "style",
"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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_catches_without_on_clauses",
"description": "Avoid catches without on clauses.",
"group": "style",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**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}\ncatch(e) {\n doSomething(e);\n}\n```\n\n**GOOD:**\n```dart\ntry {\n somethingRisky()\n}\non Exception catch(e) {\n doSomething(e);\n}\n```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_catching_errors",
"description": "Don't explicitly catch Error or types that implement it.",
"group": "style",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "unregistered",
"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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_classes_with_only_static_members",
"description": "Avoid defining a class that contains only static members.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_double_and_int_checks",
"description": "Avoid double and int checks.",
"group": "style",
"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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_equals_and_hash_code_on_mutable_classes",
"description": "Avoid overloading operator == and hashCode on classes not marked `@immutable`.",
"group": "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```\n\n",
"sinceDartSdk": "2.6.0"
},
{
"name": "avoid_escaping_inner_quotes",
"description": "Avoid escaping inner quotes by converting surrounding quotes.",
"group": "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```\n\n",
"sinceDartSdk": "2.8.1"
},
{
"name": "avoid_field_initializers_in_const_classes",
"description": "Avoid field initializers in const classes.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_final_parameters",
"description": "Avoid final for parameter declarations.",
"group": "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, especially\nwhen 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```\n\n",
"sinceDartSdk": "2.16.0"
},
{
"name": "avoid_function_literals_in_foreach_calls",
"description": "Avoid using `forEach` with a function literal.",
"group": "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```\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_implementing_value_types",
"description": "Don't implement classes that override `==`.",
"group": "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```\n\n",
"sinceDartSdk": "2.1.0"
},
{
"name": "avoid_init_to_null",
"description": "Don't explicitly initialize variables to null.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_js_rounded_ints",
"description": "Avoid JavaScript rounded ints.",
"group": "style",
"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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_multiple_declarations_per_line",
"description": "Don't declare multiple variables on a single line.",
"group": "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```\n\n",
"sinceDartSdk": "2.13.0"
},
{
"name": "avoid_null_checks_in_equality_operators",
"description": "Don't check for null in custom == operators.",
"group": "style",
"state": "stable",
"incompatible": [],
"sets": [
"recommended",
"flutter"
],
"fixStatus": "hasFix",
"details": "**DON'T** check for null in custom == operators.\n\nAs null is a special value, no instance of any class (other than `Null`) can be\nequivalent to it. Thus, it is redundant to check whether the other instance is\nnull.\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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_positional_boolean_parameters",
"description": "Avoid positional boolean parameters.",
"group": "style",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_private_typedef_functions",
"description": "Avoid private typedef functions.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_redundant_argument_values",
"description": "Avoid redundant argument values.",
"group": "style",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "hasFix",
"details": "**DON'T** pass an argument that matches the corresponding parameter's default\nvalue.\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```\n",
"sinceDartSdk": "2.8.1"
},
{
"name": "avoid_renaming_method_parameters",
"description": "Don't rename parameters of overridden methods.",
"group": "style",
"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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_return_types_on_setters",
"description": "Avoid return types on setters.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_returning_null",
"description": "Avoid returning null from members whose return type is bool, double, int, or num.",
"group": "style",
"state": "deprecated",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_returning_null_for_void",
"description": "Avoid returning null for void.",
"group": "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```\n\n",
"sinceDartSdk": "2.1.0"
},
{
"name": "avoid_returning_this",
"description": "Avoid returning this from methods just to enable a fluent interface.",
"group": "style",
"state": "stable",
"incompatible": [],
"sets": [],
"fixStatus": "noFix",
"details": "**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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_setters_without_getters",
"description": "Avoid setters without getters.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_shadowing_type_parameters",
"description": "Avoid shadowing type parameters.",
"group": "style",
"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```\n\n",
"sinceDartSdk": "2.1.1"
},
{
"name": "avoid_single_cascade_in_expression_statements",
"description": "Avoid single cascade in expression statements.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_types_on_closure_parameters",
"description": "Avoid annotating types for function expression parameters.",
"group": "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```\n\n",
"sinceDartSdk": "2.0.0"
},
{
"name": "avoid_unnecessary_containers",
"description": "Avoid unnecessary containers.",
"group": "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```\n",
"sinceDartSdk": "2.7.0"
},
{
"name": "avoid_unused_constructor_parameters",
"description": "Avoid defining unused parameters in constructors.",
"group": "style",
"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```\n\n",