| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 /** | |
| 6 * The [Collections] class implements static methods useful when | |
| 7 * writing a class that implements [Collection] and the [iterator] | |
| 8 * method. | |
| 9 */ | |
| 10 class Collections { | |
| 11 static void forEach(Iterable iterable, void f(o)) { | |
| 12 for (final e in iterable) { | |
| 13 f(e); | |
| 14 } | |
| 15 } | |
| 16 | |
| 17 static bool some(Iterable iterable, bool f(o)) { | |
| 18 for (final e in iterable) { | |
| 19 if (f(e)) return true; | |
| 20 } | |
| 21 return false; | |
| 22 } | |
| 23 | |
| 24 static bool every(Iterable iterable, bool f(o)) { | |
| 25 for (final e in iterable) { | |
| 26 if (!f(e)) return false; | |
| 27 } | |
| 28 return true; | |
| 29 } | |
| 30 | |
| 31 static List map(Iterable source, List destination, f(o)) { | |
| 32 for (final e in source) { | |
| 33 destination.add(f(e)); | |
| 34 } | |
| 35 return destination; | |
| 36 } | |
| 37 | |
| 38 static Dynamic reduce(Iterable iterable, | |
| 39 Dynamic initialValue, | |
| 40 Dynamic combine(Dynamic previousValue, element)) { | |
| 41 for (final element in iterable) { | |
| 42 initialValue = combine(initialValue, element); | |
| 43 } | |
| 44 return initialValue; | |
| 45 } | |
| 46 | |
| 47 static List filter(Iterable source, List destination, bool f(o)) { | |
| 48 for (final e in source) { | |
| 49 if (f(e)) destination.add(e); | |
| 50 } | |
| 51 return destination; | |
| 52 } | |
| 53 | |
| 54 static bool isEmpty(Iterable iterable) { | |
| 55 return !iterable.iterator().hasNext(); | |
| 56 } | |
| 57 | |
| 58 // TODO(jjb): visiting list should be an identityHashSet when it exists | |
| 59 | |
| 60 /** | |
| 61 * Returns a string representing the specified collection. If the | |
| 62 * collection is a [List], the returned string looks like this: | |
| 63 * [:'[element0, element1, ... elementN]':]. The value returned by its | |
| 64 * [toString] method is used to represent each element. If the specified | |
| 65 * collection is not a list, the returned string looks like this: | |
| 66 * [:{element0, element1, ... elementN}:]. In other words, the strings | |
| 67 * returned for lists are surrounded by square brackets, while the strings | |
| 68 * returned for other collections are surrounded by curly braces. | |
| 69 * | |
| 70 * If the specified collection contains a reference to itself, either | |
| 71 * directly or indirectly through other collections or maps, the contained | |
| 72 * reference is rendered as [:'[...]':] if it is a list, or [:'{...}':] if | |
| 73 * it is not. This prevents the infinite regress that would otherwise occur. | |
| 74 * So, for example, calling this method on a list whose sole element is a | |
| 75 * reference to itself would return [:'[[...]]':]. | |
| 76 * | |
| 77 * A typical implementation of a collection's [toString] method will | |
| 78 * simply return the results of this method applied to the collection. | |
| 79 */ | |
| 80 static String collectionToString(Collection c) { | |
| 81 var result = new StringBuffer(); | |
| 82 _emitCollection(c, result, new List()); | |
| 83 return result.toString(); | |
| 84 } | |
| 85 | |
| 86 /** | |
| 87 * Appends a string representing the specified collection to the specified | |
| 88 * string buffer. The string is formatted as per [collectionToString]. | |
| 89 * The [:visiting:] list contains references to all of the enclosing | |
| 90 * collections and maps (which are currently in the process of being | |
| 91 * emitted into [:result:]). The [:visiting:] parameter allows this method to | |
| 92 * generate a [:'[...]':] or [:'{...}':] where required. In other words, | |
| 93 * it allows this method and [_emitMap] to identify recursive collections | |
| 94 * and maps. | |
| 95 */ | |
| 96 static void _emitCollection(Collection c, StringBuffer result, List visiting)
{ | |
| 97 visiting.add(c); | |
| 98 bool isList = c is List; | |
| 99 result.add(isList ? '[' : '{'); | |
| 100 | |
| 101 bool first = true; | |
| 102 for (var e in c) { | |
| 103 if (!first) { | |
| 104 result.add(', '); | |
| 105 } | |
| 106 first = false; | |
| 107 _emitObject(e, result, visiting); | |
| 108 } | |
| 109 | |
| 110 result.add(isList ? ']' : '}'); | |
| 111 visiting.removeLast(); | |
| 112 } | |
| 113 | |
| 114 /** | |
| 115 * Appends a string representing the specified object to the specified | |
| 116 * string buffer. If the object is a [Collection] or [Map], it is formatted | |
| 117 * as per [collectionToString] or [mapToString]; otherwise, it is formatted | |
| 118 * by invoking its own [toString] method. | |
| 119 * | |
| 120 * The [:visiting:] list contains references to all of the enclosing | |
| 121 * collections and maps (which are currently in the process of being | |
| 122 * emitted into [:result:]). The [:visiting:] parameter allows this method | |
| 123 * to generate a [:'[...]':] or [:'{...}':] where required. In other words, | |
| 124 * it allows this method and [_emitCollection] to identify recursive maps | |
| 125 * and collections. | |
| 126 */ | |
| 127 static void _emitObject(Object o, StringBuffer result, List visiting) { | |
| 128 if (o is Collection) { | |
| 129 if (_containsRef(visiting, o)) { | |
| 130 result.add(o is List ? '[...]' : '{...}'); | |
| 131 } else { | |
| 132 _emitCollection(o, result, visiting); | |
| 133 } | |
| 134 } else if (o is Map) { | |
| 135 if (_containsRef(visiting, o)) { | |
| 136 result.add('{...}'); | |
| 137 } else { | |
| 138 Maps._emitMap(o, result, visiting); | |
| 139 } | |
| 140 } else { // o is neither a collection nor a map | |
| 141 result.add(o == null ? 'null' : o); // TODO(jjb): remove the null check | |
| 142 } | |
| 143 } | |
| 144 | |
| 145 /** | |
| 146 * Returns true if the specified collection contains the specified object | |
| 147 * reference. | |
| 148 */ | |
| 149 static _containsRef(Collection c, Object ref) { | |
| 150 for (var e in c) { | |
| 151 if (e === ref) return true; | |
| 152 } | |
| 153 return false; | |
| 154 } | |
| 155 } | |
| OLD | NEW |