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