bazel syntax: rename SkylarkList.Tuple to Tuple
Tuple is one of the core data types of Starlark.
SkylarkList, which should be named Sequence, is the interface common to all indexable sequences.
Also, remove is SkylarkList.isTuple method.
The only class that isTuple is Tuple.
By a minor miracle, there were no references to Tuple from within the
copybara code base, so this renaming is unusually straightforward.
PiperOrigin-RevId: 279730954
diff --git a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java
index d2f8d39..eb9cf73 100644
--- a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java
+++ b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java
@@ -23,7 +23,7 @@
import com.google.devtools.build.lib.syntax.Runtime.NoneType;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
+import com.google.devtools.build.lib.syntax.Tuple;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Map;
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
index e758d8a..2b6b85e 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleContext.java
@@ -85,11 +85,11 @@
import com.google.devtools.build.lib.syntax.SkylarkIndexable;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.Starlark;
import com.google.devtools.build.lib.syntax.StarlarkSemantics;
import com.google.devtools.build.lib.syntax.StarlarkThread;
+import com.google.devtools.build.lib.syntax.Tuple;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.ArrayList;
import java.util.Collection;
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
index 4401db5..b7b3d87 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcModule.java
@@ -34,8 +34,8 @@
import com.google.devtools.build.lib.skylarkbuildapi.cpp.BazelCcModuleApi;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.StarlarkThread;
+import com.google.devtools.build.lib.syntax.Tuple;
/**
* A module that contains Skylark utilities for C++ support.
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java
index 5e37a0f2..48740de 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkNativeModule.java
@@ -44,6 +44,7 @@
import com.google.devtools.build.lib.syntax.SkylarkType;
import com.google.devtools.build.lib.syntax.SkylarkUtils;
import com.google.devtools.build.lib.syntax.StarlarkThread;
+import com.google.devtools.build.lib.syntax.Tuple;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
@@ -377,7 +378,7 @@
l.add(elt);
}
- return SkylarkList.Tuple.copyOf(l);
+ return Tuple.copyOf(l);
}
if (val instanceof Map) {
Map<Object, Object> m = new TreeMap<>();
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
index 9193042..5e27588 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java
@@ -63,9 +63,9 @@
import com.google.devtools.build.lib.syntax.Runtime.NoneType;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.StarlarkThread;
+import com.google.devtools.build.lib.syntax.Tuple;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.util.StringUtil;
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/GoogleLegacyStubs.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/GoogleLegacyStubs.java
index df0f826..ac31b17 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/GoogleLegacyStubs.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/GoogleLegacyStubs.java
@@ -39,8 +39,8 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.Tuple;
/**
* Fake stub implementations for C++-related Starlark API which are unsupported without use of
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java
index dd2c6b2..a5b2f32 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/SkylarkRuleContextApi.java
@@ -30,10 +30,10 @@
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkIndexable;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
import com.google.devtools.build.lib.syntax.StarlarkThread;
+import com.google.devtools.build.lib.syntax.Tuple;
import javax.annotation.Nullable;
/** Interface for a context object given to rule implementation functions. */
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
index 57f57ef..4865d44 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/BazelCcModuleApi.java
@@ -25,9 +25,9 @@
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Runtime.NoneType;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.StarlarkThread;
+import com.google.devtools.build.lib.syntax.Tuple;
/** Utilites related to C++ support. */
@SkylarkModule(
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
index 668a934..021db3b 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/CcModuleApi.java
@@ -29,10 +29,10 @@
import com.google.devtools.build.lib.syntax.Runtime.NoneType;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
import com.google.devtools.build.lib.syntax.StarlarkThread;
+import com.google.devtools.build.lib.syntax.Tuple;
/** Utilites related to C++ support. */
@SkylarkModule(
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/GoWrapCcHelperApi.java b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/GoWrapCcHelperApi.java
index b4f919b..5fcd3d4 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/GoWrapCcHelperApi.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkbuildapi/cpp/GoWrapCcHelperApi.java
@@ -30,7 +30,7 @@
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Runtime.NoneType;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
+import com.google.devtools.build.lib.syntax.Tuple;
/**
* Helper class for the C++ functionality needed from Skylark specifically to implement go_wrap_cc.
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BUILD b/src/main/java/com/google/devtools/build/lib/syntax/BUILD
index 3edd3d7..bc679aa 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BUILD
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BUILD
@@ -130,6 +130,7 @@
"StarlarkMutable.java",
"StarlarkThread.java",
"StringModule.java",
+ "Tuple.java",
],
deps = [
":frontend",
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java
index fb42720..dbef082 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java
@@ -21,7 +21,6 @@
import com.google.common.collect.Sets;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java
index 056231d..69037ce 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java
@@ -30,7 +30,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.syntax.Runtime.NoneType;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
import com.google.devtools.build.lib.util.Pair;
import java.lang.reflect.Method;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Eval.java b/src/main/java/com/google/devtools/build/lib/syntax/Eval.java
index 8619814..f90614b 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Eval.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Eval.java
@@ -555,7 +555,7 @@
result.add(eval(thread, elem));
}
return list.isTuple()
- ? SkylarkList.Tuple.copyOf(result) // TODO(adonovan): opt: avoid copy
+ ? Tuple.copyOf(result) // TODO(adonovan): opt: avoid copy
: SkylarkList.MutableList.wrapUnsafe(thread, result);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
index dd65b51..44daf6c 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
@@ -28,7 +28,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.Concatable.Concatter;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.util.SpellChecker;
import java.util.Collection;
import java.util.IllegalFormatException;
@@ -95,7 +94,7 @@
if (o1 instanceof SkylarkList
&& o2 instanceof SkylarkList
- && ((SkylarkList) o1).isTuple() == ((SkylarkList) o2).isTuple()) {
+ && o1 instanceof Tuple == o2 instanceof Tuple) {
return compareLists((SkylarkList) o1, (SkylarkList) o2);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java
index 253375a..11b9ed9 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodDescriptor.java
@@ -154,9 +154,7 @@
return Runtime.NONE;
} else {
throw new IllegalStateException(
- "method invocation returned None: "
- + getName()
- + SkylarkList.Tuple.copyOf(Arrays.asList(args)));
+ "method invocation returned None: " + getName() + Tuple.copyOf(Arrays.asList(args)));
}
}
// TODO(bazel-team): get rid of this, by having everyone use the Skylark data structures
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index 0945991..9288f41 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -34,7 +34,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.EvalUtils.ComparisonException;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
import java.util.ArrayDeque;
import java.util.ArrayList;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Printer.java b/src/main/java/com/google/devtools/build/lib/syntax/Printer.java
index 695ceef..3d1c297 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Printer.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Printer.java
@@ -17,7 +17,6 @@
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.io.IOException;
import java.util.Arrays;
import java.util.Formattable;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/RangeList.java b/src/main/java/com/google/devtools/build/lib/syntax/RangeList.java
index 75261af..010acc0 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/RangeList.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/RangeList.java
@@ -176,11 +176,6 @@
}
@Override
- public boolean isTuple() {
- return false;
- }
-
- @Override
public ImmutableList<Integer> getImmutableList() {
return ImmutableList.copyOf(contents);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java
index 37be0da..175fcbb 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkDict.java
@@ -23,7 +23,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.StarlarkMutable.MutableMap;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
index 578d926..aed34e6 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkList.java
@@ -47,9 +47,6 @@
public abstract class SkylarkList<E> extends BaseMutableList<E>
implements List<E>, RandomAccess, SkylarkIndexable {
- /** Returns true if this list is a Skylark tuple. */
- public abstract boolean isTuple();
-
@Override
public final boolean truth() {
return !isEmpty();
@@ -107,7 +104,7 @@
@Override
public void repr(SkylarkPrinter printer) {
- printer.printList(getContentsUnsafe(), isTuple());
+ printer.printList(getContentsUnsafe(), this instanceof Tuple);
}
@Override
@@ -321,11 +318,6 @@
}
@Override
- public boolean isTuple() {
- return false;
- }
-
- @Override
public ImmutableList<E> getImmutableList() {
return ImmutableList.copyOf(contents);
}
@@ -597,157 +589,4 @@
return result;
}
}
-
- /**
- * A Skylark tuple, i.e. the value represented by {@code (1, 2, 3)}. Tuples are always immutable
- * (regardless of the {@link StarlarkThread} they are created in).
- */
- @SkylarkModule(
- name = "tuple",
- category = SkylarkModuleCategory.BUILTIN,
- doc =
- "The built-in tuple type. Example tuple expressions:<br>"
- + "<pre class=language-python>x = (1, 2, 3)</pre>"
- + "Accessing elements is possible using indexing (starts from <code>0</code>):<br>"
- + "<pre class=language-python>e = x[1] # e == 2</pre>"
- + "Lists support the <code>+</code> operator to concatenate two tuples. Example:<br>"
- + "<pre class=language-python>x = (1, 2) + (3, 4) # x == (1, 2, 3, 4)\n"
- + "x = (\"a\", \"b\")\n"
- + "x += (\"c\",) # x == (\"a\", \"b\", \"c\")</pre>"
- + "Similar to lists, tuples support slice operations:"
- + "<pre class=language-python>('a', 'b', 'c', 'd')[1:3] # ('b', 'c')\n"
- + "('a', 'b', 'c', 'd')[::2] # ('a', 'c')\n"
- + "('a', 'b', 'c', 'd')[3:0:-1] # ('d', 'c', 'b')</pre>"
- + "Tuples are immutable, therefore <code>x[1] = \"a\"</code> is not supported.")
- public static final class Tuple<E> extends SkylarkList<E> {
-
- private final ImmutableList<E> contents;
-
- private Tuple(ImmutableList<E> contents) {
- this.contents = contents;
- }
-
- /**
- * A shared instance for the empty tuple.
- *
- * <p>This instance should be the only empty tuple.
- */
- private static final Tuple<?> EMPTY = new Tuple<>(ImmutableList.of());
-
- /** Returns the empty tuple, cast to have an arbitrary content type. */
- @SuppressWarnings("unchecked")
- public static <T> Tuple<T> empty() {
- return (Tuple<T>) EMPTY;
- }
-
- /**
- * Creates a {@code Tuple} from an {@link ImmutableList}, reusing the empty instance if
- * applicable.
- */
- private static <T> Tuple<T> create(ImmutableList<T> contents) {
- if (contents.isEmpty()) {
- return empty();
- }
- return new Tuple<>(contents);
- }
-
- /** Returns a {@code Tuple} whose items are given by an iterable. */
- public static <T> Tuple<T> copyOf(Iterable<? extends T> contents) {
- return create(ImmutableList.<T>copyOf(contents));
- }
-
- /**
- * Returns a {@code Tuple} whose items are given by an immutable list.
- *
- * <p>This method is a specialization of a {@link #copyOf(Iterable)} that avoids an unnecessary
- * {@code copyOf} invocation.
- */
- public static <T> Tuple<T> copyOf(ImmutableList<T> contents) {
- return create(contents);
- }
-
- /** Returns a {@code Tuple} with the given items. */
- public static <T> Tuple<T> of(T... elements) {
- return Tuple.create(ImmutableList.copyOf(elements));
- }
-
- // Overridden to recurse over children, since tuples use SHALLOW_IMMUTABLE and other
- // StarlarkMutable subclasses do not.
- @Override
- public boolean isImmutable() {
- for (Object item : this) {
- if (!EvalUtils.isImmutable(item)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public boolean isHashable() {
- for (Object item : this) {
- if (!EvalUtils.isHashable(item)) {
- return false;
- }
- }
- return true;
- }
-
- @Override
- public Mutability mutability() {
- return Mutability.SHALLOW_IMMUTABLE;
- }
-
- @Override
- public boolean isTuple() {
- return true;
- }
-
- @Override
- public ImmutableList<E> getImmutableList() {
- return contents;
- }
-
- @Override
- protected List<E> getContentsUnsafe() {
- return contents;
- }
-
- /** Returns a {@code Tuple} that is the concatenation of two {@code Tuple}s. */
- public static <T> Tuple<T> concat(Tuple<? extends T> left, Tuple<? extends T> right) {
- // Build the ImmutableList directly rather than use Iterables.concat, to avoid unnecessary
- // array resizing.
- return create(
- ImmutableList.<T>builderWithExpectedSize(left.size() + right.size())
- .addAll(left)
- .addAll(right)
- .build());
- }
-
- @Override
- public Tuple<E> getSlice(
- Object start, Object end, Object step, Location loc, Mutability mutability)
- throws EvalException {
- List<Integer> sliceIndices = EvalUtils.getSliceIndices(start, end, step, this.size(), loc);
- ImmutableList.Builder<E> builder = ImmutableList.builderWithExpectedSize(sliceIndices.size());
- // foreach is not used to avoid iterator overhead
- for (int i = 0; i < sliceIndices.size(); ++i) {
- builder.add(this.get(sliceIndices.get(i)));
- }
- return copyOf(builder.build());
- }
-
- @Override
- public Tuple<E> repeat(int times, Mutability mutability) {
- if (times <= 0) {
- return empty();
- }
-
- ImmutableList.Builder<E> builder = ImmutableList.builderWithExpectedSize(this.size() * times);
- for (int i = 0; i < times; i++) {
- builder.addAll(this);
- }
- return copyOf(builder.build());
- }
- }
}
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 b06c931..2714b9c 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
@@ -28,7 +28,6 @@
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/StringModule.java b/src/main/java/com/google/devtools/build/lib/syntax/StringModule.java
index 3d59dfb..33740d6 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/StringModule.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/StringModule.java
@@ -26,7 +26,6 @@
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.syntax.SkylarkList.Tuple;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Tuple.java b/src/main/java/com/google/devtools/build/lib/syntax/Tuple.java
new file mode 100644
index 0000000..91f5b855
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Tuple.java
@@ -0,0 +1,169 @@
+// Copyright 2014 The Bazel Authors. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.devtools.build.lib.syntax;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
+import java.util.List;
+
+/**
+ * A Skylark tuple, i.e. the value represented by {@code (1, 2, 3)}. Tuples are always immutable
+ * (regardless of the {@link StarlarkThread} they are created in).
+ */
+@SkylarkModule(
+ name = "tuple",
+ category = SkylarkModuleCategory.BUILTIN,
+ doc =
+ "The built-in tuple type. Example tuple expressions:<br>"
+ + "<pre class=language-python>x = (1, 2, 3)</pre>"
+ + "Accessing elements is possible using indexing (starts from <code>0</code>):<br>"
+ + "<pre class=language-python>e = x[1] # e == 2</pre>"
+ + "Lists support the <code>+</code> operator to concatenate two tuples. Example:<br>"
+ + "<pre class=language-python>x = (1, 2) + (3, 4) # x == (1, 2, 3, 4)\n"
+ + "x = (\"a\", \"b\")\n"
+ + "x += (\"c\",) # x == (\"a\", \"b\", \"c\")</pre>"
+ + "Similar to lists, tuples support slice operations:"
+ + "<pre class=language-python>('a', 'b', 'c', 'd')[1:3] # ('b', 'c')\n"
+ + "('a', 'b', 'c', 'd')[::2] # ('a', 'c')\n"
+ + "('a', 'b', 'c', 'd')[3:0:-1] # ('d', 'c', 'b')</pre>"
+ + "Tuples are immutable, therefore <code>x[1] = \"a\"</code> is not supported.")
+public final class Tuple<E> extends SkylarkList<E> {
+
+ private final ImmutableList<E> contents;
+
+ private Tuple(ImmutableList<E> contents) {
+ this.contents = contents;
+ }
+
+ /**
+ * A shared instance for the empty tuple.
+ *
+ * <p>This instance should be the only empty tuple.
+ */
+ private static final Tuple<?> EMPTY = new Tuple<>(ImmutableList.of());
+
+ /** Returns the empty tuple, cast to have an arbitrary content type. */
+ @SuppressWarnings("unchecked")
+ public static <T> Tuple<T> empty() {
+ return (Tuple<T>) EMPTY;
+ }
+
+ /**
+ * Creates a {@code Tuple} from an {@link ImmutableList}, reusing the empty instance if
+ * applicable.
+ */
+ private static <T> Tuple<T> create(ImmutableList<T> contents) {
+ if (contents.isEmpty()) {
+ return empty();
+ }
+ return new Tuple<>(contents);
+ }
+
+ /** Returns a {@code Tuple} whose items are given by an iterable. */
+ public static <T> Tuple<T> copyOf(Iterable<? extends T> contents) {
+ return create(ImmutableList.<T>copyOf(contents));
+ }
+
+ /**
+ * Returns a {@code Tuple} whose items are given by an immutable list.
+ *
+ * <p>This method is a specialization of a {@link #copyOf(Iterable)} that avoids an unnecessary
+ * {@code copyOf} invocation.
+ */
+ public static <T> Tuple<T> copyOf(ImmutableList<T> contents) {
+ return create(contents);
+ }
+
+ /** Returns a {@code Tuple} with the given items. */
+ public static <T> Tuple<T> of(T... elements) {
+ return Tuple.create(ImmutableList.copyOf(elements));
+ }
+
+ // Overridden to recurse over children, since tuples use SHALLOW_IMMUTABLE and other
+ // StarlarkMutable subclasses do not.
+ @Override
+ public boolean isImmutable() {
+ for (Object item : this) {
+ if (!EvalUtils.isImmutable(item)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isHashable() {
+ for (Object item : this) {
+ if (!EvalUtils.isHashable(item)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public Mutability mutability() {
+ return Mutability.SHALLOW_IMMUTABLE;
+ }
+
+ @Override
+ public ImmutableList<E> getImmutableList() {
+ return contents;
+ }
+
+ @Override
+ protected List<E> getContentsUnsafe() {
+ return contents;
+ }
+
+ /** Returns a {@code Tuple} that is the concatenation of two {@code Tuple}s. */
+ public static <T> Tuple<T> concat(Tuple<? extends T> left, Tuple<? extends T> right) {
+ // Build the ImmutableList directly rather than use Iterables.concat, to avoid unnecessary
+ // array resizing.
+ return create(
+ ImmutableList.<T>builderWithExpectedSize(left.size() + right.size())
+ .addAll(left)
+ .addAll(right)
+ .build());
+ }
+
+ @Override
+ public Tuple<E> getSlice(
+ Object start, Object end, Object step, Location loc, Mutability mutability)
+ throws EvalException {
+ List<Integer> sliceIndices = EvalUtils.getSliceIndices(start, end, step, this.size(), loc);
+ ImmutableList.Builder<E> builder = ImmutableList.builderWithExpectedSize(sliceIndices.size());
+ // foreach is not used to avoid iterator overhead
+ for (int i = 0; i < sliceIndices.size(); ++i) {
+ builder.add(this.get(sliceIndices.get(i)));
+ }
+ return copyOf(builder.build());
+ }
+
+ @Override
+ public Tuple<E> repeat(int times, Mutability mutability) {
+ if (times <= 0) {
+ return empty();
+ }
+
+ ImmutableList.Builder<E> builder = ImmutableList.builderWithExpectedSize(this.size() * times);
+ for (int i = 0; i < times; i++) {
+ builder.addAll(this);
+ }
+ return copyOf(builder.build());
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
index fdede8c..8604ea9 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeCcModule.java
@@ -37,8 +37,8 @@
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.StarlarkThread;
+import com.google.devtools.build.lib.syntax.Tuple;
import com.google.devtools.build.skydoc.fakebuildapi.FakeProviderApi;
/** Fake implementation of {@link CcModuleApi}. */
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeGoWrapCcHelper.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeGoWrapCcHelper.java
index 35d5d20..a140c5d 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeGoWrapCcHelper.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeGoWrapCcHelper.java
@@ -33,8 +33,8 @@
import com.google.devtools.build.lib.skylarkbuildapi.go.GoContextInfoApi;
import com.google.devtools.build.lib.skylarkbuildapi.go.GoPackageInfoApi;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.Tuple;
/** Fake implementation of {@link GoWrapCcHelperApi}. */
public class FakeGoWrapCcHelper
diff --git a/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java b/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java
index b789291..50f41fb 100644
--- a/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java
+++ b/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java
@@ -30,8 +30,8 @@
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.Tuple;
import com.google.devtools.build.lib.util.Classpath;
import java.util.ArrayList;
import java.util.Collection;
diff --git a/src/test/java/com/google/devtools/build/lib/packages/TypeTest.java b/src/test/java/com/google/devtools/build/lib/packages/TypeTest.java
index 3278cbf..ce1506f 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/TypeTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/TypeTest.java
@@ -24,8 +24,8 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
+import com.google.devtools.build.lib.syntax.Tuple;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import java.util.Arrays;
import java.util.List;
diff --git a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
index bb29a57..ed4f0cf 100644
--- a/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skylark/SkylarkRuleClassFunctionsTest.java
@@ -52,11 +52,11 @@
import com.google.devtools.build.lib.syntax.ParserInput;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
import com.google.devtools.build.lib.syntax.StarlarkFile;
import com.google.devtools.build.lib.syntax.StarlarkThread;
import com.google.devtools.build.lib.syntax.SyntaxError;
+import com.google.devtools.build.lib.syntax.Tuple;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import com.google.devtools.build.lib.util.FileTypeSet;
import java.util.Collection;
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java
index a834dcb..d761038 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EvalUtilsTest.java
@@ -25,7 +25,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.EvalUtils.ComparisonException;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -97,8 +96,8 @@
2,
true,
Runtime.NONE,
- SkylarkList.Tuple.of(1, 2, 3),
- SkylarkList.Tuple.of("1", "2", "3"),
+ Tuple.of(1, 2, 3),
+ Tuple.of("1", "2", "3"),
SkylarkList.MutableList.of(thread, 1, 2, 3),
SkylarkList.MutableList.of(thread, "1", "2", "3"),
SkylarkDict.of(thread, "key", 123),
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
index 954a6b8..109de9b 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
@@ -20,7 +20,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
import com.google.devtools.build.lib.testutil.TestMode;
import java.util.Collections;
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/PrinterTest.java b/src/test/java/com/google/devtools/build/lib/syntax/PrinterTest.java
index 63cccc2..bbf6f18 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/PrinterTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/PrinterTest.java
@@ -23,7 +23,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import java.util.IllegalFormatException;
import java.util.LinkedHashMap;
import java.util.List;
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
index ec4a25e..672fee8 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -1682,10 +1682,7 @@
" t2 += (3, 4)",
" return t1, t2",
"tuples = func()")
- .testLookup("tuples", SkylarkList.Tuple.of(
- SkylarkList.Tuple.of(1, 2),
- SkylarkList.Tuple.of(1, 2, 3, 4)
- ));
+ .testLookup("tuples", Tuple.of(Tuple.of(1, 2), Tuple.of(1, 2, 3, 4)));
}
@Test
@@ -2024,11 +2021,11 @@
// tuple
x = eval("(1,2)");
assertThat((Iterable<Object>) x).containsExactly(1, 2).inOrder();
- assertThat(((SkylarkList) x).isTuple()).isTrue();
+ assertThat(x).isInstanceOf(Tuple.class);
x = eval("(1,2) + (3,4)");
assertThat((Iterable<Object>) x).containsExactly(1, 2, 3, 4).inOrder();
- assertThat(((SkylarkList) x).isTuple()).isTrue();
+ assertThat(x).isInstanceOf(Tuple.class);
}
@Override
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java
index a566f15..08c7889 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkListTest.java
@@ -19,7 +19,6 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
import java.util.ArrayList;
import org.junit.Test;
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java
index e737188..62bfbc9 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkNestedSetTest.java
@@ -20,7 +20,6 @@
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.syntax.util.EvaluationTestCase;
import java.util.Arrays;
import java.util.HashMap;
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/StarlarkFileTest.java b/src/test/java/com/google/devtools/build/lib/syntax/StarlarkFileTest.java
index a590be9..feb49ae 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/StarlarkFileTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/StarlarkFileTest.java
@@ -17,7 +17,6 @@
import com.google.common.base.Joiner;
import com.google.devtools.build.lib.events.Event;
-import com.google.devtools.build.lib.syntax.SkylarkList.Tuple;
import com.google.devtools.build.lib.testutil.MoreAsserts;
import com.google.devtools.build.lib.vfs.PathFragment;
import org.junit.Test;