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

Side by Side Diff: sdk/lib/collection/iterable.dart

Issue 26481002: Change the toString method of IterableBase/IterableMixin to show some elements. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Adapted other test too. Created 7 years, 2 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 | 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 part of dart.collection; 5 part of dart.collection;
6 6
7 /** 7 /**
8 * This [Iterable] mixin implements all [Iterable] members except `iterator`. 8 * This [Iterable] mixin implements all [Iterable] members except `iterator`.
9 * 9 *
10 * All other methods are implemented in terms of `iterator`. 10 * All other methods are implemented in terms of `iterator`.
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 181
182 E elementAt(int index) { 182 E elementAt(int index) {
183 if (index is! int || index < 0) throw new RangeError.value(index); 183 if (index is! int || index < 0) throw new RangeError.value(index);
184 int remaining = index; 184 int remaining = index;
185 for (E element in this) { 185 for (E element in this) {
186 if (remaining == 0) return element; 186 if (remaining == 0) return element;
187 remaining--; 187 remaining--;
188 } 188 }
189 throw new RangeError.value(index); 189 throw new RangeError.value(index);
190 } 190 }
191
192 String toString() => _iterableToString(this);
191 } 193 }
192 194
193 /** 195 /**
194 * Base class for implementing [Iterable]. 196 * Base class for implementing [Iterable].
195 * 197 *
196 * This class implements all methods of [Iterable] except [Iterable.iterator] 198 * This class implements all methods of [Iterable] except [Iterable.iterator]
197 * in terms of `iterator`. 199 * in terms of `iterator`.
198 */ 200 */
199 abstract class IterableBase<E> implements Iterable<E> { 201 abstract class IterableBase<E> implements Iterable<E> {
200 // TODO(lrn): Base this on IterableMixin if there ever becomes a way 202 // TODO(lrn): Base this on IterableMixin if there ever becomes a way
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 374
373 E elementAt(int index) { 375 E elementAt(int index) {
374 if (index is! int || index < 0) throw new RangeError.value(index); 376 if (index is! int || index < 0) throw new RangeError.value(index);
375 int remaining = index; 377 int remaining = index;
376 for (E element in this) { 378 for (E element in this) {
377 if (remaining == 0) return element; 379 if (remaining == 0) return element;
378 remaining--; 380 remaining--;
379 } 381 }
380 throw new RangeError.value(index); 382 throw new RangeError.value(index);
381 } 383 }
384
385 /**
386 * Returns a string representation of (some of) the elements of this
387 * Iterabele.
floitsch 2013/10/11 09:29:43 of `this`. I don't like to repeat the name of the
Lasse Reichstein Nielsen 2013/10/11 20:25:37 Done.
388 *
389 * Elements are represented by their own `toString` results.
390 *
391 * The representation always contains the first three elements.
392 * If there are less than a hundred elements in the iterable, it also
393 * contains the last two elements.
394 *
395 * If the resulting string isn't above 80 characters, more elements are
396 * included from the start of the iterable.
397 *
398 * The conversion may omit calling `toString` on some elements if they
floitsch 2013/10/11 09:29:43 Not sure we want to keep this sentence. If it's no
Lasse Reichstein Nielsen 2013/10/11 20:25:37 I think it's worth emphasizing, to avoid someone t
399 * are known to now occur in the output, and it may stop iterating after
400 * a hundred elements.
401 */
402 String toString() => _iterableToString(this);
382 } 403 }
404
405 String _iterableToString(Iterable iterable) {
406 const int LENGTH_LIMIT = 80;
407 const int MIN_COUNT = 3; // Always at least this many elements at the start.
408 const int MAX_COUNT = 100;
409 // Per entry length overhead for ", " (or for "(" and ")" for initial entry)
410 const int OVERHEAD = 2;
411 const int ELLIPSIS_SIZE = 3; // "...".length.
412 if (_toStringVisiting.contains(iterable)) return "(...)";
413 _toStringVisiting.add(iterable);
414 List result = [];
415 try {
416 building: { // Break this block to complete the toString.
417 int length = 0;
418 int count = 0;
419 Iterator it = iterable.iterator;
420 // Initial run of elements, at least MIN_COUNT, and then continue until
421 // passing at most LENGTH_LIMIT characters.
422 while (length < LENGTH_LIMIT || count < MIN_COUNT) {
floitsch 2013/10/11 09:29:43 nit. reorder: while (count < MIN_COUNT || length <
Lasse Reichstein Nielsen 2013/10/11 20:25:37 Done. Although for efficiency, I'd expect the leng
423 if (!it.moveNext()) break building;
424 String next = "${it.current}";
floitsch 2013/10/11 09:29:43 it.current.toString() is more explicit. But ok to
Lasse Reichstein Nielsen 2013/10/11 20:25:37 It may be slightly faster to call toString because
425 result.add(next);
426 length += next.length + OVERHEAD; // Includes ")" for the first entry.
427 count++;
428 }
429 String penultimateString;
430 String ultimateString;
431
432 // Find last two elements. One or more of them may already be in the
433 // result array. Include their length in `length`.
434 var penultimate = null;
435 var ultimate = null;
436 if (!it.moveNext()) {
437 if (count <= MIN_COUNT + 2) break building;
floitsch 2013/10/11 09:29:43 Add comment?: // No need for ellipsis.
Lasse Reichstein Nielsen 2013/10/11 20:25:37 Done.
438 ultimateString = result.removeLast();
439 penultimateString = result.removeLast();
440 } else {
441 penultimate = it.current;
442 count++;
443 if (!it.moveNext()) {
444 if (count <= MIN_COUNT + 1) {
445 result.add("$penultimate");
446 break building;
447 }
448 ultimateString = "$penultimate";
449 penultimateString = result.removeLast();
450 length += ultimateString.length + OVERHEAD;
451 } else {
452 ultimate = it.current;
453 count++;
454 // Then keep looping, keeping the last two elements in variables.
floitsch 2013/10/11 09:29:43 "Then" doesn't fit. Loop, keeping ...
Lasse Reichstein Nielsen 2013/10/11 20:25:37 Done.
455 assert(count < MAX_COUNT);
456 while (it.moveNext()) {
457 penultimate = ultimate;
458 ultimate = it.current;
459 count++;
460 if (count > MAX_COUNT) {
461 // If we haven't found the end before MAX_COUNT, give up.
462 // This cannot happen before because each count increases
463 // length by at least two, so there is no way to see more
464 // than ~40 elements before this loop.
465
466 // Remove any surplus elements until length including ", ...)"
467 // is at most LENGTH_LIMIT.
468 while (length > LENGTH_LIMIT - ELLIPSIS_SIZE - OVERHEAD &&
469 count > MIN_COUNT) {
470 length -= result.removeLast().length + OVERHEAD;
471 count--;
472 }
473 result.add("...");
474 break building;
475 }
476 }
477 penultimateString = "$penultimate";
478 ultimateString = "$ultimate";
479 length +=
480 ultimateString.length + penultimateString.length + 2 * OVERHEAD;
481 }
482 }
483
484 // If there is a gap between the initial run and the last two,
485 // prepare to add an ellipsis.
486 String elision = null;
487 if (count > result.length + 2) {
488 elision = "...";
489 length += ELLIPSIS_SIZE + OVERHEAD;
490 }
491
492 // If the last two elements were very long, and we have more than
493 // MIN_COUNT elements in the initial run, drop some to make room for
494 // the last two.
495 while (length > LENGTH_LIMIT && result.length > MIN_COUNT) {
496 length -= result.removeLast().length + OVERHEAD;
497 if (elision == null) {
498 elision = "...";
499 length += ELLIPSIS_SIZE + OVERHEAD;
500 }
501 }
502 if (elision != null) {
503 result.add(elision);
504 }
505 result.add(penultimateString);
506 result.add(ultimateString);
507 }
508 } finally {
509 _toStringVisiting.remove(iterable);
510 }
511 return (new StringBuffer("(")..writeAll(result, ", ")..write(")")).toString();
512 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698