| Index: lib/dartdoc/mirrors/util.dart
|
| diff --git a/lib/dartdoc/mirrors/util.dart b/lib/dartdoc/mirrors/util.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..252f531b1097715bd197bb63787265d4b2d58450
|
| --- /dev/null
|
| +++ b/lib/dartdoc/mirrors/util.dart
|
| @@ -0,0 +1,161 @@
|
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +#library('util');
|
| +
|
| +/**
|
| + * An abstract map implementation. This class can be used as a superclass for
|
| + * implementing maps, requiring only the further implementation of the
|
| + * [:operator []:], [:forEach:] and [:length:] methods to provide a fully
|
| + * implemented immutable map.
|
| + */
|
| +abstract class AbstractMap<K,V> implements Map<K,V> {
|
| + AbstractMap();
|
| + AbstractMap.from(Map<K,V> other) {
|
| + other.forEach((k,v) => this[k] = v);
|
| + }
|
| + void operator []=(K key, value) {
|
| + throw new UnsupportedOperationException('[]= is not supported');
|
| + }
|
| + void clear() {
|
| + throw new UnsupportedOperationException('clear() is not supported');
|
| + }
|
| + bool containsKey(K key) {
|
| + var found = false;
|
| + forEach((k,_) {
|
| + if (k == key) {
|
| + found = true;
|
| + }
|
| + });
|
| + return found;
|
| + }
|
| + bool containsValue(V value) {
|
| + var found = false;
|
| + forEach((_,v) {
|
| + if (v == value) {
|
| + found = true;
|
| + }
|
| + });
|
| + return found;
|
| + }
|
| + Collection<K> getKeys() {
|
| + var keys = <K>[];
|
| + forEach((k,_) => keys.add(k));
|
| + return keys;
|
| + }
|
| + Collection<V> getValues() {
|
| + var values = <V>[];
|
| + forEach((_,v) => values.add(v));
|
| + return values;
|
| + }
|
| + bool isEmpty() => length == 0;
|
| + V putIfAbsent(K key, V ifAbsent()) {
|
| + if (!containsKey(key)) {
|
| + V value = this[key];
|
| + this[key] = ifAbsent();
|
| + return value;
|
| + }
|
| + return null;
|
| + }
|
| + V remove(K key) {
|
| + throw new UnsupportedOperationException('V remove(K key) is not supported');
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * [ImmutableMapWrapper] wraps a (mutable) map as an immutable map where all
|
| + * mutating operations throw [UnsupportedOperationException] upon invocation.
|
| + */
|
| +class ImmutableMapWrapper<K,V> extends AbstractMap<K,V> {
|
| + final Map<K,V> _map;
|
| +
|
| + ImmutableMapWrapper(this._map);
|
| +
|
| + int get length() => _map.length;
|
| +
|
| + V operator [](K key) {
|
| + if (key is K) {
|
| + return _map[key];
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + void forEach(void f(K key, V value)) {
|
| + _map.forEach(f);
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * A [Filter] function returns [:true:] iff [value] should be included.
|
| + */
|
| +typedef bool Filter<V>(V value);
|
| +
|
| +/**
|
| + * An immutable map wrapper capable of filtering the input map.
|
| + */
|
| +class FilteredImmutableMap<K,V> extends ImmutableMapWrapper<K,V> {
|
| + final Filter<V> _filter;
|
| +
|
| + FilteredImmutableMap(Map<K,V> map, this._filter) : super(map);
|
| +
|
| + int get length() {
|
| + var count = 0;
|
| + forEach((k,v) {
|
| + count++;
|
| + });
|
| + return count;
|
| + }
|
| +
|
| + void forEach(void f(K key, V value)) {
|
| + _map.forEach((K k, V v) {
|
| + if (_filter(v)) {
|
| + f(k, v);
|
| + }
|
| + });
|
| + }
|
| +}
|
| +
|
| +/**
|
| + * An [AsFilter] takes a [value] of type [V1] and returns [value] iff it is of
|
| + * type [V2] or [:null:] otherwise. An [AsFilter] therefore behaves like the
|
| + * [:as:] expression.
|
| + */
|
| +typedef V2 AsFilter<V1, V2>(V1 value);
|
| +
|
| +/**
|
| + * An immutable map wrapper capable of filtering the input map based on types.
|
| + * It takes an [AsFilter] function which converts the original values of type
|
| + * [Vin] into values of type [Vout], or returns [:null:] if the value should
|
| + * not be included in the filtered map.
|
| + */
|
| +class AsFilteredImmutableMap<K, Vin, Vout> extends AbstractMap<K, Vout> {
|
| + final Map<K, Vin> _map;
|
| + final AsFilter<Vin, Vout> _filter;
|
| +
|
| + AsFilteredImmutableMap(this._map, this._filter);
|
| +
|
| + int get length() {
|
| + var count = 0;
|
| + forEach((k,v) {
|
| + count++;
|
| + });
|
| + return count;
|
| + }
|
| +
|
| + Vout operator [](K key) {
|
| + if (key is K) {
|
| + return _filter(_map[key]);
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + void forEach(void f(K key, Vout value)) {
|
| + _map.forEach((K k, Vin v) {
|
| + var value = _filter(v);
|
| + if (value !== null) {
|
| + f(k, value);
|
| + }
|
| + });
|
| + }
|
| +}
|
|
|