Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes the strong-mode analysis errors. #290

Merged
merged 2 commits into from
Apr 22, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/async.dart
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@ typedef Timer CreateTimerPeriodic(Duration duration, void callback(Timer));
* Creates a new periodic [Timer] using
* `new Timer.periodic(duration, callback)`.
*/
Timer createTimerPeriodic(Duration duration, void callback(Timer)) =>
Timer createTimerPeriodic(Duration duration, void callback(Timer t)) =>
new Timer.periodic(duration, callback);
2 changes: 1 addition & 1 deletion lib/check.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ int checkListIndex(int index, int size, {message}) {

/// Throws an [ArgumentError] if the given [reference] is `null`. Otherwise,
/// returns the [reference] parameter.
dynamic checkNotNull(reference, {message}) {
dynamic/*=T*/ checkNotNull/*<T>*/(/*=T*/reference, {message}) {
if (reference == null) {
throw new ArgumentError(_resolveMessage(message, 'null pointer'));
}
Expand Down
3 changes: 2 additions & 1 deletion lib/io.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import 'package:quiver/async.dart';
*/
Future<String> byteStreamToString(Stream<List<int>> stream,
{Encoding encoding: UTF8}) {
return stream.transform(encoding.decoder).join();
return stream.transform(
encoding.decoder as StreamTransformer<List<int>, dynamic>).join();
}

/**
Expand Down
6 changes: 3 additions & 3 deletions lib/pattern.dart
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class _MultiPattern extends Pattern {
{Iterable<Pattern> this.exclude});

Iterable<Match> allMatches(String str, [int start = 0]) {
var _allMatches = [];
final _allMatches = <Match>[];
for (var pattern in include) {
var matches = pattern.allMatches(str, start);
if (_hasMatch(matches)) {
Expand All @@ -61,10 +61,10 @@ class _MultiPattern extends Pattern {
}
}
}
_allMatches.add(matches);
_allMatches.addAll(matches);
}
}
return _allMatches.expand((x) => x);
return _allMatches;
}

Match matchAsPrefix(String str, [int start = 0]) {
Expand Down
4 changes: 3 additions & 1 deletion lib/src/async/future_stream.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ part of quiver.async;
* return new FutureStream(futureOfStream);
*/
class FutureStream<T> extends Stream<T> {
static /*=T*/ _identity/*<T>*/(/*=T*/ t) => t;

Future<Stream<T>> _future;
StreamController<T> _controller;
StreamSubscription _subscription;

FutureStream(Future<Stream<T>> future, {bool broadcast: false}) {
_future = future.catchError((e, stackTrace) {
_future = future.then(_identity, onError: (e, stackTrace) {
// Since [controller] is synchronous, it's likely that emitting an error
// will cause it to be cancelled before we call close.
if (_controller != null) {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/async/metronome.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class Metronome extends Stream<DateTime> {
final DateTime anchor;

Timer _timer;
StreamController _controller;
StreamController<DateTime> _controller;
final int _intervalMs;
final int _anchorMs;

Expand Down
12 changes: 6 additions & 6 deletions lib/src/async/stream_buffer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class UnderflowError extends Error {
* Throws [UnderflowError] if [throwOnError] is true. Useful for unexpected
* [Socket] disconnects.
*/
class StreamBuffer<T> implements StreamConsumer {
class StreamBuffer<T> implements StreamConsumer<T> {
List _chunks = [];
int _offset = 0;
int _counter = 0; // sum(_chunks[*].length) - _offset
Expand Down Expand Up @@ -91,17 +91,17 @@ class StreamBuffer<T> implements StreamConsumer {

List<T> _consume(int size) {
var follower = 0;
var ret = new List(size);
var ret = new List<T>(size);
var leftToRead = size;
while (leftToRead > 0) {
var chunk = _chunks.first;
var listCap = (chunk is List) ? chunk.length - _offset : 1;
var subsize = leftToRead > listCap ? listCap : leftToRead;
if (chunk is List) {
ret.setRange(follower, follower + subsize,
chunk.getRange(_offset, _offset + subsize));
(chunk as List<T>).getRange(_offset, _offset + subsize));
} else {
ret[follower] = chunk;
ret[follower] = chunk as T;
}
follower += subsize;
_offset += subsize;
Expand Down Expand Up @@ -133,7 +133,7 @@ class StreamBuffer<T> implements StreamConsumer {
if (size <= buffered && _readers.isEmpty) {
return new Future.value(_consume(size));
}
Completer completer = new Completer<List<T>>();
final completer = new Completer<List<T>>();
_readers.add(new _ReaderInWaiting<List<T>>(size, completer));
return completer.future;
}
Expand All @@ -149,7 +149,7 @@ class StreamBuffer<T> implements StreamConsumer {
Completer streamDone = new Completer();
_sub = stream.listen((items) {
_chunks.add(items);
_counter += items is List ? items.length : 1;
_counter += items is List ? (items as List).length : 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vsmenon @leafpetersen Can this be inferred?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think not, if I read the code correctly, because of the Dart rules about type promotion. In regular Dart, items is dynamic, and promotion is not allowed to promote from dynamic. We allow promotion from dynamic in strong mode, but we still don't allow promotion between non-subtype related types, and I believe (if I read this correctly) that items will be inferred to have type T, and T and List are not subtype related, and so no type promotion will be done.

if (limited && _counter >= limit) {
_sub.pause();
}
Expand Down
6 changes: 3 additions & 3 deletions lib/src/async/stream_router.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class StreamRouter<T> {
final Stream<T> _incoming;
StreamSubscription _subscription;

final List<_Route> _routes = <_Route>[];
final List<_Route<T>> _routes = <_Route<T>>[];
final StreamController<T> _defaultController =
new StreamController<T>.broadcast();

Expand Down Expand Up @@ -75,9 +75,9 @@ class StreamRouter<T> {

typedef bool _Predicate(event);

class _Route {
class _Route<T> {
final _Predicate predicate;
final StreamController controller;
final StreamController<T> controller;

_Route(this.predicate, this.controller);
}
8 changes: 4 additions & 4 deletions lib/src/cache/map_cache.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ class MapCache<K, V> implements Cache<K, V> {
var valOrFuture = ifAbsent(key);
if (valOrFuture is Future) {
return valOrFuture.then((v) {
_map[key] = v;
return v;
_map[key] = v as V;
return v as V;
});
} else {
_map[key] = valOrFuture;
return new Future.value(valOrFuture);
_map[key] = valOrFuture as V;
return new Future<V>.value(valOrFuture);
}
}
return new Future.value(_map[key]);
Expand Down
7 changes: 4 additions & 3 deletions lib/src/collection/delegates/iterable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,15 @@ abstract class DelegatingIterable<E> implements Iterable<E> {

bool every(bool test(E element)) => delegate.every(test);

Iterable expand(Iterable f(E element)) => delegate.expand(f);
Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element)) => delegate.expand(f);

E get first => delegate.first;

E firstWhere(bool test(E element), {E orElse()}) =>
delegate.firstWhere(test, orElse: orElse);

fold(initialValue, combine(previousValue, E element)) =>
dynamic/*=T*/ fold/*<T>*/(var/*=T*/ initialValue,
dynamic/*=T*/ combine(var/*=T*/ previousValue, E element)) =>
delegate.fold(initialValue, combine);

void forEach(void f(E element)) => delegate.forEach(f);
Expand All @@ -65,7 +66,7 @@ abstract class DelegatingIterable<E> implements Iterable<E> {

int get length => delegate.length;

Iterable map(f(E element)) => delegate.map(f);
Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E e)) => delegate.map(f);

E reduce(E combine(E value, E element)) => delegate.reduce(combine);

Expand Down
10 changes: 5 additions & 5 deletions lib/src/collection/lru_map.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ abstract class LruMap<K, V> implements Map<K, V> {
/**
* Creates a [LruMap] instance with the default implementation.
*/
factory LruMap({int maximumSize}) = LinkedLruHashMap;
factory LruMap({int maximumSize}) = LinkedLruHashMap<K, V>;

/**
* Maximum size of the [Map]. If [length] exceeds this value at any time,
Expand Down Expand Up @@ -102,10 +102,10 @@ class LinkedLruHashMap<K, V> implements LruMap<K, V> {
}

@override
bool containsKey(K key) => _entries.containsKey(key);
bool containsKey(Object key) => _entries.containsKey(key);

@override
bool containsValue(V value) => values.contains(value);
bool containsValue(Object value) => values.contains(value);

/**
* Applies [action] to each key-value pair of the map in order of MRU to LRU.
Expand Down Expand Up @@ -193,7 +193,7 @@ class LinkedLruHashMap<K, V> implements LruMap<K, V> {
* need information about entries without modifying their position.
*/
@override
V operator[](K key) {
V operator[](Object key) {
final entry = _entries[key];
if (entry != null) {
_promoteEntry(entry);
Expand Down Expand Up @@ -222,7 +222,7 @@ class LinkedLruHashMap<K, V> implements LruMap<K, V> {
}

@override
V remove(K key) {
V remove(Object key) {
final entry = _entries.remove(key);
if (entry != null) {
if (entry == _head) {
Expand Down
19 changes: 10 additions & 9 deletions lib/src/collection/multimap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ abstract class Multimap<K, V> {
*/
abstract class _BaseMultimap<K, V, C extends Iterable<V>>
implements Multimap<K, V> {
static _id(x) => x;
static /*=T*/ _id/*<T>*/(/*=T*/ x) => x;

_BaseMultimap();

Expand All @@ -165,9 +165,9 @@ abstract class _BaseMultimap<K, V, C extends Iterable<V>>
}
}

final Map<K, Iterable<V>> _map = new HashMap();
final Map<K, C> _map = new HashMap();

Iterable<V> _create();
C _create();
void _add(C iterable, V value);
void _addAll(C iterable, Iterable<V> value);
void _clear(C iterable);
Expand Down Expand Up @@ -222,15 +222,15 @@ abstract class _BaseMultimap<K, V, C extends Iterable<V>>
retValues.addAll(values);
values.clear();
}
return retValues;
return retValues as Iterable<V>;
}

void clear() {
_map.forEach((K key, Iterable<V> value) => _clear(value));
_map.clear();
}

void forEachKey(void f(K key, Iterable<V> value)) => _map.forEach(f);
void forEachKey(void f(K key, C value)) => _map.forEach(f);

void forEach(void f(K key, V value)) {
_map.forEach((K key, Iterable<V> values) {
Expand Down Expand Up @@ -407,7 +407,7 @@ class _WrappedIterable<K, V, C extends Iterable<V>> implements Iterable<V> {
return _delegate.every(test);
}

Iterable expand(Iterable f(V element)) {
Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(V element)) {
_syncDelegate();
return _delegate.expand(f);
}
Expand All @@ -422,7 +422,8 @@ class _WrappedIterable<K, V, C extends Iterable<V>> implements Iterable<V> {
return _delegate.firstWhere(test, orElse: orElse);
}

fold(initialValue, combine(previousValue, V element)) {
dynamic/*=T*/ fold/*<T>*/(var/*=T*/ initialValue,
dynamic/*=T*/ combine(var/*=T*/ previousValue, V element)) {
_syncDelegate();
return _delegate.fold(initialValue, combine);
}
Expand Down Expand Up @@ -467,7 +468,7 @@ class _WrappedIterable<K, V, C extends Iterable<V>> implements Iterable<V> {
return _delegate.length;
}

Iterable map(f(V element)) {
Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(V element)) {
_syncDelegate();
return _delegate.map(f);
}
Expand Down Expand Up @@ -530,7 +531,7 @@ class _WrappedIterable<K, V, C extends Iterable<V>> implements Iterable<V> {

class _WrappedList<K, V> extends _WrappedIterable<K, V, List<V>>
implements List<V> {
_WrappedList(Map<K, List<V>> map, K key, List<V> delegate)
_WrappedList(Map<K, Iterable<V>> map, K key, List<V> delegate)
: super(map, key, delegate);

V operator [](int index) => elementAt(index);
Expand Down
24 changes: 12 additions & 12 deletions lib/src/collection/treeset.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ abstract class TreeSet<V> extends IterableBase<V> implements Set<V> {
* default `(a, b) => a.compareTo(b)`.
*/
factory TreeSet({Comparator<V> comparator}) {
if (comparator == null) {
comparator = (a, b) => a.compareTo(b);
}
comparator ??= (a, b) => (a as dynamic).compareTo(b);
return new AvlTreeSet(comparator: comparator);
}

Expand Down Expand Up @@ -148,7 +146,7 @@ abstract class _TreeNode<V> {
if (node.left != null) {
return node.left.maximumNode;
}
while (node.parent != null && node.parent._left == node) {
while (node.parent != null && node.parent.left == node) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh oh! Seems like our tests are not reaching this code. @cbracken

node = node.parent;
}
return node.parent;
Expand Down Expand Up @@ -438,7 +436,9 @@ class AvlTreeSet<V> extends TreeSet<V> {
}

bool remove(Object item) {
AvlNode<V> x = _getNode(item);
if (item is! V) return false;

AvlNode<V> x = _getNode(item as V);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will throw if item is not a V, is this the intended behaviour?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_getNode feeds item into comparator, which is generic and demands a V. I would therefore go further and make item parameter V rather than Object.

@cbracken What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, nvm, we are implementing Iterable. In that case we can probably do this:

if (item is! V) {
  return false;
}

...

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shame that the analyzer doesn't infer that... FYI filed dart-lang/sdk#26195

if (x != null) {
_removeNode(x);
return true;
Expand Down Expand Up @@ -627,9 +627,9 @@ class AvlTreeSet<V> extends TreeSet<V> {
* See [Set.retainAll]
*/
void retainAll(Iterable<Object> elements) {
List<V> chosen = [];
List<V> chosen = <V>[];
for (var target in elements) {
if (contains(target)) {
if (target is V && contains(target)) {
chosen.add(target);
}
}
Expand Down Expand Up @@ -686,11 +686,11 @@ class AvlTreeSet<V> extends TreeSet<V> {
* See [Set.lookup]
*/
V lookup(Object element) {
if (element == null || _root == null) return null;
if (element is! V || _root == null) return null;
AvlNode<V> x = _root;
int compare = 0;
while (x != null) {
compare = comparator(element, x.object);
compare = comparator(element as V, x.object);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar situation here. It seems everywhere we take Object we first should check

if (element is! V) {
  // return false, or otherwise ignore the element
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the check to the preconditions

if (compare == 0) {
return x.object;
} else if (compare < 0) {
Expand Down Expand Up @@ -792,8 +792,8 @@ class AvlTreeSet<V> extends TreeSet<V> {
Set<V> intersection(Set<Object> other) {
TreeSet<V> set = new TreeSet(comparator: comparator);

// Opitimized for sorted sets
if (other is TreeSet) {
// Optimized for sorted sets
if (other is TreeSet<V>) {
var i1 = iterator;
var i2 = other.iterator;
var hasMore1 = i1.moveNext();
Expand Down Expand Up @@ -925,7 +925,7 @@ class _AvlTreeIterator<V> implements BidirectionalIterator<V> {
final bool reversed;
final AvlTreeSet<V> tree;
final int _modCountGuard;
final Object anchorObject;
final V anchorObject;
final bool inclusive;

_IteratorMove _moveNext;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/iterables/cycle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class _CycleIterator<T> implements Iterator<T> {
final Iterable<T> _iterable;
Iterator<T> _iterator;

_CycleIterator(_iterable)
_CycleIterator(Iterable<T> _iterable)
: _iterable = _iterable,
_iterator = _iterable.iterator;

Expand Down
Loading