OLD | NEW |
| (Empty) |
1 // Copyright (c) 2014, 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 part of dart2js.helpers; | |
6 | |
7 typedef void DebugCallback(String methodName, var arg1, var arg2); | |
8 | |
9 class DebugMap<K, V> implements Map<K, V> { | |
10 final Map<K, V> map; | |
11 DebugCallback indexSetCallBack; | |
12 DebugCallback putIfAbsentCallBack; | |
13 | |
14 DebugMap(this.map, {DebugCallback addCallback}) { | |
15 if (addCallback != null) { | |
16 this.addCallback = addCallback; | |
17 } | |
18 } | |
19 | |
20 void set addCallback(DebugCallback value) { | |
21 indexSetCallBack = value; | |
22 putIfAbsentCallBack = value; | |
23 } | |
24 | |
25 bool containsValue(Object value) { | |
26 return map.containsValue(value); | |
27 } | |
28 | |
29 bool containsKey(Object key) => map.containsKey(key); | |
30 | |
31 V operator [](Object key) => map[key]; | |
32 | |
33 void operator []=(K key, V value) { | |
34 if (indexSetCallBack != null) { | |
35 indexSetCallBack('[]=', key, value); | |
36 } | |
37 map[key] = value; | |
38 } | |
39 | |
40 V putIfAbsent(K key, V ifAbsent()) { | |
41 return map.putIfAbsent(key, () { | |
42 V v = ifAbsent(); | |
43 if (putIfAbsentCallBack != null) { | |
44 putIfAbsentCallBack('putIfAbsent', key, v); | |
45 } | |
46 return v; | |
47 }); | |
48 } | |
49 | |
50 void addAll(Map<K, V> other) => map.addAll(other); | |
51 | |
52 V remove(Object key) => map.remove(key); | |
53 | |
54 void clear() => map.clear(); | |
55 | |
56 void forEach(void f(K key, V value)) => map.forEach(f); | |
57 | |
58 Iterable<K> get keys => map.keys; | |
59 | |
60 Iterable<V> get values => map.values; | |
61 | |
62 int get length => map.length; | |
63 | |
64 bool get isEmpty => map.isEmpty; | |
65 | |
66 bool get isNotEmpty => map.isNotEmpty; | |
67 } | |
68 | |
69 class DebugIterable<E> implements Iterable<E> { | |
70 final Iterable<E> iterable; | |
71 | |
72 DebugIterable(this.iterable); | |
73 | |
74 Iterator<E> get iterator => iterable.iterator; | |
75 | |
76 Iterable map(f(E element)) => iterable.map(f); | |
77 | |
78 Iterable<E> where(bool test(E element)) => iterable.where(test); | |
79 | |
80 Iterable expand(Iterable f(E element)) => iterable.expand(f); | |
81 | |
82 bool contains(Object element) => iterable.contains(element); | |
83 | |
84 void forEach(void f(E element)) => iterable.forEach(f); | |
85 | |
86 E reduce(E combine(E value, E element)) => iterable.reduce(combine); | |
87 | |
88 dynamic fold(var initialValue, | |
89 dynamic combine(var previousValue, E element)) { | |
90 return iterable.fold(initialValue, combine); | |
91 } | |
92 | |
93 bool every(bool test(E element)) => iterable.every(test); | |
94 | |
95 String join([String separator = ""]) => iterable.join(separator); | |
96 | |
97 bool any(bool test(E element)) => iterable.any(test); | |
98 | |
99 List<E> toList({ bool growable: true }) { | |
100 return iterable.toList(growable: growable); | |
101 } | |
102 | |
103 Set<E> toSet() => iterable.toSet(); | |
104 | |
105 int get length => iterable.length; | |
106 | |
107 bool get isEmpty => iterable.isEmpty; | |
108 | |
109 bool get isNotEmpty => iterable.isNotEmpty; | |
110 | |
111 Iterable<E> take(int n) => iterable.take(n); | |
112 | |
113 Iterable<E> takeWhile(bool test(E value)) => iterable.takeWhile(test); | |
114 | |
115 Iterable<E> skip(int n) => iterable.skip(n); | |
116 | |
117 Iterable<E> skipWhile(bool test(E value)) => iterable.skipWhile(test); | |
118 | |
119 E get first => iterable.first; | |
120 | |
121 E get last => iterable.last; | |
122 | |
123 E get single => iterable.single; | |
124 | |
125 E firstWhere(bool test(E element), { E orElse() }) { | |
126 return iterable.firstWhere(test, orElse: orElse); | |
127 } | |
128 | |
129 E lastWhere(bool test(E element), {E orElse()}) { | |
130 return iterable.lastWhere(test, orElse: orElse); | |
131 } | |
132 | |
133 E singleWhere(bool test(E element)) => iterable.singleWhere(test); | |
134 | |
135 E elementAt(int index) => iterable.elementAt(index); | |
136 | |
137 } | |
138 | |
139 class DebugList<E> extends DebugIterable<E> implements List<E> { | |
140 DebugCallback addCallback; | |
141 | |
142 DebugList(List<E> list, {this.addCallback}) : super(list); | |
143 | |
144 List<E> get list => iterable; | |
145 | |
146 E operator [](int index) => list[index]; | |
147 | |
148 void operator []=(int index, E value) { | |
149 list[index] = value; | |
150 } | |
151 | |
152 int get length => list.length; | |
153 | |
154 void set length(int newLength) { | |
155 list.length = newLength; | |
156 } | |
157 | |
158 void add(E value) { | |
159 if (addCallback != null) { | |
160 addCallback('add', value, null); | |
161 } | |
162 list.add(value); | |
163 } | |
164 | |
165 void addAll(Iterable<E> iterable) => list.addAll(iterable); | |
166 | |
167 Iterable<E> get reversed => list.reversed; | |
168 | |
169 void sort([int compare(E a, E b)]) => list.sort(compare); | |
170 | |
171 void shuffle([random]) => list.shuffle(random); | |
172 | |
173 int indexOf(E element, [int start = 0]) => list.indexOf(element, start); | |
174 | |
175 int lastIndexOf(E element, [int start]) => list.lastIndexOf(element, start); | |
176 | |
177 void clear() => list.clear(); | |
178 | |
179 void insert(int index, E element) => list.insert(index, element); | |
180 | |
181 void insertAll(int index, Iterable<E> iterable) { | |
182 list.insertAll(index, iterable); | |
183 } | |
184 | |
185 void setAll(int index, Iterable<E> iterable) => list.setAll(index, iterable); | |
186 | |
187 bool remove(Object value) => list.remove(value); | |
188 | |
189 E removeAt(int index) => list.removeAt(index); | |
190 | |
191 E removeLast() => list.removeLast(); | |
192 | |
193 void removeWhere(bool test(E element)) => list.removeWhere(test); | |
194 | |
195 void retainWhere(bool test(E element)) => list.retainWhere(test); | |
196 | |
197 List<E> sublist(int start, [int end]) => list.sublist(start, end); | |
198 | |
199 Iterable<E> getRange(int start, int end) => list.getRange(start, end); | |
200 | |
201 void setRange(int start, int end, Iterable<E> iterable, [int skipCount = 0]) { | |
202 list.setRange(start, end, iterable, skipCount); | |
203 } | |
204 | |
205 void removeRange(int start, int end) { | |
206 list.removeRange(start, end); | |
207 } | |
208 | |
209 void fillRange(int start, int end, [E fillValue]) { | |
210 list.fillRange(start, end, fillValue); | |
211 } | |
212 | |
213 void replaceRange(int start, int end, Iterable<E> replacement) { | |
214 list.replaceRange(start, end, replacement); | |
215 } | |
216 | |
217 Map<int, E> asMap() => list.asMap(); | |
218 } | |
219 | |
220 class DebugSet<E> extends DebugIterable<E> implements Set<E> { | |
221 DebugCallback addCallback; | |
222 | |
223 DebugSet(Set<E> set, {this.addCallback}) : super(set); | |
224 | |
225 Set<E> get set => iterable; | |
226 | |
227 bool contains(Object value) => set.contains(value); | |
228 | |
229 bool add(E value) { | |
230 if (addCallback != null) { | |
231 addCallback('add', value, null); | |
232 } | |
233 return set.add(value); | |
234 } | |
235 | |
236 void addAll(Iterable<E> elements) => set.addAll(elements); | |
237 | |
238 bool remove(Object value) => set.remove(value); | |
239 | |
240 E lookup(Object object) => set.lookup(object); | |
241 | |
242 void removeAll(Iterable<Object> elements) => set.removeAll(elements); | |
243 | |
244 void retainAll(Iterable<Object> elements) => set.retainAll(elements); | |
245 | |
246 void removeWhere(bool test(E element)) => set.removeWhere(test); | |
247 | |
248 void retainWhere(bool test(E element)) => set.retainWhere(test); | |
249 | |
250 bool containsAll(Iterable<Object> other) => set.containsAll(other); | |
251 | |
252 Set<E> intersection(Set<Object> other) => set.intersection(other); | |
253 | |
254 Set<E> union(Set<E> other) => set.union(other); | |
255 | |
256 Set<E> difference(Set<E> other) => set.difference(other); | |
257 | |
258 void clear() => set.clear(); | |
259 | |
260 Set<E> toSet() => set.toSet(); | |
261 } | |
262 | |
263 /// Throws an exception if the runtime type of [object] is not in | |
264 /// [runtimeTypes]. | |
265 /// | |
266 /// Use this to gradually build the set of actual runtime values of [object] | |
267 /// at the call site by running test programs and adding to [runtimeTypes] when | |
268 /// new type are found. | |
269 void assertType(String name, List<String> runtimeTypes, var object, | |
270 {bool showObjects: false}) { | |
271 String runtimeType = '${object.runtimeType}'; | |
272 if (runtimeTypes != null && runtimeTypes.contains(runtimeType)) return; | |
273 throw '$name: $runtimeType' | |
274 '${showObjects ? ' ($object)' : ''}'; | |
275 } | |
276 | |
277 /// Callback for the [addCallback] of [DebugMap] that throws an exception if | |
278 /// the runtime type of key/value pairs are not in [runtimeTypes]. | |
279 /// | |
280 /// Use this to gradually build the set of actual runtime values of key/value | |
281 /// pairs of a map by running test programs and adding to [runtimeTypes] when | |
282 /// new type are found. | |
283 class MapTypeAsserter { | |
284 final String name; | |
285 final Map<String, List<String>> runtimeTypes; | |
286 final bool showObjects; | |
287 | |
288 const MapTypeAsserter(this.name, this.runtimeTypes, | |
289 {bool this.showObjects: false}); | |
290 | |
291 void call(String methodName, var key, var value) { | |
292 check(key, value, '$methodName: '); | |
293 } | |
294 | |
295 void check(var key, var value, [String text = '']) { | |
296 String keyType = '${key.runtimeType}'; | |
297 String valueType = '${value.runtimeType}'; | |
298 List<String> valuesTypes = runtimeTypes[keyType]; | |
299 if (valuesTypes != null && valuesTypes.contains(valueType)) return; | |
300 throw '$name: $text$keyType => $valueType' | |
301 '${showObjects ? ' ($key => $value)' : ''}'; | |
302 } | |
303 } | |
304 | |
305 /// Callback for the [addCallback] of [DebugSet] or [DebugList] that throws an | |
306 /// exception if the runtime type of the elements are not in [runtimeTypes]. | |
307 /// | |
308 /// Use this to gradually build the set of actual runtime values of the elements | |
309 /// of a collection by running test programs and adding to [runtimeTypes] when | |
310 /// new type are found. | |
311 class CollectionTypeAsserter { | |
312 final String name; | |
313 final List<String> runtimeTypes; | |
314 final bool showObjects; | |
315 | |
316 const CollectionTypeAsserter(this.name, this.runtimeTypes, | |
317 {bool this.showObjects: false}); | |
318 | |
319 void call(String methodName, var element, _) { | |
320 check(element, '$methodName: '); | |
321 } | |
322 | |
323 void check(var element, [String text = '']) { | |
324 String elementType = '${element.runtimeType}'; | |
325 if (runtimeTypes.contains(elementType)) return; | |
326 throw '$name: $text$elementType' | |
327 '${showObjects ? ' ($element)' : ''}'; | |
328 } | |
329 } | |
OLD | NEW |