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;
+}