blob: 424c8a1e50afc4d59fb368be2610c20e9095cfed [file] [log] [blame]
// Copyright (c) 2018, 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.
import 'dart:collection';
import '../path.dart' as p;
/// A set containing paths, compared using [p.equals] and [p.hash].
class PathSet extends IterableBase<String?> implements Set<String?> {
/// The set to which we forward implementation methods.
final Set<String?> _inner;
/// Creates an empty [PathSet] whose contents are compared using
/// `context.equals` and `context.hash`.
///
/// The [context] defaults to the current path context.
PathSet({p.Context? context}) : _inner = _create(context);
/// Creates a [PathSet] with the same contents as [other] whose elements are
/// compared using `context.equals` and `context.hash`.
///
/// The [context] defaults to the current path context. If multiple elements
/// in [other] represent the same logical path, the first value will be
/// used.
PathSet.of(Iterable<String> other, {p.Context? context})
: _inner = _create(context)..addAll(other);
/// Creates a set that uses [context] for equality and hashing.
static Set<String?> _create(p.Context? context) {
context ??= p.context;
return LinkedHashSet(
equals: (path1, path2) {
if (path1 == null) return path2 == null;
if (path2 == null) return false;
return context!.equals(path1, path2);
},
hashCode: (path) => path == null ? 0 : context!.hash(path),
isValidKey: (path) => path is String || path == null);
}
// Normally we'd use DelegatingSetView from the collection package to
// implement these, but we want to avoid adding dependencies from path because
// it's so widely used that even brief version skew can be very painful.
@override
Iterator<String?> get iterator => _inner.iterator;
@override
int get length => _inner.length;
@override
bool add(String? value) => _inner.add(value);
@override
void addAll(Iterable<String?> elements) => _inner.addAll(elements);
@override
Set<T> cast<T>() => _inner.cast<T>();
@override
void clear() => _inner.clear();
@override
bool contains(Object? element) => _inner.contains(element);
@override
bool containsAll(Iterable<Object?> other) => _inner.containsAll(other);
@override
Set<String?> difference(Set<Object?> other) => _inner.difference(other);
@override
Set<String?> intersection(Set<Object?> other) => _inner.intersection(other);
@override
String? lookup(Object? element) => _inner.lookup(element);
@override
bool remove(Object? value) => _inner.remove(value);
@override
void removeAll(Iterable<Object?> elements) => _inner.removeAll(elements);
@override
void removeWhere(bool Function(String?) test) => _inner.removeWhere(test);
@override
void retainAll(Iterable<Object?> elements) => _inner.retainAll(elements);
@override
void retainWhere(bool Function(String?) test) => _inner.retainWhere(test);
@override
Set<String?> union(Set<String?> other) => _inner.union(other);
@override
Set<String?> toSet() => _inner.toSet();
}