contribute a dart fix declaritive fix
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e21d2e9..9df2428 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -64,3 +64,23 @@
       - name: Run Chrome tests - wasm
         run: dart test --platform chrome --compiler dart2wasm
         if: always() && steps.install.outcome == 'success' && matrix.sdk == 'dev'
+
+  # Test the contributed `dart fix` fixes.
+  dart-fix:
+    needs: analyze
+    runs-on: ${{ matrix.os }}
+    strategy:
+      fail-fast: false
+      matrix:
+        os: [ubuntu-latest]
+        sdk: [main]
+    steps:
+      - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29
+      - uses: dart-lang/setup-dart@f0ead981b4d9a35b37f30d36160575d60931ec30
+        with:
+          sdk: ${{ matrix.sdk }}
+      - name: Install Dart dependencies
+        run: dart pub get
+      - name: Test the declarative fixes
+        run: dart fix --compare-to-golden
+        working-directory: test_fixes
diff --git a/analysis_options.yaml b/analysis_options.yaml
index 3321f3b..7e824f8 100644
--- a/analysis_options.yaml
+++ b/analysis_options.yaml
@@ -3,6 +3,8 @@
 analyzer:
   language:
     strict-casts: true
+  exclude:
+    - test_fixes/**
 
 linter:
   rules:
diff --git a/lib/fix_data.yaml b/lib/fix_data.yaml
new file mode 100644
index 0000000..ed7232b
--- /dev/null
+++ b/lib/fix_data.yaml
@@ -0,0 +1,24 @@
+# Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# Please add new fixes to the top of the file. For documentation about this file
+# format, see https://dart.dev/go/data-driven-fixes.
+
+version: 1
+
+transforms:
+  # whereNotNull() => nonNulls
+  # https://github.com/dart-lang/collection/issues/350
+  - title: "Replace with 'nonNulls'"
+    date: 2024-06-11
+    element:
+      uris: [ 'package:collection/collection.dart' ]
+      inClass: 'IterableNullableExtension'
+      method: 'whereNotNull'
+    changes:
+      - kind: 'replacedBy'
+        newElement:
+          uris: [ 'dart:core' ]
+          inClass: 'NullableIterableExtensions'
+          getter: 'nonNulls'
diff --git a/pubspec.yaml b/pubspec.yaml
index 7a92e22..cd7b9fb 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -13,4 +13,5 @@
 
 dev_dependencies:
   dart_flutter_team_lints: ^3.0.0
+  path: ^1.9.0
   test: ^1.16.0
diff --git a/test/dart_fix_test.dart b/test/dart_fix_test.dart
new file mode 100644
index 0000000..01a6fa9
--- /dev/null
+++ b/test/dart_fix_test.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@TestOn('vm')
+library;
+
+import 'dart:io';
+
+import 'package:path/path.dart' as p;
+import 'package:test/test.dart';
+
+// Used for debugging the test.
+const keepTempDir = false;
+
+void main() {
+  test("'dart fix' integration", () {
+    // create temp dir
+    final tempDir = Directory.systemTemp.createTempSync('test');
+
+    var sdkVersion = Platform.version;
+    if (sdkVersion.contains(' ')) {
+      sdkVersion = sdkVersion.substring(0, sdkVersion.indexOf(' '));
+    }
+
+    try {
+      // set up project
+      writeFile(tempDir, 'pubspec.yaml', '''
+name: test_project
+environment:
+  sdk: '^$sdkVersion'
+dependencies:
+  collection:
+    path: ${Directory.current.path}
+''');
+      final sourceFile = File(p.join('test_fixes', 'renames.dart'));
+      writeFile(
+        tempDir,
+        p.join('lib', sourceFile.name),
+        sourceFile.readAsStringSync(),
+      );
+
+      // run pub get
+      pubGet(tempDir);
+
+      // dart fix
+      dartFix(tempDir);
+
+      // verify no analysis issues
+      dartAnalyze(tempDir);
+    } finally {
+      // ignore: dead_code
+      if (keepTempDir) {
+        print('dart fix test temp dir: ${tempDir.path}');
+      } else {
+        tempDir.deleteSync(recursive: true);
+      }
+    }
+  });
+}
+
+void writeFile(Directory dir, String filePath, String contents) {
+  final file = File(p.join(dir.path, filePath));
+  file.parent.createSync();
+  file.writeAsStringSync(contents);
+}
+
+void pubGet(Directory dir) {
+  exec('pub', ['get'], cwd: dir);
+}
+
+void dartFix(Directory dir) {
+  exec('fix', ['--apply'], cwd: dir);
+}
+
+void dartAnalyze(Directory dir) {
+  exec('analyze', [], cwd: dir);
+}
+
+void exec(String command, List<String> args, {required Directory cwd}) {
+  printOnFailure('dart $command ${args.join(', ')}');
+
+  final result = Process.runSync(
+    Platform.resolvedExecutable,
+    [command, ...args],
+    workingDirectory: cwd.path,
+  );
+
+  var out = result.stdout as String;
+  if (out.isNotEmpty) printOnFailure(out);
+  out = result.stderr as String;
+  if (out.isNotEmpty) printOnFailure(out);
+
+  if (result.exitCode != 0) {
+    fail('dart $command: exitCode ${result.exitCode}');
+  }
+}
+
+extension on File {
+  String get name => p.basename(path);
+}
diff --git a/test_fixes/README.md b/test_fixes/README.md
new file mode 100644
index 0000000..693fff7
--- /dev/null
+++ b/test_fixes/README.md
@@ -0,0 +1,20 @@
+## What's here?
+
+For information about the files in this directory, see
+https://github.com/flutter/flutter/wiki/Data-driven-Fixes#testing.
+
+## Organization
+
+The contents of this directory are used to test the `dart fix` refactorings
+offered by this package. See `lib/dart_fix.yaml` for the fix definitions.
+
+Note that files in this directory are excluded from analysis.
+
+## Running the dart fix tests
+
+In order to test the fixes manually:
+
+```bash
+> cd test_fixes
+> dart fix --compare-to-golden
+```
diff --git a/test_fixes/analysis_options.yaml b/test_fixes/analysis_options.yaml
new file mode 100644
index 0000000..d978f81
--- /dev/null
+++ b/test_fixes/analysis_options.yaml
@@ -0,0 +1 @@
+include: package:dart_flutter_team_lints/analysis_options.yaml
diff --git a/test_fixes/renames.dart b/test_fixes/renames.dart
new file mode 100644
index 0000000..5dd0a5c
--- /dev/null
+++ b/test_fixes/renames.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:collection/collection.dart';
+
+void main() {
+  final list1 = <String?>['foo', 'bar', null, 'baz'];
+  // ignore: unused_local_variable
+  final list2 = list1.whereNotNull();
+}
diff --git a/test_fixes/renames.dart.expect b/test_fixes/renames.dart.expect
new file mode 100644
index 0000000..c0e9949
--- /dev/null
+++ b/test_fixes/renames.dart.expect
@@ -0,0 +1,11 @@
+// Copyright (c) 2024, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:collection/collection.dart';
+
+void main() {
+  final list1 = <String?>['foo', 'bar', null, 'baz'];
+  // ignore: unused_local_variable
+  final list2 = list1.nonNulls;
+}