Make the analyzer happy about collections.

Fix some typing issues and a few real errors.

Review URL: https://codereview.chromium.org//14048002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@21194 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
lrn@google.com 2013-04-10 11:31:09 +00:00
parent 62358bf5e2
commit 77c8b06377
6 changed files with 193 additions and 139 deletions

View file

@ -25,6 +25,9 @@ abstract class _HashSetBase<E> extends Collection<E> implements Set<E> {
return true;
}
/** Create a new Set of the same type as this. */
Set _newSet();
Set<E> intersection(Set<E> other) {
Set<E> result = _newSet();
if (other.length < this.length) {

View file

@ -292,7 +292,7 @@ abstract class ListMixin<E> implements List<E> {
}
void retainAll(Iterable<E> iterable) {
void retainAll(Iterable<E> elements) {
if (elements is! Set) {
elements = elements.toSet();
}
@ -327,8 +327,19 @@ abstract class ListMixin<E> implements List<E> {
}
}
void clear() { this.length = 0; }
// List interface.
E removeLast() {
if (length == 0) {
throw new StateError("No elements");
}
E result = this[length - 1];
length--;
return result;
}
void sort([Comparator<E> compare]) {
Sort.sort(this, compare);
}
@ -440,8 +451,8 @@ abstract class ListMixin<E> implements List<E> {
if (startIndex < 0) {
return -1;
}
if (startIndex >= a.length) {
startIndex = a.length - 1;
if (startIndex >= this.length) {
startIndex = this.length - 1;
}
}
for (int i = startIndex; i >= 0; i--) {

View file

@ -86,10 +86,10 @@ abstract class _SplayTree<K> {
_SplayTreeNode<K> current = _root;
int comp;
while (true) {
comp = current.key.compareTo(key);
comp = _compare(current.key, key);
if (comp > 0) {
if (current.left == null) break;
comp = current.left.key.compareTo(key);
comp = _compare(current.left.key, key);
if (comp > 0) {
// Rotate right.
_SplayTreeNode<K> tmp = current.left;
@ -104,7 +104,7 @@ abstract class _SplayTree<K> {
current = current.left;
} else if (comp < 0) {
if (current.right == null) break;
comp = current.right.key.compareTo(key);
comp = _compare(current.right.key, key);
if (comp < 0) {
// Rotate left.
_SplayTreeNode<K> tmp = current.right;
@ -256,15 +256,18 @@ class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> {
if (key == null) throw new ArgumentError(key);
if (_root != null) {
int comp = _splay(key);
if (comp == 0) return _root.value;
if (comp == 0) {
_SplayTreeMapNode mapRoot = _root;
return mapRoot.value;
}
}
return null;
}
V remove(Object key) {
if (key is! K) return null;
_SplayTreeMapNode root = _remove(key);
if (root != null) return root.value;
_SplayTreeMapNode mapRoot = _remove(key);
if (mapRoot != null) return mapRoot.value;
return null;
}
@ -274,7 +277,8 @@ class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> {
// the key to the root of the tree.
int comp = _splay(key);
if (comp == 0) {
_root.value = value;
_SplayTreeMapNode mapRoot = _root;
mapRoot.value = value;
return;
}
_addNewRoot(new _SplayTreeMapNode(key, value), comp);
@ -284,7 +288,10 @@ class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> {
V putIfAbsent(K key, V ifAbsent()) {
if (key == null) throw new ArgumentError(key);
int comp = _splay(key);
if (comp == 0) return _root.value;
if (comp == 0) {
_SplayTreeMapNode mapRoot = _root;
return mapRoot.value;
}
int modificationCount = _modificationCount;
int splayCount = _splayCount;
V value = ifAbsent();
@ -330,7 +337,7 @@ class SplayTreeMap<K, V> extends _SplayTree<K> implements Map<K, V> {
bool containsValue(V value) {
bool found = false;
int initialSplayCount = _splayCount;
bool visit(_SplayTreeNode node) {
bool visit(_SplayTreeMapNode node) {
while (node != null) {
if (node.value == value) return true;
if (initialSplayCount != _splayCount) {

View file

@ -117,6 +117,13 @@ abstract class List<E> implements Collection<E> {
*/
void operator []=(int index, E value);
/**
* Returns the number of elements in the list.
*
* The valid indices for a list are 0 through `length - 1`.
*/
int get length;
/**
* Changes the length of the list. If [newLength] is greater than
* the current [length], entries are initialized to [:null:]. Throws

View file

@ -2,6 +2,7 @@
// 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 "dart:collection";
import "package:expect/expect.dart";
testRemove(Collection base) {
@ -106,7 +107,25 @@ void main() {
testRetainAll(base.toSet(), deltaSet);
testRemoveWhere(base.toSet(), deltaSet.contains);
testRetainWhere(base.toSet(), (e) => !deltaSet.contains(e));
// Test the ListBase class's List implementation.
testRemoveAll(new MyList(base.toList()), delta);
testRemoveAll(new MyList(base.toList()), deltaSet);
testRetainAll(new MyList(base.toList()), delta);
testRetainAll(new MyList(base.toList()), deltaSet);
testRemoveWhere(new MyList(base.toList()), deltaSet.contains);
testRetainWhere(new MyList(base.toList()),
(e) => !deltaSet.contains(e));
}
}
}
class MyList<E> extends ListBase<E> {
List<E> _source;
MyList(this._source);
int get length => _source.length;
void set length(int length) { _source.length = length; }
E operator[](int index) => _source[index];
void operator[]=(int index, E value) { _source[index] = value; }
}

View file

@ -2,153 +2,160 @@
// 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 "dart:collection";
import "package:expect/expect.dart";
class ListTest {
void main() {
testFixedLengthList(new List(4));
// ListBase implementation of List.
testFixedLengthList(new MyFixedList(new List(4)));
static testMain() {
testList();
testExpandableList();
testGrowableList(new List());
testGrowableList([]);
testGrowableList(new MyList([]));
}
void expectValues(list, val1, val2, val3, val4) {
Expect.isFalse(list.isEmpty);
Expect.equals(4, list.length);
Expect.equals(list[0], val1);
Expect.equals(list[1], val2);
Expect.equals(list[2], val3);
Expect.equals(list[3], val4);
}
void testClosures(List list) {
testMap(val) {return val * 2 + 10; }
List mapped = list.map(testMap).toList();
Expect.equals(mapped.length, list.length);
for (var i = 0; i < list.length; i++) {
Expect.equals(mapped[i], list[i]*2 + 10);
}
static void expectValues(list, val1, val2, val3, val4) {
Expect.equals(true, list.length == 4);
Expect.equals(true, list.length == 4);
Expect.equals(true, !list.isEmpty);
Expect.equals(list[0], val1);
Expect.equals(list[1], val2);
Expect.equals(list[2], val3);
Expect.equals(list[3], val4);
testFilter(val) { return val == 3; }
Iterable filtered = list.where(testFilter);
Expect.equals(filtered.length, 1);
testEvery(val) { return val != 11; }
bool test = list.every(testEvery);
Expect.isTrue(test);
testSome(val) { return val == 1; }
test = list.any(testSome);
Expect.isTrue(test);
testSomeFirst(val) { return val == 0; }
test = list.any(testSomeFirst);
Expect.isTrue(test);
testSomeLast(val) { return val == (list.length - 1); }
test = list.any(testSomeLast);
Expect.isTrue(test);
}
void testFixedLengthList(List list) {
Expect.equals(list.length, 4);
list[0] = 4;
expectValues(list, 4, null, null, null);
String val = "fisk";
list[1] = val;
expectValues(list, 4, val, null, null);
double d = 2.0;
list[3] = d;
expectValues(list, 4, val, null, d);
for (int i = 0; i < list.length; i++) {
list[i] = i;
}
static void testClosures(List list) {
testMap(val) {return val * 2 + 10; }
List mapped = list.map(testMap).toList();
Expect.equals(mapped.length, list.length);
for (var i = 0; i < list.length; i++) {
Expect.equals(mapped[i], list[i]*2 + 10);
}
testFilter(val) { return val == 3; }
Iterable filtered = list.where(testFilter);
Expect.equals(filtered.length, 1);
testEvery(val) { return val != 11; }
bool test = list.every(testEvery);
Expect.equals(true, test);
testSome(val) { return val == 1; }
test = list.any(testSome);
Expect.equals(true, test);
testSomeFirst(val) { return val == 0; }
test = list.any(testSomeFirst);
Expect.equals(true, test);
testSomeLast(val) { return val == (list.length - 1); }
test = list.any(testSomeLast);
Expect.equals(true, test);
for (int i = 0; i < 4; i++) {
Expect.equals(i, list[i]);
Expect.equals(i, list.indexOf(i));
Expect.equals(i, list.lastIndexOf(i));
}
static void testList() {
List list = new List(4);
Expect.equals(list.length, 4);
list[0] = 4;
expectValues(list, 4, null, null, null);
String val = "fisk";
list[1] = val;
expectValues(list, 4, val, null, null);
double d = 2.0;
list[3] = d;
expectValues(list, 4, val, null, d);
Expect.equals(-1, list.indexOf(100));
Expect.equals(-1, list.lastIndexOf(100));
list[2] = new Yes();
Expect.equals(2, list.indexOf(100));
Expect.equals(2, list.lastIndexOf(100));
list[3] = new Yes();
Expect.equals(2, list.indexOf(100));
Expect.equals(3, list.lastIndexOf(100));
list[2] = 2;
Expect.equals(3, list.indexOf(100));
Expect.equals(3, list.lastIndexOf(100));
list[3] = 3;
Expect.equals(-1, list.indexOf(100));
Expect.equals(-1, list.lastIndexOf(100));
for (int i = 0; i < list.length; i++) {
list[i] = i;
}
testClosures(list);
for (int i = 0; i < 4; i++) {
Expect.equals(i, list[i]);
Expect.equals(i, list.indexOf(i));
Expect.equals(i, list.lastIndexOf(i));
}
Expect.throws(list.clear, (e) => e is UnsupportedError);
}
Expect.equals(-1, list.indexOf(100));
Expect.equals(-1, list.lastIndexOf(100));
list[2] = new Yes();
Expect.equals(2, list.indexOf(100));
Expect.equals(2, list.lastIndexOf(100));
list[3] = new Yes();
Expect.equals(2, list.indexOf(100));
Expect.equals(3, list.lastIndexOf(100));
list[2] = 2;
Expect.equals(3, list.indexOf(100));
Expect.equals(3, list.lastIndexOf(100));
list[3] = 3;
Expect.equals(-1, list.indexOf(100));
Expect.equals(-1, list.lastIndexOf(100));
void testGrowableList(List list) {
Expect.isTrue(list.isEmpty);
Expect.equals(list.length, 0);
list.add(4);
Expect.equals(1, list.length);
Expect.isTrue(!list.isEmpty);
Expect.equals(list.length, 1);
Expect.equals(list.length, 1);
Expect.equals(list.removeLast(), 4);
testClosures(list);
var exception = null;
try {
list.clear();
} on UnsupportedError catch (e) {
exception = e;
}
Expect.equals(true, exception != null);
for (int i = 0; i < 10; i++) {
list.add(i);
}
static void testExpandableList() {
List list = new List();
Expect.equals(true, list.isEmpty);
Expect.equals(list.length, 0);
list.add(4);
Expect.equals(1, list.length);
Expect.equals(true, !list.isEmpty);
Expect.equals(list.length, 1);
Expect.equals(list.length, 1);
Expect.equals(list.removeLast(), 4);
for (int i = 0; i < 10; i++) {
list.add(i);
}
Expect.equals(list.length, 10);
for (int i = 0; i < 10; i++) {
Expect.equals(i, list[i]);
Expect.equals(i, list.indexOf(i));
Expect.equals(i, list.lastIndexOf(i));
}
Expect.equals(-1, list.indexOf(100));
Expect.equals(-1, list.lastIndexOf(100));
list[2] = new Yes();
Expect.equals(2, list.indexOf(100));
Expect.equals(2, list.lastIndexOf(100));
list[3] = new Yes();
Expect.equals(2, list.indexOf(100));
Expect.equals(3, list.lastIndexOf(100));
list[2] = 2;
Expect.equals(3, list.indexOf(100));
Expect.equals(3, list.lastIndexOf(100));
list[3] = 3;
Expect.equals(-1, list.indexOf(100));
Expect.equals(-1, list.lastIndexOf(100));
testClosures(list);
Expect.equals(list.removeLast(), 9);
list.clear();
Expect.equals(list.length, 0);
Expect.equals(list.length, 0);
Expect.equals(true, list.isEmpty);
Expect.equals(list.length, 10);
for (int i = 0; i < 10; i++) {
Expect.equals(i, list[i]);
Expect.equals(i, list.indexOf(i));
Expect.equals(i, list.lastIndexOf(i));
}
Expect.equals(-1, list.indexOf(100));
Expect.equals(-1, list.lastIndexOf(100));
list[2] = new Yes();
Expect.equals(2, list.indexOf(100));
Expect.equals(2, list.lastIndexOf(100));
list[3] = new Yes();
Expect.equals(2, list.indexOf(100));
Expect.equals(3, list.lastIndexOf(100));
list[2] = 2;
Expect.equals(3, list.indexOf(100));
Expect.equals(3, list.lastIndexOf(100));
list[3] = 3;
Expect.equals(-1, list.indexOf(100));
Expect.equals(-1, list.lastIndexOf(100));
testClosures(list);
Expect.equals(9, list.removeLast());
list.clear();
Expect.equals(0, list.length);
Expect.isTrue(list.isEmpty);
}
class Yes {
operator ==(var other) => true;
}
main() {
ListTest.testMain();
class MyList<E> extends ListBase<E> {
List<E> _source;
MyList(this._source);
int get length => _source.length;
void set length(int length) { _source.length = length; }
E operator[](int index) => _source[index];
void operator[]=(int index, E value) { _source[index] = value; }
}
class MyFixedList<E> extends ListBase<E> {
List<E> _source;
MyFixedList(this._source);
int get length => _source.length;
void set length(int length) { throw new UnsupportedError("Fixed length!"); }
E operator[](int index) => _source[index];
void operator[]=(int index, E value) { _source[index] = value; }
}