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

Side by Side Diff: runtime/lib/array.dart

Issue 730543002: Remove use of IterableMixinWorkaround from _List, _ImmutableList and _GrowableList. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments Created 6 years, 1 month 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 | Annotate | Revision Log
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 5
6 // TODO(srdjan): Use shared array implementation. 6 // TODO(srdjan): Use shared array implementation.
7 class _List<E> implements List<E> { 7 class _List<E> extends FixedLengthListBase<E> {
8 8
9 factory _List(length) native "List_allocate"; 9 factory _List(length) native "List_allocate";
10 10
11 E operator [](int index) native "List_getIndexed"; 11 E operator [](int index) native "List_getIndexed";
12 12
13 void operator []=(int index, E value) native "List_setIndexed"; 13 void operator []=(int index, E value) native "List_setIndexed";
14 14
15 String toString() {
16 return ListBase.listToString(this);
17 }
18
19 int get length native "List_getLength"; 15 int get length native "List_getLength";
20 16
21 List _slice(int start, int count, bool needsTypeArgument) { 17 List _slice(int start, int count, bool needsTypeArgument) {
22 if (count <= 64) { 18 if (count <= 64) {
23 final result = needsTypeArgument ? new _List<E>(count) 19 final result = needsTypeArgument ? new _List<E>(count)
24 : new _List(count); 20 : new _List(count);
25 for (int i = 0; i < result.length; i++) { 21 for (int i = 0; i < result.length; i++) {
26 result[i] = this[start + i]; 22 result[i] = this[start + i];
27 } 23 }
28 return result; 24 return result;
29 } else { 25 } else {
30 return _sliceInternal(start, count, needsTypeArgument); 26 return _sliceInternal(start, count, needsTypeArgument);
31 } 27 }
32 } 28 }
33 29
34 List _sliceInternal(int start, int count, bool needsTypeArgument) 30 List _sliceInternal(int start, int count, bool needsTypeArgument)
35 native "List_slice"; 31 native "List_slice";
36 32
37 void insert(int index, E element) {
38 throw NonGrowableListError.add();
39 }
40
41 void insertAll(int index, Iterable<E> iterable) {
42 throw NonGrowableListError.add();
43 }
44
45 void setAll(int index, Iterable<E> iterable) {
46 IterableMixinWorkaround.setAllList(this, index, iterable);
47 }
48
49 E removeAt(int index) {
50 throw NonGrowableListError.remove();
51 }
52
53 bool remove(Object element) {
54 throw NonGrowableListError.remove();
55 }
56
57 void removeWhere(bool test(E element)) {
58 throw NonGrowableListError.remove();
59 }
60
61 void retainWhere(bool test(E element)) {
62 throw NonGrowableListError.remove();
63 }
64
65 Iterable<E> getRange(int start, [int end]) {
66 return new IterableMixinWorkaround<E>().getRangeList(this, start, end);
67 }
68
69 // List interface. 33 // List interface.
70 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) { 34 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
71 if (start < 0 || start > this.length) { 35 if (start < 0 || start > this.length) {
72 throw new RangeError.range(start, 0, this.length); 36 throw new RangeError.range(start, 0, this.length);
73 } 37 }
74 if (end < start || end > this.length) { 38 if (end < start || end > this.length) {
75 throw new RangeError.range(end, start, this.length); 39 throw new RangeError.range(end, start, this.length);
76 } 40 }
77 int length = end - start; 41 int length = end - start;
78 if (length == 0) return; 42 if (length == 0) return;
79 if (identical(this, iterable)) { 43 if (identical(this, iterable)) {
80 Lists.copy(iterable, skipCount, this, start, length); 44 Lists.copy(iterable, skipCount, this, start, length);
81 } else if (ClassID.getID(iterable) == ClassID.cidArray) { 45 } else if (ClassID.getID(iterable) == ClassID.cidArray) {
82 Lists.copy(iterable, skipCount, this, start, length); 46 Lists.copy(iterable, skipCount, this, start, length);
83 } else if (iterable is List) { 47 } else if (iterable is List) {
84 Lists.copy(iterable, skipCount, this, start, length); 48 Lists.copy(iterable, skipCount, this, start, length);
85 } else { 49 } else {
86 Iterator it = iterable.iterator; 50 Iterator it = iterable.iterator;
87 while (skipCount > 0) { 51 while (skipCount > 0) {
88 if (!it.moveNext()) return; 52 if (!it.moveNext()) return;
89 skipCount--; 53 skipCount--;
90 } 54 }
91 for (int i = start; i < end; i++) { 55 for (int i = start; i < end; i++) {
92 if (!it.moveNext()) return; 56 if (!it.moveNext()) return;
93 this[i] = it.current; 57 this[i] = it.current;
94 } 58 }
95 } 59 }
96 } 60 }
97 61
98 void removeRange(int start, int end) {
99 throw NonGrowableListError.remove();
100 }
101
102 void replaceRange(int start, int end, Iterable<E> iterable) {
103 throw NonGrowableListError.remove();
104 }
105
106 void fillRange(int start, int end, [E fillValue]) {
107 IterableMixinWorkaround.fillRangeList(this, start, end, fillValue);
108 }
109
110 List<E> sublist(int start, [int end]) { 62 List<E> sublist(int start, [int end]) {
111 Lists.indicesCheck(this, start, end); 63 Lists.indicesCheck(this, start, end);
112 if (end == null) end = this.length; 64 if (end == null) end = this.length;
113 int length = end - start; 65 int length = end - start;
114 if (start == end) return <E>[]; 66 if (start == end) return <E>[];
115 var result = new _GrowableList<E>.withData(_slice(start, length, false)); 67 var result = new _GrowableList<E>.withData(_slice(start, length, false));
116 result._setLength(length); 68 result._setLength(length);
117 return result; 69 return result;
118 } 70 }
119 71
120 // Iterable interface. 72 // Iterable interface.
121 73
122 bool contains(Object element) {
123 return IterableMixinWorkaround.contains(this, element);
124 }
125
126 void forEach(f(E element)) { 74 void forEach(f(E element)) {
127 final length = this.length; 75 final length = this.length;
128 for (int i = 0; i < length; i++) { 76 for (int i = 0; i < length; i++) {
129 f(this[i]); 77 f(this[i]);
130 } 78 }
131 } 79 }
132 80
133 String join([String separator = ""]) {
134 return IterableMixinWorkaround.joinList(this, separator);
135 }
136
137 Iterable map(f(E element)) {
138 return IterableMixinWorkaround.mapList(this, f);
139 }
140
141 E reduce(E combine(E value, E element)) {
142 return IterableMixinWorkaround.reduce(this, combine);
143 }
144
145 fold(initialValue, combine(previousValue, E element)) {
146 return IterableMixinWorkaround.fold(this, initialValue, combine);
147 }
148
149 Iterable<E> where(bool f(E element)) {
150 return new IterableMixinWorkaround<E>().where(this, f);
151 }
152
153 Iterable expand(Iterable f(E element)) {
154 return IterableMixinWorkaround.expand(this, f);
155 }
156
157 Iterable<E> take(int n) {
158 return new IterableMixinWorkaround<E>().takeList(this, n);
159 }
160
161 Iterable<E> takeWhile(bool test(E value)) {
162 return new IterableMixinWorkaround<E>().takeWhile(this, test);
163 }
164
165 Iterable<E> skip(int n) {
166 return new IterableMixinWorkaround<E>().skipList(this, n);
167 }
168
169 Iterable<E> skipWhile(bool test(E value)) {
170 return new IterableMixinWorkaround<E>().skipWhile(this, test);
171 }
172
173 bool every(bool f(E element)) {
174 return IterableMixinWorkaround.every(this, f);
175 }
176
177 bool any(bool f(E element)) {
178 return IterableMixinWorkaround.any(this, f);
179 }
180
181 E firstWhere(bool test(E value), {E orElse()}) {
182 return IterableMixinWorkaround.firstWhere(this, test, orElse);
183 }
184
185 E lastWhere(bool test(E value), {E orElse()}) {
186 return IterableMixinWorkaround.lastWhereList(this, test, orElse);
187 }
188
189 E singleWhere(bool test(E value)) {
190 return IterableMixinWorkaround.singleWhere(this, test);
191 }
192
193 E elementAt(int index) {
194 return this[index];
195 }
196
197 bool get isEmpty {
198 return this.length == 0;
199 }
200
201 bool get isNotEmpty => !isEmpty;
202
203 Iterable<E> get reversed =>
204 new IterableMixinWorkaround<E>().reversedList(this);
205
206 void sort([int compare(E a, E b)]) {
207 IterableMixinWorkaround.sortList(this, compare);
208 }
209
210 void shuffle([Random random]) {
211 IterableMixinWorkaround.shuffleList(this, random);
212 }
213
214 int indexOf(Object element, [int start = 0]) {
215 return Lists.indexOf(this, element, start, this.length);
216 }
217
218 int lastIndexOf(Object element, [int start = null]) {
219 if (start == null) start = length - 1;
220 return Lists.lastIndexOf(this, element, start);
221 }
222
223 Iterator<E> get iterator { 81 Iterator<E> get iterator {
224 return new _FixedSizeArrayIterator<E>(this); 82 return new _FixedSizeArrayIterator<E>(this);
225 } 83 }
226 84
227 void add(E element) {
228 throw NonGrowableListError.add();
229 }
230
231 void addAll(Iterable<E> iterable) {
232 throw NonGrowableListError.add();
233 }
234
235 void clear() {
236 throw NonGrowableListError.remove();
237 }
238
239 void set length(int length) {
240 throw NonGrowableListError.length();
241 }
242
243 E removeLast() {
244 throw NonGrowableListError.remove();
245 }
246
247 E get first { 85 E get first {
248 if (length > 0) return this[0]; 86 if (length > 0) return this[0];
249 throw IterableElementError.noElement(); 87 throw IterableElementError.noElement();
250 } 88 }
251 89
252 E get last { 90 E get last {
253 if (length > 0) return this[length - 1]; 91 if (length > 0) return this[length - 1];
254 throw IterableElementError.noElement(); 92 throw IterableElementError.noElement();
255 } 93 }
256 94
257 E get single { 95 E get single {
258 if (length == 1) return this[0]; 96 if (length == 1) return this[0];
259 if (length == 0) throw IterableElementError.noElement(); 97 if (length == 0) throw IterableElementError.noElement();
260 throw IterableElementError.tooMany(); 98 throw IterableElementError.tooMany();
261 } 99 }
262 100
263 List<E> toList({ bool growable: true }) { 101 List<E> toList({ bool growable: true }) {
264 var length = this.length; 102 var length = this.length;
265 if (length > 0) { 103 if (length > 0) {
266 var result = _slice(0, length, !growable); 104 var result = _slice(0, length, !growable);
267 if (growable) { 105 if (growable) {
268 result = new _GrowableList<E>.withData(result); 106 result = new _GrowableList<E>.withData(result);
269 result._setLength(length); 107 result._setLength(length);
270 } 108 }
271 return result; 109 return result;
272 } 110 }
273 // _GrowableList.withData must not be called with empty list. 111 // _GrowableList.withData must not be called with empty list.
274 return growable ? <E>[] : new List<E>(0); 112 return growable ? <E>[] : new List<E>(0);
275 } 113 }
276
277 Set<E> toSet() {
278 return new Set<E>.from(this);
279 }
280
281 Map<int, E> asMap() {
282 return new IterableMixinWorkaround<E>().asMapList(this);
283 }
284 } 114 }
285 115
286 116
287 // This is essentially the same class as _List, but it does not 117 // This is essentially the same class as _List, but it does not
288 // permit any modification of array elements from Dart code. We use 118 // permit any modification of array elements from Dart code. We use
289 // this class for arrays constructed from Dart array literals. 119 // this class for arrays constructed from Dart array literals.
290 // TODO(hausner): We should consider the trade-offs between two 120 // TODO(hausner): We should consider the trade-offs between two
291 // classes (and inline cache misses) versus a field in the native 121 // classes (and inline cache misses) versus a field in the native
292 // implementation (checks when modifying). We should keep watching 122 // implementation (checks when modifying). We should keep watching
293 // the inline cache misses. 123 // the inline cache misses.
294 class _ImmutableList<E> implements List<E> { 124 class _ImmutableList<E> extends UnmodifiableListBase<E> {
295 125
296 factory _ImmutableList._uninstantiable() { 126 factory _ImmutableList._uninstantiable() {
297 throw new UnsupportedError( 127 throw new UnsupportedError(
298 "ImmutableArray can only be allocated by the VM"); 128 "ImmutableArray can only be allocated by the VM");
299 } 129 }
300 130
301 factory _ImmutableList._from(List from, int offset, int length) 131 factory _ImmutableList._from(List from, int offset, int length)
302 native "ImmutableList_from"; 132 native "ImmutableList_from";
303 133
304 E operator [](int index) native "List_getIndexed"; 134 E operator [](int index) native "List_getIndexed";
305 135
306 void operator []=(int index, E value) {
307 throw UnmodifiableListError.change();
308 }
309
310 int get length native "List_getLength"; 136 int get length native "List_getLength";
311 137
312 void insert(int index, E element) {
313 throw UnmodifiableListError.add();
314 }
315
316 void insertAll(int index, Iterable<E> iterable) {
317 throw UnmodifiableListError.add();
318 }
319
320 void setAll(int index, Iterable<E> iterable) {
321 throw UnmodifiableListError.change();
322 }
323
324 E removeAt(int index) {
325 throw UnmodifiableListError.remove();
326 }
327
328 bool remove(Object element) {
329 throw UnmodifiableListError.remove();
330 }
331
332 void removeWhere(bool test(E element)) {
333 throw UnmodifiableListError.remove();
334 }
335
336 void retainWhere(bool test(E element)) {
337 throw UnmodifiableListError.remove();
338 }
339
340 void copyFrom(List src, int srcStart, int dstStart, int count) {
341 throw UnmodifiableListError.change();
342 }
343
344 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) {
345 throw UnmodifiableListError.change();
346 }
347
348 void removeRange(int start, int end) {
349 throw UnmodifiableListError.remove();
350 }
351
352 void fillRange(int start, int end, [E fillValue]) {
353 throw UnmodifiableListError.change();
354 }
355
356 void replaceRange(int start, int end, Iterable<E> iterable) {
357 throw UnmodifiableListError.change();
358 }
359
360 List<E> sublist(int start, [int end]) { 138 List<E> sublist(int start, [int end]) {
361 Lists.indicesCheck(this, start, end); 139 Lists.indicesCheck(this, start, end);
362 if (end == null) end = this.length; 140 if (end == null) end = this.length;
363 int length = end - start; 141 int length = end - start;
364 if (length == 0) return <E>[]; 142 if (length == 0) return <E>[];
365 List list = new _List(length); 143 List list = new _List(length);
366 for (int i = 0; i < length; i++) { 144 for (int i = 0; i < length; i++) {
367 list[i] = this[start + i]; 145 list[i] = this[start + i];
368 } 146 }
369 var result = new _GrowableList<E>.withData(list); 147 var result = new _GrowableList<E>.withData(list);
370 result._setLength(length); 148 result._setLength(length);
371 return result; 149 return result;
372 } 150 }
373 151
374 Iterable<E> getRange(int start, int end) {
375 return new IterableMixinWorkaround<E>().getRangeList(this, start, end);
376 }
377
378 // Collection interface. 152 // Collection interface.
379 153
380 bool contains(Object element) {
381 return IterableMixinWorkaround.contains(this, element);
382 }
383
384 void forEach(f(E element)) { 154 void forEach(f(E element)) {
385 final length = this.length; 155 final length = this.length;
386 for (int i = 0; i < length; i++) { 156 for (int i = 0; i < length; i++) {
387 f(this[i]); 157 f(this[i]);
388 } 158 }
389 } 159 }
390 160
391 Iterable map(f(E element)) {
392 return IterableMixinWorkaround.mapList(this, f);
393 }
394
395 String join([String separator = ""]) {
396 return IterableMixinWorkaround.joinList(this, separator);
397 }
398
399 E reduce(E combine(E value, E element)) {
400 return IterableMixinWorkaround.reduce(this, combine);
401 }
402
403 fold(initialValue, combine(previousValue, E element)) {
404 return IterableMixinWorkaround.fold(this, initialValue, combine);
405 }
406
407 Iterable<E> where(bool f(E element)) {
408 return new IterableMixinWorkaround<E>().where(this, f);
409 }
410
411 Iterable expand(Iterable f(E element)) {
412 return IterableMixinWorkaround.expand(this, f);
413 }
414
415 Iterable<E> take(int n) {
416 return new IterableMixinWorkaround<E>().takeList(this, n);
417 }
418
419 Iterable<E> takeWhile(bool test(E value)) {
420 return new IterableMixinWorkaround<E>().takeWhile(this, test);
421 }
422
423 Iterable<E> skip(int n) {
424 return new IterableMixinWorkaround<E>().skipList(this, n);
425 }
426
427 Iterable<E> skipWhile(bool test(E value)) {
428 return new IterableMixinWorkaround<E>().skipWhile(this, test);
429 }
430
431 bool every(bool f(E element)) {
432 return IterableMixinWorkaround.every(this, f);
433 }
434
435 bool any(bool f(E element)) {
436 return IterableMixinWorkaround.any(this, f);
437 }
438
439 E firstWhere(bool test(E value), {E orElse()}) {
440 return IterableMixinWorkaround.firstWhere(this, test, orElse);
441 }
442
443 E lastWhere(bool test(E value), {E orElse()}) {
444 return IterableMixinWorkaround.lastWhereList(this, test, orElse);
445 }
446
447 E singleWhere(bool test(E value)) {
448 return IterableMixinWorkaround.singleWhere(this, test);
449 }
450
451 E elementAt(int index) {
452 return this[index];
453 }
454
455 bool get isEmpty {
456 return this.length == 0;
457 }
458
459 bool get isNotEmpty => !isEmpty;
460
461 Iterable<E> get reversed =>
462 new IterableMixinWorkaround<E>().reversedList(this);
463
464 void sort([int compare(E a, E b)]) {
465 throw UnmodifiableListError.change();
466 }
467
468 void shuffle([Random random]) {
469 throw UnmodifiableListError.change();
470 }
471
472 String toString() {
473 return ListBase.listToString(this);
474 }
475
476 int indexOf(Object element, [int start = 0]) {
477 return Lists.indexOf(this, element, start, this.length);
478 }
479
480 int lastIndexOf(Object element, [int start = null]) {
481 if (start == null) start = length - 1;
482 return Lists.lastIndexOf(this, element, start);
483 }
484
485 Iterator<E> get iterator { 161 Iterator<E> get iterator {
486 return new _FixedSizeArrayIterator<E>(this); 162 return new _FixedSizeArrayIterator<E>(this);
487 } 163 }
488 164
489 void add(E element) {
490 throw UnmodifiableListError.add();
491 }
492
493 void addAll(Iterable<E> elements) {
494 throw UnmodifiableListError.add();
495 }
496
497 void clear() {
498 throw UnmodifiableListError.remove();
499 }
500
501 void set length(int length) {
502 throw UnmodifiableListError.length();
503 }
504
505 E removeLast() {
506 throw UnmodifiableListError.remove();
507 }
508
509 E get first { 165 E get first {
510 if (length > 0) return this[0]; 166 if (length > 0) return this[0];
511 throw IterableElementError.noElement(); 167 throw IterableElementError.noElement();
512 } 168 }
513 169
514 E get last { 170 E get last {
515 if (length > 0) return this[length - 1]; 171 if (length > 0) return this[length - 1];
516 throw IterableElementError.noElement(); 172 throw IterableElementError.noElement();
517 } 173 }
518 174
(...skipping 10 matching lines...) Expand all
529 for (int i = 0; i < length; i++) { 185 for (int i = 0; i < length; i++) {
530 list[i] = this[i]; 186 list[i] = this[i];
531 } 187 }
532 if (!growable) return list; 188 if (!growable) return list;
533 var result = new _GrowableList<E>.withData(list); 189 var result = new _GrowableList<E>.withData(list);
534 result._setLength(length); 190 result._setLength(length);
535 return result; 191 return result;
536 } 192 }
537 return growable ? <E>[] : new _List<E>(0); 193 return growable ? <E>[] : new _List<E>(0);
538 } 194 }
539
540 Set<E> toSet() {
541 return new Set<E>.from(this);
542 }
543
544 Map<int, E> asMap() {
545 return new IterableMixinWorkaround<E>().asMapList(this);
546 }
547 } 195 }
548 196
549 197
550 // Iterator for arrays with fixed size. 198 // Iterator for arrays with fixed size.
551 class _FixedSizeArrayIterator<E> implements Iterator<E> { 199 class _FixedSizeArrayIterator<E> implements Iterator<E> {
552 final List<E> _array; 200 final List<E> _array;
553 final int _length; // Cache array length for faster access. 201 final int _length; // Cache array length for faster access.
554 int _index; 202 int _index;
555 E _current; 203 E _current;
556 204
557 _FixedSizeArrayIterator(List array) 205 _FixedSizeArrayIterator(List array)
558 : _array = array, _length = array.length, _index = 0 { 206 : _array = array, _length = array.length, _index = 0 {
559 assert(array is _List || array is _ImmutableList); 207 assert(array is _List || array is _ImmutableList);
560 } 208 }
561 209
562 E get current => _current; 210 E get current => _current;
563 211
564 bool moveNext() { 212 bool moveNext() {
565 if (_index >= _length) { 213 if (_index >= _length) {
566 _current = null; 214 _current = null;
567 return false; 215 return false;
568 } 216 }
569 _current = _array[_index]; 217 _current = _array[_index];
570 _index++; 218 _index++;
571 return true; 219 return true;
572 } 220 }
573 } 221 }
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/growable_array.dart » ('j') | tests/lib/mirrors/intercepted_object_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698