From b3d0bdd0e0c2f0d766a7fd8e8428ab5b5a43ad48 Mon Sep 17 00:00:00 2001 From: Jon Brandvein Date: Fri, 13 Jan 2017 17:46:29 +0000 Subject: Add a to_list() method to depsets This is the preferred way to test for membership in, or iterate over, depsets (aka nested sets, aka plain old set()). The old way of doing membership tests or iterations over the raw depset itself is deprecated and may be removed in the future. Note that membership testing in a depset was always an O(n) operation, perhaps contrary to the user's expectation, so using to_list() does not make things asymptotically worse. It just makes things more explicit. RELNOTES: To iterate over or test for membership in a set, prefer using the new to_list() method. E.g., "for x in myset.to_list():", or "print(x in myset.to_list())". Iteration/membership-test on the raw set itself is deprecated. -- PiperOrigin-RevId: 144452510 MOS_MIGRATED_REVID=144452510 --- .../build/lib/syntax/SkylarkNestedSet.java | 29 ++++++++++++++-------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib') diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java index b4cab445b5..23535f6fc3 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkNestedSet.java @@ -13,22 +13,22 @@ // limitations under the License. package com.google.devtools.build.lib.syntax; -import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.collect.nestedset.Order; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory; import com.google.devtools.build.lib.skylarkinterface.SkylarkValue; +import com.google.devtools.build.lib.syntax.SkylarkList.MutableList; import com.google.devtools.build.lib.util.Preconditions; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; -import java.util.Set; import javax.annotation.Nullable; /** @@ -243,9 +243,14 @@ public final class SkylarkNestedSet implements Iterable, SkylarkValue, S } /** - * Returns the NestedSet embedded in this SkylarkNestedSet if it is of the parameter type. + * Returns the embedded {@link NestedSet}, while asserting that its elements all have the given + * type. + * + * @param type a {@link Class} representing the expected type of the contents + * @return the {@code NestedSet}, with the appropriate generic type + * @throws IllegalArgumentException if the type does not accurately describe all elements */ - // The precondition ensures generic type safety + // The precondition ensures generic type safety. @SuppressWarnings("unchecked") public NestedSet getSet(Class type) { // Empty sets don't need have to have a type since they don't have items @@ -254,14 +259,17 @@ public final class SkylarkNestedSet implements Iterable, SkylarkValue, S } Preconditions.checkArgument( contentType.canBeCastTo(type), - String.format( - "Expected a depset of '%s' but got a depset of '%s'", - EvalUtils.getDataTypeNameFromClass(type), contentType)); + "Expected a depset of '%s' but got a depset of '%s'", + EvalUtils.getDataTypeNameFromClass(type), contentType); return (NestedSet) set; } - public Set expandedSet() { - return set.toSet(); + @SkylarkCallable( + name = "to_list", + doc = "Returns a frozen list of the elements, without duplicates, in the depset's traversal " + + "order.") + public MutableList skylarkToList() { + return new MutableList(set, null); } // For some reason this cast is unsafe in Java @@ -280,7 +288,6 @@ public final class SkylarkNestedSet implements Iterable, SkylarkValue, S return set.isEmpty(); } - @VisibleForTesting public SkylarkType getContentType() { return contentType; } @@ -312,6 +319,6 @@ public final class SkylarkNestedSet implements Iterable, SkylarkValue, S @Override public final boolean containsKey(Object key, Location loc) throws EvalException { - return (this.expandedSet().contains(key)); + return (set.toSet().contains(key)); } } -- cgit v1.2.3