Add List.stablePartition(), use in CreateConstructorForFinalFields. See https://en.cppreference.com/w/cpp/algorithm/stable_partition Change-Id: I1cf77ed7c057e4e42009ec4dd1d15ee2af7dd128 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/308812 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Reviewed-by: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart index 7cf19d9..cb5de29 100644 --- a/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart +++ b/pkg/analysis_server/lib/src/services/correction/dart/create_constructor_for_final_fields.dart
@@ -11,6 +11,7 @@ import 'package:analyzer/dart/element/element.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:analyzer/dart/element/type.dart'; +import 'package:analyzer/src/utilities/extensions/collection.dart'; import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart'; import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart'; import 'package:analyzer_plugin/utilities/fixes/fixes.dart'; @@ -355,10 +356,9 @@ return; } - final childrenLast = [ - ...fields.whereNot((field) => field.isChild), - ...fields.where((field) => field.isChild), - ]; + final childrenLast = fields.stablePartition( + (field) => !field.isChild, + ); for (final field in childrenLast) { builder.write(', ');
diff --git a/pkg/analyzer/lib/src/utilities/extensions/collection.dart b/pkg/analyzer/lib/src/utilities/extensions/collection.dart index 12478ee..2208634 100644 --- a/pkg/analyzer/lib/src/utilities/extensions/collection.dart +++ b/pkg/analyzer/lib/src/utilities/extensions/collection.dart
@@ -2,6 +2,8 @@ // 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'; + extension IterableExtension<E> on Iterable<E> { /// Returns the fixed-length [List] with elements of `this`. List<E> toFixedList() { @@ -28,6 +30,17 @@ return null; } } + + /// Returns a new list with all elements of the target, arranged such that + /// all elements for which the [predicate] specified returns `true` come + /// before those for which the [predicate] returns `false`. The partitioning + /// is stable, i.e. the relative ordering of the elements is preserved. + List<E> stablePartition(bool Function(E element) predicate) { + return [ + ...where(predicate), + ...whereNot(predicate), + ]; + } } extension SetExtension<E> on Set<E> {
diff --git a/pkg/analyzer/test/src/utilities/extensions/collection_test.dart b/pkg/analyzer/test/src/utilities/extensions/collection_test.dart index e92ab71..e6c85cf 100644 --- a/pkg/analyzer/test/src/utilities/extensions/collection_test.dart +++ b/pkg/analyzer/test/src/utilities/extensions/collection_test.dart
@@ -33,6 +33,17 @@ expect(elements.nextOrNull(2), null); expect(elements.nextOrNull(3), null); } + + test_stablePartition() { + expect( + [0, 1, 2, 3, 4, 5].stablePartition((e) => e.isEven), + [0, 2, 4, 1, 3, 5], + ); + expect( + [5, 4, 3, 2, 1, 0].stablePartition((e) => e.isEven), + [4, 2, 0, 5, 3, 1], + ); + } } @reflectiveTest