| Index: pkg/compiler_util/lib/link.dart
|
| diff --git a/pkg/compiler_util/lib/link.dart b/pkg/compiler_util/lib/link.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..58d2cb98cf09b71e3abc52de0d149b02ebbaa9cb
|
| --- /dev/null
|
| +++ b/pkg/compiler_util/lib/link.dart
|
| @@ -0,0 +1,172 @@
|
| +// Copyright (c) 2011, 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.
|
| +
|
| +part of dart2js.util;
|
| +
|
| +class Link<T> implements Iterable<T> {
|
| + T get head => throw new StateError("no elements");
|
| + Link<T> get tail => null;
|
| +
|
| + const Link();
|
| +
|
| + Link<T> prepend(T element) {
|
| + return new LinkEntry<T>(element, this);
|
| + }
|
| +
|
| + Iterator<T> get iterator => new LinkIterator<T>(this);
|
| +
|
| + void printOn(StringBuffer buffer, [separatedBy]) {}
|
| +
|
| + List<T> toList({bool growable: true}) {
|
| + List<T> result;
|
| + if (!growable) {
|
| + result = new List<T>(slowLength());
|
| + } else {
|
| + result = new List<T>();
|
| + result.length = slowLength();
|
| + }
|
| + int i = 0;
|
| + for (Link<T> link = this; !link.isEmpty; link = link.tail) {
|
| + result[i++] = link.head;
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + /// Lazily maps over this linked list, returning an [Iterable].
|
| + Iterable map(dynamic fn(T item)) {
|
| + return new MappedLinkIterable<T, dynamic>(this, fn);
|
| + }
|
| +
|
| + /// Invokes `fn` for every item in the linked list and returns the results
|
| + /// in a [List].
|
| + List mapToList(dynamic fn(T item), {bool growable: true}) {
|
| + List result;
|
| + if (!growable) {
|
| + result = new List(slowLength());
|
| + } else {
|
| + result = new List();
|
| + result.length = slowLength();
|
| + }
|
| + int i = 0;
|
| + for (Link<T> link = this; !link.isEmpty; link = link.tail) {
|
| + result[i++] = fn(link.head);
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + bool get isEmpty => true;
|
| + bool get isNotEmpty => false;
|
| +
|
| + Link<T> reverse() => this;
|
| +
|
| + Link<T> reversePrependAll(Link<T> from) {
|
| + if (from.isEmpty) return this;
|
| + return this.prepend(from.head).reversePrependAll(from.tail);
|
| + }
|
| +
|
| + Link<T> skip(int n) {
|
| + if (n == 0) return this;
|
| + throw new RangeError('Index $n out of range');
|
| + }
|
| +
|
| + void forEach(void f(T element)) {}
|
| +
|
| + bool operator ==(other) {
|
| + if (other is! Link<T>) return false;
|
| + return other.isEmpty;
|
| + }
|
| +
|
| + int get hashCode => throw new UnsupportedError('Link.hashCode');
|
| +
|
| + String toString() => "[]";
|
| +
|
| + get length {
|
| + throw new UnsupportedError('get:length');
|
| + }
|
| +
|
| + int slowLength() => 0;
|
| +
|
| + // TODO(ahe): Remove this method?
|
| + bool contains(T element) {
|
| + for (Link<T> link = this; !link.isEmpty; link = link.tail) {
|
| + if (link.head == element) return true;
|
| + }
|
| + return false;
|
| + }
|
| +
|
| + // TODO(ahe): Remove this method?
|
| + T get single {
|
| + if (isEmpty) throw new StateError('No elements');
|
| + if (!tail.isEmpty) throw new StateError('More than one element');
|
| + return head;
|
| + }
|
| +
|
| + // TODO(ahe): Remove this method?
|
| + T get first {
|
| + if (isEmpty) throw new StateError('No elements');
|
| + return head;
|
| + }
|
| +
|
| + /// Returns true if f returns true for all elements of this list.
|
| + ///
|
| + /// Returns true for the empty list.
|
| + bool every(bool f(T)) {
|
| + for (Link<T> link = this; !link.isEmpty; link = link.tail) {
|
| + if (!f(link.head)) return false;
|
| + }
|
| + return true;
|
| + }
|
| +
|
| + Link copyWithout(e) => this;
|
| +
|
| + //
|
| + // Unsupported Iterable<T> methods.
|
| + //
|
| + bool any(bool f(T e)) => _unsupported('any');
|
| + T elementAt(int i) => _unsupported('elementAt');
|
| + Iterable expand(Iterable f(T e)) => _unsupported('expand');
|
| + T firstWhere(bool f(T e), {T orElse()}) => _unsupported('firstWhere');
|
| + fold(initialValue, combine(value, T element)) => _unsupported('fold');
|
| + T get last => _unsupported('get:last');
|
| + T lastWhere(bool f(T e), {T orElse()}) => _unsupported('lastWhere');
|
| + String join([separator = '']) => _unsupported('join');
|
| + T reduce(T combine(T a, T b)) => _unsupported('reduce');
|
| + T singleWhere(bool f(T e)) => _unsupported('singleWhere');
|
| + Iterable<T> skipWhile(bool f(T e)) => _unsupported('skipWhile');
|
| + Iterable<T> take(int n) => _unsupported('take');
|
| + Iterable<T> takeWhile(bool f(T e)) => _unsupported('takeWhile');
|
| + Set<T> toSet() => _unsupported('toSet');
|
| + Iterable<T> where(bool f(T e)) => _unsupported('where');
|
| +
|
| + _unsupported(String method) => throw new UnsupportedError(method);
|
| +}
|
| +
|
| +/// Builder object for creating linked lists using [Link] or fixed-length [List]
|
| +/// objects.
|
| +abstract class LinkBuilder<T> {
|
| + factory LinkBuilder() = LinkBuilderImplementation;
|
| +
|
| + /// Prepends all elements added to the builder to [tail]. The resulting list
|
| + /// is returned and the builder is cleared.
|
| + Link<T> toLink([Link<T> tail = const Link()]);
|
| +
|
| + /// Creates a new fixed length containing all added elements. The
|
| + /// resulting list is returned and the builder is cleared.
|
| + List<T> toList();
|
| +
|
| + /// Adds the element [t] to the end of the list being built.
|
| + Link<T> addLast(T t);
|
| +
|
| + /// Returns the first element in the list being built.
|
| + T get first;
|
| +
|
| + /// Returns the number of elements in the list being built.
|
| + final int length;
|
| +
|
| + /// Returns `true` if the list being built is empty.
|
| + final bool isEmpty;
|
| +
|
| + /// Removes all added elements and resets the builder.
|
| + void clear();
|
| +}
|
|
|