Skip to content

Commit 9a13cec

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 81fcbef commit 9a13cec

File tree

6 files changed

+53
-41
lines changed

6 files changed

+53
-41
lines changed

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

-10
Original file line numberDiff line numberDiff line change
@@ -193,14 +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-
// ignore: provide_deprecation_message
199-
@deprecated
200-
set first(Object? _) => _throw();
201-
202-
/// Throws an [UnsupportedError].
203-
// ignore: provide_deprecation_message
204-
@deprecated
205-
set last(Object? _) => _throw();
206196
}

pkgs/collection/pubspec.yaml

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: collection
2-
version: 1.20.0-wip
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
@@ -8,11 +8,15 @@ issue_tracker: https://github.com/dart-lang/core/issues?q=is%3Aissue+is%3Aopen+l
88
topics:
99
- collections
1010
- data-structures
11+
- equality
1112

1213
environment:
13-
sdk: ^3.4.0
14+
sdk: ^3.7.0
15+
16+
dependencies:
17+
meta: ^1.16.0
1418

1519
dev_dependencies:
1620
benchmark_harness: ^2.3.1
17-
dart_flutter_team_lints: ^3.0.0
18-
test: ^1.16.6
21+
dart_flutter_team_lints: ^3.3.0
22+
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
@@ -2225,7 +2225,7 @@ Iterable<T> iterable<T>(Iterable<T> values) sync* {
22252225
yield* values;
22262226
}
22272227

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

22302230
String toString(Object? o) => '$o';
22312231

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)