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

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/private/js_array.dart

Issue 2994203002: Optimize DDC private library files. (Closed)
Patch Set: Address comments Created 3 years, 3 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._interceptors; 5 part of dart._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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 if (JS('bool', r'#.fixed$length', this)) { 57 if (JS('bool', r'#.fixed$length', this)) {
58 throw new UnsupportedError(reason); 58 throw new UnsupportedError(reason);
59 } 59 }
60 } 60 }
61 61
62 void add(E value) { 62 void add(E value) {
63 checkGrowable('add'); 63 checkGrowable('add');
64 JS('void', r'#.push(#)', this, value); 64 JS('void', r'#.push(#)', this, value);
65 } 65 }
66 66
67 E removeAt(int index) { 67 E removeAt(@nullCheck int index) {
68 checkGrowable('removeAt'); 68 checkGrowable('removeAt');
69 if (index is! int) throw argumentErrorValue(index);
70 if (index < 0 || index >= length) { 69 if (index < 0 || index >= length) {
71 throw new RangeError.value(index); 70 throw new RangeError.value(index);
72 } 71 }
73 return JS('-dynamic', r'#.splice(#, 1)[0]', this, index); 72 return JS('-dynamic', r'#.splice(#, 1)[0]', this, index);
74 } 73 }
75 74
76 void insert(int index, E value) { 75 void insert(@nullCheck int index, E value) {
77 checkGrowable('insert'); 76 checkGrowable('insert');
78 if (index is! int) throw argumentErrorValue(index);
79 if (index < 0 || index > length) { 77 if (index < 0 || index > length) {
80 throw new RangeError.value(index); 78 throw new RangeError.value(index);
81 } 79 }
82 JS('void', r'#.splice(#, 0, #)', this, index, value); 80 JS('void', r'#.splice(#, 0, #)', this, index, value);
83 } 81 }
84 82
85 void insertAll(int index, Iterable<E> iterable) { 83 void insertAll(@nullCheck int index, Iterable<E> iterable) {
86 checkGrowable('insertAll'); 84 checkGrowable('insertAll');
87 RangeError.checkValueInInterval(index, 0, this.length, "index"); 85 RangeError.checkValueInInterval(index, 0, this.length, "index");
88 if (iterable is! EfficientLengthIterable) { 86 if (iterable is! EfficientLengthIterable) {
89 iterable = iterable.toList(); 87 iterable = iterable.toList();
90 } 88 }
89 @nullCheck
91 int insertionLength = iterable.length; 90 int insertionLength = iterable.length;
92 this.length += insertionLength; 91 this.length += insertionLength;
93 int end = index + insertionLength; 92 int end = index + insertionLength;
94 this.setRange(end, this.length, this, index); 93 this.setRange(end, this.length, this, index);
95 this.setRange(index, end, iterable); 94 this.setRange(index, end, iterable);
96 } 95 }
97 96
98 void setAll(int index, Iterable<E> iterable) { 97 void setAll(@nullCheck int index, Iterable<E> iterable) {
99 checkMutable('setAll'); 98 checkMutable('setAll');
100 RangeError.checkValueInInterval(index, 0, this.length, "index"); 99 RangeError.checkValueInInterval(index, 0, this.length, "index");
101 for (var element in iterable) { 100 for (var element in iterable) {
102 this[index++] = element; 101 this[index++] = element;
103 } 102 }
104 } 103 }
105 104
106 E removeLast() { 105 E removeLast() {
107 checkGrowable('removeLast'); 106 checkGrowable('removeLast');
108 if (length == 0) throw diagnoseIndexError(this, -1); 107 if (length == 0) throw diagnoseIndexError(this, -1);
109 return JS('var', r'#.pop()', this); 108 return JS('var', r'#.pop()', this);
110 } 109 }
111 110
112 bool remove(Object element) { 111 bool remove(Object element) {
113 checkGrowable('remove'); 112 checkGrowable('remove');
114 for (int i = 0; i < this.length; i++) { 113 var length = this.length;
114 for (int i = 0; i < length; i++) {
115 if (this[i] == element) { 115 if (this[i] == element) {
116 JS('var', r'#.splice(#, 1)', this, i); 116 JS('var', r'#.splice(#, 1)', this, i);
117 return true; 117 return true;
118 } 118 }
119 } 119 }
120 return false; 120 return false;
121 } 121 }
122 122
123 /** 123 /**
124 * Removes elements matching [test] from [this] List. 124 * Removes elements matching [test] from [this] List.
(...skipping 14 matching lines...) Expand all
139 // the original list is updated to contain those elements. 139 // the original list is updated to contain those elements.
140 140
141 // TODO(sra): Replace this algorithm with one that retains a list of ranges 141 // TODO(sra): Replace this algorithm with one that retains a list of ranges
142 // to be removed. Most real uses remove 0, 1 or a few clustered elements. 142 // to be removed. Most real uses remove 0, 1 or a few clustered elements.
143 143
144 List retained = []; 144 List retained = [];
145 int end = this.length; 145 int end = this.length;
146 for (int i = 0; i < end; i++) { 146 for (int i = 0; i < end; i++) {
147 // TODO(22407): Improve bounds check elimination to allow this JS code to 147 // TODO(22407): Improve bounds check elimination to allow this JS code to
148 // be replaced by indexing. 148 // be replaced by indexing.
149 var element = JS('', '#[#]', this, i); 149 E element = JS('-dynamic', '#[#]', this, i);
150 // !test() ensures bool conversion in checked mode. 150 // !test() ensures bool conversion in checked mode.
151 if (!test(element) == removeMatching) { 151 if (!test(element) == removeMatching) {
152 retained.add(element); 152 retained.add(element);
153 } 153 }
154 if (this.length != end) throw new ConcurrentModificationError(this); 154 if (this.length != end) throw new ConcurrentModificationError(this);
155 } 155 }
156 if (retained.length == end) return; 156 if (retained.length == end) return;
157 this.length = retained.length; 157 this.length = retained.length;
158 for (int i = 0; i < retained.length; i++) { 158 @nullCheck
159 this[i] = retained[i]; 159 var length = retained.length;
160 for (int i = 0; i < length; i++) {
161 JS('', '#[#] = #[#]', this, i, retained, i);
160 } 162 }
161 } 163 }
162 164
163 Iterable<E> where(bool f(E element)) { 165 Iterable<E> where(bool f(E element)) {
164 return new WhereIterable<E>(this, f); 166 return new WhereIterable<E>(this, f);
165 } 167 }
166 168
167 Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element)) { 169 Iterable/*<T>*/ expand/*<T>*/(Iterable/*<T>*/ f(E element)) {
168 return new ExpandIterable<E, dynamic/*=T*/ >(this, f); 170 return new ExpandIterable<E, dynamic/*=T*/ >(this, f);
169 } 171 }
(...skipping 21 matching lines...) Expand all
191 f(element); 193 f(element);
192 if (this.length != end) throw new ConcurrentModificationError(this); 194 if (this.length != end) throw new ConcurrentModificationError(this);
193 } 195 }
194 } 196 }
195 197
196 Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) { 198 Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) {
197 return new MappedListIterable<E, T>(this, f); 199 return new MappedListIterable<E, T>(this, f);
198 } 200 }
199 201
200 String join([String separator = ""]) { 202 String join([String separator = ""]) {
201 var list = new List(this.length); 203 var length = this.length;
202 for (int i = 0; i < this.length; i++) { 204 var list = new List(length);
205 for (int i = 0; i < length; i++) {
203 list[i] = "${this[i]}"; 206 list[i] = "${this[i]}";
204 } 207 }
205 return JS('String', "#.join(#)", list, separator); 208 return JS('String', "#.join(#)", list, separator);
206 } 209 }
207 210
208 Iterable<E> take(int n) { 211 Iterable<E> take(int n) {
209 return new SubListIterable<E>(this, 0, n); 212 return new SubListIterable<E>(this, 0, n);
210 } 213 }
211 214
212 Iterable<E> takeWhile(bool test(E value)) { 215 Iterable<E> takeWhile(bool test(E value)) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 throw IterableElementError.noElement(); 281 throw IterableElementError.noElement();
279 } 282 }
280 283
281 E singleWhere(bool test(E element)) { 284 E singleWhere(bool test(E element)) {
282 int length = this.length; 285 int length = this.length;
283 E match = null; 286 E match = null;
284 bool matchFound = false; 287 bool matchFound = false;
285 for (int i = 0; i < length; i++) { 288 for (int i = 0; i < length; i++) {
286 // TODO(22407): Improve bounds check elimination to allow this JS code to 289 // TODO(22407): Improve bounds check elimination to allow this JS code to
287 // be replaced by indexing. 290 // be replaced by indexing.
288 var element = JS('', '#[#]', this, i); 291 E element = JS('-dynamic', '#[#]', this, i);
289 if (test(element)) { 292 if (test(element)) {
290 if (matchFound) { 293 if (matchFound) {
291 throw IterableElementError.tooMany(); 294 throw IterableElementError.tooMany();
292 } 295 }
293 matchFound = true; 296 matchFound = true;
294 match = element; 297 match = element;
295 } 298 }
296 if (length != this.length) { 299 if (length != this.length) {
297 throw new ConcurrentModificationError(this); 300 throw new ConcurrentModificationError(this);
298 } 301 }
299 } 302 }
300 if (matchFound) return match; 303 if (matchFound) return match;
301 throw IterableElementError.noElement(); 304 throw IterableElementError.noElement();
302 } 305 }
303 306
304 E elementAt(int index) { 307 E elementAt(int index) {
305 return this[index]; 308 return this[index];
306 } 309 }
307 310
308 List<E> sublist(int start, [int end]) { 311 List<E> sublist(@nullCheck int start, [int end]) {
309 checkNull(start); // TODO(ahe): This is not specified but co19 tests it.
310 if (start is! int) throw argumentErrorValue(start);
311 if (start < 0 || start > length) { 312 if (start < 0 || start > length) {
312 throw new RangeError.range(start, 0, length, "start"); 313 throw new RangeError.range(start, 0, length, "start");
313 } 314 }
314 if (end == null) { 315 if (end == null) {
315 end = length; 316 end = length;
316 } else { 317 } else {
317 if (end is! int) throw argumentErrorValue(end); 318 @notNull
318 if (end < start || end > length) { 319 var _end = end;
320 if (_end < start || _end > length) {
319 throw new RangeError.range(end, start, length, "end"); 321 throw new RangeError.range(end, start, length, "end");
320 } 322 }
321 } 323 }
322 if (start == end) return <E>[]; 324 if (start == end) return <E>[];
323 return new JSArray<E>.of(JS('', r'#.slice(#, #)', this, start, end)); 325 return new JSArray<E>.of(JS('', r'#.slice(#, #)', this, start, end));
324 } 326 }
325 327
326 Iterable<E> getRange(int start, int end) { 328 Iterable<E> getRange(int start, int end) {
327 RangeError.checkValidRange(start, end, this.length); 329 RangeError.checkValidRange(start, end, this.length);
328 return new SubListIterable<E>(this, start, end); 330 return new SubListIterable<E>(this, start, end);
329 } 331 }
330 332
331 E get first { 333 E get first {
332 if (length > 0) return this[0]; 334 if (length > 0) return this[0];
333 throw IterableElementError.noElement(); 335 throw IterableElementError.noElement();
334 } 336 }
335 337
336 E get last { 338 E get last {
337 if (length > 0) return this[length - 1]; 339 if (length > 0) return this[length - 1];
338 throw IterableElementError.noElement(); 340 throw IterableElementError.noElement();
339 } 341 }
340 342
341 E get single { 343 E get single {
342 if (length == 1) return this[0]; 344 if (length == 1) return this[0];
343 if (length == 0) throw IterableElementError.noElement(); 345 if (length == 0) throw IterableElementError.noElement();
344 throw IterableElementError.tooMany(); 346 throw IterableElementError.tooMany();
345 } 347 }
346 348
347 void removeRange(int start, int end) { 349 void removeRange(@nullCheck int start, @nullCheck int end) {
348 checkGrowable('removeRange'); 350 checkGrowable('removeRange');
349 RangeError.checkValidRange(start, end, this.length); 351 RangeError.checkValidRange(start, end, this.length);
350 int deleteCount = end - start; 352 int deleteCount = end - start;
351 JS('', '#.splice(#, #)', this, start, deleteCount); 353 JS('', '#.splice(#, #)', this, start, deleteCount);
352 } 354 }
353 355
354 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) { 356 void setRange(@nullCheck int start, @nullCheck int end, Iterable<E> iterable,
357 [@nullCheck int skipCount = 0]) {
355 checkMutable('set range'); 358 checkMutable('set range');
356 359
357 RangeError.checkValidRange(start, end, this.length); 360 RangeError.checkValidRange(start, end, this.length);
358 int length = end - start; 361 int length = end - start;
359 if (length == 0) return; 362 if (length == 0) return;
360 RangeError.checkNotNegative(skipCount, "skipCount"); 363 RangeError.checkNotNegative(skipCount, "skipCount");
361 364
362 List/*<E>*/ otherList; 365 List<E> otherList;
363 int otherStart; 366 int otherStart = 0;
364 // TODO(floitsch): Make this accept more. 367 // TODO(floitsch): Make this accept more.
365 if (iterable is List) { 368 if (iterable is List<E>) {
366 otherList = iterable; 369 otherList = iterable;
367 otherStart = skipCount; 370 otherStart = skipCount;
368 } else { 371 } else {
369 otherList = iterable.skip(skipCount).toList(growable: false); 372 otherList = iterable.skip(skipCount).toList(growable: false);
370 otherStart = 0; 373 otherStart = 0;
371 } 374 }
372 if (otherStart + length > otherList.length) { 375 if (otherStart + length > otherList.length) {
373 throw IterableElementError.tooFew(); 376 throw IterableElementError.tooFew();
374 } 377 }
375 if (otherStart < start) { 378 if (otherStart < start) {
376 // Copy backwards to ensure correct copy if [from] is this. 379 // Copy backwards to ensure correct copy if [from] is this.
377 // TODO(sra): If [from] is the same Array as [this], we can copy without 380 // TODO(sra): If [from] is the same Array as [this], we can copy without
378 // type annotation checks on the stores. 381 // type annotation checks on the stores.
379 for (int i = length - 1; i >= 0; i--) { 382 for (int i = length - 1; i >= 0; i--) {
380 // Use JS to avoid bounds check (the bounds check elimination 383 // Use JS to avoid bounds check (the bounds check elimination
381 // optimzation is too weak). The 'E' type annotation is a store type 384 // optimzation is too weak). The 'E' type annotation is a store type
382 // check - we can't rely on iterable, it could be List<dynamic>. 385 // check - we can't rely on iterable, it could be List<dynamic>.
383 E element = otherList[otherStart + i]; 386 E element = otherList[otherStart + i];
384 JS('', '#[#] = #', this, start + i, element); 387 JS('', '#[#] = #', this, start + i, element);
385 } 388 }
386 } else { 389 } else {
387 for (int i = 0; i < length; i++) { 390 for (int i = 0; i < length; i++) {
388 E element = otherList[otherStart + i]; 391 E element = otherList[otherStart + i];
389 JS('', '#[#] = #', this, start + i, element); 392 JS('', '#[#] = #', this, start + i, element);
390 } 393 }
391 } 394 }
392 } 395 }
393 396
394 void fillRange(int start, int end, [E fillValue]) { 397 void fillRange(@nullCheck int start, @nullCheck int end, [E fillValue]) {
395 checkMutable('fill range'); 398 checkMutable('fill range');
396 RangeError.checkValidRange(start, end, this.length); 399 RangeError.checkValidRange(start, end, this.length);
397 for (int i = start; i < end; i++) { 400 for (int i = start; i < end; i++) {
398 // Store is safe since [fillValue] type has been checked as parameter. 401 // Store is safe since [fillValue] type has been checked as parameter.
399 JS('', '#[#] = #', this, i, fillValue); 402 JS('', '#[#] = #', this, i, fillValue);
400 } 403 }
401 } 404 }
402 405
403 void replaceRange(int start, int end, Iterable<E> replacement) { 406 void replaceRange(
407 @nullCheck int start, @nullCheck int end, Iterable<E> replacement) {
404 checkGrowable('replace range'); 408 checkGrowable('replace range');
405 RangeError.checkValidRange(start, end, this.length); 409 RangeError.checkValidRange(start, end, this.length);
406 if (replacement is! EfficientLengthIterable) { 410 if (replacement is! EfficientLengthIterable) {
407 replacement = replacement.toList(); 411 replacement = replacement.toList();
408 } 412 }
409 int removeLength = end - start; 413 int removeLength = end - start;
414 @nullCheck
410 int insertLength = replacement.length; 415 int insertLength = replacement.length;
411 if (removeLength >= insertLength) { 416 if (removeLength >= insertLength) {
412 int delta = removeLength - insertLength; 417 int delta = removeLength - insertLength;
413 int insertEnd = start + insertLength; 418 int insertEnd = start + insertLength;
414 int newLength = this.length - delta; 419 int newLength = this.length - delta;
415 this.setRange(start, insertEnd, replacement); 420 this.setRange(start, insertEnd, replacement);
416 if (delta != 0) { 421 if (delta != 0) {
417 this.setRange(insertEnd, newLength, this, end); 422 this.setRange(insertEnd, newLength, this, end);
418 this.length = newLength; 423 this.length = newLength;
419 } 424 }
(...skipping 17 matching lines...) Expand all
437 if (this.length != end) throw new ConcurrentModificationError(this); 442 if (this.length != end) throw new ConcurrentModificationError(this);
438 } 443 }
439 return false; 444 return false;
440 } 445 }
441 446
442 bool every(bool test(E element)) { 447 bool every(bool test(E element)) {
443 int end = this.length; 448 int end = this.length;
444 for (int i = 0; i < end; i++) { 449 for (int i = 0; i < end; i++) {
445 // TODO(22407): Improve bounds check elimination to allow this JS code to 450 // TODO(22407): Improve bounds check elimination to allow this JS code to
446 // be replaced by indexing. 451 // be replaced by indexing.
447 var/*=E*/ element = JS('', '#[#]', this, i); 452 E element = JS('-dynamic', '#[#]', this, i);
448 if (!test(element)) return false; 453 if (!test(element)) return false;
449 if (this.length != end) throw new ConcurrentModificationError(this); 454 if (this.length != end) throw new ConcurrentModificationError(this);
450 } 455 }
451 return true; 456 return true;
452 } 457 }
453 458
454 Iterable<E> get reversed => new ReversedListIterable<E>(this); 459 Iterable<E> get reversed => new ReversedListIterable<E>(this);
455 460
456 void sort([int compare(E a, E b)]) { 461 void sort([int compare(E a, E b)]) {
457 checkMutable('sort'); 462 checkMutable('sort');
(...skipping 10 matching lines...) Expand all
468 int length = this.length; 473 int length = this.length;
469 while (length > 1) { 474 while (length > 1) {
470 int pos = random.nextInt(length); 475 int pos = random.nextInt(length);
471 length -= 1; 476 length -= 1;
472 var tmp = this[length]; 477 var tmp = this[length];
473 this[length] = this[pos]; 478 this[length] = this[pos];
474 this[pos] = tmp; 479 this[pos] = tmp;
475 } 480 }
476 } 481 }
477 482
478 int indexOf(Object element, [int start = 0]) { 483 int indexOf(Object element, [@nullCheck int start = 0]) {
479 if (start >= this.length) { 484 int length = this.length;
485 if (start >= length) {
480 return -1; 486 return -1;
481 } 487 }
482 if (start < 0) { 488 if (start < 0) {
483 start = 0; 489 start = 0;
484 } 490 }
485 for (int i = start; i < this.length; i++) { 491 for (int i = start; i < length; i++) {
486 if (this[i] == element) { 492 if (this[i] == element) {
487 return i; 493 return i;
488 } 494 }
489 } 495 }
490 return -1; 496 return -1;
491 } 497 }
492 498
493 int lastIndexOf(Object element, [int startIndex]) { 499 int lastIndexOf(Object element, [int _startIndex]) {
494 if (startIndex == null) { 500 @notNull
501 int startIndex = _startIndex ?? this.length - 1;
502 if (startIndex >= this.length) {
495 startIndex = this.length - 1; 503 startIndex = this.length - 1;
496 } else { 504 } else if (startIndex < 0) {
497 if (startIndex < 0) { 505 return -1;
498 return -1;
499 }
500 if (startIndex >= this.length) {
501 startIndex = this.length - 1;
502 }
503 } 506 }
504 for (int i = startIndex; i >= 0; i--) { 507 for (int i = startIndex; i >= 0; i--) {
505 if (this[i] == element) { 508 if (this[i] == element) {
506 return i; 509 return i;
507 } 510 }
508 } 511 }
509 return -1; 512 return -1;
510 } 513 }
511 514
512 bool contains(Object other) { 515 bool contains(Object other) {
516 var length = this.length;
513 for (int i = 0; i < length; i++) { 517 for (int i = 0; i < length; i++) {
514 if (this[i] == other) return true; 518 E element = JS('-dynamic | Null', '#[#]', this, i);
519 if (element == other) return true;
515 } 520 }
516 return false; 521 return false;
517 } 522 }
518 523
524 @notNull
519 bool get isEmpty => length == 0; 525 bool get isEmpty => length == 0;
520 526
527 @notNull
521 bool get isNotEmpty => !isEmpty; 528 bool get isNotEmpty => !isEmpty;
522 529
523 String toString() => ListBase.listToString(this); 530 String toString() => ListBase.listToString(this);
524 531
525 List<E> toList({bool growable: true}) { 532 List<E> toList({@nullCheck bool growable: true}) {
526 var list = JS('', '#.slice()', this); 533 var list = JS('', '#.slice()', this);
527 if (!growable) markFixedList(list); 534 if (!growable) markFixedList(list);
528 return new JSArray<E>.of(list); 535 return new JSArray<E>.of(list);
529 } 536 }
530 537
531 Set<E> toSet() => new Set<E>.from(this); 538 Set<E> toSet() => new Set<E>.from(this);
532 539
533 Iterator<E> get iterator => new ArrayIterator<E>(this); 540 Iterator<E> get iterator => new ArrayIterator<E>(this);
534 541
535 int get hashCode => Primitives.objectHashCode(this); 542 int get hashCode => Primitives.objectHashCode(this);
536 543
544 @notNull
537 bool operator ==(other) => identical(this, other); 545 bool operator ==(other) => identical(this, other);
538 546
547 @notNull
539 int get length => JS('int', r'#.length', this); 548 int get length => JS('int', r'#.length', this);
540 549
541 void set length(int newLength) { 550 void set length(@nullCheck int newLength) {
542 checkGrowable('set length'); 551 checkGrowable('set length');
543 if (newLength is! int) {
544 throw new ArgumentError.value(newLength, 'newLength');
545 }
546 // TODO(sra): Remove this test and let JavaScript throw an error. 552 // TODO(sra): Remove this test and let JavaScript throw an error.
547 if (newLength < 0) { 553 if (newLength < 0) {
548 throw new RangeError.range(newLength, 0, null, 'newLength'); 554 throw new RangeError.range(newLength, 0, null, 'newLength');
549 } 555 }
550 // JavaScript with throw a RangeError for numbers that are too big. The 556 // JavaScript with throw a RangeError for numbers that are too big. The
551 // message does not contain the value. 557 // message does not contain the value.
552 JS('void', r'#.length = #', this, newLength); 558 JS('void', r'#.length = #', this, newLength);
553 } 559 }
554 560
555 E operator [](int index) { 561 E operator [](int index) {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 class JSFixedArray<E> extends JSMutableArray<E> {} 602 class JSFixedArray<E> extends JSMutableArray<E> {}
597 603
598 class JSExtendableArray<E> extends JSMutableArray<E> {} 604 class JSExtendableArray<E> extends JSMutableArray<E> {}
599 605
600 class JSUnmodifiableArray<E> extends JSArray<E> {} // Already is JSIndexable. 606 class JSUnmodifiableArray<E> extends JSArray<E> {} // Already is JSIndexable.
601 607
602 /// An [Iterator] that iterates a JSArray. 608 /// An [Iterator] that iterates a JSArray.
603 /// 609 ///
604 class ArrayIterator<E> implements Iterator<E> { 610 class ArrayIterator<E> implements Iterator<E> {
605 final JSArray<E> _iterable; 611 final JSArray<E> _iterable;
612 @notNull
606 final int _length; 613 final int _length;
614 @notNull
607 int _index; 615 int _index;
608 E _current; 616 E _current;
609 617
610 ArrayIterator(JSArray<E> iterable) 618 ArrayIterator(JSArray<E> iterable)
611 : _iterable = iterable, 619 : _iterable = iterable,
612 _length = iterable.length, 620 _length = iterable.length,
613 _index = 0; 621 _index = 0;
614 622
615 E get current => _current; 623 E get current => _current;
616 624
617 bool moveNext() { 625 bool moveNext() {
626 @notNull
618 int length = _iterable.length; 627 int length = _iterable.length;
619 628
620 // We have to do the length check even on fixed length Arrays. If we can 629 // We have to do the length check even on fixed length Arrays. If we can
621 // inline moveNext() we might be able to GVN the length and eliminate this 630 // inline moveNext() we might be able to GVN the length and eliminate this
622 // check on known fixed length JSArray. 631 // check on known fixed length JSArray.
623 if (_length != length) { 632 if (_length != length) {
624 throw throwConcurrentModificationError(_iterable); 633 throw throwConcurrentModificationError(_iterable);
625 } 634 }
626 635
627 if (_index >= length) { 636 if (_index >= length) {
628 _current = null; 637 _current = null;
629 return false; 638 return false;
630 } 639 }
631 _current = _iterable[_index]; 640 _current = _iterable[_index];
632 _index++; 641 _index++;
633 return true; 642 return true;
634 } 643 }
635 } 644 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698