OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 part of _interceptors; | 5 part of _interceptors; |
6 | 6 |
7 /** | 7 /** |
8 * The interceptor class for [List]. The compiler recognizes this | 8 * The interceptor class for [List]. The compiler recognizes this |
9 * class as an interceptor, and changes references to [:this:] to | 9 * class as an interceptor, and changes references to [:this:] to |
10 * actually use the receiver of the method, which is generated as an extra | 10 * actually use the receiver of the method, which is generated as an extra |
(...skipping 15 matching lines...) Expand all Loading... |
26 checkGrowable(this, 'removeAt'); | 26 checkGrowable(this, 'removeAt'); |
27 return JS('var', r'#.splice(#, 1)[0]', this, index); | 27 return JS('var', r'#.splice(#, 1)[0]', this, index); |
28 } | 28 } |
29 | 29 |
30 E removeLast() { | 30 E removeLast() { |
31 checkGrowable(this, 'removeLast'); | 31 checkGrowable(this, 'removeLast'); |
32 if (length == 0) throw new RangeError.value(-1); | 32 if (length == 0) throw new RangeError.value(-1); |
33 return JS('var', r'#.pop()', this); | 33 return JS('var', r'#.pop()', this); |
34 } | 34 } |
35 | 35 |
36 List<E> filter(bool f(E element)) { | 36 Iterable<E> where(bool f(E element)) { |
37 return Collections.filter(this, <E>[], f); | 37 return new WhereIterable<E>(this, f); |
38 } | 38 } |
39 | 39 |
40 void addAll(Collection<E> collection) { | 40 void addAll(Collection<E> collection) { |
41 for (E e in collection) { | 41 for (E e in collection) { |
42 this.add(e); | 42 this.add(e); |
43 } | 43 } |
44 } | 44 } |
45 | 45 |
46 void addLast(E value) { | 46 void addLast(E value) { |
47 checkGrowable(this, 'addLast'); | 47 checkGrowable(this, 'addLast'); |
48 JS('void', r'#.push(#)', this, value); | 48 JS('void', r'#.push(#)', this, value); |
49 } | 49 } |
50 | 50 |
51 void clear() { | 51 void clear() { |
52 length = 0; | 52 length = 0; |
53 } | 53 } |
54 | 54 |
55 void forEach(void f(E element)) { | 55 void forEach(void f(E element)) { |
56 return Collections.forEach(this, f); | 56 return Collections.forEach(this, f); |
57 } | 57 } |
58 | 58 |
59 Collection map(f(E element)) { | 59 List mappedBy(f(E element)) { |
60 return Collections.map(this, [], f); | 60 return new MappedList(this, f); |
| 61 } |
| 62 |
| 63 String join([String separator]) { |
| 64 if (separator == null) separator = ""; |
| 65 var list = new List(this.length); |
| 66 for (int i = 0; i < this.length; i++) { |
| 67 list[i] = "${this[i]}"; |
| 68 } |
| 69 return JS('String', "#.join(#)", list, separator); |
| 70 } |
| 71 |
| 72 List<E> take(int n) { |
| 73 return new ListView<E>(this, 0, n); |
| 74 } |
| 75 |
| 76 Iterable<E> takeWhile(bool test(E value)) { |
| 77 return new TakeWhileIterable<E>(this, test); |
| 78 } |
| 79 |
| 80 List<E> skip(int n) { |
| 81 return new ListView<E>(this, n, null); |
| 82 } |
| 83 |
| 84 Iterable<E> skipWhile(bool test(E value)) { |
| 85 return new SkipWhileIterable<E>(this, test); |
61 } | 86 } |
62 | 87 |
63 reduce(initialValue, combine(previousValue, E element)) { | 88 reduce(initialValue, combine(previousValue, E element)) { |
64 return Collections.reduce(this, initialValue, combine); | 89 return Collections.reduce(this, initialValue, combine); |
65 } | 90 } |
66 | 91 |
| 92 E firstMatching(bool test(E value), {E orElse()}) { |
| 93 return Collections.firstMatching(this, test, orElse); |
| 94 } |
| 95 |
| 96 E lastMatching(bool test(E value), {E orElse()}) { |
| 97 return Collections.lastMatchingInList(this, test, orElse); |
| 98 } |
| 99 |
| 100 E singleMatching(bool test(E value)) { |
| 101 return Collections.singleMatching(this, test); |
| 102 } |
| 103 |
| 104 E elementAt(int index) { |
| 105 return this[index]; |
| 106 } |
| 107 |
67 List<E> getRange(int start, int length) { | 108 List<E> getRange(int start, int length) { |
68 // TODO(ngeoffray): Parameterize the return value. | 109 // TODO(ngeoffray): Parameterize the return value. |
69 if (0 == length) return []; | 110 if (0 == length) return []; |
70 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. | 111 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. |
71 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. | 112 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. |
72 if (start is !int) throw new ArgumentError(start); | 113 if (start is !int) throw new ArgumentError(start); |
73 if (length is !int) throw new ArgumentError(length); | 114 if (length is !int) throw new ArgumentError(length); |
74 if (length < 0) throw new ArgumentError(length); | 115 if (length < 0) throw new ArgumentError(length); |
75 if (start < 0) throw new RangeError.value(start); | 116 if (start < 0) throw new RangeError.value(start); |
76 int end = start + length; | 117 int end = start + length; |
77 if (end > this.length) { | 118 if (end > this.length) { |
78 throw new RangeError.value(length); | 119 throw new RangeError.value(length); |
79 } | 120 } |
80 if (length < 0) throw new ArgumentError(length); | 121 if (length < 0) throw new ArgumentError(length); |
81 return JS('=List', r'#.slice(#, #)', this, start, end); | 122 return JS('=List', r'#.slice(#, #)', this, start, end); |
82 } | 123 } |
83 | 124 |
84 void insertRange(int start, int length, [E initialValue]) { | 125 void insertRange(int start, int length, [E initialValue]) { |
85 return listInsertRange(this, start, length, initialValue); | 126 return listInsertRange(this, start, length, initialValue); |
86 } | 127 } |
87 | 128 |
88 E get last => this[length - 1]; | 129 E get first { |
| 130 if (length > 0) return this[0]; |
| 131 throw new StateError("No elements"); |
| 132 } |
89 | 133 |
90 E get first => this[0]; | 134 E get last { |
| 135 if (length > 0) return this[length - 1]; |
| 136 throw new StateError("No elements"); |
| 137 } |
| 138 |
| 139 E get single { |
| 140 if (length == 1) return this[0]; |
| 141 if (length == 0) throw new StateError("No elements"); |
| 142 throw new StateError("More than one element"); |
| 143 } |
| 144 |
| 145 E min([int compare(E a, E b)]) => Collections.min(this, compare); |
| 146 |
| 147 E max([int compare(E a, E b)]) => Collections.max(this, compare); |
91 | 148 |
92 void removeRange(int start, int length) { | 149 void removeRange(int start, int length) { |
93 checkGrowable(this, 'removeRange'); | 150 checkGrowable(this, 'removeRange'); |
94 if (length == 0) { | 151 if (length == 0) { |
95 return; | 152 return; |
96 } | 153 } |
97 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. | 154 checkNull(start); // TODO(ahe): This is not specified but co19 tests it. |
98 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. | 155 checkNull(length); // TODO(ahe): This is not specified but co19 tests it. |
99 if (start is !int) throw new ArgumentError(start); | 156 if (start is !int) throw new ArgumentError(start); |
100 if (length is !int) throw new ArgumentError(length); | 157 if (length is !int) throw new ArgumentError(length); |
(...skipping 25 matching lines...) Expand all Loading... |
126 if (startFrom is !int) throw new ArgumentError(startFrom); | 183 if (startFrom is !int) throw new ArgumentError(startFrom); |
127 if (length < 0) throw new ArgumentError(length); | 184 if (length < 0) throw new ArgumentError(length); |
128 if (start < 0) throw new RangeError.value(start); | 185 if (start < 0) throw new RangeError.value(start); |
129 if (start + length > this.length) { | 186 if (start + length > this.length) { |
130 throw new RangeError.value(start + length); | 187 throw new RangeError.value(start + length); |
131 } | 188 } |
132 | 189 |
133 Arrays.copy(from, startFrom, this, start, length); | 190 Arrays.copy(from, startFrom, this, start, length); |
134 } | 191 } |
135 | 192 |
136 bool some(bool f(E element)) => Collections.some(this, f); | 193 bool any(bool f(E element)) => Collections.any(this, f); |
137 | 194 |
138 bool every(bool f(E element)) => Collections.every(this, f); | 195 bool every(bool f(E element)) => Collections.every(this, f); |
139 | 196 |
140 void sort([int compare(E a, E b)]) { | 197 void sort([int compare(E a, E b)]) { |
141 checkMutable(this, 'sort'); | 198 checkMutable(this, 'sort'); |
142 if (compare == null) compare = Comparable.compare; | 199 if (compare == null) compare = Comparable.compare; |
143 coreSort(this, compare); | 200 coreSort(this, compare); |
144 } | 201 } |
145 | 202 |
146 int indexOf(E element, [int start = 0]) { | 203 int indexOf(E element, [int start = 0]) { |
(...skipping 10 matching lines...) Expand all Loading... |
157 for (int i = 0; i < length; i++) { | 214 for (int i = 0; i < length; i++) { |
158 if (other == this[i]) return true; | 215 if (other == this[i]) return true; |
159 } | 216 } |
160 return false; | 217 return false; |
161 } | 218 } |
162 | 219 |
163 bool get isEmpty => length == 0; | 220 bool get isEmpty => length == 0; |
164 | 221 |
165 String toString() => Collections.collectionToString(this); | 222 String toString() => Collections.collectionToString(this); |
166 | 223 |
167 ListIterator iterator() => new ListIterator(this); | 224 List<E> toList() => new List<E>.from(this); |
| 225 |
| 226 Set<E> toSet() => new Set<E>.from(this); |
| 227 |
| 228 _ArrayIterator get iterator => new _ArrayIterator(this); |
168 | 229 |
169 int get hashCode => Primitives.objectHashCode(this); | 230 int get hashCode => Primitives.objectHashCode(this); |
170 | 231 |
171 Type get runtimeType { | 232 Type get runtimeType { |
172 // Call getRuntimeTypeString to get the name including type arguments. | 233 // Call getRuntimeTypeString to get the name including type arguments. |
173 return new TypeImpl(getRuntimeTypeString(this)); | 234 return new TypeImpl(getRuntimeTypeString(this)); |
174 } | 235 } |
175 | 236 |
176 int get length => JS('int', r'#.length', this); | 237 int get length => JS('int', r'#.length', this); |
177 | 238 |
178 void set length(int newLength) { | 239 void set length(int newLength) { |
179 if (newLength is !int) throw new ArgumentError(newLength); | 240 if (newLength is !int) throw new ArgumentError(newLength); |
180 if (newLength < 0) throw new RangeError.value(newLength); | 241 if (newLength < 0) throw new RangeError.value(newLength); |
181 checkGrowable(this, 'set length'); | 242 checkGrowable(this, 'set length'); |
182 JS('void', r'#.length = #', this, newLength); | 243 JS('void', r'#.length = #', this, newLength); |
183 } | 244 } |
184 | 245 |
185 E operator [](int index) { | 246 E operator [](int index) { |
186 if (index is !int) throw new ArgumentError(index); | 247 if (index is !int) throw new ArgumentError(index); |
187 if (index >= length || index < 0) throw new RangeError.value(index); | 248 if (index >= length || index < 0) throw new RangeError.value(index); |
188 return JS('var', '#[#]', this, index); | 249 return JS('var', '#[#]', this, index); |
189 } | 250 } |
190 } | 251 } |
| 252 |
| 253 /** Iterator for JavaScript Arrays. */ |
| 254 class _ArrayIterator<T> implements Iterator<T> { |
| 255 final List<T> _list; |
| 256 int _position; |
| 257 T _current; |
| 258 |
| 259 _ArrayIterator(List<T> this._list) : _position = -1; |
| 260 |
| 261 T get current => _current; |
| 262 |
| 263 bool moveNext() { |
| 264 int nextPosition = _position + 1; |
| 265 int length = _list.length; |
| 266 if (nextPosition < length) { |
| 267 _position = nextPosition; |
| 268 _current = _list[nextPosition]; |
| 269 return true; |
| 270 } |
| 271 _position = length; |
| 272 _current = null; |
| 273 return false; |
| 274 } |
| 275 } |
OLD | NEW |