@sun-asterisk/sunlint 1.3.41 → 1.3.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/package.json +1 -1
  2. package/rules/security/S024_xpath_xxe_protection/typescript/regex-based-analyzer.js +4 -4
  3. package/rules/security/S024_xpath_xxe_protection/typescript/symbol-based-analyzer.js +1 -1
  4. package/rules/security/S025_server_side_validation/typescript/regex-based-analyzer.js +5 -5
  5. package/rules/security/S025_server_side_validation/typescript/symbol-based-analyzer.js +6 -6
  6. package/rules/security/S032_httponly_session_cookies/typescript/regex-based-analyzer.js +8 -8
  7. package/rules/security/S033_samesite_session_cookies/typescript/regex-based-analyzer.js +12 -12
  8. package/rules/security/S033_samesite_session_cookies/typescript/symbol-based-analyzer.js +1 -1
  9. package/rules/security/S034_host_prefix_session_cookies/typescript/regex-based-analyzer.js +1 -1
  10. package/rules/security/S041_session_token_invalidation/typescript/regex-based-analyzer.js +4 -4
  11. package/rules/security/S041_session_token_invalidation/typescript/symbol-based-analyzer.js +1 -1
  12. package/rules/security/S044_re_authentication_required/typescript/regex-based-analyzer.js +1 -1
  13. package/rules/security/S044_re_authentication_required/typescript/symbol-based-analyzer.js +1 -1
  14. package/rules/security/S045_brute_force_protection/typescript/analyzer.js +1 -1
  15. package/rules/security/S045_brute_force_protection/typescript/symbol-based-analyzer.js +1 -1
  16. package/skill-assets/sunlint-code-quality/rules/dart/D001-recommended-lints.md +36 -0
  17. package/skill-assets/sunlint-code-quality/rules/dart/D002-dispose-resources.md +44 -0
  18. package/skill-assets/sunlint-code-quality/rules/dart/D003-prefer-widget-classes.md +53 -0
  19. package/skill-assets/sunlint-code-quality/rules/dart/D004-avoid-shrinkwrap.md +31 -0
  20. package/skill-assets/sunlint-code-quality/rules/dart/D005-widget-nesting.md +62 -0
  21. package/skill-assets/sunlint-code-quality/rules/dart/D006-large-callbacks.md +54 -0
  22. package/skill-assets/sunlint-code-quality/rules/dart/D007-lifecycle-order.md +44 -0
  23. package/skill-assets/sunlint-code-quality/rules/dart/D008-long-functions.md +37 -0
  24. package/skill-assets/sunlint-code-quality/rules/dart/D009-function-parameters.md +38 -0
  25. package/skill-assets/sunlint-code-quality/rules/dart/D010-cyclomatic-complexity.md +46 -0
  26. package/skill-assets/sunlint-code-quality/rules/dart/D011-named-parameters.md +31 -0
  27. package/skill-assets/sunlint-code-quality/rules/dart/D012-named-booleans.md +28 -0
  28. package/skill-assets/sunlint-code-quality/rules/dart/D013-single-public-class.md +34 -0
  29. package/skill-assets/sunlint-code-quality/rules/dart/D014-safe-collection-access.md +30 -0
  30. package/skill-assets/sunlint-code-quality/rules/dart/D015-copywith-consistency.md +52 -0
  31. package/skill-assets/sunlint-code-quality/rules/dart/D016-project-tests.md +32 -0
  32. package/skill-assets/sunlint-code-quality/rules/dart/D017-review-dependencies.md +24 -0
  33. package/skill-assets/sunlint-code-quality/rules/dart/D018-no-commented-code.md +34 -0
  34. package/skill-assets/sunlint-code-quality/rules/dart/D019-single-child-wrappers.md +31 -0
  35. package/skill-assets/sunlint-code-quality/rules/dart/D020-if-else-limit.md +41 -0
  36. package/skill-assets/sunlint-code-quality/rules/dart/D021-negated-booleans.md +26 -0
  37. package/skill-assets/sunlint-code-quality/rules/dart/D022-setstate-usage.md +35 -0
  38. package/skill-assets/sunlint-code-quality/rules/dart/D023-unnecessary-overrides.md +32 -0
  39. package/skill-assets/sunlint-code-quality/rules/dart/D024-avoid-unnecessary-statefulwidget.md +45 -0
  40. package/skill-assets/sunlint-code-quality/rules/dart/D025-nested-ternaries.md +35 -0
  41. package/skill-assets/sunlint-code-quality/rules/ruby/RB001-use-snake-case.md +30 -0
  42. package/skill-assets/sunlint-code-quality/rules/ruby/RB002-use-camel-case.md +38 -0
  43. package/skill-assets/sunlint-code-quality/rules/ruby/RB003-use-screaming-snake-case.md +26 -0
  44. package/skill-assets/sunlint-code-quality/rules/ruby/RB004-predicate-methods.md +36 -0
  45. package/skill-assets/sunlint-code-quality/rules/ruby/RB005-dangerous-methods.md +36 -0
  46. package/skill-assets/sunlint-code-quality/rules/ruby/RB006-indentation.md +32 -0
  47. package/skill-assets/sunlint-code-quality/rules/ruby/RB007-line-length.md +25 -0
  48. package/skill-assets/sunlint-code-quality/rules/ruby/RB008-rescue-exception.md +36 -0
  49. package/skill-assets/sunlint-code-quality/rules/ruby/RB009-save-bang.md +41 -0
  50. package/skill-assets/sunlint-code-quality/rules/ruby/RB010-avoid-n-plus-one.md +32 -0
  51. package/skill-assets/sunlint-code-quality/rules/ruby/RB011-use-find-each.md +30 -0
  52. package/skill-assets/sunlint-code-quality/rules/ruby/RB012-sql-injection.md +29 -0
  53. package/skill-assets/sunlint-code-quality/rules/ruby/RB013-prefer-has-many-through.md +35 -0
  54. package/skill-assets/sunlint-code-quality/rules/ruby/RB014-dependent-associations.md +28 -0
  55. package/skill-assets/sunlint-code-quality/rules/ruby/RB015-modern-validations.md +29 -0
  56. package/skill-assets/sunlint-code-quality/rules/ruby/RB016-thin-controllers.md +45 -0
  57. package/skill-assets/sunlint-code-quality/rules/ruby/RB017-avoid-fat-models.md +41 -0
  58. package/skill-assets/sunlint-code-quality/rules/ruby/RB018-service-objects.md +36 -0
  59. package/skill-assets/sunlint-code-quality/rules/ruby/RB019-avoid-metaprogramming.md +40 -0
  60. package/skill-assets/sunlint-code-quality/rules/ruby/RB020-use-pluck.md +29 -0
  61. package/skill-assets/sunlint-code-quality/rules/ruby/RB021-use-size.md +27 -0
  62. package/skill-assets/sunlint-code-quality/rules/ruby/RB022-order-by-timestamps.md +24 -0
  63. package/skill-assets/sunlint-code-quality/rules/ruby/RB023-where-missing.md +24 -0
  64. package/skill-assets/sunlint-code-quality/rules/ruby/RB024-method-length.md +41 -0
  65. package/skill-assets/sunlint-code-quality/rules/ruby/RB025-parameter-limits.md +28 -0
  66. package/skill-assets/sunlint-code-quality/rules/ruby/RB026-avoid-deep-nesting.md +38 -0
  67. package/skill-assets/sunlint-code-quality/rules/ruby/RB027-guard-clauses.md +37 -0
  68. package/skill-assets/sunlint-code-quality/rules/ruby/RB028-class-length.md +32 -0
  69. package/skill-assets/sunlint-code-quality/rules/ruby/RB029-meaningful-names.md +30 -0
  70. package/skill-assets/sunlint-code-quality/rules/ruby/RB030-dry-principle.md +37 -0
  71. package/skill-assets/sunlint-code-quality/rules/ruby/RB031-mvc-architecture.md +37 -0
  72. package/skill-assets/sunlint-code-quality/rules/ruby/RB032-use-concerns.md +31 -0
  73. package/skill-assets/sunlint-code-quality/rules/ruby/RB033-moderate-callbacks.md +31 -0
  74. package/skill-assets/sunlint-code-quality/rules/ruby/RB034-use-decorators.md +33 -0
  75. package/skill-assets/sunlint-code-quality/rules/ruby/RB035-comprehensive-tests.md +32 -0
  76. package/skill-assets/sunlint-code-quality/rules/ruby/RB036-frozen-string-literal.md +29 -0
  77. package/skill-assets/sunlint-code-quality/rules/ruby/RB037-it-parameter.md +25 -0
  78. package/skill-assets/sunlint-code-quality/rules/ruby/RB038-modern-enum-syntax.md +28 -0
  79. package/skill-assets/sunlint-code-quality/rules/ruby/RB039-solid-adapters.md +29 -0
  80. package/skill-assets/sunlint-code-quality/rules/ruby/RB040-rails-authentication.md +26 -0
  81. package/skill-assets/sunlint-code-quality/rules/ruby/RB041-async-query-loading.md +29 -0
  82. package/skill-assets/sunlint-code-quality/rules/ruby/RB042-hotwire-turbo.md +30 -0
  83. package/skill-assets/sunlint-code-quality/rules/ruby/RB043-use-propshaft.md +27 -0
  84. package/skill-assets/sunlint-code-quality/rules/ruby/RB044-structured-logging.md +35 -0
  85. package/skill-assets/sunlint-code-quality/rules/ruby/RB045-prism-parser.md +29 -0
  86. package/skill-assets/sunlint-code-quality/rules/swift/SW001-block-based-kvo.md +40 -0
  87. package/skill-assets/sunlint-code-quality/rules/swift/SW002-class-delegate-protocol.md +36 -0
  88. package/skill-assets/sunlint-code-quality/rules/swift/SW003-compiler-protocol-init.md +28 -0
  89. package/skill-assets/sunlint-code-quality/rules/swift/SW004-contains-over-filter-count.md +28 -0
  90. package/skill-assets/sunlint-code-quality/rules/swift/SW005-convenience-type.md +34 -0
  91. package/skill-assets/sunlint-code-quality/rules/swift/SW006-discarded-notification-center-observer.md +41 -0
  92. package/skill-assets/sunlint-code-quality/rules/swift/SW007-discouraged-direct-init.md +28 -0
  93. package/skill-assets/sunlint-code-quality/rules/swift/SW008-discouraged-optional-boolean.md +32 -0
  94. package/skill-assets/sunlint-code-quality/rules/swift/SW009-empty-count.md +30 -0
  95. package/skill-assets/sunlint-code-quality/rules/swift/SW010-empty-string.md +30 -0
  96. package/skill-assets/sunlint-code-quality/rules/swift/SW011-explicit-init.md +26 -0
  97. package/skill-assets/sunlint-code-quality/rules/swift/SW012-fatal-error-message.md +28 -0
  98. package/skill-assets/sunlint-code-quality/rules/swift/SW013-for-where.md +30 -0
  99. package/skill-assets/sunlint-code-quality/rules/swift/SW014-force-cast.md +26 -0
  100. package/skill-assets/sunlint-code-quality/rules/swift/SW015-force-try.md +30 -0
  101. package/skill-assets/sunlint-code-quality/rules/swift/SW016-force-unwrapping.md +32 -0
  102. package/skill-assets/sunlint-code-quality/rules/swift/SW017-function-parameter-count.md +37 -0
  103. package/skill-assets/sunlint-code-quality/rules/swift/SW018-large-tuple.md +41 -0
  104. package/skill-assets/sunlint-code-quality/rules/swift/SW019-legacy-constructor.md +28 -0
  105. package/skill-assets/sunlint-code-quality/rules/swift/SW020-nesting.md +38 -0
  106. package/skill-assets/sunlint-code-quality/rules/swift/SW021-no-extension-access-modifier.md +28 -0
  107. package/skill-assets/sunlint-code-quality/rules/swift/SW022-overridden-super-call.md +30 -0
  108. package/skill-assets/sunlint-code-quality/rules/swift/SW023-override-in-extension.md +32 -0
  109. package/skill-assets/sunlint-code-quality/rules/swift/SW024-private-over-fileprivate.md +28 -0
  110. package/skill-assets/sunlint-code-quality/rules/swift/SW025-private-unit-test.md +32 -0
  111. package/skill-assets/sunlint-code-quality/rules/swift/SW026-prohibited-super-call.md +29 -0
  112. package/skill-assets/sunlint-code-quality/rules/swift/SW027-sorted-first-last.md +28 -0
  113. package/skill-assets/sunlint-code-quality/rules/swift/SW028-syntactic-sugar.md +28 -0
  114. package/skill-assets/sunlint-code-quality/rules/swift/SW029-unused-closure-parameter.md +28 -0
  115. package/skill-assets/sunlint-code-quality/rules/swift/SW030-unused-enumerated.md +28 -0
  116. package/skill-assets/sunlint-code-quality/rules/swift/SW031-unused-optional-binding.md +26 -0
  117. package/skill-assets/sunlint-code-quality/rules/swift/SW032-valid-ibinspectable.md +26 -0
  118. package/skill-assets/sunlint-code-quality/rules/swift/SW033-vertical-parameter-alignment.md +36 -0
  119. package/skill-assets/sunlint-code-quality/rules/swift/SW034-void-return.md +28 -0
  120. package/skill-assets/sunlint-code-quality/rules/swift/SW035-weak-delegate.md +28 -0
@@ -0,0 +1,54 @@
1
+ ---
2
+ title: Prefer Extracting Large Callbacks from Build
3
+ impact: LOW
4
+ impactDescription: Improve code readability and testability by extracting large callback functions
5
+ tags: readability, maintainability, testability, callback
6
+ ---
7
+
8
+ ## Prefer Extracting Large Callbacks from Build
9
+
10
+ Callback functions (onTap, onPressed, onChanged, etc.) in widget builders should not exceed 5 lines. Large inline callbacks make the build method harder to read and maintain. Extract callbacks that exceed this limit to separate methods or functions.
11
+
12
+ **Incorrect (large inline callback):**
13
+
14
+ ```dart
15
+ @override
16
+ Widget build(BuildContext context) {
17
+ return ElevatedButton(
18
+ onPressed: () {
19
+ final data = _formKey.currentState?.value;
20
+ if (data != null && data.isNotEmpty) {
21
+ _logger.info('Submitting data: $data');
22
+ _repository.save(data).then((_) {
23
+ Navigator.pop(context);
24
+ });
25
+ }
26
+ },
27
+ child: Text('Submit'),
28
+ );
29
+ }
30
+ ```
31
+
32
+ **Correct (extracted callback method):**
33
+
34
+ ```dart
35
+ void _handleSubmit() {
36
+ final data = _formKey.currentState?.value;
37
+ if (data != null && data.isNotEmpty) {
38
+ _logger.info('Submitting data: $data');
39
+ _repository.save(data).then((_) {
40
+ Navigator.pop(context);
41
+ });
42
+ }
43
+ }
44
+
45
+ @override
46
+ Widget build(BuildContext context) {
47
+ return ElevatedButton(
48
+ onPressed: _handleSubmit,
49
+ child: Text('Submit'),
50
+ );
51
+ }
52
+ ```
53
+
54
+ **Tools:** Custom analyzer (D006)
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: Prefer Init First, Dispose Last
3
+ impact: MEDIUM
4
+ impactDescription: Ensure proper lifecycle method ordering in StatefulWidget
5
+ tags: lifecycle, maintenance, flutter, statefulwidget
6
+ ---
7
+
8
+ ## Prefer Init First, Dispose Last
9
+
10
+ In StatefulWidget lifecycle methods, `super.initState()` should be called first before any initialization code, and `super.dispose()` should be called last after all cleanup code. This ensures that the framework's internal state management is properly initialized before your code runs and is the last to clean up.
11
+
12
+ **Incorrect (wrong order):**
13
+
14
+ ```dart
15
+ @override
16
+ void initState() {
17
+ _controller = TextEditingController();
18
+ super.initState(); // Called after custom logic
19
+ }
20
+
21
+ @override
22
+ void dispose() {
23
+ super.dispose(); // Called before cleanup
24
+ _controller.dispose();
25
+ }
26
+ ```
27
+
28
+ **Correct (framework-friendly order):**
29
+
30
+ ```dart
31
+ @override
32
+ void initState() {
33
+ super.initState(); // Always first
34
+ _controller = TextEditingController();
35
+ }
36
+
37
+ @override
38
+ void dispose() {
39
+ _controller.dispose();
40
+ super.dispose(); // Always last
41
+ }
42
+ ```
43
+
44
+ **Tools:** Custom analyzer (D007)
@@ -0,0 +1,37 @@
1
+ ---
2
+ title: Avoid Long Functions
3
+ impact: MEDIUM
4
+ impactDescription: Improve code readability and maintainability by limiting function length
5
+ tags: readability, maintainability, clean-code, dev-efficiency
6
+ ---
7
+
8
+ ## Avoid Long Functions
9
+
10
+ Functions should not exceed 60 lines of effective code (excluding comments and opening/closing braces). Long functions are harder to understand, test, and maintain. They often indicate that the function is doing too much and should be broken down into smaller, more focused functions.
11
+
12
+ **Incorrect (too long):**
13
+
14
+ ```dart
15
+ void processOrder(Order order) {
16
+ // Line 1
17
+ // ... 60+ more lines of logic ...
18
+ // Line 70
19
+ }
20
+ ```
21
+
22
+ **Correct (modular functions):**
23
+
24
+ ```dart
25
+ void processOrder(Order order) {
26
+ validateOrder(order);
27
+ calculateTotal(order);
28
+ saveToDatabase(order);
29
+ sendNotification(order);
30
+ }
31
+
32
+ void validateOrder(Order order) { ... }
33
+ void calculateTotal(Order order) { ... }
34
+ // Each function is focused and short
35
+ ```
36
+
37
+ **Tools:** Custom analyzer (D008)
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: Limit Function Parameters
3
+ impact: MEDIUM
4
+ impactDescription: Improve code readability by limiting the number of function parameters
5
+ tags: readability, maintainability, clean-code
6
+ ---
7
+
8
+ ## Limit Function Parameters
9
+
10
+ Functions, methods, and constructors should not have more than 5 parameters. Too many parameters make code harder to read, understand, and maintain. When a function needs many parameters, consider grouping related parameters into a data class or using a configuration object.
11
+
12
+ **Incorrect (too many positional parameters):**
13
+
14
+ ```dart
15
+ void createUser(String firstName, String lastName, int age, String email, String phone, String address, String city) {
16
+ // ...
17
+ }
18
+ ```
19
+
20
+ **Correct (using data object or named parameters):**
21
+
22
+ ```dart
23
+ // Option 1: Data class
24
+ void createUser(UserDetail details) {
25
+ // ...
26
+ }
27
+
28
+ // Option 2: Grouped named parameters
29
+ void createUser({
30
+ required String name,
31
+ required ContactInfo contact,
32
+ required Address address,
33
+ }) {
34
+ // ...
35
+ }
36
+ ```
37
+
38
+ **Tools:** Custom analyzer (D009)
@@ -0,0 +1,46 @@
1
+ ---
2
+ title: Limit Cyclomatic Complexity
3
+ impact: MEDIUM
4
+ impactDescription: Improve code readability and maintainability by limiting cyclomatic complexity
5
+ tags: complexity, maintainability, clean-code
6
+ ---
7
+
8
+ ## Limit Cyclomatic Complexity
9
+
10
+ Functions, methods, and constructors should not have cyclomatic complexity exceeding 10. High cyclomatic complexity indicates that the code has too many independent paths, making it harder to understand, test, and maintain. Use early returns or extract complex logic into sub-functions.
11
+
12
+ **Incorrect (high complexity):**
13
+
14
+ ```dart
15
+ String getStatusDescription(int status, bool isUrgent, bool isAdmin) {
16
+ if (status == 1) {
17
+ if (isUrgent) return "Urgent Pending";
18
+ return "Pending";
19
+ } else if (status == 2) {
20
+ if (isAdmin) return "Admin Approved";
21
+ return "Approved";
22
+ } else if (status == 3) {
23
+ return "Rejected";
24
+ } else {
25
+ return "Unknown";
26
+ }
27
+ }
28
+ ```
29
+
30
+ **Correct (reduced complexity with Map or early returns):**
31
+
32
+ ```dart
33
+ static const statusMap = {
34
+ 1: "Pending",
35
+ 2: "Approved",
36
+ 3: "Rejected",
37
+ };
38
+
39
+ String getStatusDescription(int status, bool isUrgent, bool isAdmin) {
40
+ if (status == 1 && isUrgent) return "Urgent Pending";
41
+ if (status == 2 && isAdmin) return "Admin Approved";
42
+ return statusMap[status] ?? "Unknown";
43
+ }
44
+ ```
45
+
46
+ **Tools:** Custom analyzer (D010)
@@ -0,0 +1,31 @@
1
+ ---
2
+ title: Prefer Named Parameters
3
+ impact: LOW
4
+ impactDescription: Improve code readability and prevent parameter confusion
5
+ tags: readability, safety, clean-code
6
+ ---
7
+
8
+ ## Prefer Named Parameters
9
+
10
+ Functions, methods, and constructors with more than 3 parameters that have 2 or more adjacent parameters of the same type should use named parameters. This improves code clarity by making it explicit which value corresponds to which parameter, reducing the risk of accidentally swapping arguments of the same type.
11
+
12
+ **Incorrect (confusing positional parameters):**
13
+
14
+ ```dart
15
+ // At call site, hard to tell which is width and which is height
16
+ final rect = Rectangle(100.0, 50.0, 10.0, "red");
17
+ ```
18
+
19
+ **Correct (clear named parameters):**
20
+
21
+ ```dart
22
+ // Much clearer at call site
23
+ final rect = Rectangle(
24
+ width: 100.0,
25
+ height: 50.0,
26
+ padding: 10.0,
27
+ color: "red",
28
+ );
29
+ ```
30
+
31
+ **Tools:** Custom analyzer (D011)
@@ -0,0 +1,28 @@
1
+ ---
2
+ title: Prefer Named Boolean Parameters
3
+ impact: LOW
4
+ impactDescription: Improve code readability by avoiding unclear boolean parameters
5
+ tags: readability, clean-code, boolean
6
+ ---
7
+
8
+ ## Prefer Named Boolean Parameters
9
+
10
+ Boolean parameters in functions make code harder to understand at call sites (the "Boolean Trap"). When a function has boolean parameters, use named parameters to make the intent explicit. Better yet, create separate functions (e.g., `enableUser()` instead of `setUser(true)`).
11
+
12
+ **Incorrect (unclear boolean meaning):**
13
+
14
+ ```dart
15
+ updateStatus(user, true); // What does true mean? Is it active? deleted? admin?
16
+ ```
17
+
18
+ **Correct (explicit naming):**
19
+
20
+ ```dart
21
+ // Option 1: Named parameter
22
+ updateStatus(user, isActive: true);
23
+
24
+ // Option 2: Semantic function
25
+ activateUser(user);
26
+ ```
27
+
28
+ **Tools:** Custom analyzer (D012)
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: Prefer a Single Public Class Per File
3
+ impact: LOW
4
+ impactDescription: Improve code organization and maintainability
5
+ tags: organization, maintainability, clean-code
6
+ ---
7
+
8
+ ## Prefer a Single Public Class Per File
9
+
10
+ Each Dart file should contain only one public class. Multiple public classes in a single file make code harder to navigate, test, and maintain. Private implementation classes (starting with `_`) are allowed in the same file.
11
+
12
+ **Incorrect (multiple public classes):**
13
+
14
+ ```dart
15
+ // user_models.dart
16
+ class User { ... }
17
+ class UserProfile { ... }
18
+ class UserSettings { ... }
19
+ ```
20
+
21
+ **Correct (split into separate files):**
22
+
23
+ ```dart
24
+ // user.dart
25
+ class User { ... }
26
+
27
+ // user_profile.dart
28
+ class UserProfile { ... }
29
+
30
+ // user_settings.dart
31
+ class UserSettings { ... }
32
+ ```
33
+
34
+ **Tools:** Custom analyzer (D013)
@@ -0,0 +1,30 @@
1
+ ---
2
+ title: Avoid Unsafe Collection Access
3
+ impact: HIGH
4
+ impactDescription: Prevent runtime errors from accessing empty collections
5
+ tags: safety, stability, collections, crash-prevention
6
+ ---
7
+
8
+ ## Avoid Unsafe Collection Access
9
+
10
+ Using `.first`, `.last`, or `.single` on collections without checking if they're empty causes runtime `StateError` exceptions. Always check `isEmpty`, `isNotEmpty`, or use safe alternatives from `collection` package or built-in `firstOrNull`.
11
+
12
+ **Incorrect (potential crash):**
13
+
14
+ ```dart
15
+ final firstUser = users.first; // Throws StateError if users is empty
16
+ ```
17
+
18
+ **Correct (safe access):**
19
+
20
+ ```dart
21
+ // Option 1: check length
22
+ if (users.isNotEmpty) {
23
+ final firstUser = users.first;
24
+ }
25
+
26
+ // Option 2: use null-safe getter (Dart 3.0+)
27
+ final firstUser = users.firstOrNull;
28
+ ```
29
+
30
+ **Tools:** Custom analyzer (D014)
@@ -0,0 +1,52 @@
1
+ ---
2
+ title: Ensure copyWith includes all constructor parameters
3
+ impact: MEDIUM
4
+ impactDescription: Maintain data integrity and completeness in immutable objects
5
+ tags: safety, immutability, data-integrity, boilerplate
6
+ ---
7
+
8
+ ## Ensure copyWith includes all constructor parameters
9
+
10
+ When a class implements a `copyWith` method for creating modified copies, it should include all constructor parameters. Missing parameters in `copyWith` can lead to unintended data loss or inability to update certain fields. This is especially important for data classes, models, and immutable state objects.
11
+
12
+ **Incorrect (incomplete copyWith):**
13
+
14
+ ```dart
15
+ class User {
16
+ final String id;
17
+ final String name;
18
+ final int age;
19
+
20
+ User({required this.id, required this.name, required this.age});
21
+
22
+ User copyWith({String? name}) {
23
+ return User(
24
+ id: this.id,
25
+ name: name ?? this.name,
26
+ age: this.age, // age cannot be updated via copyWith
27
+ );
28
+ }
29
+ }
30
+ ```
31
+
32
+ **Correct (complete copyWith):**
33
+
34
+ ```dart
35
+ class User {
36
+ final String id;
37
+ final String name;
38
+ final int age;
39
+
40
+ User({required this.id, required this.name, required this.age});
41
+
42
+ User copyWith({String? name, int? age}) {
43
+ return User(
44
+ id: this.id,
45
+ name: name ?? this.name,
46
+ age: age ?? this.age,
47
+ );
48
+ }
49
+ }
50
+ ```
51
+
52
+ **Tools:** Custom analyzer (D015)
@@ -0,0 +1,32 @@
1
+ ---
2
+ title: Project should have tests
3
+ impact: HIGH
4
+ impactDescription: Ensure code quality and prevent regressions through automated testing
5
+ tags: testing, quality, reliability
6
+ ---
7
+
8
+ ## Project should have tests
9
+
10
+ Every Dart/Flutter project should have a `test` directory containing test files (files ending with `_test.dart`). Tests are essential for maintaining code quality, catching bugs early, and enabling safe refactoring.
11
+
12
+ **Incorrect (no tests):**
13
+
14
+ ```text
15
+ my_project/
16
+ lib/
17
+ pubspec.yaml
18
+ # MISSING test/ directory
19
+ ```
20
+
21
+ **Correct (testing infrastructure included):**
22
+
23
+ ```text
24
+ my_project/
25
+ lib/
26
+ test/
27
+ unit_test.dart
28
+ widget_test.dart
29
+ pubspec.yaml
30
+ ```
31
+
32
+ **Tools:** Custom analyzer (D016)
@@ -0,0 +1,24 @@
1
+ ---
2
+ title: Pubspec dependencies should be reviewed regularly
3
+ impact: MEDIUM
4
+ impactDescription: Ensure dependencies are kept up-to-date for security and stability
5
+ tags: maintenance, security, dependencies
6
+ ---
7
+
8
+ ## Pubspec dependencies should be reviewed regularly
9
+
10
+ Dependencies in `pubspec.yaml` should be reviewed and updated regularly (at least every 4 months). Outdated dependencies may contain security vulnerabilities or miss critical performance improvements.
11
+
12
+ **Incorrect (old lock file):**
13
+
14
+ ```text
15
+ # pubspec.lock last modified: 6 months ago
16
+ ```
17
+
18
+ **Correct (regularly updated):**
19
+
20
+ ```text
21
+ # run 'flutter pub upgrade' and review dependencies regularly
22
+ ```
23
+
24
+ **Tools:** Custom analyzer (D017)
@@ -0,0 +1,34 @@
1
+ ---
2
+ title: Remove Commented-Out Code
3
+ impact: LOW
4
+ impactDescription: Keep codebase clean by removing commented-out code
5
+ tags: cleanliness, readability, maintenance
6
+ ---
7
+
8
+ ## Remove Commented-Out Code
9
+
10
+ Commented-out code should be removed instead of being left in the source files. Dead code comments create clutter and confusion. If you need to reference old code, rely on version control (Git).
11
+
12
+ **Incorrect (abandoned code):**
13
+
14
+ ```dart
15
+ void calculate() {
16
+ final result = 10 + 5;
17
+ // print("Debug result: $result");
18
+ // if (result > 10) {
19
+ // doSomething();
20
+ // }
21
+ return result;
22
+ }
23
+ ```
24
+
25
+ **Correct (clean file):**
26
+
27
+ ```dart
28
+ void calculate() {
29
+ final result = 10 + 5;
30
+ return result;
31
+ }
32
+ ```
33
+
34
+ **Tools:** Custom analyzer (D018)
@@ -0,0 +1,31 @@
1
+ ---
2
+ title: Avoid Single Child in Multi-Child Widget
3
+ impact: LOW
4
+ impactDescription: Use appropriate widget types for the number of children
5
+ tags: performance, efficiency, best-practices
6
+ ---
7
+
8
+ ## Avoid Single Child in Multi-Child Widget
9
+
10
+ Multi-child widgets like `Column`, `Row`, `Stack`, `ListView`, or `GridView` are inefficient when used with only a single child. Use single-child optimized widgets like `SizedBox`, `Padding`, `Center`, or `Container` instead.
11
+
12
+ **Incorrect (inefficient Column):**
13
+
14
+ ```dart
15
+ Column(
16
+ children: [
17
+ Text("Only one child here"),
18
+ ],
19
+ )
20
+ ```
21
+
22
+ **Correct (efficient wrapper):**
23
+
24
+ ```dart
25
+ Padding(
26
+ padding: const EdgeInsets.all(8.0),
27
+ child: Text("Only one child here"),
28
+ )
29
+ ```
30
+
31
+ **Tools:** Custom analyzer (D019)
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: Limit If/Else Branches
3
+ impact: LOW
4
+ impactDescription: Reduce complexity by limiting the number of if/else branches
5
+ tags: readability, complexity, clean-code
6
+ ---
7
+
8
+ ## Limit If/Else Branches
9
+
10
+ Complex if/else chains with more than 3 branches reduce code readability and increase cyclomatic complexity. When facing multiple branches, consider using `switch` statements, lookup tables (Maps), or the Strategy pattern.
11
+
12
+ **Incorrect (long if/else chain):**
13
+
14
+ ```dart
15
+ if (type == 'A') {
16
+ doA();
17
+ } else if (type == 'B') {
18
+ doB();
19
+ } else if (type == 'C') {
20
+ doC();
21
+ } else if (type == 'D') {
22
+ doD();
23
+ } else {
24
+ doDefault();
25
+ }
26
+ ```
27
+
28
+ **Correct (using switch or Map):**
29
+
30
+ ```dart
31
+ // Option 1: Switch (better readability)
32
+ switch (type) {
33
+ case 'A': doA(); break;
34
+ case 'B': doB(); break;
35
+ case 'C': doC(); break;
36
+ case 'D': doD(); break;
37
+ default: doDefault();
38
+ }
39
+ ```
40
+
41
+ **Tools:** Custom analyzer (D020)
@@ -0,0 +1,26 @@
1
+ ---
2
+ title: Avoid Negated Boolean Checks
3
+ impact: LOW
4
+ impactDescription: Improve code readability by avoiding inverted or negated boolean conditions
5
+ tags: readability, logic, clean-code
6
+ ---
7
+
8
+ ## Avoid Negated Boolean Checks
9
+
10
+ Negated boolean checks (using `!`) make code harder to read and understand. Replace negative conditions with positive ones wherever possible, and avoid double negations like `!!`.
11
+
12
+ **Incorrect (fragmented logic):**
13
+
14
+ ```dart
15
+ if (!isNotAuthorized) { ... }
16
+ if (!(a == b)) { ... }
17
+ ```
18
+
19
+ **Correct (clear logic):**
20
+
21
+ ```dart
22
+ if (isAuthorized) { ... }
23
+ if (a != b) { ... }
24
+ ```
25
+
26
+ **Tools:** Custom analyzer (D021)
@@ -0,0 +1,35 @@
1
+ ---
2
+ title: Use setState Correctly
3
+ impact: HIGH
4
+ impactDescription: Ensure setState is used correctly in StatefulWidget to avoid performance issues and bugs
5
+ tags: performance, best-practices, lifecycle, state-management
6
+ ---
7
+
8
+ ## Use setState Correctly
9
+
10
+ Common `setState` anti-patterns include: calling `setState` inside `build()`, nesting `setState` calls, making multiple `setState` calls in the same method, or using async callbacks inside `setState`. These lead to performance issues, unnecessary rebuilds, or hard-to-track UI bugs.
11
+
12
+ **Incorrect (async inside setState):**
13
+
14
+ ```dart
15
+ setState(() async {
16
+ await fetchData(); // WRONG: setState should be synchronous
17
+ _data = "new data";
18
+ });
19
+ ```
20
+
21
+ **Correct (sync update after async):**
22
+
23
+ ```dart
24
+ // Fetch data first
25
+ final newData = await fetchData();
26
+
27
+ // Update state synchronously
28
+ if (mounted) {
29
+ setState(() {
30
+ _data = newData;
31
+ });
32
+ }
33
+ ```
34
+
35
+ **Tools:** Custom analyzer (D022)
@@ -0,0 +1,32 @@
1
+ ---
2
+ title: Avoid Unnecessary Method Overrides
3
+ impact: LOW
4
+ impactDescription: Remove methods that only call super with the same parameters as they add no value
5
+ tags: readability, clean-code, refactoring
6
+ ---
7
+
8
+ ## Avoid Unnecessary Method Overrides
9
+
10
+ Methods that override a parent method but only call `super.methodName()` with the same parameters are unnecessary and should be removed. These empty overrides add no functionality and create unnecessary code clutter. Common examples include lifecycle methods like `initState()`, `dispose()`, or `didUpdateWidget()` that only call their super implementation.
11
+
12
+ **Incorrect (super call only):**
13
+
14
+ ```dart
15
+ @override
16
+ void initState() {
17
+ super.initState();
18
+ }
19
+
20
+ @override
21
+ void dispose() {
22
+ super.dispose();
23
+ }
24
+ ```
25
+
26
+ **Correct (remove if no logic):**
27
+
28
+ ```dart
29
+ // Just remove the method override entirely if it only calls super
30
+ ```
31
+
32
+ **Tools:** Custom analyzer (D023)