aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
authorGravatar Dmitry Lomov <dslomov@google.com>2016-08-09 09:35:40 +0000
committerGravatar Yue Gan <yueg@google.com>2016-08-09 13:45:20 +0000
commitea9de07ece727b397e427d11db9611db44753c75 (patch)
tree642e346746acffe9e32d0db65ab92eeb1f6cbfb0 /src/main/java/com/google/devtools/build/lib
parent31d70619943fe28a8dcc3e7ecac776fda0d017b6 (diff)
Add SkylarkClassObjectConstructor - a future return value of "provider" function.
-- MOS_MIGRATED_REVID=129726780
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/Attribute.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunction.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObject.java24
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObjectConstructor.java76
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java3
12 files changed, 124 insertions, 26 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
index f8d10cfab5..4ed66e965b 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/skylark/SkylarkRepositoryContext.java
@@ -26,6 +26,7 @@ import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.packages.AggregatingAttributeMapper;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
import com.google.devtools.build.lib.rules.repository.RepositoryFunction.RepositoryFunctionException;
import com.google.devtools.build.lib.skyframe.FileSymlinkException;
import com.google.devtools.build.lib.skyframe.FileValue;
@@ -108,7 +109,8 @@ public class SkylarkRepositoryContext {
: SkylarkType.convertToSkylark(val, null));
}
}
- attrObject = new SkylarkClassObject(attrBuilder.build(), "No such attribute '%s'");
+ attrObject = SkylarkClassObjectConstructor.STRUCT.create(
+ attrBuilder.build(), "No such attribute '%s'");
}
@SkylarkCallable(
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 f2fb3355e9..996371494d 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
@@ -1250,7 +1250,8 @@ public final class Attribute implements Comparable<Attribute> {
}
}
}
- ClassObject attrs = new SkylarkClassObject(attrValues,
+ ClassObject attrs = SkylarkClassObjectConstructor.STRUCT.create(
+ attrValues,
"No such regular (non late-bound) attribute '%s'.");
return callback.call(attrs, o);
}
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 3789091663..8ddffdd764 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
@@ -94,7 +94,9 @@ public abstract class ImplicitOutputsFunction {
attrValues.put(attrName, value == null ? Runtime.NONE : value);
}
}
- ClassObject attrs = new SkylarkClassObject(attrValues, "Attribute '%s' either doesn't exist "
+ ClassObject attrs = SkylarkClassObjectConstructor.STRUCT.create(
+ attrValues,
+ "Attribute '%s' either doesn't exist "
+ "or uses a select() (i.e. could have multiple values)");
try {
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
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 7b8e57f500..df26e80295 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
@@ -1526,7 +1526,8 @@ public final class PackageFactory {
builder.put(function.getName(), function);
}
}
- return new SkylarkClassObject(builder.build(), "no native function or rule '%s'");
+ return SkylarkClassObjectConstructor.STRUCT.create(
+ builder.build(), "no native function or rule '%s'");
}
private void buildPkgEnv(Environment pkgEnv, PackageContext context, RuleFactory ruleFactory) {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObject.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObject.java
index d28146a526..f5190965b7 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObject.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObject.java
@@ -46,6 +46,7 @@ public class SkylarkClassObject implements ClassObject, SkylarkValue, Concatable
/** Error message to use when errorMessage argument is null. */
private static final String DEFAULT_ERROR_MESSAGE = "'struct' object has no attribute '%s'";
+ private final SkylarkClassObjectConstructor constructor;
private final ImmutableMap<String, Object> values;
private final Location creationLoc;
private final String errorMessage;
@@ -54,7 +55,9 @@ public class SkylarkClassObject implements ClassObject, SkylarkValue, Concatable
* Primarily for testing purposes where no location is available and the default
* errorMessage suffices.
*/
- public SkylarkClassObject(Map<String, Object> values) {
+ public SkylarkClassObject(SkylarkClassObjectConstructor constructor,
+ Map<String, Object> values) {
+ this.constructor = constructor;
this.values = copyValues(values);
this.creationLoc = null;
this.errorMessage = DEFAULT_ERROR_MESSAGE;
@@ -64,13 +67,17 @@ public class SkylarkClassObject implements ClassObject, SkylarkValue, Concatable
* Creates a built-in struct (i.e. without creation loc). The errorMessage has to have
* exactly one '%s' parameter to substitute the struct field name.
*/
- public SkylarkClassObject(Map<String, Object> values, String errorMessage) {
+ public SkylarkClassObject(SkylarkClassObjectConstructor constructor,
+ Map<String, Object> values, String errorMessage) {
+ this.constructor = constructor;
this.values = copyValues(values);
this.creationLoc = null;
this.errorMessage = Preconditions.checkNotNull(errorMessage);
}
- public SkylarkClassObject(Map<String, Object> values, Location creationLoc) {
+ public SkylarkClassObject(SkylarkClassObjectConstructor constructor,
+ Map<String, Object> values, Location creationLoc) {
+ this.constructor = constructor;
this.values = copyValues(values);
this.creationLoc = Preconditions.checkNotNull(creationLoc);
this.errorMessage = DEFAULT_ERROR_MESSAGE;
@@ -133,8 +140,12 @@ public class SkylarkClassObject implements ClassObject, SkylarkValue, Concatable
throw new EvalException(loc, "Cannot concat structs with common field(s): "
+ Joiner.on(",").join(commonFields));
}
- return new SkylarkClassObject(ImmutableMap.<String, Object>builder()
- .putAll(lval.values).putAll(rval.values).build(), loc);
+ return new SkylarkClassObject(lval.constructor,
+ ImmutableMap.<String, Object>builder()
+ .putAll(lval.values)
+ .putAll(rval.values)
+ .build(),
+ loc);
}
}
@@ -163,7 +174,8 @@ public class SkylarkClassObject implements ClassObject, SkylarkValue, Concatable
@Override
public void write(Appendable buffer, char quotationMark) {
boolean first = true;
- Printer.append(buffer, "struct(");
+ Printer.append(buffer, constructor.getName());
+ Printer.append(buffer, "(");
// Sort by key to ensure deterministic output.
for (String key : Ordering.natural().sortedCopy(values.keySet())) {
if (!first) {
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObjectConstructor.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObjectConstructor.java
new file mode 100644
index 0000000000..b451efe583
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkClassObjectConstructor.java
@@ -0,0 +1,76 @@
+// Copyright 2016 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.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.Environment;
+import com.google.devtools.build.lib.syntax.EvalException;
+import com.google.devtools.build.lib.syntax.FuncallExpression;
+import com.google.devtools.build.lib.syntax.FunctionSignature;
+import com.google.devtools.build.lib.syntax.FunctionSignature.WithValues;
+import com.google.devtools.build.lib.syntax.SkylarkType;
+import com.google.devtools.build.lib.syntax.Type.ConversionException;
+import java.util.Map;
+import javax.annotation.Nullable;
+
+/**
+ * A constructor for {@link SkylarkClassObject}.
+ */
+public final class SkylarkClassObjectConstructor extends BaseFunction {
+ /**
+ * "struct" function.
+ */
+ public static final SkylarkClassObjectConstructor STRUCT =
+ new SkylarkClassObjectConstructor("struct");
+
+
+ private static final FunctionSignature.WithValues<Object, SkylarkType> SIGNATURE =
+ WithValues.create(FunctionSignature.KWARGS);
+
+ public SkylarkClassObjectConstructor(String name, Location location) {
+ super(name, SIGNATURE, location);
+ }
+
+ public SkylarkClassObjectConstructor(String name) {
+ this(name, Location.BUILTIN);
+ }
+
+ @Override
+ protected Object call(Object[] args, @Nullable FuncallExpression ast, @Nullable Environment env)
+ throws EvalException, ConversionException, InterruptedException {
+ @SuppressWarnings("unchecked")
+ Map<String, Object> kwargs = (Map<String, Object>) args[0];
+ return new SkylarkClassObject(this, kwargs, ast != null ? ast.getLocation() : Location.BUILTIN);
+ }
+
+ /**
+ * Creates a built-in class object (i.e. without creation loc). The errorMessage has to have
+ * exactly one '%s' parameter to substitute the field name.
+ */
+ public SkylarkClassObject create(Map<String, Object> values, String message) {
+ return new SkylarkClassObject(this, values, message);
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ return other == this;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
index 54b393a7dc..12c5caa66b 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/WorkspaceFactory.java
@@ -454,7 +454,8 @@ public class WorkspaceFactory {
}
builder.put("bazel_version", version);
- return new SkylarkClassObject(builder.build(), "no native function or rule '%s'");
+ return SkylarkClassObjectConstructor.STRUCT.create(
+ builder.build(), "no native function or rule '%s'");
}
public static ClassObject newNativeModule(RuleClassProvider ruleClassProvider, String version) {
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
index cb22b50ba3..9433807410 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java
@@ -63,6 +63,7 @@ import com.google.devtools.build.lib.packages.RuleFactory.BuildLangTypedAttribut
import com.google.devtools.build.lib.packages.RuleFactory.InvalidRuleException;
import com.google.devtools.build.lib.packages.SkylarkAspect;
import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.packages.TestSize;
import com.google.devtools.build.lib.rules.SkylarkAttr.Descriptor;
@@ -199,13 +200,8 @@ public class SkylarkRuleClassFunctions {
+ "return s.x + getattr(s, \"y\") # returns 5</pre>",
extraKeywords = @Param(name = "kwargs", doc = "the struct attributes"),
useLocation = true)
- private static final BuiltinFunction struct = new BuiltinFunction("struct") {
- @SuppressWarnings("unchecked")
- public SkylarkClassObject invoke(SkylarkDict<String, Object> kwargs, Location loc)
- throws EvalException {
- return new SkylarkClassObject(kwargs, loc);
- }
- };
+ private static final SkylarkClassObjectConstructor struct =
+ SkylarkClassObjectConstructor.STRUCT;
// TODO(bazel-team): implement attribute copy and other rule properties
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
index 248bbfd33b..b95554cfe8 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleContext.java
@@ -43,6 +43,7 @@ import com.google.devtools.build.lib.packages.OutputFile;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.RawAttributeMapper;
import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
import com.google.devtools.build.lib.shell.ShellUtils;
import com.google.devtools.build.lib.shell.ShellUtils.TokenizationException;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
@@ -219,7 +220,7 @@ public final class SkylarkRuleContext {
this.artifactsLabelMap = artifactLabelMapBuilder.build();
this.outputsObject =
- new SkylarkClassObject(
+ SkylarkClassObjectConstructor.STRUCT.create(
outputsBuilder,
"No attribute '%s' in outputs. Make sure you declared a rule output with this name.");
@@ -351,21 +352,21 @@ public final class SkylarkRuleContext {
ImmutableMap<Artifact, FilesToRunProvider> executableRunfilesMap) {
this.ruleClassName = ruleClassName;
attrObject =
- new SkylarkClassObject(
+ SkylarkClassObjectConstructor.STRUCT.create(
attrs,
"No attribute '%s' in attr. Make sure you declared a rule attribute with this name.");
executableObject =
- new SkylarkClassObject(
+ SkylarkClassObjectConstructor.STRUCT.create(
executables,
"No attribute '%s' in executable. Make sure there is a label type attribute marked "
+ "as 'executable' with this name");
fileObject =
- new SkylarkClassObject(
+ SkylarkClassObjectConstructor.STRUCT.create(
singleFiles,
"No attribute '%s' in file. Make sure there is a label type attribute marked "
+ "as 'single_file' with this name");
filesObject =
- new SkylarkClassObject(
+ SkylarkClassObjectConstructor.STRUCT.create(
files,
"No attribute '%s' in files. Make sure there is a label or label_list type attribute "
+ "with this name");
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
index 8249fd121a..4051f81ff5 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProvider.java
@@ -27,6 +27,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
import com.google.devtools.build.lib.rules.cpp.CppModuleMap;
import com.google.devtools.build.lib.rules.cpp.LinkerInputs;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
@@ -416,12 +417,15 @@ public final class ObjcProvider extends SkylarkClassObject implements Transitive
// Items which should be passed to strictly direct dependers, but not transitive dependers.
private final ImmutableMap<Key<?>, NestedSet<?>> strictDependencyItems;
+ private static final SkylarkClassObjectConstructor OBJC_PROVIDER =
+ new SkylarkClassObjectConstructor("objc_provider");
+
private ObjcProvider(
ImmutableMap<Key<?>, NestedSet<?>> items,
ImmutableMap<Key<?>, NestedSet<?>> nonPropagatedItems,
ImmutableMap<Key<?>, NestedSet<?>> strictDependencyItems,
ImmutableMap<String, Object> skylarkFields) {
- super(skylarkFields, "ObjcProvider field %s could not be instantiated");
+ super(OBJC_PROVIDER, skylarkFields, "ObjcProvider field %s could not be instantiated");
this.items = Preconditions.checkNotNull(items);
this.nonPropagatedItems = Preconditions.checkNotNull(nonPropagatedItems);
this.strictDependencyItems = Preconditions.checkNotNull(strictDependencyItems);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java
index 727891e820..caf0021c8c 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcProviderSkylarkConverters.java
@@ -25,6 +25,7 @@ import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
import com.google.devtools.build.lib.rules.objc.ObjcProvider.Key;
import com.google.devtools.build.lib.syntax.EvalException;
import com.google.devtools.build.lib.syntax.EvalUtils;
@@ -133,7 +134,7 @@ public class ObjcProviderSkylarkConverters {
public Object valueForSkylark(Key<?> javaKey, NestedSet<?> javaValue) {
NestedSetBuilder<SkylarkClassObject> result = NestedSetBuilder.stableOrder();
for (BundleableFile bundleableFile : (Iterable<BundleableFile>) javaValue) {
- result.add(new SkylarkClassObject(
+ result.add(SkylarkClassObjectConstructor.STRUCT.create(
ImmutableMap.<String, Object>of(
BUNDLED_FIELD, bundleableFile.getBundled(),
BUNDLE_PATH_FIELD, bundleableFile.getBundlePath()
diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java
index 842e9b7d7b..d03f380e9d 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/python/PyCommon.java
@@ -44,6 +44,7 @@ import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.Rule;
import com.google.devtools.build.lib.packages.SkylarkClassObject;
+import com.google.devtools.build.lib.packages.SkylarkClassObjectConstructor;
import com.google.devtools.build.lib.rules.cpp.CppFileTypes;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector;
import com.google.devtools.build.lib.rules.test.InstrumentedFilesCollector.LocalMetadataCollector;
@@ -161,7 +162,7 @@ public final class PyCommon {
*/
public static SkylarkClassObject createSourceProvider(
NestedSet<Artifact> transitivePythonSources, boolean isUsingSharedLibrary) {
- return new SkylarkClassObject(
+ return SkylarkClassObjectConstructor.STRUCT.create(
ImmutableMap.<String, Object>of(
TRANSITIVE_PYTHON_SRCS,
SkylarkNestedSet.of(Artifact.class, transitivePythonSources),