squiggly 1.0.3
squiggly: ^1.0.3 copied to clipboard
A Dart analyzer plugin that provides custom linting rules and code analysis for Dart projects.
Squiggly #
A Dart analyzer plugin that provides IDE assists and lint rules.
Features #
IDE Assists #
Squiggly provides quick-fix assists accessible via your IDE's action menu:
| Assist | Description |
|---|---|
| Add equality and hashCode overrides | Generates == operator and hashCode getter based on all class fields |
| Add toString override | Generates a toString() method that includes all class fields |
| Add copyWith method | Generates a null-safe copyWith() method based on constructor parameters |
| Implement Data class methods | Adds all missing data class methods (==, hashCode, and copyWith) at once |
Lint Rules #
Squiggly detects when your data class methods are out of sync with your class fields:
| Rule | Description |
|---|---|
equality_incomplete |
Warns when == or hashCode is missing fields |
copywith_incomplete |
Warns when copyWith is missing constructor parameters |
tostring_incomplete |
Warns when toString is missing fields |
Each lint rule comes with a quick-fix to automatically update the method to include all fields.
Installation #
Add squiggly as a dev dependency in your pubspec.yaml:
dev_dependencies:
squiggly: ^1.0.0
Then configure the plugin in your analysis_options.yaml:
plugins:
squiggly:
diagnostics:
equality_incomplete: true
copywith_incomplete: true
tostring_incomplete: true
Usage #
Generated Code Examples #
Equality & HashCode
import 'package:collection/collection.dart';
class Person {
final String name;
final int age;
final List<String> hobbies;
Person(this.name, this.age, this.hobbies);
// Generated by "Add equality and hashCode overrides"
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is Person &&
name == other.name &&
age == other.age &&
const DeepCollectionEquality().equals(hobbies, other.hobbies);
@override
int get hashCode => Object.hash(
name, age, const DeepCollectionEquality().hash(hobbies));
}
Note: When your class contains list, set, or map fields, Squiggly automatically imports and uses
DeepCollectionEqualityfrom thecollectionpackage for proper equality comparison. Make sure to addcollectionto your pubspec.yaml dependencies.
ToString
class Person {
final String name;
final int age;
Person(this.name, this.age);
// Generated by "Add toString override"
@override
String toString() {
return 'Person{name: $name, age: $age}';
}
}
CopyWith
Squiggly generates a null-safe copyWith using record types, allowing you to explicitly set nullable fields to null:
class Person {
final String? name;
final int age;
Person({this.name, required this.age});
// Generated by "Add copyWith method"
Person copyWith({
({String? value})? name,
({int value})? age,
}) {
return Person(
name: name == null ? this.name : name.value,
age: age == null ? this.age : age.value,
);
}
}
// Usage:
final person = Person(name: 'Alice', age: 30);
// Update a field
final updated = person.copyWith(age: (value: 31));
// Set a nullable field to null explicitly
final cleared = person.copyWith(name: (value: null));
// Copy without changes
final copy = person.copyWith();
Incomplete Method Detection #
When you add a new field to your class, Squiggly will warn you if your existing methods don't include it:
class Person {
final String name;
final int age;
final String email; // New field added
Person(this.name, this.age, this.email);
@override
bool operator ==(Object other) => // ⚠️ equality_incomplete: All fields should be included in equality and hashCode: email
identical(this, other) ||
other is Person && name == other.name && age == other.age;
@override
int get hashCode => Object.hashAll([name, age]); // ⚠️ equality_incomplete: All fields should be included in equality and hashCode: email
@override
String toString() {
return 'Person{name: $name, age: $age}'; // ⚠️ tostring_incomplete: All fields should be included in toString: email
}
}
Use the quick-fix to automatically update the methods with the missing fields.
Requirements #
- Dart SDK
^3.10.0
License #
MIT License - see LICENSE for details.