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(); }