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

Side by Side Diff: test/generated_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 unified diff | Download patch
OLDNEW
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 dart.core; 5 part of dart.core;
6 6
7 /** 7 /**
8 * An indexable collection of objects with a length. 8 * An indexable collection of objects with a length.
9 * 9 *
10 * Subclasses of this class implement different kinds of lists. 10 * Subclasses of this class implement different kinds of lists.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 * growableList.length; // 0; 69 * growableList.length; // 0;
70 * growableList.length = 3; 70 * growableList.length = 3;
71 * 71 *
72 * To create a growable list with a given length, just assign the length 72 * To create a growable list with a given length, just assign the length
73 * right after creation: 73 * right after creation:
74 * 74 *
75 * List growableList = new List()..length = 500; 75 * List growableList = new List()..length = 500;
76 * 76 *
77 * The [length] must not be negative or null, if it is provided. 77 * The [length] must not be negative or null, if it is provided.
78 */ 78 */
79 factory List([int length = const _ListConstructorSentinel()]) { 79 factory List([int length]) {
80 if (length == const _ListConstructorSentinel()) { 80 if (length == null) {
81 return new JSArray<E>.emptyGrowable(); 81 return JS('', '[]');
82 } 82 }
83 return new JSArray<E>.fixed(length); 83 // Explicit type test is necessary to guard against JavaScript conversions
84 // in unchecked mode.
85 if ((length is !int) || (length < 0)) {
86 throw new ArgumentError("Length must be a non-negative integer: $length");
87 }
88 var list = JS('', 'new Array(#)', length);
89 // TODO(jmesserly): consider a fixed array subclass instead.
90 JS('void', r'#.fixed$length = Array', list);
91 return list;
84 } 92 }
85 93
86 /** 94 /**
87 * Creates a fixed-length list of the given length, and initializes the 95 * Creates a fixed-length list of the given length, and initializes the
88 * value at each position with [fill]: 96 * value at each position with [fill]:
89 * 97 *
90 * new List<int>.filled(3, 0); // [0, 0, 0] 98 * new List<int>.filled(3, 0); // [0, 0, 0]
91 * 99 *
92 * The [length] must not be negative or null. 100 * The [length] must not be negative or null.
93 */ 101 */
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 result = <E>[]..length = length; 144 result = <E>[]..length = length;
137 } else { 145 } else {
138 result = new List<E>(length); 146 result = new List<E>(length);
139 } 147 }
140 for (int i = 0; i < length; i++) { 148 for (int i = 0; i < length; i++) {
141 result[i] = generator(i); 149 result[i] = generator(i);
142 } 150 }
143 return result; 151 return result;
144 } 152 }
145 153
154 checkMutable(reason) {
155 /* TODO(jacobr): implement.
156 if (this is !JSMutableArray) {
157 throw new UnsupportedError(reason);
158 }
159 * */
160 }
161
162 checkGrowable(reason) {
163 /* TODO(jacobr): implement
164 if (this is !JSExtendableArray) {
165 throw new UnsupportedError(reason);
166 }
167 * */
168 }
169
170 Iterable<E> where(bool f(E element)) {
171 return new IterableMixinWorkaround<E>().where(this, f);
172 }
173
174 Iterable expand(Iterable f(E element)) {
175 return IterableMixinWorkaround.expand(this, f);
176 }
177
178 void forEach(void f(E element)) {
179 int length = this.length;
180 for (int i = 0; i < length; i++) {
181 f(JS('', '#[#]', this, i));
182 if (length != this.length) {
183 throw new ConcurrentModificationError(this);
184 }
185 }
186 }
187
188 Iterable map(f(E element)) {
189 return IterableMixinWorkaround.mapList(this, f);
190 }
191
192 String join([String separator = ""]) {
193 var list = new List(this.length);
194 for (int i = 0; i < this.length; i++) {
195 list[i] = "${this[i]}";
196 }
197 return JS('String', "#.join(#)", list, separator);
198 }
199
200 Iterable<E> take(int n) {
201 return new IterableMixinWorkaround<E>().takeList(this, n);
202 }
203
204 Iterable<E> takeWhile(bool test(E value)) {
205 return new IterableMixinWorkaround<E>().takeWhile(this, test);
206 }
207
208 Iterable<E> skip(int n) {
209 return new IterableMixinWorkaround<E>().skipList(this, n);
210 }
211
212 Iterable<E> skipWhile(bool test(E value)) {
213 return new IterableMixinWorkaround<E>().skipWhile(this, test);
214 }
215
216 E reduce(E combine(E value, E element)) {
217 return IterableMixinWorkaround.reduce(this, combine);
218 }
219
220 fold(initialValue, combine(previousValue, E element)) {
221 return IterableMixinWorkaround.fold(this, initialValue, combine);
222 }
223
224 E firstWhere(bool test(E value), {E orElse()}) {
225 return IterableMixinWorkaround.firstWhere(this, test, orElse);
226 }
227
228 E lastWhere(bool test(E value), {E orElse()}) {
229 return IterableMixinWorkaround.lastWhereList(this, test, orElse);
230 }
231
232 E singleWhere(bool test(E value)) {
233 return IterableMixinWorkaround.singleWhere(this, test);
234 }
235
236 E elementAt(int index) {
237 return this[index];
238 }
239
240 E get first {
241 if (length > 0) return this[0];
242 throw new StateError("No elements");
243 }
244
245 E get last {
246 if (length > 0) return this[length - 1];
247 throw new StateError("No elements");
248 }
249
250 E get single {
251 if (length == 1) return this[0];
252 if (length == 0) throw new StateError("No elements");
253 throw new StateError("More than one element");
254 }
255
256 bool any(bool f(E element)) => IterableMixinWorkaround.any(this, f);
257
258 bool every(bool f(E element)) => IterableMixinWorkaround.every(this, f);
259
260 void sort([int compare(E a, E b)]) {
261 checkMutable('sort');
262 IterableMixinWorkaround.sortList(this, compare);
263 }
264
265 bool contains(Object other) {
266 for (int i = 0; i < length; i++) {
267 if (this[i] == other) return true;
268 }
269 return false;
270 }
271
272 bool get isEmpty => length == 0;
273
274 bool get isNotEmpty => !isEmpty;
275
276 String toString() => ListBase.listToString(this);
277
278 List<E> toList({ bool growable: true }) {
279 if (growable) {
280 return new JSArray<E>.markGrowable(JS('', '#.slice()', this));
281 } else {
282 return new JSArray<E>.markFixed(JS('', '#.slice()', this));
283 }
284 }
285
286 Set<E> toSet() => new Set<E>.from(this);
287
288 Iterator<E> get iterator => new ListIterator<E>(this);
289
290 int get hashCode => Primitives.objectHashCode(this);
291
292 // BORDER XXXX
293
146 /** 294 /**
147 * Returns the object at the given [index] in the list 295 * Returns the object at the given [index] in the list
148 * or throws a [RangeError] if [index] is out of bounds. 296 * or throws a [RangeError] if [index] is out of bounds.
149 */ 297 */
150 E operator [](int index); 298 E operator [](int index) {
299 if (index is !int) throw new ArgumentError(index);
300 if (index >= length || index < 0) throw new RangeError.value(index);
301 return JS('var', '#[#]', this, index);
302 }
151 303
152 /** 304 /**
153 * Sets the value at the given [index] in the list to [value] 305 * Sets the value at the given [index] in the list to [value]
154 * or throws a [RangeError] if [index] is out of bounds. 306 * or throws a [RangeError] if [index] is out of bounds.
155 */ 307 */
156 void operator []=(int index, E value); 308 void operator []=(int index, E value) {
309 checkMutable('indexed set');
310 if (index is !int) throw new ArgumentError(index);
311 if (index >= length || index < 0) throw new RangeError.value(index);
312 JS('void', r'#[#] = #', this, index, value);
313 }
157 314
158 /** 315 /**
159 * Returns the number of objects in this list. 316 * Returns the number of objects in this list.
160 * 317 *
161 * The valid indices for a list are `0` through `length - 1`. 318 * The valid indices for a list are `0` through `length - 1`.
162 */ 319 */
163 int get length; 320 int get length => JS('JSUInt32', r'#.length', this);
164 321
165 /** 322 /**
166 * Changes the length of this list. 323 * Changes the length of this list.
167 * 324 *
168 * If [newLength] is greater than 325 * If [newLength] is greater than
169 * the current length, entries are initialized to [:null:]. 326 * the current length, entries are initialized to [:null:].
170 * 327 *
171 * Throws an [UnsupportedError] if the list is fixed-length. 328 * Throws an [UnsupportedError] if the list is fixed-length.
172 */ 329 */
173 void set length(int newLength); 330 void set length(int newLength) {
331 if (newLength is !int) throw new ArgumentError(newLength);
332 if (newLength < 0) throw new RangeError.value(newLength);
333 checkGrowable('set length');
334 JS('void', r'#.length = #', this, newLength);
335 }
174 336
175 /** 337 /**
176 * Adds [value] to the end of this list, 338 * Adds [value] to the end of this list,
177 * extending the length by one. 339 * extending the length by one.
178 * 340 *
179 * Throws an [UnsupportedError] if the list is fixed-length. 341 * Throws an [UnsupportedError] if the list is fixed-length.
180 */ 342 */
181 void add(E value); 343 void add(E value) {
344 checkGrowable('add');
345 JS('void', r'#.push(#)', this, value);
346 }
182 347
183 /** 348 /**
184 * Appends all objects of [iterable] to the end of this list. 349 * Appends all objects of [iterable] to the end of this list.
185 * 350 *
186 * Extends the length of the list by the number of objects in [iterable]. 351 * Extends the length of the list by the number of objects in [iterable].
187 * Throws an [UnsupportedError] if this list is fixed-length. 352 * Throws an [UnsupportedError] if this list is fixed-length.
188 */ 353 */
189 void addAll(Iterable<E> iterable); 354 void addAll(Iterable<E> iterable) {
355 for (E e in iterable) {
356 this.add(e);
357 }
358 }
190 359
191 /** 360 /**
192 * Returns an [Iterable] of the objects in this list in reverse order. 361 * Returns an [Iterable] of the objects in this list in reverse order.
193 */ 362 */
194 Iterable<E> get reversed; 363 Iterable<E> get reversed =>
364 new IterableMixinWorkaround<E>().reversedList(this);
195 365
196 /** 366 /**
197 * Sorts this list according to the order specified by the [compare] function. 367 * Sorts this list according to the order specified by the [compare] function.
198 * 368 *
199 * The [compare] function must act as a [Comparator]. 369 * The [compare] function must act as a [Comparator].
200 370
201 * List<String> numbers = ['one', 'two', 'three', 'four']; 371 * List<String> numbers = ['one', 'two', 'three', 'four'];
202 * // Sort from shortest to longest. 372 * // Sort from shortest to longest.
203 * numbers.sort((x, y) => x.length.compareTo(y.length)); 373 * numbers.sort((x, y) => x.length.compareTo(y.length));
204 * numbers.join(', '); // 'one, two, four, three' 374 * numbers.join(', '); // 'one, two, four, three'
205 * 375 *
206 * The default List implementations use [Comparable.compare] if 376 * The default List implementations use [Comparable.compare] if
207 * [compare] is omitted. 377 * [compare] is omitted.
208 * 378 *
209 * List<int> nums = [13, 2, -11]; 379 * List<int> nums = [13, 2, -11];
210 * nums.sort(); 380 * nums.sort();
211 nums.join(', '); // '-11, 2, 13' 381 nums.join(', '); // '-11, 2, 13'
212 */ 382 */
213 void sort([int compare(E a, E b)]); 383 void sort([int compare(E a, E b)]) {
384 // XXX checkMutable('sort');
385 IterableMixinWorkaround.sortList(this, compare);
386 }
214 387
215 /** 388 /**
216 * Shuffles the elements of this list randomly. 389 * Shuffles the elements of this list randomly.
217 */ 390 */
218 void shuffle([Random random]); 391 void shuffle([Random random]) {
392 IterableMixinWorkaround.shuffleList(this, random);
393 }
219 394
220 /** 395 /**
221 * Returns the first index of [element] in this list. 396 * Returns the first index of [element] in this list.
222 * 397 *
223 * Searches the list from index [start] to the end of the list. 398 * Searches the list from index [start] to the end of the list.
224 * The first time an object [:o:] is encountered so that [:o == element:], 399 * The first time an object [:o:] is encountered so that [:o == element:],
225 * the index of [:o:] is returned. 400 * the index of [:o:] is returned.
226 * 401 *
227 * List<String> notes = ['do', 're', 'mi', 're']; 402 * List<String> notes = ['do', 're', 'mi', 're'];
228 * notes.indexOf('re'); // 1 403 * notes.indexOf('re'); // 1
229 * notes.indexOf('re', 2); // 3 404 * notes.indexOf('re', 2); // 3
230 * 405 *
231 * Returns -1 if [element] is not found. 406 * Returns -1 if [element] is not found.
232 * 407 *
233 * notes.indexOf('fa'); // -1 408 * notes.indexOf('fa'); // -1
234 */ 409 */
235 int indexOf(E element, [int start = 0]); 410 int indexOf(E element, [int start = 0]) {
411 return IterableMixinWorkaround.indexOfList(this, element, start);
412 }
236 413
237 /** 414 /**
238 * Returns the last index of [element] in this list. 415 * Returns the last index of [element] in this list.
239 * 416 *
240 * Searches the list backwards from index [start] to 0. 417 * Searches the list backwards from index [start] to 0.
241 * 418 *
242 * The first time an object [:o:] is encountered so that [:o == element:], 419 * The first time an object [:o:] is encountered so that [:o == element:],
243 * the index of [:o:] is returned. 420 * the index of [:o:] is returned.
244 * 421 *
245 * List<String> notes = ['do', 're', 'mi', 're']; 422 * List<String> notes = ['do', 're', 'mi', 're'];
246 * notes.lastIndexOf('re', 2); // 1 423 * notes.lastIndexOf('re', 2); // 1
247 * 424 *
248 * If [start] is not provided, this method searches from the end of the 425 * If [start] is not provided, this method searches from the end of the
249 * list./Returns 426 * list./Returns
250 * 427 *
251 * notes.lastIndexOf('re'); // 3 428 * notes.lastIndexOf('re'); // 3
252 * 429 *
253 * Returns -1 if [element] is not found. 430 * Returns -1 if [element] is not found.
254 * 431 *
255 * notes.lastIndexOf('fa'); // -1 432 * notes.lastIndexOf('fa'); // -1
256 */ 433 */
257 int lastIndexOf(E element, [int start]); 434 int lastIndexOf(E element, [int start]) {
435 return IterableMixinWorkaround.lastIndexOfList(this, element, start);
436 }
258 437
259 /** 438 /**
260 * Removes all objects from this list; 439 * Removes all objects from this list;
261 * the length of the list becomes zero. 440 * the length of the list becomes zero.
262 * 441 *
263 * Throws an [UnsupportedError], and retains all objects, if this 442 * Throws an [UnsupportedError], and retains all objects, if this
264 * is a fixed-length list. 443 * is a fixed-length list.
265 */ 444 */
266 void clear(); 445 void clear() {
446 length = 0;
447 }
267 448
268 /** 449 /**
269 * Inserts the object at position [index] in this list. 450 * Inserts the object at position [index] in this list.
270 * 451 *
271 * This increases the length of the list by one and shifts all objects 452 * This increases the length of the list by one and shifts all objects
272 * at or after the index towards the end of the list. 453 * at or after the index towards the end of the list.
273 * 454 *
274 * An error occurs if the [index] is less than 0 or greater than length. 455 * An error occurs if the [index] is less than 0 or greater than length.
275 * An [UnsupportedError] occurs if the list is fixed-length. 456 * An [UnsupportedError] occurs if the list is fixed-length.
276 */ 457 */
277 void insert(int index, E element); 458 void insert(int index, E element) {
459 if (index is !int) throw new ArgumentError(index);
460 if (index < 0 || index > length) {
461 throw new RangeError.value(index);
462 }
463 checkGrowable('insert');
464 JS('void', r'#.splice(#, 0, #)', this, index, element);
465 }
466
278 467
279 /** 468 /**
280 * Inserts all objects of [iterable] at position [index] in this list. 469 * Inserts all objects of [iterable] at position [index] in this list.
281 * 470 *
282 * This increases the length of the list by the length of [iterable] and 471 * This increases the length of the list by the length of [iterable] and
283 * shifts all later objects towards the end of the list. 472 * shifts all later objects towards the end of the list.
284 * 473 *
285 * An error occurs if the [index] is less than 0 or greater than length. 474 * An error occurs if the [index] is less than 0 or greater than length.
286 * An [UnsupportedError] occurs if the list is fixed-length. 475 * An [UnsupportedError] occurs if the list is fixed-length.
287 */ 476 */
288 void insertAll(int index, Iterable<E> iterable); 477 void insertAll(int index, Iterable<E> iterable) {
478 checkGrowable('insertAll');
479 IterableMixinWorkaround.insertAllList(this, index, iterable);
480 }
289 481
290 /** 482 /**
291 * Overwrites objects of `this` with the objects of [iterable], starting 483 * Overwrites objects of `this` with the objects of [iterable], starting
292 * at position [index] in this list. 484 * at position [index] in this list.
293 * 485 *
294 * List<String> list = ['a', 'b', 'c']; 486 * List<String> list = ['a', 'b', 'c'];
295 * list.setAll(1, ['bee', 'sea']); 487 * list.setAll(1, ['bee', 'sea']);
296 * list.join(', '); // 'a, bee, sea' 488 * list.join(', '); // 'a, bee, sea'
297 * 489 *
298 * This operation does not increase the length of `this`. 490 * This operation does not increase the length of `this`.
299 * 491 *
300 * The [index] must be non-negative and no greater than [length]. 492 * The [index] must be non-negative and no greater than [length].
301 * 493 *
302 * The [iterable] must not have more elements than what can fit from [index] 494 * The [iterable] must not have more elements than what can fit from [index]
303 * to [length]. 495 * to [length].
304 * 496 *
305 * If `iterable` is based on this list, its values may change /during/ the 497 * If `iterable` is based on this list, its values may change /during/ the
306 * `setAll` operation. 498 * `setAll` operation.
307 */ 499 */
308 void setAll(int index, Iterable<E> iterable); 500 void setAll(int index, Iterable<E> iterable) {
501 checkMutable('setAll');
502 IterableMixinWorkaround.setAllList(this, index, iterable);
503 }
309 504
310 /** 505 /**
311 * Removes the first occurence of [value] from this list. 506 * Removes the first occurence of [value] from this list.
312 * 507 *
313 * Returns true if [value] was in the list, false otherwise. 508 * Returns true if [value] was in the list, false otherwise.
314 * 509 *
315 * List<String> parts = ['head', 'shoulders', 'knees', 'toes']; 510 * List<String> parts = ['head', 'shoulders', 'knees', 'toes'];
316 * parts.remove('head'); // true 511 * parts.remove('head'); // true
317 * parts.join(', '); // 'shoulders, knees, toes' 512 * parts.join(', '); // 'shoulders, knees, toes'
318 * 513 *
319 * The method has no effect if [value] was not in the list. 514 * The method has no effect if [value] was not in the list.
320 * 515 *
321 * // Note: 'head' has already been removed. 516 * // Note: 'head' has already been removed.
322 * parts.remove('head'); // false 517 * parts.remove('head'); // false
323 * parts.join(', '); // 'shoulders, knees, toes' 518 * parts.join(', '); // 'shoulders, knees, toes'
324 * 519 *
325 * An [UnsupportedError] occurs if the list is fixed-length. 520 * An [UnsupportedError] occurs if the list is fixed-length.
326 */ 521 */
327 bool remove(Object value); 522 bool remove(Object element) {
523 checkGrowable('remove');
524 for (int i = 0; i < this.length; i++) {
525 if (this[i] == value) {
526 JS('var', r'#.splice(#, 1)', this, i);
527 return true;
528 }
529 }
530 return false;
531 }
328 532
329 /** 533 /**
330 * Removes the object at position [index] from this list. 534 * Removes the object at position [index] from this list.
331 * 535 *
332 * This method reduces the length of `this` by one and moves all later objects 536 * This method reduces the length of `this` by one and moves all later objects
333 * down by one position. 537 * down by one position.
334 * 538 *
335 * Returns the removed object. 539 * Returns the removed object.
336 * 540 *
337 * The [index] must be in the range `0 ≤ index < length`. 541 * The [index] must be in the range `0 ≤ index < length`.
338 * 542 *
339 * Throws an [UnsupportedError] if this is a fixed-length list. In that case 543 * Throws an [UnsupportedError] if this is a fixed-length list. In that case
340 * the list is not modified. 544 * the list is not modified.
341 */ 545 */
342 E removeAt(int index); 546 E removeAt(int index) {
547 if (index is !int) throw new ArgumentError(index);
548 if (index < 0 || index >= length) {
549 throw new RangeError.value(index);
550 }
551 checkGrowable('removeAt');
552 return JS('var', r'#.splice(#, 1)[0]', this, index);
553 }
343 554
344 /** 555 /**
345 * Pops and returns the last object in this list. 556 * Pops and returns the last object in this list.
346 * 557 *
347 * Throws an [UnsupportedError] if this is a fixed-length list. 558 * Throws an [UnsupportedError] if this is a fixed-length list.
348 */ 559 */
349 E removeLast(); 560 E removeLast() {
561 checkGrowable('removeLast');
562 if (length == 0) throw new RangeError.value(-1);
563 return JS('var', r'#.pop()', this);
564 }
350 565
351 /** 566 /**
352 * Removes all objects from this list that satisfy [test]. 567 * Removes all objects from this list that satisfy [test].
353 * 568 *
354 * An object [:o:] satisfies [test] if [:test(o):] is true. 569 * An object [:o:] satisfies [test] if [:test(o):] is true.
355 * 570 *
356 * List<String> numbers = ['one', 'two', 'three', 'four']; 571 * List<String> numbers = ['one', 'two', 'three', 'four'];
357 * numbers.removeWhere((item) => item.length == 3); 572 * numbers.removeWhere((item) => item.length == 3);
358 * numbers.join(', '); // 'three, four' 573 * numbers.join(', '); // 'three, four'
359 * 574 *
360 * Throws an [UnsupportedError] if this is a fixed-length list. 575 * Throws an [UnsupportedError] if this is a fixed-length list.
361 */ 576 */
362 void removeWhere(bool test(E element)); 577 void removeWhere(bool test(E element)) {
578 // This could, and should, be optimized.
579 IterableMixinWorkaround.removeWhereList(this, test);
580 }
581
363 582
364 /** 583 /**
365 * Removes all objects from this list that fail to satisfy [test]. 584 * Removes all objects from this list that fail to satisfy [test].
366 * 585 *
367 * An object [:o:] satisfies [test] if [:test(o):] is true. 586 * An object [:o:] satisfies [test] if [:test(o):] is true.
368 * 587 *
369 * List<String> numbers = ['one', 'two', 'three', 'four']; 588 * List<String> numbers = ['one', 'two', 'three', 'four'];
370 * numbers.retainWhere((item) => item.length == 3); 589 * numbers.retainWhere((item) => item.length == 3);
371 * numbers.join(', '); // 'one, two' 590 * numbers.join(', '); // 'one, two'
372 * 591 *
373 * Throws an [UnsupportedError] if this is a fixed-length list. 592 * Throws an [UnsupportedError] if this is a fixed-length list.
374 */ 593 */
375 void retainWhere(bool test(E element)); 594 void retainWhere(bool test(E element)) {
595 IterableMixinWorkaround.removeWhereList(this,
596 (E element) => !test(element));
597 }
376 598
377 /** 599 /**
378 * Returns a new list containing the objects from [start] inclusive to [end] 600 * Returns a new list containing the objects from [start] inclusive to [end]
379 * exclusive. 601 * exclusive.
380 * 602 *
381 * List<String> colors = ['red', 'green', 'blue', 'orange', 'pink']; 603 * List<String> colors = ['red', 'green', 'blue', 'orange', 'pink'];
382 * colors.sublist(1, 3); // ['green', 'blue'] 604 * colors.sublist(1, 3); // ['green', 'blue']
383 * 605 *
384 * If [end] is omitted, the [length] of `this` is used. 606 * If [end] is omitted, the [length] of `this` is used.
385 * 607 *
386 * colors.sublist(1); // ['green', 'blue', 'orange', 'pink'] 608 * colors.sublist(1); // ['green', 'blue', 'orange', 'pink']
387 * 609 *
388 * An error occurs if [start] is outside the range `0` .. `length` or if 610 * An error occurs if [start] is outside the range `0` .. `length` or if
389 * [end] is outside the range `start` .. `length`. 611 * [end] is outside the range `start` .. `length`.
390 */ 612 */
391 List<E> sublist(int start, [int end]); 613 List<E> sublist(int start, [int end]) {
614 checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
615 if (start is !int) throw new ArgumentError(start);
616 if (start < 0 || start > length) {
617 throw new RangeError.range(start, 0, length);
618 }
619 if (end == null) {
620 end = length;
621 } else {
622 if (end is !int) throw new ArgumentError(end);
623 if (end < start || end > length) {
624 throw new RangeError.range(end, start, length);
625 }
626 }
627 if (start == end) return <E>[];
628 return new JSArray<E>.markGrowable(
629 JS('', r'#.slice(#, #)', this, start, end));
630 }
392 631
393 /** 632 /**
394 * Returns an [Iterable] that iterates over the objects in the range 633 * Returns an [Iterable] that iterates over the objects in the range
395 * [start] inclusive to [end] exclusive. 634 * [start] inclusive to [end] exclusive.
396 * 635 *
397 * An error occurs if [end] is before [start]. 636 * An error occurs if [end] is before [start].
398 * 637 *
399 * An error occurs if the [start] and [end] are not valid ranges at the time 638 * An error occurs if the [start] and [end] are not valid ranges at the time
400 * of the call to this method. The returned [Iterable] behaves like 639 * of the call to this method. The returned [Iterable] behaves like
401 * `skip(start).take(end - start)`. That is, it does not throw exceptions 640 * `skip(start).take(end - start)`. That is, it does not throw exceptions
402 * if `this` changes size. 641 * if `this` changes size.
403 * 642 *
404 * List<String> colors = ['red', 'green', 'blue', 'orange', 'pink']; 643 * List<String> colors = ['red', 'green', 'blue', 'orange', 'pink'];
405 * Iterable<String> range = colors.getRange(1, 4); 644 * Iterable<String> range = colors.getRange(1, 4);
406 * range.join(', '); // 'green, blue, orange' 645 * range.join(', '); // 'green, blue, orange'
407 * colors.length = 3; 646 * colors.length = 3;
408 * range.join(', '); // 'green, blue' 647 * range.join(', '); // 'green, blue'
409 */ 648 */
410 Iterable<E> getRange(int start, int end); 649 Iterable<E> getRange(int start, int end) {
650 return new IterableMixinWorkaround<E>().getRangeList(this, start, end);
651 }
652
411 653
412 /** 654 /**
413 * Copies the objects of [iterable], skipping [skipCount] objects first, 655 * Copies the objects of [iterable], skipping [skipCount] objects first,
414 * into the range [start], inclusive, to [end], exclusive, of the list. 656 * into the range [start], inclusive, to [end], exclusive, of the list.
415 * 657 *
416 * List<int> list1 = [1, 2, 3, 4]; 658 * List<int> list1 = [1, 2, 3, 4];
417 * List<int> list2 = [5, 6, 7, 8, 9]; 659 * List<int> list2 = [5, 6, 7, 8, 9];
418 * // Copies the 4th and 5th items in list2 as the 2nd and 3rd items 660 * // Copies the 4th and 5th items in list2 as the 2nd and 3rd items
419 * // of list1. 661 * // of list1.
420 * list1.setRange(1, 3, list2, 3); 662 * list1.setRange(1, 3, list2, 3);
421 * list1.join(', '); // '1, 8, 9, 4' 663 * list1.join(', '); // '1, 8, 9, 4'
422 * 664 *
423 * The [start] and [end] indices must satisfy `0 ≤ start ≤ end ≤ length`. 665 * The [start] and [end] indices must satisfy `0 ≤ start ≤ end ≤ length`.
424 * If [start] equals [end], this method has no effect. 666 * If [start] equals [end], this method has no effect.
425 * 667 *
426 * The [iterable] must have enough objects to fill the range from `start` 668 * The [iterable] must have enough objects to fill the range from `start`
427 * to `end` after skipping [skipCount] objects. 669 * to `end` after skipping [skipCount] objects.
428 * 670 *
429 * If `iterable` is this list, the operation will copy the elements originally 671 * If `iterable` is this list, the operation will copy the elements originally
430 * in the range from `skipCount` to `skipCount + (end - start)` to the 672 * in the range from `skipCount` to `skipCount + (end - start)` to the
431 * range `start` to `end`, even if the two ranges overlap. 673 * range `start` to `end`, even if the two ranges overlap.
432 * 674 *
433 * If `iterable` depends on this list in some other way, no guarantees are 675 * If `iterable` depends on this list in some other way, no guarantees are
434 * made. 676 * made.
435 */ 677 */
436 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]); 678 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
679 checkMutable('set range');
680 IterableMixinWorkaround.setRangeList(this, start, end, iterable, skipCount);
681 }
437 682
438 /** 683 /**
439 * Removes the objects in the range [start] inclusive to [end] exclusive. 684 * Removes the objects in the range [start] inclusive to [end] exclusive.
440 * 685 *
441 * The [start] and [end] indices must be in the range 686 * The [start] and [end] indices must be in the range
442 * `0 ≤ index ≤ length`, and `start ≤ end`. 687 * `0 ≤ index ≤ length`, and `start ≤ end`.
443 * 688 *
444 * Throws an [UnsupportedError] if this is a fixed-length list. In that case 689 * Throws an [UnsupportedError] if this is a fixed-length list. In that case
445 * the list is not modified. 690 * the list is not modified.
446 */ 691 */
447 void removeRange(int start, int end); 692 void removeRange(int start, int end) {
693 checkGrowable('removeRange');
694 int receiverLength = this.length;
695 if (start < 0 || start > receiverLength) {
696 throw new RangeError.range(start, 0, receiverLength);
697 }
698 if (end < start || end > receiverLength) {
699 throw new RangeError.range(end, start, receiverLength);
700 }
701 Lists.copy(this,
702 end,
703 this,
704 start,
705 receiverLength - end);
706 this.length = receiverLength - (end - start);
707 }
448 708
449 /** 709 /**
450 * Sets the objects in the range [start] inclusive to [end] exclusive 710 * Sets the objects in the range [start] inclusive to [end] exclusive
451 * to the given [fillValue]. 711 * to the given [fillValue].
452 * 712 *
453 * An error occurs if [start]..[end] is not a valid range for `this`. 713 * An error occurs if [start]..[end] is not a valid range for `this`.
454 */ 714 */
455 void fillRange(int start, int end, [E fillValue]); 715 void fillRange(int start, int end, [E fillValue]) {
716 checkMutable('fill range');
717 IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
718 }
456 719
457 /** 720 /**
458 * Removes the objects in the range [start] inclusive to [end] exclusive 721 * Removes the objects in the range [start] inclusive to [end] exclusive
459 * and inserts the contents of [replacement] in its place. 722 * and inserts the contents of [replacement] in its place.
460 * 723 *
461 * List<int> list = [1, 2, 3, 4, 5]; 724 * List<int> list = [1, 2, 3, 4, 5];
462 * list.replaceRange(1, 4, [6, 7]); 725 * list.replaceRange(1, 4, [6, 7]);
463 * list.join(', '); // '1, 6, 7, 5' 726 * list.join(', '); // '1, 6, 7, 5'
464 * 727 *
465 * An error occurs if [start]..[end] is not a valid range for `this`. 728 * An error occurs if [start]..[end] is not a valid range for `this`.
466 */ 729 */
467 void replaceRange(int start, int end, Iterable<E> replacement); 730 void replaceRange(int start, int end, Iterable<E> replacement) {
731 checkGrowable('removeRange');
732 IterableMixinWorkaround.replaceRangeList(this, start, end, replacement);
733 }
468 734
469 /** 735 /**
470 * Returns an unmodifiable [Map] view of `this`. 736 * Returns an unmodifiable [Map] view of `this`.
471 * 737 *
472 * The map uses the indices of this list as keys and the corresponding objects 738 * The map uses the indices of this list as keys and the corresponding objects
473 * as values. The `Map.keys` [Iterable] iterates the indices of this list 739 * as values. The `Map.keys` [Iterable] iterates the indices of this list
474 * in numerical order. 740 * in numerical order.
475 * 741 *
476 * List<String> words = ['fee', 'fi', 'fo', 'fum']; 742 * List<String> words = ['fee', 'fi', 'fo', 'fum'];
477 * Map<int, String> map = words.asMap(); 743 * Map<int, String> map = words.asMap();
478 * map[0] + map[1]; // 'feefi'; 744 * map[0] + map[1]; // 'feefi';
479 * map.keys.toList(); // [0, 1, 2, 3] 745 * map.keys.toList(); // [0, 1, 2, 3]
480 */ 746 */
481 Map<int, E> asMap(); 747 Map<int, E> asMap() {
748 return new IterableMixinWorkaround<E>().asMapList(this);
749 }
482 } 750 }
OLDNEW
« no previous file with comments | « test/generated_sdk/lib/_internal/compiler/js_lib/js_helper.dart ('k') | tool/input_sdk/lib/core/list.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698