bazel packages: move lib.syntax.Type here
Type is a concept of the build language, not of core Starlark.
(Witness all the references to Label. That said, there appear to be
three concepts---BuildType, Type, StarlarkType---where only two
are necessary: the types of rule attributes, and a library of
Starlark-to-Java conversion combinators.)
This change is mostly mechanical, except:
- MethodLibrary: two uses of Type.XYZ.convert replaced by ad-hoc code.
- SkylarkDict: getDictFromArgs substantially rewritten to avoid Type.
Its error messages were improved.
I added comments re: harmful type parameterization.
This CL depends on unknown commit, which first breaks
Copybara's dependency on syntax.Type.
PiperOrigin-RevId: 267694761
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java
index 20ee302..0d2632d 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AbstractAttributeMapper.java
@@ -18,7 +18,6 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.BuildType.SelectorList;
-import com.google.devtools.build.lib.syntax.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java
index f157a75..b82a76e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AggregatingAttributeMapper.java
@@ -25,9 +25,8 @@
import com.google.devtools.build.lib.packages.Attribute.ComputationLimiter;
import com.google.devtools.build.lib.packages.BuildType.Selector;
import com.google.devtools.build.lib.packages.BuildType.SelectorList;
-import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.syntax.Type.LabelClass;
-import com.google.devtools.build.lib.syntax.Type.ListType;
+import com.google.devtools.build.lib.packages.Type.LabelClass;
+import com.google.devtools.build.lib.packages.Type.ListType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
index 8237982..bbe9db3 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java
@@ -25,10 +25,9 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.ConfigurationFragmentPolicy.MissingFragmentPolicy;
+import com.google.devtools.build.lib.packages.Type.LabelClass;
+import com.google.devtools.build.lib.packages.Type.LabelVisitor;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
-import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.syntax.Type.LabelClass;
-import com.google.devtools.build.lib.syntax.Type.LabelVisitor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
index a6fad4e..79a5ec5 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java
@@ -37,15 +37,14 @@
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassNamePredicate;
+import com.google.devtools.build.lib.packages.Type.ConversionException;
+import com.google.devtools.build.lib.packages.Type.LabelClass;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.syntax.ClassObject;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
import com.google.devtools.build.lib.syntax.Runtime;
-import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.syntax.Type.ConversionException;
-import com.google.devtools.build.lib.syntax.Type.LabelClass;
import com.google.devtools.build.lib.util.FileType;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.devtools.build.lib.util.StringUtil;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AttributeFormatter.java b/src/main/java/com/google/devtools/build/lib/packages/AttributeFormatter.java
index cda20bd..2fad851 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AttributeFormatter.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AttributeFormatter.java
@@ -25,13 +25,13 @@
import static com.google.devtools.build.lib.packages.BuildType.OUTPUT;
import static com.google.devtools.build.lib.packages.BuildType.OUTPUT_LIST;
import static com.google.devtools.build.lib.packages.BuildType.TRISTATE;
-import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
-import static com.google.devtools.build.lib.syntax.Type.INTEGER;
-import static com.google.devtools.build.lib.syntax.Type.INTEGER_LIST;
-import static com.google.devtools.build.lib.syntax.Type.STRING;
-import static com.google.devtools.build.lib.syntax.Type.STRING_DICT;
-import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
-import static com.google.devtools.build.lib.syntax.Type.STRING_LIST_DICT;
+import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
+import static com.google.devtools.build.lib.packages.Type.INTEGER;
+import static com.google.devtools.build.lib.packages.Type.INTEGER_LIST;
+import static com.google.devtools.build.lib.packages.Type.STRING;
+import static com.google.devtools.build.lib.packages.Type.STRING_DICT;
+import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
+import static com.google.devtools.build.lib.packages.Type.STRING_LIST_DICT;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
@@ -47,7 +47,6 @@
import com.google.devtools.build.lib.query2.proto.proto2api.Build.LabelListDictEntry;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.StringDictEntry;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.StringListDictEntry;
-import com.google.devtools.build.lib.syntax.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/AttributeMap.java b/src/main/java/com/google/devtools/build/lib/packages/AttributeMap.java
index 2d48499..27e2026 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/AttributeMap.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/AttributeMap.java
@@ -17,7 +17,6 @@
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.syntax.Type;
import java.util.Collection;
import javax.annotation.Nullable;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/BuildSetting.java b/src/main/java/com/google/devtools/build/lib/packages/BuildSetting.java
index f3f6773..f2e9694 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/BuildSetting.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/BuildSetting.java
@@ -16,7 +16,6 @@
import com.google.common.annotations.VisibleForTesting;
import com.google.devtools.build.lib.skylarkbuildapi.StarlarkConfigApi.BuildSettingApi;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.syntax.Type;
/**
* Metadata of a build setting rule's properties. This describes the build setting's type (for
diff --git a/src/main/java/com/google/devtools/build/lib/packages/BuildType.java b/src/main/java/com/google/devtools/build/lib/packages/BuildType.java
index 182f967..5ada61b 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/BuildType.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/BuildType.java
@@ -25,6 +25,10 @@
import com.google.devtools.build.lib.cmdline.RepositoryName;
import com.google.devtools.build.lib.packages.License.DistributionType;
import com.google.devtools.build.lib.packages.License.LicenseParsingException;
+import com.google.devtools.build.lib.packages.Type.ConversionException;
+import com.google.devtools.build.lib.packages.Type.DictType;
+import com.google.devtools.build.lib.packages.Type.LabelClass;
+import com.google.devtools.build.lib.packages.Type.ListType;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
@@ -33,11 +37,6 @@
import com.google.devtools.build.lib.syntax.Printer.BasePrinter;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SelectorValue;
-import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.syntax.Type.ConversionException;
-import com.google.devtools.build.lib.syntax.Type.DictType;
-import com.google.devtools.build.lib.syntax.Type.LabelClass;
-import com.google.devtools.build.lib.syntax.Type.ListType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ConfiguredAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/ConfiguredAttributeMapper.java
index 690127e..b884d6a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ConfiguredAttributeMapper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/ConfiguredAttributeMapper.java
@@ -24,7 +24,6 @@
import com.google.devtools.build.lib.packages.BuildType.Selector;
import com.google.devtools.build.lib.packages.BuildType.SelectorList;
import com.google.devtools.build.lib.syntax.EvalException;
-import com.google.devtools.build.lib.syntax.Type;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/DelegatingAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/DelegatingAttributeMapper.java
index 577904a..24e64aeb 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/DelegatingAttributeMapper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/DelegatingAttributeMapper.java
@@ -17,7 +17,6 @@
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.syntax.Type;
import java.util.Collection;
import javax.annotation.Nullable;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/DependencyFilter.java b/src/main/java/com/google/devtools/build/lib/packages/DependencyFilter.java
index 971eef9..aaa4306 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/DependencyFilter.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/DependencyFilter.java
@@ -14,7 +14,7 @@
package com.google.devtools.build.lib.packages;
import com.google.devtools.build.lib.packages.DependencyFilter.AttributeInfoProvider;
-import com.google.devtools.build.lib.syntax.Type.LabelClass;
+import com.google.devtools.build.lib.packages.Type.LabelClass;
import com.google.devtools.build.lib.util.BinaryPredicate;
/**
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java b/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java
index adc9dec..fc22881 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java
@@ -34,7 +34,6 @@
import com.google.devtools.build.lib.syntax.ClassObject;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.Runtime;
-import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.StringUtil;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/NonconfigurableAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/NonconfigurableAttributeMapper.java
index e2b8c3b..f69a02d 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/NonconfigurableAttributeMapper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/NonconfigurableAttributeMapper.java
@@ -41,7 +41,7 @@
}
@Override
- public <T> T get(String attributeName, com.google.devtools.build.lib.syntax.Type<T> type) {
+ public <T> T get(String attributeName, com.google.devtools.build.lib.packages.Type<T> type) {
T attr = super.get(attributeName, type);
Preconditions.checkState(!getAttributeDefinition(attributeName).isConfigurable(),
"Attribute '%s' is potentially configurable - not allowed here", attributeName);
diff --git a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
index 8fb1fda..03843a1 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java
@@ -37,6 +37,7 @@
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy;
import com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttributeValuesMap;
+import com.google.devtools.build.lib.packages.Type.ConversionException;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
@@ -68,8 +69,6 @@
import com.google.devtools.build.lib.syntax.Statement;
import com.google.devtools.build.lib.syntax.StringLiteral;
import com.google.devtools.build.lib.syntax.SyntaxTreeVisitor;
-import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.syntax.Type.ConversionException;
import com.google.devtools.build.lib.syntax.ValidationEnvironment;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ProtoUtils.java b/src/main/java/com/google/devtools/build/lib/packages/ProtoUtils.java
index f012e05..0080e1a 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ProtoUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/ProtoUtils.java
@@ -26,18 +26,17 @@
import static com.google.devtools.build.lib.packages.BuildType.OUTPUT;
import static com.google.devtools.build.lib.packages.BuildType.OUTPUT_LIST;
import static com.google.devtools.build.lib.packages.BuildType.TRISTATE;
-import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
-import static com.google.devtools.build.lib.syntax.Type.INTEGER;
-import static com.google.devtools.build.lib.syntax.Type.INTEGER_LIST;
-import static com.google.devtools.build.lib.syntax.Type.STRING;
-import static com.google.devtools.build.lib.syntax.Type.STRING_DICT;
-import static com.google.devtools.build.lib.syntax.Type.STRING_LIST;
-import static com.google.devtools.build.lib.syntax.Type.STRING_LIST_DICT;
+import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
+import static com.google.devtools.build.lib.packages.Type.INTEGER;
+import static com.google.devtools.build.lib.packages.Type.INTEGER_LIST;
+import static com.google.devtools.build.lib.packages.Type.STRING;
+import static com.google.devtools.build.lib.packages.Type.STRING_DICT;
+import static com.google.devtools.build.lib.packages.Type.STRING_LIST;
+import static com.google.devtools.build.lib.packages.Type.STRING_LIST_DICT;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.query2.proto.proto2api.Build.Attribute.Discriminator;
-import com.google.devtools.build.lib.syntax.Type;
/** Shared code used in proto buffer output for rules and rule classes. */
public class ProtoUtils {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RawAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/packages/RawAttributeMapper.java
index dffc107..018f72e 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RawAttributeMapper.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RawAttributeMapper.java
@@ -20,7 +20,6 @@
import com.google.devtools.build.lib.packages.Attribute.ComputedDefault;
import com.google.devtools.build.lib.packages.BuildType.Selector;
import com.google.devtools.build.lib.packages.BuildType.SelectorList;
-import com.google.devtools.build.lib.syntax.Type;
import java.util.Collection;
import java.util.List;
import javax.annotation.Nullable;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Rule.java b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
index 8de293a..052c2fe 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/Rule.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/Rule.java
@@ -34,7 +34,6 @@
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.License.DistributionType;
import com.google.devtools.build.lib.syntax.EvalException;
-import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.BinaryPredicate;
import java.util.Collection;
import java.util.LinkedHashSet;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index e23e491..8ca63fc 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -17,7 +17,7 @@
import static com.google.devtools.build.lib.packages.Attribute.ANY_RULE;
import static com.google.devtools.build.lib.packages.Attribute.attr;
import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST;
-import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
+import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
@@ -52,6 +52,7 @@
import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType;
import com.google.devtools.build.lib.packages.RuleClass.Builder.ThirdPartyLicenseExistencePolicy;
import com.google.devtools.build.lib.packages.RuleFactory.AttributeValues;
+import com.google.devtools.build.lib.packages.Type.ConversionException;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.lib.syntax.Argument;
@@ -60,8 +61,6 @@
import com.google.devtools.build.lib.syntax.FuncallExpression;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkList;
-import com.google.devtools.build.lib.syntax.Type;
-import com.google.devtools.build.lib.syntax.Type.ConversionException;
import com.google.devtools.build.lib.util.FileTypeSet;
import com.google.devtools.build.lib.util.StringUtil;
import com.google.devtools.build.lib.vfs.PathFragment;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkDefinedAspect.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkDefinedAspect.java
index e1e1d55..8db6504 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkDefinedAspect.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkDefinedAspect.java
@@ -26,7 +26,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.syntax.BaseFunction;
import com.google.devtools.build.lib.syntax.EvalException;
-import com.google.devtools.build.lib.syntax.Type;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
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 310b667..ec4ce5b 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
@@ -16,6 +16,7 @@
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.packages.Type.ConversionException;
import com.google.devtools.build.lib.skylarkbuildapi.SkylarkNativeModuleApi;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.EvalException;
@@ -24,7 +25,6 @@
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkUtils;
-import com.google.devtools.build.lib.syntax.Type.ConversionException;
/**
* A class for the Skylark native module. TODO(laurentlb): Some definitions are duplicated from
diff --git a/src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java b/src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java
index 82f220a..a8d2d9f 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/TargetUtils.java
@@ -15,7 +15,7 @@
package com.google.devtools.build.lib.packages;
import static com.google.devtools.build.lib.packages.BuildType.TRISTATE;
-import static com.google.devtools.build.lib.syntax.Type.BOOLEAN;
+import static com.google.devtools.build.lib.packages.Type.BOOLEAN;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
@@ -26,7 +26,6 @@
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.SkylarkDict;
-import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.Pair;
import java.util.ArrayList;
import java.util.Collection;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/TestSize.java b/src/main/java/com/google/devtools/build/lib/packages/TestSize.java
index 3a7e7ca..b43f60f 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/TestSize.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/TestSize.java
@@ -15,7 +15,6 @@
package com.google.devtools.build.lib.packages;
import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.common.options.OptionsParsingException;
import java.util.Set;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/TestTargetUtils.java b/src/main/java/com/google/devtools/build/lib/packages/TestTargetUtils.java
index ec68b81..282ebee 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/TestTargetUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/TestTargetUtils.java
@@ -20,7 +20,6 @@
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.pkgcache.TargetProvider;
-import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.build.lib.util.Pair;
import java.util.ArrayList;
import java.util.Collection;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/TestTimeout.java b/src/main/java/com/google/devtools/build/lib/packages/TestTimeout.java
index 86ff65b..1c24197 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/TestTimeout.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/TestTimeout.java
@@ -20,7 +20,6 @@
import com.google.common.collect.Maps;
import com.google.common.collect.Range;
import com.google.common.collect.RangeMap;
-import com.google.devtools.build.lib.syntax.Type;
import com.google.devtools.common.options.Converter;
import com.google.devtools.common.options.OptionsParsingException;
import java.time.Duration;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/Type.java b/src/main/java/com/google/devtools/build/lib/packages/Type.java
new file mode 100644
index 0000000..32b70bf
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/Type.java
@@ -0,0 +1,686 @@
+// 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.packages;
+
+import com.google.common.base.Joiner;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.EvalUtils;
+import com.google.devtools.build.lib.syntax.Printer;
+import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.lib.util.LoggingUtil;
+import com.google.devtools.build.lib.util.StringCanonicalizer;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import javax.annotation.Nullable;
+
+/**
+ * <p>Root of Type symbol hierarchy for values in the build language.</p>
+ *
+ * <p>Type symbols are primarily used for their <code>convert</code> method,
+ * which is a kind of cast operator enabling conversion from untyped (Object)
+ * references to values in the build language, to typed references.</p>
+ *
+ * <p>For example, this code type-converts a value <code>x</code> returned by
+ * the evaluator, to a list of strings:</p>
+ *
+ * <pre>
+ * Object x = expr.eval(env);
+ * List<String> s = Type.STRING_LIST.convert(x);
+ * </pre>
+ */
+public abstract class Type<T> {
+
+ protected Type() {}
+
+ /**
+ * Converts untyped Object x resulting from the evaluation of an expression in the build language,
+ * into a typed object of type T.
+ *
+ * <p>x must be *directly* convertible to this type. This therefore disqualifies "selector
+ * expressions" of the form "{ config1: 'value1_of_orig_type', config2: 'value2_of_orig_type; }"
+ * (which support configurable attributes). To handle those expressions, see
+ * {@link com.google.devtools.build.lib.packages.BuildType#selectableConvert}.
+ *
+ * @param x the build-interpreter value to convert.
+ * @param what an object having a toString describing what x is for; should be included in
+ * any exception thrown. Grammatically, must produce a string describe a syntactic
+ * construct, e.g. "attribute 'srcs' of rule foo".
+ * @param context the label of the current BUILD rule; must be non-null if resolution of
+ * package-relative label strings is required
+ * @throws ConversionException if there was a problem performing the type conversion
+ */
+ public abstract T convert(Object x, Object what, @Nullable Object context)
+ throws ConversionException;
+ // TODO(bazel-team): Check external calls (e.g. in PackageFactory), verify they always want
+ // this over selectableConvert.
+
+ /**
+ * Equivalent to {@link #convert(Object, Object, Object)} where the label is {@code null}.
+ * Useful for converting values to types that do not involve the type {@code LABEL}
+ * and hence do not require the label of the current package.
+ */
+ public final T convert(Object x, Object what) throws ConversionException {
+ return convert(x, what, null);
+ }
+
+ /**
+ * Like {@link #convert(Object, Object, Object)}, but converts skylark {@code None}
+ * to given {@code defaultValue}.
+ */
+ @Nullable public final T convertOptional(Object x,
+ String what, @Nullable Object context, T defaultValue)
+ throws ConversionException {
+ if (EvalUtils.isNullOrNone(x)) {
+ return defaultValue;
+ }
+ return convert(x, what, context);
+ }
+
+ /**
+ * Like {@link #convert(Object, Object, Object)}, but converts skylark {@code None}
+ * to java {@code null}.
+ */
+ @Nullable public final T convertOptional(Object x, String what, @Nullable Object context)
+ throws ConversionException {
+ return convertOptional(x, what, context, null);
+ }
+
+ /**
+ * Like {@link #convert(Object, Object)}, but converts skylark {@code NONE} to java {@code null}.
+ */
+ @Nullable public final T convertOptional(Object x, String what) throws ConversionException {
+ return convertOptional(x, what, null);
+ }
+
+ public abstract T cast(Object value);
+
+ @Override
+ public abstract String toString();
+
+ /**
+ * Returns the default value for this type; may return null iff no default is defined for this
+ * type.
+ */
+ public abstract T getDefaultValue();
+
+ /**
+ * Function accepting a (potentially null) {@link Label} and an arbitrary context object. Used by
+ * {@link #visitLabels}.
+ */
+ public interface LabelVisitor<C> {
+ void visit(@Nullable Label label, @Nullable C context);
+ }
+
+ /**
+ * Invokes {@code visitor.visit(label, context)} for each {@link Label} {@code label} associated
+ * with {@code value}, which is assumed an instance of this {@link Type}.
+ *
+ * <p>This is used to support reliable label visitation in {@link
+ * com.google.devtools.build.lib.packages.AbstractAttributeMapper#visitLabels}. To preserve that
+ * reliability, every type should faithfully define its own instance of this method. In other
+ * words, be careful about defining default instances in base types that get auto-inherited by
+ * their children. Keep all definitions as explicit as possible.
+ */
+ public abstract <C> void visitLabels(LabelVisitor<C> visitor, Object value, @Nullable C context);
+
+ /** Classifications of labels by their usage. */
+ public enum LabelClass {
+ /** Used for types which are not labels. */
+ NONE,
+ /** Used for types which use labels to declare a dependency. */
+ DEPENDENCY,
+ /**
+ * Used for types which use labels to reference another target but do not declare a dependency,
+ * in cases where doing so would cause a dependency cycle.
+ */
+ NONDEP_REFERENCE,
+ /** Used for types which use labels to declare an output path. */
+ OUTPUT,
+ /**
+ * Used for types which contain Fileset entries, which contain labels but do not produce
+ * normal dependencies.
+ */
+ FILESET_ENTRY
+ }
+
+ /** Returns the class of labels contained by this type, if any. */
+ public LabelClass getLabelClass() {
+ return LabelClass.NONE;
+ }
+
+ /**
+ * Implementation of concatenation for this type (e.g. "val1 + val2"). Returns null to
+ * indicate concatenation isn't supported.
+ */
+ public T concat(@SuppressWarnings("unused") Iterable<T> elements) {
+ return null;
+ }
+
+ /**
+ * Converts an initialized Type object into a tag set representation.
+ * This operation is only valid for certain sub-Types which are guaranteed
+ * to be properly initialized.
+ *
+ * @param value the actual value
+ * @throws UnsupportedOperationException if the concrete type does not support
+ * tag conversion or if a convertible type has no initialized value.
+ */
+ public Set<String> toTagSet(Object value, String name) {
+ String msg = "Attribute " + name + " does not support tag conversion.";
+ throw new UnsupportedOperationException(msg);
+ }
+
+ /** The type of an integer. */
+ @AutoCodec public static final Type<Integer> INTEGER = new IntegerType();
+
+ /** The type of a string. */
+ @AutoCodec public static final Type<String> STRING = new StringType();
+
+ /** The type of a boolean. */
+ @AutoCodec public static final Type<Boolean> BOOLEAN = new BooleanType();
+
+ /** The type of a list of not-yet-typed objects. */
+ @AutoCodec public static final ObjectListType OBJECT_LIST = new ObjectListType();
+
+ /** The type of a list of {@linkplain #STRING strings}. */
+ @AutoCodec public static final ListType<String> STRING_LIST = ListType.create(STRING);
+
+ /** The type of a list of {@linkplain #INTEGER strings}. */
+ @AutoCodec public static final ListType<Integer> INTEGER_LIST = ListType.create(INTEGER);
+
+ /** The type of a dictionary of {@linkplain #STRING strings}. */
+ @AutoCodec
+ public static final DictType<String, String> STRING_DICT = DictType.create(STRING, STRING);
+
+ /** The type of a dictionary of {@linkplain #STRING_LIST label lists}. */
+ @AutoCodec
+ public static final DictType<String, List<String>> STRING_LIST_DICT =
+ DictType.create(STRING, STRING_LIST);
+
+ /**
+ * For ListType objects, returns the type of the elements of the list; for
+ * all other types, returns null. (This non-obvious implementation strategy
+ * is necessitated by the wildcard capture rules of the Java type system,
+ * which disallow conversion from Type{List{ELEM}} to Type{List{?}}.)
+ */
+ public Type<?> getListElementType() {
+ return null;
+ }
+
+ /**
+ * ConversionException is thrown when a type conversion fails; it contains an explanatory error
+ * message.
+ */
+ public static class ConversionException extends EvalException {
+ private static String message(Type<?> type, Object value, @Nullable Object what) {
+ Printer.BasePrinter printer = Printer.getPrinter();
+ printer.append("expected value of type '").append(type.toString()).append("'");
+ if (what != null) {
+ printer.append(" for ").append(what.toString());
+ }
+ printer.append(", but got ");
+ printer.repr(value);
+ printer.append(" (").append(EvalUtils.getDataTypeName(value)).append(")");
+ return printer.toString();
+ }
+
+ public ConversionException(Type<?> type, Object value, @Nullable Object what) {
+ super(null, message(type, value, what));
+ }
+
+ public ConversionException(String message) {
+ super(null, message);
+ }
+ }
+
+ /********************************************************************
+ * *
+ * Subclasses *
+ * *
+ ********************************************************************/
+
+ private static class ObjectType extends Type<Object> {
+ @Override
+ public Object cast(Object value) {
+ return value;
+ }
+
+ @Override
+ public String getDefaultValue() {
+ throw new UnsupportedOperationException(
+ "ObjectType has no default value");
+ }
+
+ @Override
+ public <T> void visitLabels(LabelVisitor<T> visitor, Object value, T context) {
+ }
+
+ @Override
+ public String toString() {
+ return "object";
+ }
+
+ @Override
+ public Object convert(Object x, Object what, Object context) {
+ return x;
+ }
+ }
+
+ private static class IntegerType extends Type<Integer> {
+ @Override
+ public Integer cast(Object value) {
+ return (Integer) value;
+ }
+
+ @Override
+ public Integer getDefaultValue() {
+ return 0;
+ }
+
+ @Override
+ public <T> void visitLabels(LabelVisitor<T> visitor, Object value, T context) {
+ }
+
+ @Override
+ public String toString() {
+ return "int";
+ }
+
+ @Override
+ public Integer convert(Object x, Object what, Object context)
+ throws ConversionException {
+ if (!(x instanceof Integer)) {
+ throw new ConversionException(this, x, what);
+ }
+ return (Integer) x;
+ }
+
+ @Override
+ public Integer concat(Iterable<Integer> elements) {
+ int ans = 0;
+ for (Integer elem : elements) {
+ ans += elem;
+ }
+ return Integer.valueOf(ans);
+ }
+ }
+
+ private static class BooleanType extends Type<Boolean> {
+ @Override
+ public Boolean cast(Object value) {
+ return (Boolean) value;
+ }
+
+ @Override
+ public Boolean getDefaultValue() {
+ return false;
+ }
+
+ @Override
+ public <T> void visitLabels(LabelVisitor<T> visitor, Object value, T context) {
+ }
+
+ @Override
+ public String toString() {
+ return "boolean";
+ }
+
+ // Conversion to boolean must also tolerate integers of 0 and 1 only.
+ @Override
+ public Boolean convert(Object x, Object what, Object context)
+ throws ConversionException {
+ if (x instanceof Boolean) {
+ return (Boolean) x;
+ }
+ Integer xAsInteger = INTEGER.convert(x, what, context);
+ if (xAsInteger == 0) {
+ return false;
+ } else if (xAsInteger == 1) {
+ return true;
+ }
+ throw new ConversionException("boolean is not one of [0, 1]");
+ }
+
+ /**
+ * Booleans attributes are converted to tags based on their names.
+ */
+ @Override
+ public Set<String> toTagSet(Object value, String name) {
+ if (value == null) {
+ String msg = "Illegal tag conversion from null on Attribute " + name + ".";
+ throw new IllegalStateException(msg);
+ }
+ String tag = (Boolean) value ? name : "no" + name;
+ return ImmutableSet.of(tag);
+ }
+ }
+
+ private static class StringType extends Type<String> {
+ @Override
+ public String cast(Object value) {
+ return (String) value;
+ }
+
+ @Override
+ public String getDefaultValue() {
+ return "";
+ }
+
+ @Override
+ public <T> void visitLabels(LabelVisitor<T> visitor, Object value, T context) {
+ }
+
+ @Override
+ public String toString() {
+ return "string";
+ }
+
+ @Override
+ public String convert(Object x, Object what, Object context)
+ throws ConversionException {
+ if (!(x instanceof String)) {
+ throw new ConversionException(this, x, what);
+ }
+ return StringCanonicalizer.intern((String) x);
+ }
+
+ @Override
+ public String concat(Iterable<String> elements) {
+ return Joiner.on("").join(elements);
+ }
+
+ /**
+ * A String is representable as a set containing its value.
+ */
+ @Override
+ public Set<String> toTagSet(Object value, String name) {
+ if (value == null) {
+ String msg = "Illegal tag conversion from null on Attribute " + name + ".";
+ throw new IllegalStateException(msg);
+ }
+ return ImmutableSet.of((String) value);
+ }
+ }
+
+ /**
+ * A type to support dictionary attributes.
+ */
+ public static class DictType<KeyT, ValueT> extends Type<Map<KeyT, ValueT>> {
+
+ private final Type<KeyT> keyType;
+ private final Type<ValueT> valueType;
+
+ private final Map<KeyT, ValueT> empty = ImmutableMap.of();
+
+ private final LabelClass labelClass;
+
+ @Override
+ public <T> void visitLabels(LabelVisitor<T> visitor, Object value, T context) {
+ for (Map.Entry<KeyT, ValueT> entry : cast(value).entrySet()) {
+ keyType.visitLabels(visitor, entry.getKey(), context);
+ valueType.visitLabels(visitor, entry.getValue(), context);
+ }
+ }
+
+ public static <KEY, VALUE> DictType<KEY, VALUE> create(
+ Type<KEY> keyType, Type<VALUE> valueType) {
+ LabelClass keyLabelClass = keyType.getLabelClass();
+ LabelClass valueLabelClass = valueType.getLabelClass();
+ Preconditions.checkArgument(
+ keyLabelClass == LabelClass.NONE
+ || valueLabelClass == LabelClass.NONE
+ || keyLabelClass == valueLabelClass,
+ "A DictType's keys and values must be the same class of label if both contain labels, "
+ + "but the key type %s contains %s labels, while "
+ + "the value type %s contains %s labels.",
+ keyType,
+ keyLabelClass,
+ valueType,
+ valueLabelClass);
+ LabelClass labelClass = (keyLabelClass != LabelClass.NONE) ? keyLabelClass : valueLabelClass;
+
+ return new DictType<>(keyType, valueType, labelClass);
+ }
+
+ protected DictType(Type<KeyT> keyType, Type<ValueT> valueType, LabelClass labelClass) {
+ this.keyType = keyType;
+ this.valueType = valueType;
+ this.labelClass = labelClass;
+ }
+
+ public Type<KeyT> getKeyType() {
+ return keyType;
+ }
+
+ public Type<ValueT> getValueType() {
+ return valueType;
+ }
+
+ @Override
+ public LabelClass getLabelClass() {
+ return labelClass;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public Map<KeyT, ValueT> cast(Object value) {
+ return (Map<KeyT, ValueT>) value;
+ }
+
+ @Override
+ public String toString() {
+ return "dict(" + keyType + ", " + valueType + ")";
+ }
+
+ @Override
+ public Map<KeyT, ValueT> convert(Object x, Object what, Object context)
+ throws ConversionException {
+ if (!(x instanceof Map<?, ?>)) {
+ throw new ConversionException(this, x, what);
+ }
+ Map<?, ?> o = (Map<?, ?>) x;
+ // It's possible that #convert() calls transform non-equal keys into equal ones so we can't
+ // just use ImmutableMap.Builder() here (that throws on collisions).
+ LinkedHashMap<KeyT, ValueT> result = new LinkedHashMap<>();
+ for (Map.Entry<?, ?> elem : o.entrySet()) {
+ result.put(
+ keyType.convert(elem.getKey(), "dict key element", context),
+ valueType.convert(elem.getValue(), "dict value element", context));
+ }
+ return ImmutableMap.copyOf(result);
+ }
+
+ @Override
+ public Map<KeyT, ValueT> getDefaultValue() {
+ return empty;
+ }
+ }
+
+ /** A type for lists of a given element type */
+ public static class ListType<ElemT> extends Type<List<ElemT>> {
+
+ private final Type<ElemT> elemType;
+
+ private final List<ElemT> empty = ImmutableList.of();
+
+ public static <ELEM> ListType<ELEM> create(Type<ELEM> elemType) {
+ return new ListType<>(elemType);
+ }
+
+ private ListType(Type<ElemT> elemType) {
+ this.elemType = elemType;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<ElemT> cast(Object value) {
+ return (List<ElemT>) value;
+ }
+
+ @Override
+ public Type<ElemT> getListElementType() {
+ return elemType;
+ }
+
+ @Override
+ public LabelClass getLabelClass() {
+ return elemType.getLabelClass();
+ }
+
+ @Override
+ public List<ElemT> getDefaultValue() {
+ return empty;
+ }
+
+ @Override
+ public <T> void visitLabels(LabelVisitor<T> visitor, Object value, T context) {
+ List<ElemT> elems = cast(value);
+ // Hot code path. Optimize for lists with O(1) access to avoid iterator garbage.
+ if (elems instanceof ImmutableList || elems instanceof ArrayList) {
+ for (int i = 0; i < elems.size(); i++) {
+ elemType.visitLabels(visitor, elems.get(i), context);
+ }
+ } else {
+ for (ElemT elem : elems) {
+ elemType.visitLabels(visitor, elem, context);
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "list(" + elemType + ")";
+ }
+
+ @Override
+ public List<ElemT> convert(Object x, Object what, Object context)
+ throws ConversionException {
+ Iterable<?> iterable;
+ try {
+ iterable = EvalUtils.toIterableStrict(x, null, null);
+ } catch (EvalException ex) {
+ throw new ConversionException(this, x, what);
+ }
+ int index = 0;
+ List<ElemT> result = new ArrayList<>(Iterables.size(iterable));
+ ListConversionContext conversionContext = new ListConversionContext(what);
+ for (Object elem : iterable) {
+ conversionContext.update(index);
+ ElemT converted = elemType.convert(elem, conversionContext, context);
+ if (converted != null) {
+ result.add(converted);
+ } else {
+ // shouldn't happen but it does, rarely
+ String message = "Converting a list with a null element: "
+ + "element " + index + " of " + what + " in " + context;
+ LoggingUtil.logToRemote(Level.WARNING, message,
+ new ConversionException(message));
+ }
+ ++index;
+ }
+ return result;
+ }
+
+ @Override
+ public List<ElemT> concat(Iterable<List<ElemT>> elements) {
+ ImmutableList.Builder<ElemT> builder = ImmutableList.builder();
+ for (List<ElemT> list : elements) {
+ builder.addAll(list);
+ }
+ return builder.build();
+ }
+
+ /**
+ * A list is representable as a tag set as the contents of itself expressed
+ * as Strings. So a {@code List<String>} is effectively converted to a {@code Set<String>}.
+ */
+ @Override
+ public Set<String> toTagSet(Object items, String name) {
+ if (items == null) {
+ String msg = "Illegal tag conversion from null on Attribute" + name + ".";
+ throw new IllegalStateException(msg);
+ }
+ Set<String> tags = new LinkedHashSet<>();
+ @SuppressWarnings("unchecked")
+ List<ElemT> itemsAsListofElem = (List<ElemT>) items;
+ for (ElemT element : itemsAsListofElem) {
+ tags.add(element.toString());
+ }
+ return tags;
+ }
+
+ /**
+ * Provides a {@link #toString()} description of the context of the value in a list being
+ * converted. This is preferred over a raw string to avoid uselessly constructing strings which
+ * are never used. This class is mutable (the index is updated).
+ */
+ private static class ListConversionContext {
+ private final Object what;
+ private int index = 0;
+
+ ListConversionContext(Object what) {
+ this.what = what;
+ }
+
+ void update(int index) {
+ this.index = index;
+ }
+
+ @Override
+ public String toString() {
+ return "element " + index + " of " + what;
+ }
+
+ }
+ }
+
+ /** Type for lists of arbitrary objects */
+ public static class ObjectListType extends ListType<Object> {
+
+ private static final Type<Object> elemType = new ObjectType();
+
+ private ObjectListType() {
+ super(elemType);
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public List<Object> convert(Object x, Object what, Object context)
+ throws ConversionException {
+ // TODO(adonovan): converge on EvalUtils.toIterable.
+ if (x instanceof SkylarkList) {
+ return ((SkylarkList) x).getImmutableList();
+ } else if (x instanceof List) {
+ return (List<Object>) x;
+ } else if (x instanceof Iterable) {
+ return ImmutableList.copyOf((Iterable<?>) x);
+ } else {
+ throw new ConversionException(this, x, what);
+ }
+ }
+ }
+}