# 📘 Dart Specific Coding Rules

---

### 📘 Rule D001 – Recommended Lint Rules Should Be Enabled

- **Objective**: Ensure code quality through standard lint configurations
- **Details**: The `analysis_options.yaml` file should include recommended lint packages (flutter_lints, very_good_analysis, or lints) and critical lint rules should not be disabled. This ensures consistent code quality standards across the project.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D001)
- **Principles**: CODE_QUALITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: major

### 📘 Rule D002 – Always Dispose Resources and Remove Listeners

- **Objective**: Prevent memory leaks by ensuring proper resource disposal
- **Details**: All disposable resources (Controllers, StreamSubscriptions, FocusNodes, Listeners) must be properly disposed in the `dispose()` method. This includes TextEditingController, AnimationController, ScrollController, StreamSubscription, FocusNode, and other resources that implement Disposable. Failing to dispose these resources leads to memory leaks.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D002)
- **Principles**: CODE_QUALITY, PERFORMANCE
- **Version**: 1.0
- **Status**: activated
- **Severity**: error

### 📘 Rule D003 – Prefer Widgets Over Methods Returning Widgets

- **Objective**: Improve performance and maintainability by extracting widget-returning methods into widget classes
- **Details**: Methods that return widgets should be extracted into separate StatelessWidget or StatefulWidget classes. This improves performance as Flutter can optimize widget rebuilds, makes code more reusable, and follows Flutter best practices. Only the build() method and lifecycle methods are exempt from this rule.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D003)
- **Principles**: CODE_QUALITY, PERFORMANCE
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D004 – Avoid shrinkWrap in ListView

- **Objective**: Prevent performance issues caused by shrinkWrap in scrollable widgets
- **Details**: Using `shrinkWrap: true` in ListView or GridView disables lazy loading and forces all items to render at once, causing severe performance degradation. Instead, use Expanded or Flexible widgets to constrain the ListView size, or use SliverList within a CustomScrollView for better performance. The shrinkWrap parameter should only be used in rare cases where the list is guaranteed to be small.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D004)
- **Principles**: CODE_QUALITY, PERFORMANCE
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D005 – Limit Widget Nesting Depth to 6

- **Objective**: Maintain code readability and prevent performance issues caused by deeply nested widgets
- **Details**: Widget nesting should not exceed 6 levels in the build method. Deeply nested widgets make code harder to understand, maintain, and can impact performance. When nesting exceeds this limit, extract nested widgets into separate StatelessWidget or StatefulWidget classes. This improves code organization, reusability, and allows Flutter to optimize widget rebuilds more effectively.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D005)
- **Principles**: CODE_QUALITY, MAINTAINABILITY, PERFORMANCE
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D006 – Prefer Extracting Large Callbacks from Build

- **Objective**: Improve code readability and testability by extracting large callback functions
- **Details**: 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. This improves code organization, makes the build method more readable, and allows callbacks to be tested independently. Common callback properties include onTap, onPressed, onChanged, onSubmitted, onLongPress, builder, and itemBuilder.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D006)
- **Principles**: CODE_QUALITY, MAINTAINABILITY, TESTABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D007 – Prefer Init First, Dispose Last

- **Objective**: Ensure proper lifecycle method ordering in StatefulWidget
- **Details**: 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. Calling super.initState() first allows the framework to set up necessary internal state before your initialization logic. Calling super.dispose() last ensures all your cleanup code executes before the framework's cleanup, preventing potential null pointer exceptions or resource leaks.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D007)
- **Principles**: CODE_QUALITY, MAINTAINABILITY, LIFECYCLE_MANAGEMENT
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D008 – Avoid Long Functions

- **Objective**: Improve code readability and maintainability by limiting function length
- **Details**: 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. The line count excludes blank lines, comments (both single-line // and multi-line /\* \*/), and the opening `{` and closing `}` braces. The maximum line limit is configurable.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D008)
- **Principles**: CODE_QUALITY, MAINTAINABILITY, READABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D009 – Limit Function Parameters

- **Objective**: Improve code readability by limiting the number of function parameters
- **Details**: Functions, methods, and constructors should not have more than 5 parameters (configurable). 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 named parameters with a configuration object.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D009)
- **Principles**: CODE_QUALITY, MAINTAINABILITY, READABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D010 – Limit Cyclomatic Complexity

- **Objective**: Improve code readability and maintainability by limiting cyclomatic complexity
- **Details**: Functions, methods, and constructors should not have cyclomatic complexity exceeding 10 (configurable). High cyclomatic complexity indicates that the code has too many independent paths, making it harder to understand, test, and maintain. The metric counts: if statements, catch blocks, loops (for, while, do), conditional expressions (? :), switch cases (except default/last), null-aware operators (?., ?[], ...?, ??), logical operators (&& and ||), and null coalescing operators (?? and ??=).
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D010)
- **Principles**: CODE_QUALITY, MAINTAINABILITY, READABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D011 – Prefer Named Parameters

- **Objective**: Improve code readability and prevent parameter confusion
- **Details**: 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. Named parameters make function calls self-documenting and easier to maintain.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D011)
- **Principles**: CODE_QUALITY, READABILITY, MAINTAINABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D012 – Prefer Named Boolean Parameters

- **Objective**: Improve code readability by avoiding unclear boolean parameters
- **Details**: Boolean parameters in functions make code harder to understand at call sites. When a function has 1-2 parameters with a boolean, consider creating separate functions (e.g., `enableUser`/`disableUser` instead of `setUser(userId, true)`). For functions with multiple parameters including booleans, use named parameters to make the intent explicit (e.g., `createUser(name: 'John', isActive: true)` instead of `createUser('John', true)`).
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D012)
- **Principles**: CODE_QUALITY, READABILITY, MAINTAINABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D013 – Prefer a Single Public Class Per File

- **Objective**: Improve code organization and maintainability
- **Details**: Each Dart file should contain only one public class (class names not starting with underscore). Multiple public classes in a single file make code harder to navigate, test, and maintain. Private classes (names starting with `_`) can coexist with a single public class as they are implementation details. This rule encourages better file organization and follows Dart's convention of one public declaration per file.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D013)
- **Principles**: CODE_QUALITY, ORGANIZATION, MAINTAINABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D014 – Avoid Unsafe Collection Access

- **Objective**: Prevent runtime errors from accessing empty collections
- **Details**: Using `.first`, `.last`, `.single`, or `.elementAt()` on collections without checking if they're empty or have sufficient length can cause runtime exceptions. Always check `isEmpty`, `isNotEmpty`, or `length` before accessing, or use safe alternatives like `firstOrNull`, `lastOrNull`, `singleOrNull`. These methods throw `StateError` when the collection is empty or doesn't meet the required conditions, leading to crashes in production.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D014)
- **Principles**: CODE_QUALITY, SAFETY, ERROR_PREVENTION
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D015 – Ensure copyWith includes all constructor parameters

- **Objective**: Maintain data integrity and completeness in immutable objects
- **Details**: 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.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D015)
- **Principles**: CODE_QUALITY, IMMUTABILITY, DATA_INTEGRITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D016 – Project should have tests

- **Objective**: Ensure code quality and prevent regressions through automated testing
- **Details**: 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. Without tests, code changes become risky and technical debt accumulates. Projects should have at least one test file to demonstrate testing infrastructure is in place.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D016)
- **Principles**: CODE_QUALITY, TESTING, MAINTAINABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D017 – Pubspec dependencies should be reviewed regularly

- **Objective**: Ensure dependencies are kept up-to-date for security and stability
- **Details**: Dependencies in `pubspec.yaml` should be reviewed and updated regularly (default: every 4 months). Outdated dependencies may contain security vulnerabilities, bugs, or miss performance improvements. Regular reviews help maintain project health and reduce technical debt. The rule checks the last modification time of `pubspec.lock` (or `pubspec.yaml` if lock file is not available) and warns if it exceeds the configured threshold. This encourages teams to regularly audit dependencies, update to newer versions, and test for compatibility issues.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D017)
- **Principles**: SECURITY, MAINTAINABILITY, CODE_QUALITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D018 – Remove Commented-Out Code

- **Objective**: Keep codebase clean by removing commented-out code
- **Details**: Commented-out code should be removed instead of being left in the source files. Dead code comments create clutter, make the codebase harder to read, and cause confusion about what code is actually active. If you need to reference old code, use version control systems (Git) to track history. The rule detects blocks of 2 or more consecutive lines that appear to be commented-out code (containing keywords like var, if, class, function calls, operators, etc.) and suggests removing them. Documentation comments (///, /**) are excluded from this check.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D018)
- **Principles**: CODE_QUALITY, MAINTAINABILITY, READABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D019 – Avoid Single Child in Multi-Child Widget

- **Objective**: Use appropriate widget types for the number of children
- **Details**: Multi-child widgets like Column, Row, Wrap, Stack, Flex, ListView, GridView, and CustomScrollView are designed to handle multiple children (via `children` or `slivers` parameters). Using these widgets with only a single child or sliver is inefficient and indicates poor widget choice. Instead, use single-child widgets like Container, SizedBox, Padding, or Center which are optimized for single children. This improves performance and makes the code intent clearer.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D019)
- **Principles**: CODE_QUALITY, PERFORMANCE, MAINTAINABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning
### 📘 Rule D020 – Limit If/Else Branches

- **Objective**: Reduce complexity by limiting the number of if/else branches
- **Details**: 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), polymorphism, or strategy pattern. This makes code easier to understand, test, and maintain. The default limit is 3 branches (e.g., if + else if + else).
- **Applies to**: Dart/Flutter
- **Tools**: Custom analyzer (D020)
- **Principles**: CODE_QUALITY, MAINTAINABILITY, READABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D021 – Avoid Negated Boolean Checks

- **Objective**: Improve code readability by avoiding inverted or negated boolean conditions
- **Details**: Negated boolean checks (using `!` operator) make code harder to read and understand. Replace negative conditions with positive ones: use `if (isSuccess)` instead of `if (!isError)`, use `a != b` instead of `!(a == b)`, avoid double negation like `!(!isValid)`. For boolean variables frequently used with negation, consider renaming them to express the positive state (e.g., `isEnabled` instead of using `!isDisabled`). Apply De Morgan's law for compound conditions: `!(a && b)` becomes `!a || !b`.
- **Applies to**: Dart/Flutter
- **Tools**: Custom analyzer (D021)
- **Principles**: CODE_QUALITY, READABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D022 – Use setState Correctly

- **Objective**: Ensure setState is used correctly in StatefulWidget to avoid performance issues and bugs
- **Details**: Common setState anti-patterns include: calling setState inside the build() method (causes infinite rebuild loops), nesting setState calls (unnecessary rebuilds), making multiple setState calls in the same method (should be combined for performance), using async callbacks in setState (state updates should be synchronous). Always perform async operations outside setState and combine multiple state changes into a single setState call.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D022)
- **Principles**: CODE_QUALITY, PERFORMANCE, BEST_PRACTICES
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D023 – Avoid Unnecessary Method Overrides

- **Objective**: Remove methods that only call super with the same parameters as they add no value
- **Details**: 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. Removing these unnecessary overrides improves code readability and reduces maintenance burden.
- **Applies to**: Dart/Flutter
- **Tools**: Custom analyzer (D023)
- **Principles**: CODE_QUALITY, MAINTAINABILITY, READABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D024 – Avoid Unnecessary StatefulWidget

- **Objective**: Use StatelessWidget when no state management is needed to improve performance
- **Details**: StatefulWidget should only be used when the widget needs to maintain mutable state that changes over time. If a widget extends StatefulWidget but its State class has no mutable fields, never calls setState(), and doesn't use lifecycle methods beyond build(), it should be converted to StatelessWidget. StatelessWidget is more efficient as it doesn't maintain state and has less overhead. This rule detects StatefulWidget classes where the State has no mutable fields, no setState() calls, and no state-related lifecycle methods.
- **Applies to**: Flutter/Dart
- **Tools**: Custom analyzer (D024)
- **Principles**: CODE_QUALITY, PERFORMANCE, BEST_PRACTICES
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning

### 📘 Rule D025 – Avoid Nested Conditional Expressions

- **Objective**: Improve code readability by avoiding nested ternary operators
- **Details**: Nested conditional expressions (ternary operators like `condition ? value1 : value2`) reduce code readability and make logic harder to understand. When ternary operators are nested within the then or else branches of another ternary, the code becomes difficult to follow. Instead, use if-else statements for complex conditional logic, or extract the logic into a well-named function. Simple, non-nested ternary operators are acceptable for straightforward cases, but nesting should always be avoided.
- **Applies to**: Dart/Flutter
- **Tools**: Custom analyzer (D025)
- **Principles**: CODE_QUALITY, READABILITY, MAINTAINABILITY
- **Version**: 1.0
- **Status**: activated
- **Severity**: warning
