Skip to content

Commit d174bd0

Browse files
committed
v2.0.0 breaking changes for package:collection
Starts using Dart 3.0 class modifiers. This is a breaking change, making some classes be `final` or `interface` which prevents behavior that was previously possible. Removes existing deprecated API, except for `whereNotNull`. Deprecates API that is available in platform libraries (`IterableZip` class). Changes behavior of `UnorderedIterableEquality`, `SetEquality` and `MapEquality` to assume the compared collections' notions of equality agree with the `Equality` object for elements/keys in the `UnorderedIterableEquality`/ `SetEquality`/`MapEquality` object. This should improve performance of the equality comparisons, which currently try to assume nothing, and therefore cannot use `.contains`/`.containsKey`/`[]` on one collection with keys/values from the other collection Exceptions: - `CanonicalizedMap` marked `@sealed` instead of `final`. Was extended in at least one place. Fix to that package sent.
1 parent 4704472 commit d174bd0

7 files changed

+52
-39
lines changed

pkgs/collection/analysis_options.yaml

-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,4 @@ linter:
1212
- missing_whitespace_between_adjacent_strings
1313
- no_adjacent_strings_in_list
1414
- no_runtimeType_toString
15-
- package_api_docs
1615
- unnecessary_await_in_return

pkgs/collection/lib/src/canonicalized_map.dart

+41-25
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44

55
import 'dart:collection';
66

7+
import 'package:meta/meta.dart';
8+
79
/// A map whose keys are converted to canonical values of type `C`.
810
///
911
/// This is useful for using case-insensitive String keys, for example. It's
1012
/// more efficient than a [LinkedHashMap] with a custom equality operator
1113
/// because it only canonicalizes each key once, rather than doing so for each
1214
/// comparison.
13-
final class CanonicalizedMap<C, K, V> implements Map<K, V> {
15+
@sealed // TODO: Make `final` when no longer extended.
16+
class CanonicalizedMap<C, K, V> implements Map<K, V> {
1417
final C Function(K) _canonicalize;
1518

1619
final bool Function(K)? _isValidKeyFn;
@@ -25,10 +28,11 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
2528
/// The [isValidKey] function is called before calling [canonicalize] for
2629
/// methods that take arbitrary objects. It can be used to filter out keys
2730
/// that can't be canonicalized.
28-
CanonicalizedMap(C Function(K key) canonicalize,
29-
{bool Function(K key)? isValidKey})
30-
: _canonicalize = canonicalize,
31-
_isValidKeyFn = isValidKey;
31+
CanonicalizedMap(
32+
C Function(K key) canonicalize, {
33+
bool Function(K key)? isValidKey,
34+
}) : _canonicalize = canonicalize,
35+
_isValidKeyFn = isValidKey;
3236

3337
/// Creates a canonicalized map that is initialized with the key/value pairs
3438
/// of [other].
@@ -39,10 +43,12 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
3943
/// The [isValidKey] function is called before calling [canonicalize] for
4044
/// methods that take arbitrary objects. It can be used to filter out keys
4145
/// that can't be canonicalized.
42-
CanonicalizedMap.from(Map<K, V> other, C Function(K key) canonicalize,
43-
{bool Function(K key)? isValidKey})
44-
: _canonicalize = canonicalize,
45-
_isValidKeyFn = isValidKey {
46+
CanonicalizedMap.from(
47+
Map<K, V> other,
48+
C Function(K key) canonicalize, {
49+
bool Function(K key)? isValidKey,
50+
}) : _canonicalize = canonicalize,
51+
_isValidKeyFn = isValidKey {
4652
addAll(other);
4753
}
4854

@@ -56,15 +62,19 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
5662
/// methods that take arbitrary objects. It can be used to filter out keys
5763
/// that can't be canonicalized.
5864
CanonicalizedMap.fromEntries(
59-
Iterable<MapEntry<K, V>> entries, C Function(K key) canonicalize,
60-
{bool Function(K key)? isValidKey})
61-
: _canonicalize = canonicalize,
62-
_isValidKeyFn = isValidKey {
65+
Iterable<MapEntry<K, V>> entries,
66+
C Function(K key) canonicalize, {
67+
bool Function(K key)? isValidKey,
68+
}) : _canonicalize = canonicalize,
69+
_isValidKeyFn = isValidKey {
6370
addEntries(entries);
6471
}
6572

6673
CanonicalizedMap._(
67-
this._canonicalize, this._isValidKeyFn, Map<C, MapEntry<K, V>> base) {
74+
this._canonicalize,
75+
this._isValidKeyFn,
76+
Map<C, MapEntry<K, V>> base,
77+
) {
6878
_base.addAll(base);
6979
}
7080

@@ -92,8 +102,11 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
92102
}
93103

94104
@override
95-
void addEntries(Iterable<MapEntry<K, V>> entries) => _base.addEntries(entries
96-
.map((e) => MapEntry(_canonicalize(e.key), MapEntry(e.key, e.value))));
105+
void addEntries(Iterable<MapEntry<K, V>> entries) => _base.addEntries(
106+
entries.map(
107+
(e) => MapEntry(_canonicalize(e.key), MapEntry(e.key, e.value)),
108+
),
109+
);
97110

98111
@override
99112
Map<K2, V2> cast<K2, V2>() => _base.cast<K2, V2>();
@@ -158,14 +171,16 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
158171

159172
@override
160173
V update(K key, V Function(V) update, {V Function()? ifAbsent}) =>
161-
_base.update(_canonicalize(key), (pair) {
162-
var value = pair.value;
163-
var newValue = update(value);
164-
if (identical(newValue, value)) return pair;
165-
return MapEntry(key, newValue);
166-
},
167-
ifAbsent:
168-
ifAbsent == null ? null : () => MapEntry(key, ifAbsent())).value;
174+
_base.update(
175+
_canonicalize(key),
176+
(pair) {
177+
var value = pair.value;
178+
var newValue = update(value);
179+
if (identical(newValue, value)) return pair;
180+
return MapEntry(key, newValue);
181+
},
182+
ifAbsent: ifAbsent == null ? null : () => MapEntry(key, ifAbsent()),
183+
).value;
169184

170185
@override
171186
void updateAll(V Function(K key, V value) update) =>
@@ -193,5 +208,6 @@ final class CanonicalizedMap<C, K, V> implements Map<K, V> {
193208
/// Creates a `Map<C,V>` (with the canonicalized keys).
194209
/// See [toMap].
195210
Map<C, V> toMapOfCanonicalKeys() => Map<C, V>.fromEntries(
196-
_base.entries.map((e) => MapEntry<C, V>(e.key, e.value.value)));
211+
_base.entries.map((e) => MapEntry<C, V>(e.key, e.value.value)),
212+
);
197213
}

pkgs/collection/lib/src/unmodifiable_wrappers.dart

-8
Original file line numberDiff line numberDiff line change
@@ -193,12 +193,4 @@ abstract mixin class UnmodifiableMapMixin<K, V> implements Map<K, V> {
193193
/// operations that change the map are disallowed.
194194
@override
195195
void clear() => _throw();
196-
197-
/// Throws an [UnsupportedError];
198-
/// operations that change the map are disallowed.
199-
set first(_) => _throw();
200-
201-
/// Throws an [UnsupportedError];
202-
/// operations that change the map are disallowed.
203-
set last(_) => _throw();
204196
}

pkgs/collection/pubspec.yaml

+7-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
name: collection
2-
version: 1.19.1
2+
version: 1.20.0-2.0.0.wip
33
description: >-
44
Collections and utilities functions and classes related to collections.
55
repository: https://github.com/dart-lang/core/tree/main/pkgs/collection
66

77
topics:
88
- collections
99
- data-structures
10+
- equality
1011

1112
environment:
12-
sdk: ^3.4.0
13+
sdk: ^3.7.0
14+
15+
dependencies:
16+
meta: ^1.16.0
1317

1418
dev_dependencies:
15-
dart_flutter_team_lints: ^3.0.0
19+
dart_flutter_team_lints: ^3.3.0
1620
test: ^1.16.0

pkgs/collection/test/analysis_options.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include: ../analysis_options.yaml
22

3-
# Turn off the avoid_dynamic_calls lint for the test/ directory.
3+
# Turn off common lint violations for the test/ directory.
44
analyzer:
55
errors:
66
avoid_dynamic_calls: ignore

pkgs/collection/test/extensions_test.dart

+1-1
Original file line numberDiff line numberDiff line change
@@ -2051,7 +2051,7 @@ Iterable<T> iterable<T>(Iterable<T> values) sync* {
20512051
yield* values;
20522052
}
20532053

2054-
Never unreachable([_, __, ___]) => fail('Unreachable');
2054+
Never unreachable([Object? _, Object? _, Object? _]) => fail('Unreachable');
20552055

20562056
String toString(Object? o) => '$o';
20572057

pkgs/collection/test/iterable_zip_test.dart

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
// ignore_for_file: deprecated_member_use_from_same_package
6+
57
import 'package:collection/collection.dart';
68
import 'package:test/test.dart';
79

0 commit comments

Comments
 (0)