@AutoCodec some expressions that show up in Java configured targets.
PiperOrigin-RevId: 189419493
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
index cc5da78..3a3a507 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
@@ -81,10 +81,11 @@
name = "items",
type = Object.class,
defaultValue = "[]",
- doc = "Deprecated: Either an iterable whose items become the direct elements of "
- + "the new depset, in left-to-right order, or else a depset that becomes "
- + "a transitive element of the new depset. In the latter case, <code>transitive</code> "
- + "cannot be specified."
+ doc =
+ "Deprecated: Either an iterable whose items become the direct elements of "
+ + "the new depset, in left-to-right order, or else a depset that becomes "
+ + "a transitive element of the new depset. In the latter case, "
+ + "<code>transitive</code> cannot be specified."
),
@Param(
name = "order",
@@ -95,13 +96,13 @@
+ "the possible values."
),
@Param(
- name = "direct",
- type = SkylarkList.class,
- defaultValue = "None",
- positional = false,
- named = true,
- noneable = true,
- doc = "A list of <i>direct</i> elements of a depset."
+ name = "direct",
+ type = SkylarkList.class,
+ defaultValue = "None",
+ positional = false,
+ named = true,
+ noneable = true,
+ doc = "A list of <i>direct</i> elements of a depset."
),
@Param(
name = "transitive",
@@ -119,11 +120,7 @@
private static final BuiltinFunction depset =
new BuiltinFunction("depset") {
public SkylarkNestedSet invoke(
- Object items,
- String orderString,
- Object direct,
- Object transitive,
- Location loc)
+ Object items, String orderString, Object direct, Object transitive, Location loc)
throws EvalException {
Order order;
try {
@@ -134,7 +131,7 @@
if (transitive == Runtime.NONE && direct == Runtime.NONE) {
// Legacy behavior.
- return new SkylarkNestedSet(order, items, loc);
+ return SkylarkNestedSet.of(order, items, loc);
}
if (direct != Runtime.NONE && !isEmptySkylarkList(items)) {
@@ -154,8 +151,8 @@
Iterable<SkylarkNestedSet> transitiveList;
if (transitive != Runtime.NONE) {
SkylarkType.checkType(transitive, SkylarkList.class, "transitive");
- transitiveList = ((SkylarkList<?>) transitive).getContents(
- SkylarkNestedSet.class, "transitive");
+ transitiveList =
+ ((SkylarkList<?>) transitive).getContents(SkylarkNestedSet.class, "transitive");
} else {
transitiveList = ImmutableList.of();
}
@@ -206,7 +203,7 @@
// newElements' type is Object because of the polymorphism on unioning two
// SkylarkNestedSets versus a set and another kind of iterable.
// Can't use EvalUtils#toIterable since that would discard this information.
- return new SkylarkNestedSet(input, newElements, loc);
+ return SkylarkNestedSet.of(input, newElements, loc);
}
};
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
index ab5badc..b56c9eb 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
@@ -331,7 +331,7 @@
+ "recommendations. Use --incompatible_depset_union=false "
+ "to temporarily disable this check.");
}
- return new SkylarkNestedSet((SkylarkNestedSet) lval, rval, location);
+ return SkylarkNestedSet.of((SkylarkNestedSet) lval, rval, location);
}
throw typeException(lval, rval, Operator.PLUS, location);
}
@@ -348,7 +348,7 @@
+ "recommendations. Use --incompatible_depset_union=false "
+ "to temporarily disable this check.");
}
- return new SkylarkNestedSet((SkylarkNestedSet) lval, rval, location);
+ return SkylarkNestedSet.of((SkylarkNestedSet) lval, rval, location);
}
throw typeException(lval, rval, Operator.PIPE, location);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
index 86d9c36..c882743 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
@@ -557,15 +557,24 @@
for (String name : names) {
Object value = bindings.get(name);
Object otherValue = otherBindings.get(name);
- if (!value.equals(otherValue)) {
- badEntries.add(String.format(
- "%s: this one has %s (class %s), but given one has %s (class %s)",
- name,
- Printer.repr(value),
- value.getClass().getName(),
- Printer.repr(otherValue),
- otherValue.getClass().getName()));
+ if (value.equals(otherValue)) {
+ continue;
}
+ if (value instanceof SkylarkNestedSet
+ && otherValue instanceof SkylarkNestedSet
+ && (((SkylarkNestedSet) value)
+ .toCollection()
+ .equals(((SkylarkNestedSet) otherValue).toCollection()))) {
+ continue;
+ }
+ badEntries.add(
+ String.format(
+ "%s: this one has %s (class %s), but given one has %s (class %s)",
+ name,
+ Printer.repr(value),
+ value.getClass().getName(),
+ Printer.repr(otherValue),
+ otherValue.getClass().getName()));
}
if (!badEntries.isEmpty()) {
throw new IllegalStateException(
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 ce6dabc..1ab3d13 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
@@ -20,12 +20,12 @@
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.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import java.util.Collection;
-import java.util.List;
import javax.annotation.Nullable;
/**
@@ -81,30 +81,34 @@
+ "(using <code>to_list()</code>). Duplicates may interfere with the ordering semantics."
)
@Immutable
+@AutoCodec
public final class SkylarkNestedSet implements SkylarkValue, SkylarkQueryable {
-
private final SkylarkType contentType;
private final NestedSet<?> set;
- @Nullable
- private final List<Object> items;
- @Nullable
- private final List<NestedSet> transitiveItems;
+ @Nullable private final ImmutableList<Object> items;
+ @Nullable private final ImmutableList<NestedSet<?>> transitiveItems;
- public SkylarkNestedSet(Order order, Object item, Location loc) throws EvalException {
- this(order, SkylarkType.TOP, item, loc, null);
+ @AutoCodec.VisibleForSerialization
+ SkylarkNestedSet(
+ SkylarkType contentType,
+ NestedSet<?> set,
+ ImmutableList<Object> items,
+ ImmutableList<NestedSet<?>> transitiveItems) {
+ this.contentType = Preconditions.checkNotNull(contentType, "type cannot be null");
+ this.set = set;
+ this.items = items;
+ this.transitiveItems = transitiveItems;
}
- public SkylarkNestedSet(SkylarkNestedSet left, Object right, Location loc) throws EvalException {
- this(left.set.getOrder(), left.contentType, right, loc, left);
- }
-
- // This is safe because of the type checking
- @SuppressWarnings("unchecked")
- private SkylarkNestedSet(Order order, SkylarkType contentType, Object item, Location loc,
- @Nullable SkylarkNestedSet left) throws EvalException {
-
+ static SkylarkNestedSet of(
+ Order order,
+ SkylarkType contentType,
+ Object item,
+ Location loc,
+ @Nullable SkylarkNestedSet left)
+ throws EvalException {
ImmutableList.Builder<Object> itemsBuilder = ImmutableList.builder();
- ImmutableList.Builder<NestedSet> transitiveItemsBuilder = ImmutableList.builder();
+ ImmutableList.Builder<NestedSet<?>> transitiveItemsBuilder = ImmutableList.builder();
if (left != null) {
if (left.items == null) { // SkylarkSet created from native NestedSet
transitiveItemsBuilder.add(left.set);
@@ -137,29 +141,36 @@
String.format(
"cannot union value of type '%s' to a depset", EvalUtils.getDataTypeName(item)));
}
- this.contentType = Preconditions.checkNotNull(contentType, "type cannot be null");
- this.items = itemsBuilder.build();
- this.transitiveItems = transitiveItemsBuilder.build();
-
+ ImmutableList<Object> items = itemsBuilder.build();
+ ImmutableList<NestedSet<?>> transitiveItems = transitiveItemsBuilder.build();
// Initializing the real nested set
NestedSetBuilder<Object> builder = new NestedSetBuilder<>(order);
- builder.addAll(this.items);
+ builder.addAll(items);
try {
- for (NestedSet<?> nestedSet : this.transitiveItems) {
+ for (NestedSet<?> nestedSet : transitiveItems) {
builder.addTransitive(nestedSet);
}
} catch (IllegalArgumentException e) {
// Order mismatch between item and builder.
throw new EvalException(loc, e.getMessage());
}
- this.set = builder.build();
+ return new SkylarkNestedSet(contentType, builder.build(), items, transitiveItems);
+ }
+
+ public static SkylarkNestedSet of(Order order, Object item, Location loc) throws EvalException {
+ return of(order, SkylarkType.TOP, item, loc, null);
+ }
+
+ public static SkylarkNestedSet of(SkylarkNestedSet left, Object right, Location loc)
+ throws EvalException {
+ return of(left.set.getOrder(), left.contentType, right, loc, left);
}
/**
* Returns a type safe SkylarkNestedSet. Use this instead of the constructor if possible.
*/
public static <T> SkylarkNestedSet of(SkylarkType contentType, NestedSet<T> set) {
- return new SkylarkNestedSet(contentType, set);
+ return new SkylarkNestedSet(contentType, set, null, null);
}
/**
@@ -169,26 +180,6 @@
return of(SkylarkType.of(contentType), set);
}
- /**
- * A not type safe constructor for SkylarkNestedSet. It's discouraged to use it unless type
- * generic safety is guaranteed from the caller side.
- */
- SkylarkNestedSet(SkylarkType contentType, NestedSet<?> set) {
- // This is here for the sake of FuncallExpression.
- this.contentType = Preconditions.checkNotNull(contentType, "type cannot be null");
- this.set = Preconditions.checkNotNull(set, "depset cannot be null");
- this.items = null;
- this.transitiveItems = null;
- }
-
- /**
- * A not type safe constructor for SkylarkNestedSet, specifying type as a Java class.
- * It's discouraged to use it unless type generic safety is guaranteed from the caller side.
- */
- public SkylarkNestedSet(Class<?> contentType, NestedSet<?> set) {
- this(SkylarkType.of(contentType), set);
- }
-
private static final SkylarkType DICT_LIST_UNION =
SkylarkType.Union.of(SkylarkType.DICT, SkylarkType.LIST);
@@ -384,7 +375,7 @@
}
public SkylarkNestedSet build() {
- return new SkylarkNestedSet(contentType, builder.build());
+ return new SkylarkNestedSet(contentType, builder.build(), null, null);
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
index f821341..b4729ac 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
@@ -733,7 +733,8 @@
*/
static Object convertToSkylark(Object object, Method method, @Nullable Environment env) {
if (object instanceof NestedSet<?>) {
- return new SkylarkNestedSet(getGenericTypeFromMethod(method), (NestedSet<?>) object);
+ return SkylarkNestedSet.of(
+ SkylarkType.of(getGenericTypeFromMethod(method)), (NestedSet<?>) object);
}
return convertToSkylark(object, env);
}