Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(228)

Unified Diff: tool/input_sdk/lib/core/list.dart

Issue 1071393007: fuse List and js Array together and a few other misc fixes. (Closed) Base URL: git@github.com:dart-lang/dart-dev-compiler.git@master
Patch Set: ptal Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « test/generated_sdk/lib/core/list.dart ('k') | tool/input_sdk/patch/core_patch.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: tool/input_sdk/lib/core/list.dart
diff --git a/tool/input_sdk/lib/core/list.dart b/tool/input_sdk/lib/core/list.dart
index e42e4105bd083ca5661776f32e024f5eb5bdfca3..19a22eb01dde28ee414f606022afb06e7a8e922e 100644
--- a/tool/input_sdk/lib/core/list.dart
+++ b/tool/input_sdk/lib/core/list.dart
@@ -123,24 +123,173 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
return result;
}
+ checkMutable(reason) {
+ /* TODO(jacobr): implement.
+ if (this is !JSMutableArray) {
+ throw new UnsupportedError(reason);
+ }
+ * */
+ }
+
+ checkGrowable(reason) {
+ /* TODO(jacobr): implement
+ if (this is !JSExtendableArray) {
+ throw new UnsupportedError(reason);
+ }
+ * */
+ }
+
+ Iterable<E> where(bool f(E element)) {
+ return new IterableMixinWorkaround<E>().where(this, f);
+ }
+
+ Iterable expand(Iterable f(E element)) {
+ return IterableMixinWorkaround.expand(this, f);
+ }
+
+ void forEach(void f(E element)) {
+ int length = this.length;
+ for (int i = 0; i < length; i++) {
+ f(JS('', '#[#]', this, i));
+ if (length != this.length) {
+ throw new ConcurrentModificationError(this);
+ }
+ }
+ }
+
+ Iterable map(f(E element)) {
+ return IterableMixinWorkaround.mapList(this, f);
+ }
+
+ String join([String separator = ""]) {
+ var list = new List(this.length);
+ for (int i = 0; i < this.length; i++) {
+ list[i] = "${this[i]}";
+ }
+ return JS('String', "#.join(#)", list, separator);
+ }
+
+ Iterable<E> take(int n) {
+ return new IterableMixinWorkaround<E>().takeList(this, n);
+ }
+
+ Iterable<E> takeWhile(bool test(E value)) {
+ return new IterableMixinWorkaround<E>().takeWhile(this, test);
+ }
+
+ Iterable<E> skip(int n) {
+ return new IterableMixinWorkaround<E>().skipList(this, n);
+ }
+
+ Iterable<E> skipWhile(bool test(E value)) {
+ return new IterableMixinWorkaround<E>().skipWhile(this, test);
+ }
+
+ E reduce(E combine(E value, E element)) {
+ return IterableMixinWorkaround.reduce(this, combine);
+ }
+
+ fold(initialValue, combine(previousValue, E element)) {
+ return IterableMixinWorkaround.fold(this, initialValue, combine);
+ }
+
+ E firstWhere(bool test(E value), {E orElse()}) {
+ return IterableMixinWorkaround.firstWhere(this, test, orElse);
+ }
+
+ E lastWhere(bool test(E value), {E orElse()}) {
+ return IterableMixinWorkaround.lastWhereList(this, test, orElse);
+ }
+
+ E singleWhere(bool test(E value)) {
+ return IterableMixinWorkaround.singleWhere(this, test);
+ }
+
+ E elementAt(int index) {
+ return this[index];
+ }
+
+ E get first {
+ if (length > 0) return this[0];
+ throw new StateError("No elements");
+ }
+
+ E get last {
+ if (length > 0) return this[length - 1];
+ throw new StateError("No elements");
+ }
+
+ E get single {
+ if (length == 1) return this[0];
+ if (length == 0) throw new StateError("No elements");
+ throw new StateError("More than one element");
+ }
+
+ bool any(bool f(E element)) => IterableMixinWorkaround.any(this, f);
+
+ bool every(bool f(E element)) => IterableMixinWorkaround.every(this, f);
+
+ void sort([int compare(E a, E b)]) {
+ checkMutable('sort');
+ IterableMixinWorkaround.sortList(this, compare);
+ }
+
+ bool contains(Object other) {
+ for (int i = 0; i < length; i++) {
+ if (this[i] == other) return true;
+ }
+ return false;
+ }
+
+ bool get isEmpty => length == 0;
+
+ bool get isNotEmpty => !isEmpty;
+
+ String toString() => ListBase.listToString(this);
+
+ List<E> toList({ bool growable: true }) {
+ if (growable) {
+ return new JSArray<E>.markGrowable(JS('', '#.slice()', this));
+ } else {
+ return new JSArray<E>.markFixed(JS('', '#.slice()', this));
+ }
+ }
+
+ Set<E> toSet() => new Set<E>.from(this);
+
+ Iterator<E> get iterator => new ListIterator<E>(this);
+
+ int get hashCode => Primitives.objectHashCode(this);
+
+ // BORDER XXXX
+
/**
* Returns the object at the given [index] in the list
* or throws a [RangeError] if [index] is out of bounds.
*/
- E operator [](int index);
+ E operator [](int index) {
+ if (index is !int) throw new ArgumentError(index);
+ if (index >= length || index < 0) throw new RangeError.value(index);
+ return JS('var', '#[#]', this, index);
+ }
/**
* Sets the value at the given [index] in the list to [value]
* or throws a [RangeError] if [index] is out of bounds.
*/
- void operator []=(int index, E value);
+ void operator []=(int index, E value) {
+ checkMutable('indexed set');
+ if (index is !int) throw new ArgumentError(index);
+ if (index >= length || index < 0) throw new RangeError.value(index);
+ JS('void', r'#[#] = #', this, index, value);
+ }
/**
* Returns the number of objects in this list.
*
* The valid indices for a list are `0` through `length - 1`.
*/
- int get length;
+ int get length => JS('JSUInt32', r'#.length', this);
/**
* Changes the length of this list.
@@ -150,7 +299,12 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
*
* Throws an [UnsupportedError] if the list is fixed-length.
*/
- void set length(int newLength);
+ void set length(int newLength) {
+ if (newLength is !int) throw new ArgumentError(newLength);
+ if (newLength < 0) throw new RangeError.value(newLength);
+ checkGrowable('set length');
+ JS('void', r'#.length = #', this, newLength);
+ }
/**
* Adds [value] to the end of this list,
@@ -158,7 +312,10 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
*
* Throws an [UnsupportedError] if the list is fixed-length.
*/
- void add(E value);
+ void add(E value) {
+ checkGrowable('add');
+ JS('void', r'#.push(#)', this, value);
+ }
/**
* Appends all objects of [iterable] to the end of this list.
@@ -166,12 +323,17 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* Extends the length of the list by the number of objects in [iterable].
* Throws an [UnsupportedError] if this list is fixed-length.
*/
- void addAll(Iterable<E> iterable);
+ void addAll(Iterable<E> iterable) {
+ for (E e in iterable) {
+ this.add(e);
+ }
+ }
/**
* Returns an [Iterable] of the objects in this list in reverse order.
*/
- Iterable<E> get reversed;
+ Iterable<E> get reversed =>
+ new IterableMixinWorkaround<E>().reversedList(this);
/**
* Sorts this list according to the order specified by the [compare] function.
@@ -190,12 +352,17 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* nums.sort();
nums.join(', '); // '-11, 2, 13'
*/
- void sort([int compare(E a, E b)]);
+ void sort([int compare(E a, E b)]) {
+ // XXX checkMutable('sort');
+ IterableMixinWorkaround.sortList(this, compare);
+ }
/**
* Shuffles the elements of this list randomly.
*/
- void shuffle([Random random]);
+ void shuffle([Random random]) {
+ IterableMixinWorkaround.shuffleList(this, random);
+ }
/**
* Returns the first index of [element] in this list.
@@ -212,7 +379,9 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
*
* notes.indexOf('fa'); // -1
*/
- int indexOf(E element, [int start = 0]);
+ int indexOf(E element, [int start = 0]) {
+ return IterableMixinWorkaround.indexOfList(this, element, start);
+ }
/**
* Returns the last index of [element] in this list.
@@ -234,7 +403,9 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
*
* notes.lastIndexOf('fa'); // -1
*/
- int lastIndexOf(E element, [int start]);
+ int lastIndexOf(E element, [int start]) {
+ return IterableMixinWorkaround.lastIndexOfList(this, element, start);
+ }
/**
* Removes all objects from this list;
@@ -243,7 +414,9 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* Throws an [UnsupportedError], and retains all objects, if this
* is a fixed-length list.
*/
- void clear();
+ void clear() {
+ length = 0;
+ }
/**
* Inserts the object at position [index] in this list.
@@ -254,7 +427,15 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* An error occurs if the [index] is less than 0 or greater than length.
* An [UnsupportedError] occurs if the list is fixed-length.
*/
- void insert(int index, E element);
+ void insert(int index, E element) {
+ if (index is !int) throw new ArgumentError(index);
+ if (index < 0 || index > length) {
+ throw new RangeError.value(index);
+ }
+ checkGrowable('insert');
+ JS('void', r'#.splice(#, 0, #)', this, index, element);
+ }
+
/**
* Inserts all objects of [iterable] at position [index] in this list.
@@ -265,7 +446,10 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* An error occurs if the [index] is less than 0 or greater than length.
* An [UnsupportedError] occurs if the list is fixed-length.
*/
- void insertAll(int index, Iterable<E> iterable);
+ void insertAll(int index, Iterable<E> iterable) {
+ checkGrowable('insertAll');
+ IterableMixinWorkaround.insertAllList(this, index, iterable);
+ }
/**
* Overwrites objects of `this` with the objects of [iterable], starting
@@ -285,7 +469,10 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* If `iterable` is based on this list, its values may change /during/ the
* `setAll` operation.
*/
- void setAll(int index, Iterable<E> iterable);
+ void setAll(int index, Iterable<E> iterable) {
+ checkMutable('setAll');
+ IterableMixinWorkaround.setAllList(this, index, iterable);
+ }
/**
* Removes the first occurence of [value] from this list.
@@ -304,7 +491,16 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
*
* An [UnsupportedError] occurs if the list is fixed-length.
*/
- bool remove(Object value);
+ bool remove(Object element) {
+ checkGrowable('remove');
+ for (int i = 0; i < this.length; i++) {
+ if (this[i] == value) {
+ JS('var', r'#.splice(#, 1)', this, i);
+ return true;
+ }
+ }
+ return false;
+ }
/**
* Removes the object at position [index] from this list.
@@ -319,14 +515,25 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* Throws an [UnsupportedError] if this is a fixed-length list. In that case
* the list is not modified.
*/
- E removeAt(int index);
+ E removeAt(int index) {
+ if (index is !int) throw new ArgumentError(index);
+ if (index < 0 || index >= length) {
+ throw new RangeError.value(index);
+ }
+ checkGrowable('removeAt');
+ return JS('var', r'#.splice(#, 1)[0]', this, index);
+ }
/**
* Pops and returns the last object in this list.
*
* Throws an [UnsupportedError] if this is a fixed-length list.
*/
- E removeLast();
+ E removeLast() {
+ checkGrowable('removeLast');
+ if (length == 0) throw new RangeError.value(-1);
+ return JS('var', r'#.pop()', this);
+ }
/**
* Removes all objects from this list that satisfy [test].
@@ -339,7 +546,11 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
*
* Throws an [UnsupportedError] if this is a fixed-length list.
*/
- void removeWhere(bool test(E element));
+ void removeWhere(bool test(E element)) {
+ // This could, and should, be optimized.
+ IterableMixinWorkaround.removeWhereList(this, test);
+ }
+
/**
* Removes all objects from this list that fail to satisfy [test].
@@ -352,7 +563,10 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
*
* Throws an [UnsupportedError] if this is a fixed-length list.
*/
- void retainWhere(bool test(E element));
+ void retainWhere(bool test(E element)) {
+ IterableMixinWorkaround.removeWhereList(this,
+ (E element) => !test(element));
+ }
/**
* Returns a new list containing the objects from [start] inclusive to [end]
@@ -368,7 +582,24 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* An error occurs if [start] is outside the range `0` .. `length` or if
* [end] is outside the range `start` .. `length`.
*/
- List<E> sublist(int start, [int end]);
+ List<E> sublist(int start, [int end]) {
+ checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
+ if (start is !int) throw new ArgumentError(start);
+ if (start < 0 || start > length) {
+ throw new RangeError.range(start, 0, length);
+ }
+ if (end == null) {
+ end = length;
+ } else {
+ if (end is !int) throw new ArgumentError(end);
+ if (end < start || end > length) {
+ throw new RangeError.range(end, start, length);
+ }
+ }
+ if (start == end) return <E>[];
+ return new JSArray<E>.markGrowable(
+ JS('', r'#.slice(#, #)', this, start, end));
+ }
/**
* Returns an [Iterable] that iterates over the objects in the range
@@ -387,7 +618,10 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* colors.length = 3;
* range.join(', '); // 'green, blue'
*/
- Iterable<E> getRange(int start, int end);
+ Iterable<E> getRange(int start, int end) {
+ return new IterableMixinWorkaround<E>().getRangeList(this, start, end);
+ }
+
/**
* Copies the objects of [iterable], skipping [skipCount] objects first,
@@ -413,7 +647,10 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* If `iterable` depends on this list in some other way, no guarantees are
* made.
*/
- void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]);
+ void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
+ checkMutable('set range');
+ IterableMixinWorkaround.setRangeList(this, start, end, iterable, skipCount);
+ }
/**
* Removes the objects in the range [start] inclusive to [end] exclusive.
@@ -424,7 +661,22 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* Throws an [UnsupportedError] if this is a fixed-length list. In that case
* the list is not modified.
*/
- void removeRange(int start, int end);
+ void removeRange(int start, int end) {
+ checkGrowable('removeRange');
+ int receiverLength = this.length;
+ if (start < 0 || start > receiverLength) {
+ throw new RangeError.range(start, 0, receiverLength);
+ }
+ if (end < start || end > receiverLength) {
+ throw new RangeError.range(end, start, receiverLength);
+ }
+ Lists.copy(this,
+ end,
+ this,
+ start,
+ receiverLength - end);
+ this.length = receiverLength - (end - start);
+ }
/**
* Sets the objects in the range [start] inclusive to [end] exclusive
@@ -432,7 +684,10 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
*
* An error occurs if [start]..[end] is not a valid range for `this`.
*/
- void fillRange(int start, int end, [E fillValue]);
+ void fillRange(int start, int end, [E fillValue]) {
+ checkMutable('fill range');
+ IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
+ }
/**
* Removes the objects in the range [start] inclusive to [end] exclusive
@@ -444,7 +699,10 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
*
* An error occurs if [start]..[end] is not a valid range for `this`.
*/
- void replaceRange(int start, int end, Iterable<E> replacement);
+ void replaceRange(int start, int end, Iterable<E> replacement) {
+ checkGrowable('removeRange');
+ IterableMixinWorkaround.replaceRangeList(this, start, end, replacement);
+ }
/**
* Returns an unmodifiable [Map] view of `this`.
@@ -458,5 +716,7 @@ abstract class List<E> implements Iterable<E>, EfficientLength {
* map[0] + map[1]; // 'feefi';
* map.keys.toList(); // [0, 1, 2, 3]
*/
- Map<int, E> asMap();
+ Map<int, E> asMap() {
+ return new IterableMixinWorkaround<E>().asMapList(this);
+ }
}
« no previous file with comments | « test/generated_sdk/lib/core/list.dart ('k') | tool/input_sdk/patch/core_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698