squiggly 1.0.3 copy "squiggly: ^1.0.3" to clipboard
squiggly: ^1.0.3 copied to clipboard

A Dart analyzer plugin that provides custom linting rules and code analysis for Dart projects.

Squiggly #

GitHub Actions pub package License: MIT Star on GitHub

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 DeepCollectionEquality from the collection package for proper equality comparison. Make sure to add collection to 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.

0
likes
140
points
345
downloads

Publisher

verified publisherklasu.dev

Weekly Downloads

A Dart analyzer plugin that provides custom linting rules and code analysis for Dart projects.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

analysis_server_plugin, analyzer, analyzer_plugin, meta

More

Packages that depend on squiggly