Move Bazel-specific functions in a separate file.
"type", "set" and "select" should not be part of the standalone Skylark
library.
--
MOS_MIGRATED_REVID=139578095
diff --git a/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java b/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java
index d8e9822..a9be763 100644
--- a/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java
+++ b/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java
@@ -34,6 +34,7 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
+import com.google.devtools.build.lib.syntax.BazelLibrary;
import com.google.devtools.build.lib.syntax.FuncallExpression;
import com.google.devtools.build.lib.syntax.MethodLibrary;
import com.google.devtools.build.lib.syntax.Runtime;
@@ -146,6 +147,7 @@
private static Map<String, SkylarkModuleDoc> collectBuiltinModules(String... clazz) {
Map<String, SkylarkModuleDoc> modules = new HashMap<>();
collectBuiltinDoc(modules, Runtime.class.getDeclaredFields());
+ collectBuiltinDoc(modules, BazelLibrary.class.getDeclaredFields());
collectBuiltinDoc(modules, MethodLibrary.class.getDeclaredFields());
for (Class<?> moduleClass : SkylarkModules.MODULES) {
collectBuiltinDoc(modules, moduleClass.getDeclaredFields());
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 4c2488d..ef13e49 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
@@ -39,6 +39,7 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.AssignmentStatement;
import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.BazelLibrary;
import com.google.devtools.build.lib.syntax.BuildFileAST;
import com.google.devtools.build.lib.syntax.BuiltinFunction;
import com.google.devtools.build.lib.syntax.ClassObject;
@@ -1631,7 +1632,7 @@
try (Mutability mutability = Mutability.create("package %s", packageId)) {
Environment pkgEnv =
Environment.builder(mutability)
- .setGlobals(Environment.DEFAULT_GLOBALS)
+ .setGlobals(BazelLibrary.GLOBALS)
.setEventHandler(eventHandler)
.setImportedExtensions(imports)
.setPhase(Phase.LOADING)
@@ -1708,7 +1709,7 @@
try (Mutability mutability = Mutability.create("prefetchGlobs for %s", packageId)) {
Environment pkgEnv =
Environment.builder(mutability)
- .setGlobals(Environment.DEFAULT_GLOBALS)
+ .setGlobals(BazelLibrary.GLOBALS)
.setEventHandler(NullEventHandler.INSTANCE)
.setPhase(Phase.LOADING)
.build();
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 3a31933..5d865b7 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
@@ -32,6 +32,7 @@
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.BazelLibrary;
import com.google.devtools.build.lib.syntax.BuildFileAST;
import com.google.devtools.build.lib.syntax.BuiltinFunction;
import com.google.devtools.build.lib.syntax.ClassObject;
@@ -180,7 +181,7 @@
throws InterruptedException {
Environment.Builder environmentBuilder =
Environment.builder(mutability)
- .setGlobals(Environment.DEFAULT_GLOBALS)
+ .setGlobals(BazelLibrary.GLOBALS)
.setEventHandler(localReporter);
if (importedExtensions != null) {
Map<String, Extension> map = new HashMap<String, Extension>(parentImportMap);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkModules.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkModules.java
index 436fe58..3f8158a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkModules.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkModules.java
@@ -16,6 +16,7 @@
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.packages.SkylarkNativeModule;
+import com.google.devtools.build.lib.syntax.BazelLibrary;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.Environment.Frame;
import com.google.devtools.build.lib.syntax.Mutability;
@@ -56,10 +57,7 @@
private static Environment.Frame createGlobals(List<Class<?>> modules) {
try (Mutability mutability = Mutability.create("SkylarkModules")) {
Environment env =
- Environment.builder(mutability)
- .setSkylark()
- .setGlobals(Environment.DEFAULT_GLOBALS)
- .build();
+ Environment.builder(mutability).setSkylark().setGlobals(BazelLibrary.GLOBALS).build();
for (Class<?> moduleClass : modules) {
Runtime.registerModuleGlobals(env, moduleClass);
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
new file mode 100644
index 0000000..8c9d476
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BazelLibrary.java
@@ -0,0 +1,162 @@
+// 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.syntax;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.collect.nestedset.Order;
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.skylarkinterface.Param;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
+import java.util.List;
+
+/**
+ * A helper class containing additional built in functions for Bazel (BUILD files and .bzl files).
+ */
+public class BazelLibrary {
+
+ @SkylarkSignature(
+ name = "type",
+ returnType = String.class,
+ doc =
+ "Returns the type name of its argument. This is useful for debugging and "
+ + "type-checking. Examples:"
+ + "<pre class=\"language-python\">"
+ + "type(2) == \"int\"\n"
+ + "type([1]) == \"list\"\n"
+ + "type(struct(a = 2)) == \"struct\""
+ + "</pre>"
+ + "This function might change in the future. To write Python-compatible code and "
+ + "be future-proof, use it only to compare return values: "
+ + "<pre class=\"language-python\">"
+ + "if type(x) == type([]): # if x is a list"
+ + "</pre>",
+ parameters = {@Param(name = "x", doc = "The object to check type of.")}
+ )
+ private static final BuiltinFunction type =
+ new BuiltinFunction("type") {
+ public String invoke(Object object) {
+ // There is no 'type' type in Skylark, so we return a string with the type name.
+ return EvalUtils.getDataTypeName(object, false);
+ }
+ };
+
+ @SkylarkSignature(
+ name = "set",
+ returnType = SkylarkNestedSet.class,
+ doc =
+ "Creates a <a href=\"set.html\">set</a> from the <code>items</code>. "
+ + "The set supports nesting other sets of the same element type in it. "
+ + "A desired <a href=\"set.html\">iteration order</a> can also be specified.<br>"
+ + "Examples:<br><pre class=\"language-python\">set([\"a\", \"b\"])\n"
+ + "set([1, 2, 3], order=\"compile\")</pre>",
+ parameters = {
+ @Param(
+ name = "items",
+ type = Object.class,
+ defaultValue = "[]",
+ doc =
+ "The items to initialize the set with. May contain both standalone items "
+ + "and other sets."
+ ),
+ @Param(
+ name = "order",
+ type = String.class,
+ defaultValue = "\"stable\"",
+ doc =
+ "The ordering strategy for the set if it's nested, "
+ + "possible values are: <code>stable</code> (default), <code>compile</code>, "
+ + "<code>link</code> or <code>naive_link</code>. An explanation of the "
+ + "values can be found <a href=\"set.html\">here</a>."
+ )
+ },
+ useLocation = true
+ )
+ private static final BuiltinFunction set =
+ new BuiltinFunction("set") {
+ public SkylarkNestedSet invoke(Object items, String order, Location loc)
+ throws EvalException {
+ try {
+ return new SkylarkNestedSet(Order.parse(order), items, loc);
+ } catch (IllegalArgumentException ex) {
+ throw new EvalException(loc, ex);
+ }
+ }
+ };
+
+ @SkylarkSignature(
+ name = "union",
+ objectType = SkylarkNestedSet.class,
+ returnType = SkylarkNestedSet.class,
+ doc =
+ "Creates a new <a href=\"set.html\">set</a> that contains both "
+ + "the input set as well as all additional elements.",
+ parameters = {
+ @Param(name = "input", type = SkylarkNestedSet.class, doc = "The input set"),
+ @Param(name = "new_elements", type = Iterable.class, doc = "The elements to be added")
+ },
+ useLocation = true
+ )
+ private static final BuiltinFunction union =
+ new BuiltinFunction("union") {
+ @SuppressWarnings("unused")
+ public SkylarkNestedSet invoke(
+ SkylarkNestedSet input, Iterable<Object> newElements, Location loc)
+ throws EvalException {
+ return new SkylarkNestedSet(input, newElements, loc);
+ }
+ };
+
+ /**
+ * Returns a function-value implementing "select" (i.e. configurable attributes) in the specified
+ * package context.
+ */
+ @SkylarkSignature(
+ name = "select",
+ doc = "Creates a SelectorValue from the dict parameter.",
+ parameters = {
+ @Param(name = "x", type = SkylarkDict.class, doc = "The parameter to convert."),
+ @Param(
+ name = "no_match_error",
+ type = String.class,
+ defaultValue = "''",
+ doc = "Optional custom error to report if no condition matches."
+ )
+ }
+ )
+ private static final BuiltinFunction select =
+ new BuiltinFunction("select") {
+ public Object invoke(SkylarkDict<?, ?> dict, String noMatchError) throws EvalException {
+ return SelectorList.of(new SelectorValue(dict, noMatchError));
+ }
+ };
+
+ private static Environment.Frame createGlobals() {
+ List<BaseFunction> bazelGlobalFunctions = ImmutableList.<BaseFunction>of(select, set, type);
+
+ try (Mutability mutability = Mutability.create("BUILD")) {
+ Environment env = Environment.builder(mutability).build();
+ Runtime.setupConstants(env);
+ Runtime.setupMethodEnvironment(env, MethodLibrary.defaultGlobalFunctions);
+ Runtime.setupMethodEnvironment(env, bazelGlobalFunctions);
+ return env.getGlobals();
+ }
+ }
+
+ public static final Environment.Frame GLOBALS = createGlobals();
+
+ static {
+ SkylarkSignatureProcessor.configureSkylarkFunctions(BazelLibrary.class);
+ }
+}
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 6157e7c..b2a33c5 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
@@ -22,7 +22,6 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
-import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkinterface.Param;
@@ -44,9 +43,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-/**
- * A helper class containing built in functions for the Build and the Build Extension Language.
- */
+/** A helper class containing built in functions for the Skylark language. */
public class MethodLibrary {
private MethodLibrary() {}
@@ -1676,49 +1673,6 @@
};
@SkylarkSignature(
- name = "set",
- returnType = SkylarkNestedSet.class,
- doc =
- "Creates a <a href=\"set.html\">set</a> from the <code>items</code>. "
- + "The set supports nesting other sets of the same element type in it. "
- + "A desired <a href=\"set.html\">iteration order</a> can also be specified.<br>"
- + "Examples:<br><pre class=\"language-python\">set([\"a\", \"b\"])\n"
- + "set([1, 2, 3], order=\"compile\")</pre>",
- parameters = {
- @Param(
- name = "items",
- type = Object.class,
- defaultValue = "[]",
- doc =
- "The items to initialize the set with. May contain both standalone items "
- + "and other sets."
- ),
- @Param(
- name = "order",
- type = String.class,
- defaultValue = "\"stable\"",
- doc =
- "The ordering strategy for the set if it's nested, "
- + "possible values are: <code>stable</code> (default), <code>compile</code>, "
- + "<code>link</code> or <code>naive_link</code>. An explanation of the "
- + "values can be found <a href=\"set.html\">here</a>."
- )
- },
- useLocation = true
- )
- private static final BuiltinFunction set =
- new BuiltinFunction("set") {
- public SkylarkNestedSet invoke(Object items, String order, Location loc)
- throws EvalException {
- try {
- return new SkylarkNestedSet(Order.parse(order), items, loc);
- } catch (IllegalArgumentException ex) {
- throw new EvalException(loc, ex);
- }
- }
- };
-
- @SkylarkSignature(
name = "dict",
returnType = SkylarkDict.class,
doc =
@@ -1785,22 +1739,6 @@
}
};
- @SkylarkSignature(name = "union", objectType = SkylarkNestedSet.class,
- returnType = SkylarkNestedSet.class,
- doc = "Creates a new <a href=\"set.html\">set</a> that contains both "
- + "the input set as well as all additional elements.",
- parameters = {
- @Param(name = "input", type = SkylarkNestedSet.class, doc = "The input set"),
- @Param(name = "new_elements", type = Iterable.class, doc = "The elements to be added")},
- useLocation = true)
- private static final BuiltinFunction union = new BuiltinFunction("union") {
- @SuppressWarnings("unused")
- public SkylarkNestedSet invoke(SkylarkNestedSet input, Iterable<Object> newElements,
- Location loc) throws EvalException {
- return new SkylarkNestedSet(input, newElements, loc);
- }
- };
-
@SkylarkSignature(
name = "enumerate",
returnType = MutableList.class,
@@ -1916,23 +1854,6 @@
}
};
- /**
- * Returns a function-value implementing "select" (i.e. configurable attributes)
- * in the specified package context.
- */
- @SkylarkSignature(name = "select",
- doc = "Creates a SelectorValue from the dict parameter.",
- parameters = {
- @Param(name = "x", type = SkylarkDict.class, doc = "The parameter to convert."),
- @Param(name = "no_match_error", type = String.class, defaultValue = "''",
- doc = "Optional custom error to report if no condition matches.")})
- private static final BuiltinFunction select = new BuiltinFunction("select") {
- public Object invoke(SkylarkDict<?, ?> dict, String noMatchError) throws EvalException {
- return SelectorList
- .of(new SelectorValue(dict, noMatchError));
- }
- };
-
/** Returns true if the object has a field of the given name, otherwise false. */
@SkylarkSignature(
name = "hasattr",
@@ -2057,32 +1978,6 @@
};
@SkylarkSignature(
- name = "type",
- returnType = String.class,
- doc =
- "Returns the type name of its argument. This is useful for debugging and "
- + "type-checking. Examples:"
- + "<pre class=\"language-python\">"
- + "type(2) == \"int\"\n"
- + "type([1]) == \"list\"\n"
- + "type(struct(a = 2)) == \"struct\""
- + "</pre>"
- + "This function might change in the future. To write Python-compatible code and "
- + "be future-proof, use it only to compare return values: "
- + "<pre class=\"language-python\">"
- + "if type(x) == type([]): # if x is a list"
- + "</pre>",
- parameters = {@Param(name = "x", doc = "The object to check type of.")}
- )
- private static final BuiltinFunction type =
- new BuiltinFunction("type") {
- public String invoke(Object object) {
- // There is no 'type' type in Skylark, so we return a string with the type name.
- return EvalUtils.getDataTypeName(object, false);
- }
- };
-
- @SkylarkSignature(
name = "fail",
doc =
"Raises an error that cannot be intercepted. It can be used anywhere, "
@@ -2211,16 +2106,7 @@
static final List<BaseFunction> defaultGlobalFunctions =
ImmutableList.<BaseFunction>of(
all, any, bool, dict, dir, fail, getattr, hasattr, hash, enumerate, int_, len, list, max,
- min, minus, print, range, repr, reversed, select, set, sorted, str, type, zip);
-
- /**
- * Collect global functions for the validation environment.
- */
- public static void setupValidationEnvironment(Set<String> builtIn) {
- for (BaseFunction function : defaultGlobalFunctions) {
- builtIn.add(function.getName());
- }
- }
+ min, minus, print, range, repr, reversed, sorted, str, zip);
static {
SkylarkSignatureProcessor.configureSkylarkFunctions(MethodLibrary.class);
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
index f303082..cf0f85b 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EnvironmentTest.java
@@ -141,11 +141,8 @@
"range",
"repr",
"reversed",
- "select",
- "set",
"sorted",
"str",
- "type",
"zip"),
outerEnv.getVariableNames());
assertEquals(
@@ -176,11 +173,8 @@
"range",
"repr",
"reversed",
- "select",
- "set",
"sorted",
"str",
- "type",
"zip"),
innerEnv.getVariableNames());
}
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java b/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
index b0ddd2f71..8d72a03 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/util/EvaluationTestCase.java
@@ -24,6 +24,7 @@
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.events.util.EventCollectionApparatus;
+import com.google.devtools.build.lib.syntax.BazelLibrary;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.Environment.Phase;
import com.google.devtools.build.lib.syntax.EvalException;
@@ -69,7 +70,7 @@
public Environment newBuildEnvironment() {
Environment env =
Environment.builder(mutability)
- .setGlobals(Environment.DEFAULT_GLOBALS)
+ .setGlobals(BazelLibrary.GLOBALS)
.setEventHandler(getEventHandler())
.setPhase(Phase.LOADING)
.build();
@@ -84,7 +85,7 @@
public Environment newSkylarkEnvironment() {
return Environment.builder(mutability)
.setSkylark()
- .setGlobals(Environment.DEFAULT_GLOBALS)
+ .setGlobals(BazelLibrary.GLOBALS)
.setEventHandler(getEventHandler())
.build();
}
diff --git a/src/test/java/com/google/devtools/build/lib/testutil/TestMode.java b/src/test/java/com/google/devtools/build/lib/testutil/TestMode.java
index b239f1b..178e775 100644
--- a/src/test/java/com/google/devtools/build/lib/testutil/TestMode.java
+++ b/src/test/java/com/google/devtools/build/lib/testutil/TestMode.java
@@ -14,6 +14,7 @@
package com.google.devtools.build.lib.testutil;
import com.google.devtools.build.lib.events.EventHandler;
+import com.google.devtools.build.lib.syntax.BazelLibrary;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.Mutability;
@@ -27,8 +28,7 @@
@Override
public Environment createEnvironment(EventHandler eventHandler, Environment environment) {
return Environment.builder(Mutability.create("build test"))
- .setGlobals(
- environment == null ? Environment.DEFAULT_GLOBALS : environment.getGlobals())
+ .setGlobals(environment == null ? BazelLibrary.GLOBALS : environment.getGlobals())
.setEventHandler(eventHandler)
.build();
}
@@ -40,8 +40,7 @@
public Environment createEnvironment(EventHandler eventHandler, Environment environment) {
return Environment.builder(Mutability.create("skylark test"))
.setSkylark()
- .setGlobals(
- environment == null ? Environment.DEFAULT_GLOBALS : environment.getGlobals())
+ .setGlobals(environment == null ? BazelLibrary.GLOBALS : environment.getGlobals())
.setEventHandler(eventHandler)
.build();
}