Fix strong mode warnings.
See also https://codereview.chromium.org/1817463002/.
R=het@google.com, ochafik@google.com
Review URL: https://codereview.chromium.org//1831103004 .
diff --git a/.analysis_options b/.analysis_options
new file mode 100644
index 0000000..a10d4c5
--- /dev/null
+++ b/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+ strong-mode: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1ab3393..1425177 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 1.4.1
+
+* Fix all strong mode warnings.
+
## 1.4.0
* Add a `new PriorityQueue()` constructor that forwards to `new
diff --git a/lib/src/algorithms.dart b/lib/src/algorithms.dart
index 2b66d7d..57456a0 100644
--- a/lib/src/algorithms.dart
+++ b/lib/src/algorithms.dart
@@ -5,7 +5,8 @@
import "dart:math" as math;
/// Version of [binarySearch] optimized for comparable keys
-int _comparableBinarySearch(List<Comparable> list, Comparable value) {
+int _comparableBinarySearch/*<T extends Comparable<T>>*/(
+ List<Comparable/*<T>*/> list, Comparable/*<T>*/ value) {
int min = 0;
int max = list.length;
while (min < max) {
@@ -31,7 +32,8 @@
/// the objects.
///
/// Returns -1 if [value] is not in the list by default.
-int binarySearch(List sortedList, value, { int compare(a, b) }) {
+int binarySearch/*<T extends Comparable<T>>*/(
+ List/*<T>*/ sortedList, /*=T*/ value, { int compare(/*=T*/ a, /*=T*/ b) }) {
if (compare == null) {
return _comparableBinarySearch(sortedList, value);
}
@@ -79,7 +81,8 @@
///
/// Returns [sortedList.length] if all the items in [sortedList] compare less
/// than [value].
-int lowerBound(List sortedList, value, { int compare(a, b) }) {
+int lowerBound/*<T extends Comparable<T>>*/(
+ List/*<T>*/ sortedList, /*=T*/ value, { int compare(/*=T*/ a, /*=T*/ b) }) {
if (compare == null) {
return _comparableLowerBound(sortedList, value);
}
diff --git a/lib/src/canonicalized_map.dart b/lib/src/canonicalized_map.dart
index d967f70..cc78105 100644
--- a/lib/src/canonicalized_map.dart
+++ b/lib/src/canonicalized_map.dart
@@ -6,6 +6,10 @@
import 'utils.dart';
+typedef C _Canonicalize<C, K>(K key);
+
+typedef bool _IsValidKey(Object key);
+
/// A map whose keys are converted to canonical values of type `C`.
///
/// This is useful for using case-insensitive String keys, for example. It's
@@ -16,9 +20,9 @@
/// By default, `null` is allowed as a key. It can be forbidden via the
/// `isValidKey` parameter.
class CanonicalizedMap<C, K, V> implements Map<K, V> {
- final Function _canonicalize;
+ final _Canonicalize<C, K> _canonicalize;
- final Function _isValidKeyFn;
+ final _IsValidKey _isValidKeyFn;
final _base = new Map<C, Pair<K, V>>();
@@ -52,7 +56,7 @@
V operator [](Object key) {
if (!_isValidKey(key)) return null;
- var pair = _base[_canonicalize(key)];
+ var pair = _base[_canonicalize(key as K)];
return pair == null ? null : pair.last;
}
@@ -71,7 +75,7 @@
bool containsKey(Object key) {
if (!_isValidKey(key)) return false;
- return _base.containsKey(_canonicalize(key));
+ return _base.containsKey(_canonicalize(key as K));
}
bool containsValue(Object value) =>
@@ -96,7 +100,7 @@
V remove(Object key) {
if (!_isValidKey(key)) return null;
- var pair = _base.remove(_canonicalize(key));
+ var pair = _base.remove(_canonicalize(key as K));
return pair == null ? null : pair.last;
}
diff --git a/lib/src/equality.dart b/lib/src/equality.dart
index 5a0d074..09f10a6 100644
--- a/lib/src/equality.dart
+++ b/lib/src/equality.dart
@@ -8,7 +8,7 @@
/// A generic equality relation on objects.
abstract class Equality<E> {
- const factory Equality() = DefaultEquality;
+ const factory Equality() = DefaultEquality<E>;
/// Compare two elements for being equal.
///
@@ -32,18 +32,18 @@
///
/// This equality uses the objects' own [Object.==] and [Object.hashCode] for
/// the equality.
-class DefaultEquality implements Equality {
+class DefaultEquality<E> implements Equality<E> {
const DefaultEquality();
- bool equals(Object e1, Object e2) => e1 == e2;
- int hash(Object e) => e.hashCode;
+ bool equals(E e1, E e2) => e1 == e2;
+ int hash(E e) => e.hashCode;
bool isValidKey(Object o) => true;
}
/// Equality of objects that compares only the identity of the objects.
-class IdentityEquality implements Equality {
+class IdentityEquality<E> implements Equality<E> {
const IdentityEquality();
- bool equals(Object e1, Object e2) => identical(e1, e2);
- int hash(Object e) => identityHashCode(e);
+ bool equals(E e1, E e2) => identical(e1, e2);
+ int hash(E e) => identityHashCode(e);
bool isValidKey(Object o) => true;
}
@@ -59,8 +59,8 @@
bool equals(Iterable<E> elements1, Iterable<E> elements2) {
if (identical(elements1, elements2)) return true;
if (elements1 == null || elements2 == null) return false;
- Iterator it1 = elements1.iterator;
- Iterator it2 = elements2.iterator;
+ var it1 = elements1.iterator;
+ var it2 = elements2.iterator;
while (true) {
bool hasNext = it1.moveNext();
if (hasNext != it2.moveNext()) return false;
diff --git a/lib/src/iterable_zip.dart b/lib/src/iterable_zip.dart
index 30acb0e..638c686 100644
--- a/lib/src/iterable_zip.dart
+++ b/lib/src/iterable_zip.dart
@@ -13,24 +13,27 @@
/// combined into a single list, which becomes the next value of this
/// [Iterable]'s [Iterator]. As soon as any of the iterators run out,
/// the zipped iterator also stops.
-class IterableZip extends IterableBase<List> {
- final Iterable<Iterable> _iterables;
- IterableZip(Iterable<Iterable> iterables)
+class IterableZip<T> extends IterableBase<List<T>> {
+ final Iterable<Iterable<T>> _iterables;
+
+ IterableZip(Iterable<Iterable<T>> iterables)
: this._iterables = iterables;
/// Returns an iterator that combines values of the iterables' iterators
/// as long as they all have values.
- Iterator<List> get iterator {
- List iterators = _iterables.map((x) => x.iterator).toList(growable: false);
+ Iterator<List<T>> get iterator {
+ var iterators = _iterables.map((x) => x.iterator).toList(growable: false);
// TODO(lrn): Return an empty iterator directly if iterators is empty?
- return new _IteratorZip(iterators);
+ return new _IteratorZip<T>(iterators);
}
}
-class _IteratorZip implements Iterator<List> {
- final List<Iterator> _iterators;
- List _current;
- _IteratorZip(List iterators) : _iterators = iterators;
+class _IteratorZip<T> implements Iterator<List<T>> {
+ final List<Iterator<T>> _iterators;
+ List<T> _current;
+
+ _IteratorZip(List<Iterator<T>> iterators) : _iterators = iterators;
+
bool moveNext() {
if (_iterators.isEmpty) return false;
for (int i = 0; i < _iterators.length; i++) {
@@ -46,5 +49,5 @@
return true;
}
- List get current => _current;
+ List<T> get current => _current;
}
diff --git a/lib/src/priority_queue.dart b/lib/src/priority_queue.dart
index 64fd84f..de91f15 100644
--- a/lib/src/priority_queue.dart
+++ b/lib/src/priority_queue.dart
@@ -16,7 +16,9 @@
/// elements. An element that compares as less than another element has
/// a higher priority.
///
- /// If [comparison] is omitted, it defaults to [Comparable.compare].
+ /// If [comparison] is omitted, it defaults to [Comparable.compare]. If this
+ /// is the case, `E` must implement [Comparable], and this is checked at
+ /// runtime for every comparison.
factory PriorityQueue([int comparison(E e1, E e2)]) = HeapPriorityQueue<E>;
/// Number of elements in the queue.
@@ -121,7 +123,7 @@
static const int _INITIAL_CAPACITY = 7;
/// The comparison being used to compare the priority of elements.
- final Comparator comparison;
+ final Comparator<E> comparison;
/// List implementation of a heap.
List<E> _queue = new List<E>(_INITIAL_CAPACITY);
@@ -137,9 +139,12 @@
/// elements. An element that compares as less than another element has
/// a higher priority.
///
- /// If [comparison] is omitted, it defaults to [Comparable.compare].
+ /// If [comparison] is omitted, it defaults to [Comparable.compare]. If this
+ /// is the case, `E` must implement [Comparable], and this is checked at
+ /// runtime for every comparison.
HeapPriorityQueue([int comparison(E e1, E e2)])
- : comparison = (comparison != null) ? comparison : Comparable.compare;
+ : comparison = comparison ??
+ ((e1, e2) => (e1 as Comparable).compareTo(e2));
void add(E element) {
_add(element);
diff --git a/lib/src/queue_list.dart b/lib/src/queue_list.dart
index a12f0b4..bf75f33 100644
--- a/lib/src/queue_list.dart
+++ b/lib/src/queue_list.dart
@@ -35,7 +35,7 @@
int length = source.length;
QueueList<E> queue = new QueueList(length + 1);
assert(queue._table.length > length);
- List sourceList = source;
+ var sourceList = source;
queue._table.setRange(0, length, sourceList, 0);
queue._tail = length;
return queue;
@@ -52,7 +52,7 @@
void addAll(Iterable<E> elements) {
if (elements is List) {
- List list = elements;
+ var list = elements;
int addCount = list.length;
int length = this.length;
if (length + addCount >= _table.length) {
diff --git a/lib/src/unmodifiable_wrappers.dart b/lib/src/unmodifiable_wrappers.dart
index 1f78470..6003286 100644
--- a/lib/src/unmodifiable_wrappers.dart
+++ b/lib/src/unmodifiable_wrappers.dart
@@ -25,7 +25,7 @@
/// Mixin class that implements a throwing version of all list operations that
/// change the List's length.
abstract class NonGrowableListMixin<E> implements List<E> {
- static _throw() {
+ static /*=T*/ _throw/*<T>*/() {
throw new UnsupportedError(
"Cannot change the length of a fixed-length list");
}
@@ -98,7 +98,7 @@
/// Mixin class that implements a throwing version of all set operations that
/// change the Set.
abstract class UnmodifiableSetMixin<E> implements Set<E> {
- _throw() {
+ static /*=T*/ _throw/*<T>*/() {
throw new UnsupportedError("Cannot modify an unmodifiable Set");
}
@@ -138,7 +138,7 @@
/// Mixin class that implements a throwing version of all map operations that
/// change the Map.
abstract class UnmodifiableMapMixin<K, V> implements Map<K, V> {
- static _throw() {
+ static /*=T*/ _throw/*<T>*/() {
throw new UnsupportedError("Cannot modify an unmodifiable Map");
}
diff --git a/lib/src/wrappers.dart b/lib/src/wrappers.dart
index ee03b5f..fcd3315 100644
--- a/lib/src/wrappers.dart
+++ b/lib/src/wrappers.dart
@@ -7,6 +7,8 @@
import "unmodifiable_wrappers.dart";
+typedef K _KeyForValue<K, V>(V value);
+
/// A base class for delegating iterables.
///
/// Subclasses can provide a [_base] that should be delegated to. Unlike
@@ -24,14 +26,17 @@
bool every(bool test(E element)) => _base.every(test);
- Iterable expand(Iterable f(E element)) => _base.expand(f);
+ Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element)) =>
+ _base.expand(f);
E get first => _base.first;
E firstWhere(bool test(E element), {E orElse()}) =>
_base.firstWhere(test, orElse: orElse);
- fold(initialValue, combine(previousValue, E element)) =>
+ /*=T*/ fold/*<T>*/(
+ /*=T*/ initialValue,
+ /*=T*/ combine(/*=T*/ previousValue, E element)) =>
_base.fold(initialValue, combine);
void forEach(void f(E element)) => _base.forEach(f);
@@ -51,7 +56,7 @@
int get length => _base.length;
- Iterable map(f(E element)) => _base.map(f);
+ Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) => _base.map(f);
E reduce(E combine(E value, E element)) => _base.reduce(combine);
@@ -391,7 +396,7 @@
}
/// Creates a modifiable [Set] view of the values of a [Map].
-///
+///
/// The `Set` view assumes that the keys of the `Map` can be uniquely determined
/// from the values. The `keyForValue` function passed to the constructor finds
/// the key for a single value. The `keyForValue` function should be consistent
@@ -413,7 +418,7 @@
/// Effectively, the map will act as a kind of index for the set.
class MapValueSet<K, V> extends _DelegatingIterableBase<V> implements Set<V> {
final Map<K, V> _baseMap;
- final Function _keyForValue;
+ final _KeyForValue<K, V> _keyForValue;
/// Creates a new [MapValueSet] based on [base].
///
@@ -428,7 +433,9 @@
bool contains(Object element) {
if (element != null && element is! V) return false;
- return _baseMap.containsKey(_keyForValue(element));
+ var key = _keyForValue(element as V);
+
+ return _baseMap.containsKey(key);
}
bool get isEmpty => _baseMap.isEmpty;
@@ -474,11 +481,17 @@
/// may be different than the equality operation [this] uses.
Set<V> intersection(Set<Object> other) => where(other.contains).toSet();
- V lookup(Object element) => _baseMap[_keyForValue(element)];
+ V lookup(Object element) {
+ if (element != null && element is! V) return null;
+ var key = _keyForValue(element as V);
- bool remove(Object value) {
- if (value != null && value is! V) return false;
- var key = _keyForValue(value);
+ return _baseMap[key];
+ }
+
+ bool remove(Object element) {
+ if (element != null && element is! V) return false;
+ var key = _keyForValue(element as V);
+
if (!_baseMap.containsKey(key)) return false;
_baseMap.remove(key);
return true;
@@ -498,7 +511,8 @@
var valuesToRetain = new Set<V>.identity();
for (var element in elements) {
if (element != null && element is! V) continue;
- var key = _keyForValue(element);
+ var key = _keyForValue(element as V);
+
if (!_baseMap.containsKey(key)) continue;
valuesToRetain.add(_baseMap[key]);
}
diff --git a/pubspec.yaml b/pubspec.yaml
index ff2607e..16a5996 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,9 +1,9 @@
name: collection
-version: 1.4.0
+version: 1.4.1
author: Dart Team <misc@dartlang.org>
description: Collections and utilities functions and classes related to collections.
homepage: https://www.github.com/dart-lang/collection
environment:
- sdk: '>=1.5.0 <2.0.0'
+ sdk: '>=1.12.0 <2.0.0'
dev_dependencies:
test: '^0.12.0'
diff --git a/test/priority_queue_test.dart b/test/priority_queue_test.dart
index c6966d6..1aabcc1 100644
--- a/test/priority_queue_test.dart
+++ b/test/priority_queue_test.dart
@@ -6,7 +6,7 @@
import "package:test/test.dart";
-import "package:collection/priority_queue.dart";
+import "package:collection/src/priority_queue.dart";
void main() {
testDefault();
diff --git a/test/wrapper_test.dart b/test/wrapper_test.dart
index 3f68aa9..035783e 100644
--- a/test/wrapper_test.dart
+++ b/test/wrapper_test.dart
@@ -85,7 +85,6 @@
// argument to DelegatingIterable/Set/List.
class IterableNSM extends NSM implements Iterable, Set, List, Queue {
IterableNSM(action(Invocation i)) : super(action);
- noSuchMethod(Invocation i) => super.noSuchMethod(i); // Silence warnings
toString() => super.noSuchMethod(TO_STRING_INVOCATION);
}
@@ -120,7 +119,6 @@
// Like NSM but implements Map to allow as argument for DelegatingMap.
class MapNSM extends NSM implements Map {
MapNSM(action(Invocation i)) : super(action);
- noSuchMethod(Invocation i) => super.noSuchMethod(i);
toString() => super.noSuchMethod(TO_STRING_INVOCATION);
}