| 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 library dart2js.mirrors.util; | |
| 6 | |
| 7 import 'dart:collection' show Maps; | |
| 8 | |
| 9 /** | |
| 10 * An abstract map implementation. This class can be used as a superclass for | |
| 11 * implementing maps, requiring only the further implementation of the | |
| 12 * [:operator []:], [:forEach:] and [:length:] methods to provide a fully | |
| 13 * implemented immutable map. | |
| 14 */ | |
| 15 // TODO(lrn): Consider using UnmodifiableBaseMap/UnmodifiableMapWrapper | |
| 16 // for these classes, or just rewrite for a bit more efficiency. | |
| 17 abstract class AbstractMap<K, V> implements Map<K, V> { | |
| 18 AbstractMap(); | |
| 19 | |
| 20 AbstractMap.from(Map<K, V> other) { | |
| 21 other.forEach((k,v) => this[k] = v); | |
| 22 } | |
| 23 | |
| 24 void operator []=(K key, value) { | |
| 25 throw new UnsupportedError('[]= is not supported'); | |
| 26 } | |
| 27 | |
| 28 void clear() { | |
| 29 throw new UnsupportedError('clear() is not supported'); | |
| 30 } | |
| 31 | |
| 32 void addAll(Map<K, V> other) { | |
| 33 throw new UnsupportedError('addAll() is not supported'); | |
| 34 } | |
| 35 | |
| 36 bool containsKey(K key) { | |
| 37 var found = false; | |
| 38 forEach((k,_) { | |
| 39 if (k == key) { | |
| 40 found = true; | |
| 41 } | |
| 42 }); | |
| 43 return found; | |
| 44 } | |
| 45 | |
| 46 bool containsValue(V value) { | |
| 47 var found = false; | |
| 48 forEach((_,v) { | |
| 49 if (v == value) { | |
| 50 found = true; | |
| 51 } | |
| 52 }); | |
| 53 return found; | |
| 54 } | |
| 55 | |
| 56 Iterable<K> get keys { | |
| 57 var keys = <K>[]; | |
| 58 forEach((k,_) => keys.add(k)); | |
| 59 return keys; | |
| 60 } | |
| 61 | |
| 62 Iterable<V> get values { | |
| 63 var values = <V>[]; | |
| 64 forEach((_,v) => values.add(v)); | |
| 65 return values; | |
| 66 } | |
| 67 | |
| 68 bool get isEmpty => length == 0; | |
| 69 bool get isNotEmpty => !isEmpty; | |
| 70 V putIfAbsent(K key, V ifAbsent()) { | |
| 71 if (!containsKey(key)) { | |
| 72 V value = this[key]; | |
| 73 this[key] = ifAbsent(); | |
| 74 return value; | |
| 75 } | |
| 76 return null; | |
| 77 } | |
| 78 | |
| 79 V remove(K key) { | |
| 80 throw new UnsupportedError('V remove(K key) is not supported'); | |
| 81 } | |
| 82 | |
| 83 String toString() => Maps.mapToString(this); | |
| 84 } | |
| 85 | |
| 86 /** | |
| 87 * [ImmutableMapWrapper] wraps a (mutable) map as an immutable map where all | |
| 88 * mutating operations throw [UnsupportedError] upon invocation. | |
| 89 */ | |
| 90 class ImmutableMapWrapper<K, V> extends AbstractMap<K, V> { | |
| 91 final Map<K, V> _map; | |
| 92 | |
| 93 ImmutableMapWrapper(this._map); | |
| 94 | |
| 95 int get length => _map.length; | |
| 96 | |
| 97 V operator [](K key) { | |
| 98 if (key is K) { | |
| 99 return _map[key]; | |
| 100 } | |
| 101 return null; | |
| 102 } | |
| 103 | |
| 104 void forEach(void f(K key, V value)) { | |
| 105 _map.forEach(f); | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 /** | |
| 110 * A [Filter] function returns [:true:] iff [value] should be included. | |
| 111 */ | |
| 112 typedef bool Filter<V>(V value); | |
| 113 | |
| 114 /** | |
| 115 * An immutable map wrapper capable of filtering the input map. | |
| 116 */ | |
| 117 class FilteredImmutableMap<K, V> extends ImmutableMapWrapper<K, V> { | |
| 118 final Filter<V> _filter; | |
| 119 | |
| 120 FilteredImmutableMap(Map<K, V> map, this._filter) : super(map); | |
| 121 | |
| 122 int get length { | |
| 123 var count = 0; | |
| 124 forEach((k,v) { | |
| 125 count++; | |
| 126 }); | |
| 127 return count; | |
| 128 } | |
| 129 | |
| 130 void forEach(void f(K key, V value)) { | |
| 131 _map.forEach((K k, V v) { | |
| 132 if (_filter(v)) { | |
| 133 f(k, v); | |
| 134 } | |
| 135 }); | |
| 136 } | |
| 137 } | |
| 138 | |
| 139 /** | |
| 140 * An [AsFilter] takes a [value] of type [V1] and returns [value] iff it is of | |
| 141 * type [V2] or [:null:] otherwise. An [AsFilter] therefore behaves like the | |
| 142 * [:as:] expression. | |
| 143 */ | |
| 144 typedef V2 AsFilter<V1, V2>(V1 value); | |
| 145 | |
| 146 /** | |
| 147 * An immutable map wrapper capable of filtering the input map based on types. | |
| 148 * It takes an [AsFilter] function which converts the original values of type | |
| 149 * [Vin] into values of type [Vout], or returns [:null:] if the value should | |
| 150 * not be included in the filtered map. | |
| 151 */ | |
| 152 class AsFilteredImmutableMap<K, Vin, Vout> extends AbstractMap<K, Vout> { | |
| 153 final Map<K, Vin> _map; | |
| 154 final AsFilter<Vin, Vout> _filter; | |
| 155 | |
| 156 AsFilteredImmutableMap(this._map, this._filter); | |
| 157 | |
| 158 int get length { | |
| 159 var count = 0; | |
| 160 forEach((k,v) { | |
| 161 count++; | |
| 162 }); | |
| 163 return count; | |
| 164 } | |
| 165 | |
| 166 Vout operator [](K key) { | |
| 167 if (key is K) { | |
| 168 Vin value = _map[key]; | |
| 169 if (value != null) { | |
| 170 return _filter(value); | |
| 171 } | |
| 172 } | |
| 173 return null; | |
| 174 } | |
| 175 | |
| 176 void forEach(void f(K key, Vout value)) { | |
| 177 _map.forEach((K k, Vin v) { | |
| 178 var value = _filter(v); | |
| 179 if (value != null) { | |
| 180 f(k, value); | |
| 181 } | |
| 182 }); | |
| 183 } | |
| 184 } | |
| OLD | NEW |