Remove old Skylark Function hierarchy

Last step in refactoring of Skylark builtin functions.

--
MOS_MIGRATED_REVID=91796746
diff --git a/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java
index 9d7faa8..55d5bb5 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java
@@ -14,6 +14,7 @@
 
 package com.google.devtools.build.lib.packages;
 
+import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
@@ -22,6 +23,7 @@
 import com.google.devtools.build.lib.events.Event;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.Type.ConversionException;
+import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.BuiltinFunction;
 import com.google.devtools.build.lib.syntax.ClassObject;
 import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject;
@@ -30,7 +32,6 @@
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
 import com.google.devtools.build.lib.syntax.FuncallExpression;
-import com.google.devtools.build.lib.syntax.Function;
 import com.google.devtools.build.lib.syntax.SelectorList;
 import com.google.devtools.build.lib.syntax.SelectorValue;
 import com.google.devtools.build.lib.syntax.SkylarkEnvironment;
@@ -1024,24 +1025,24 @@
       + "</pre>")
   public static final class DictModule {}
 
-  public static final List<Function> stringFunctions = ImmutableList.<Function>of(
+  public static final List<BaseFunction> stringFunctions = ImmutableList.<BaseFunction>of(
       count, endswith, find, index, join, lower, replace, rfind,
       rindex, slice, split, startswith, strip, upper);
 
-  public static final List<Function> listPureFunctions = ImmutableList.<Function>of(
+  public static final List<BaseFunction> listPureFunctions = ImmutableList.<BaseFunction>of(
       slice);
 
-  public static final List<Function> listFunctions = ImmutableList.<Function>of(
+  public static final List<BaseFunction> listFunctions = ImmutableList.<BaseFunction>of(
       append, extend);
 
-  public static final List<Function> dictFunctions = ImmutableList.<Function>of(
+  public static final List<BaseFunction> dictFunctions = ImmutableList.<BaseFunction>of(
       items, get, keys, values);
 
-  private static final List<Function> pureGlobalFunctions = ImmutableList.<Function>of(
+  private static final List<BaseFunction> pureGlobalFunctions = ImmutableList.<BaseFunction>of(
       bool, int_, len, minus, select, sorted, str);
 
-  private static final List<Function> skylarkGlobalFunctions = ImmutableList
-      .<Function>builder()
+  private static final List<BaseFunction> skylarkGlobalFunctions =
+      ImmutableList.<BaseFunction>builder()
       .addAll(pureGlobalFunctions)
       .add(list, struct, hasattr, getattr, set, dir, enumerate, range, type, fail, print, zip)
       .build();
@@ -1071,14 +1072,14 @@
   }
 
   private static void setupMethodEnvironment(
-      Environment env, Class<?> nameSpace, Iterable<Function> functions) {
-    for (Function function : functions) {
+      Environment env, Class<?> nameSpace, Iterable<BaseFunction> functions) {
+    for (BaseFunction function : functions) {
       env.registerFunction(nameSpace, function.getName(), function);
     }
   }
 
-  private static void setupMethodEnvironment(Environment env, Iterable<Function> functions) {
-    for (Function function : functions) {
+  private static void setupMethodEnvironment(Environment env, Iterable<BaseFunction> functions) {
+    for (BaseFunction function : functions) {
       env.update(function.getName(), function);
     }
   }
@@ -1087,7 +1088,7 @@
    * Collect global functions for the validation environment.
    */
   public static void setupValidationEnvironment(Set<String> builtIn) {
-    for (Function function : skylarkGlobalFunctions) {
+    for (BaseFunction function : skylarkGlobalFunctions) {
       builtIn.add(function.getName());
     }
   }
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 b4d4a6d..4d7b71f 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
@@ -40,7 +40,6 @@
 import com.google.devtools.build.lib.syntax.EvalUtils;
 import com.google.devtools.build.lib.syntax.Expression;
 import com.google.devtools.build.lib.syntax.FuncallExpression;
-import com.google.devtools.build.lib.syntax.Function;
 import com.google.devtools.build.lib.syntax.FunctionSignature;
 import com.google.devtools.build.lib.syntax.GlobList;
 import com.google.devtools.build.lib.syntax.Ident;
@@ -149,7 +148,7 @@
     /**
      * Returns the extra functions needed to be added to the Skylark native module.
      */
-    ImmutableList<Function> nativeModuleFunctions();
+    ImmutableList<BaseFunction> nativeModuleFunctions();
 
     Iterable<PackageArgument<?>> getPackageArguments();
   }
@@ -854,7 +853,7 @@
    * Returns a function-value implementing "package" in the specified package
    * context.
    */
-  private static Function newPackageFunction(
+  private static BaseFunction newPackageFunction(
       final ImmutableMap<String, PackageArgument<?>> packageArguments) {
     // Flatten the map of argument name of PackageArgument specifier in two co-indexed arrays:
     // one for the argument names, to create a FunctionSignature when we create the function,
@@ -1151,7 +1150,7 @@
    * PackageFactory.)
    *
    * <p>PLEASE NOTE: references to PackageContext objects are held by many
-   * Function closures, but should become unreachable once the Environment is
+   * BaseFunction closures, but should become unreachable once the Environment is
    * discarded at the end of evaluation.  Please be aware of your memory
    * footprint when making changes here!
    */
@@ -1188,8 +1187,8 @@
    * Returns the list of native rule functions created using the {@link RuleClassProvider}
    * of this {@link PackageFactory}.
    */
-  public ImmutableList<Function> collectNativeRuleFunctions() {
-    ImmutableList.Builder<Function> builder = ImmutableList.builder();
+  public ImmutableList<BaseFunction> collectNativeRuleFunctions() {
+    ImmutableList.Builder<BaseFunction> builder = ImmutableList.builder();
     for (String ruleClass : ruleFactory.getRuleClassNames()) {
       builder.add(newRuleFunction(ruleFactory, ruleClass));
     }
@@ -1215,7 +1214,7 @@
     pkgEnv.update("PACKAGE_NAME", packageName);
 
     for (String ruleClass : ruleFactory.getRuleClassNames()) {
-      Function ruleFunction = newRuleFunction(ruleFactory, ruleClass);
+      BaseFunction ruleFunction = newRuleFunction(ruleFactory, ruleClass);
       pkgEnv.update(ruleClass, ruleFunction);
     }
 
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 c604fff..93a0165 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
@@ -29,9 +29,9 @@
 import com.google.devtools.build.lib.events.EventHandler;
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.syntax.Argument;
+import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.FuncallExpression;
-import com.google.devtools.build.lib.syntax.Function;
 import com.google.devtools.build.lib.syntax.GlobList;
 import com.google.devtools.build.lib.syntax.Label;
 import com.google.devtools.build.lib.syntax.Label.SyntaxException;
@@ -427,7 +427,7 @@
         PredicatesWithMessage.<Rule>alwaysTrue();
     private Predicate<String> preferredDependencyPredicate = Predicates.alwaysFalse();
     private List<Class<?>> advertisedProviders = new ArrayList<>();
-    private Function configuredTargetFunction = null;
+    private BaseFunction configuredTargetFunction = null;
     private SkylarkEnvironment ruleDefinitionEnvironment = null;
     private Set<Class<?>> configurationFragments = new LinkedHashSet<>();
     private boolean failIfMissingConfigurationFragment;
@@ -681,7 +681,7 @@
     /**
      * Sets the rule implementation function. Meant for Skylark usage.
      */
-    public Builder setConfiguredTargetFunction(Function func) {
+    public Builder setConfiguredTargetFunction(BaseFunction func) {
       this.configuredTargetFunction = func;
       return this;
     }
@@ -834,7 +834,7 @@
   /**
    * The Skylark rule implementation of this RuleClass. Null for non Skylark executable RuleClasses.
    */
-  @Nullable private final Function configuredTargetFunction;
+  @Nullable private final BaseFunction configuredTargetFunction;
 
   /**
    * The Skylark rule definition environment of this RuleClass.
@@ -895,7 +895,7 @@
       ConfiguredTargetFactory<?, ?> configuredTargetFactory,
       PredicateWithMessage<Rule> validityPredicate, Predicate<String> preferredDependencyPredicate,
       ImmutableSet<Class<?>> advertisedProviders,
-      @Nullable Function configuredTargetFunction,
+      @Nullable BaseFunction configuredTargetFunction,
       @Nullable SkylarkEnvironment ruleDefinitionEnvironment,
       Set<Class<?>> allowedConfigurationFragments, boolean failIfMissingConfigurationFragment,
       boolean supportsConstraintChecking,
@@ -1503,7 +1503,7 @@
   /**
    * Returns this RuleClass's custom Skylark rule implementation.
    */
-  @Nullable public Function getConfiguredTargetFunction() {
+  @Nullable public BaseFunction getConfiguredTargetFunction() {
     return configuredTargetFunction;
   }
 
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 14bdcd7..10a5674 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,7 +63,6 @@
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
 import com.google.devtools.build.lib.syntax.FuncallExpression;
-import com.google.devtools.build.lib.syntax.Function;
 import com.google.devtools.build.lib.syntax.FunctionSignature;
 import com.google.devtools.build.lib.syntax.Label;
 import com.google.devtools.build.lib.syntax.SkylarkCallbackFunction;
@@ -180,9 +179,9 @@
       "Creates a new rule. Store it in a global value, so that it can be loaded and called "
       + "from BUILD files.",
       onlyLoadingPhase = true,
-      returnType = Function.class,
+      returnType = BaseFunction.class,
       mandatoryPositionals = {
-        @Param(name = "implementation", type = Function.class,
+        @Param(name = "implementation", type = BaseFunction.class,
             doc = "the function implementing this rule, has to have exactly one parameter: "
             + "<code>ctx</code>. The function is called during analysis phase for each "
             + "instance of the rule. It can access the attributes provided by the user. "
@@ -215,7 +214,7 @@
   private static final BuiltinFunction rule = new BuiltinFunction("rule") {
       @SuppressWarnings({"rawtypes", "unchecked"}) // castMap produces
       // an Attribute.Builder instead of a Attribute.Builder<?> but it's OK.
-      public Function invoke(Function implementation, Boolean test,
+      public BaseFunction invoke(BaseFunction implementation, Boolean test,
           Object attrs, Object implicitOutputs, Boolean executable, Boolean outputToGenfiles,
           FuncallExpression ast, Environment funcallEnv)
            throws EvalException, ConversionException {
@@ -250,8 +249,8 @@
         }
 
         if (implicitOutputs != Environment.NONE) {
-          if (implicitOutputs instanceof Function) {
-            Function func = (Function) implicitOutputs;
+          if (implicitOutputs instanceof BaseFunction) {
+            BaseFunction func = (BaseFunction) implicitOutputs;
             final SkylarkCallbackFunction callback =
                 new SkylarkCallbackFunction(func, ast, (SkylarkEnvironment) funcallEnv);
             builder.setImplicitOutputsFunction(
diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
index f848f91..08d313a 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java
@@ -13,6 +13,7 @@
 // limitations under the License.
 package com.google.devtools.build.lib.rules;
 
+import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -29,12 +30,12 @@
 import com.google.devtools.build.lib.events.Location;
 import com.google.devtools.build.lib.packages.TargetUtils;
 import com.google.devtools.build.lib.packages.Type;
+import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.ClassObject;
 import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject;
 import com.google.devtools.build.lib.syntax.Environment;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.EvalUtils;
-import com.google.devtools.build.lib.syntax.Function;
 import com.google.devtools.build.lib.syntax.SkylarkEnvironment;
 import com.google.devtools.build.lib.syntax.SkylarkNestedSet;
 import com.google.devtools.build.lib.syntax.SkylarkType;
@@ -49,7 +50,7 @@
    * Create a Rule Configured Target from the ruleContext and the ruleImplementation.
    */
   public static ConfiguredTarget buildRule(RuleContext ruleContext,
-      Function ruleImplementation) {
+      BaseFunction ruleImplementation) {
     String expectError = ruleContext.attributes().get("expect_failure", Type.STRING);
     try {
       SkylarkRuleContext skylarkRuleContext = new SkylarkRuleContext(ruleContext);
@@ -96,12 +97,11 @@
     if (!orphanArtifacts.isEmpty()) {
       throw new EvalException(null, "The following files have no generating action:\n"
           + Joiner.on("\n").join(Iterables.transform(orphanArtifacts,
-          new com.google.common.base.Function<Artifact, String>() {
-            @Override
-            public String apply(Artifact artifact) {
-              return artifact.getRootRelativePathString();
-            }
-          })));
+        new Function<Artifact, String>() {
+          @Override
+          public String apply(Artifact artifact) {
+            return artifact.getRootRelativePathString();
+          }})));
     }
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java
index a5ddf3d..1385647 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java
@@ -38,8 +38,8 @@
 import com.google.devtools.build.lib.skyframe.PrecomputedValue.Injected;
 import com.google.devtools.build.lib.skyframe.SkyframeExecutor;
 import com.google.devtools.build.lib.skyframe.SkyframeExecutorFactory;
+import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.Environment;
-import com.google.devtools.build.lib.syntax.Function;
 import com.google.devtools.build.lib.syntax.Label;
 import com.google.devtools.build.lib.util.AbruptExitException;
 import com.google.devtools.build.lib.util.Clock;
@@ -359,8 +359,8 @@
       }
 
       @Override
-      public ImmutableList<Function> nativeModuleFunctions() {
-        return ImmutableList.<Function>of();
+      public ImmutableList<BaseFunction> nativeModuleFunctions() {
+        return ImmutableList.<BaseFunction>of();
       }
     };
   }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
index cd997ec..60c80a0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java
@@ -23,8 +23,8 @@
 import com.google.devtools.build.lib.packages.RuleClassProvider;
 import com.google.devtools.build.lib.packages.SkylarkNativeModule;
 import com.google.devtools.build.lib.skyframe.ASTFileLookupValue.ASTLookupInputException;
+import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.BuildFileAST;
-import com.google.devtools.build.lib.syntax.Function;
 import com.google.devtools.build.lib.syntax.Label;
 import com.google.devtools.build.lib.syntax.Label.SyntaxException;
 import com.google.devtools.build.lib.syntax.SkylarkEnvironment;
@@ -44,7 +44,7 @@
 public class SkylarkImportLookupFunction implements SkyFunction {
 
   private final RuleClassProvider ruleClassProvider;
-  private final ImmutableList<Function> nativeRuleFunctions;
+  private final ImmutableList<BaseFunction> nativeRuleFunctions;
 
   public SkylarkImportLookupFunction(
       RuleClassProvider ruleClassProvider, PackageFactory packageFactory) {
@@ -173,7 +173,7 @@
         .createSkylarkRuleClassEnvironment(eventHandler, ast.getContentHashCode());
     // Adding native rules module for build extensions.
     // TODO(bazel-team): this might not be the best place to do this.
-    for (Function function : nativeRuleFunctions) {
+    for (BaseFunction function : nativeRuleFunctions) {
         extensionEnv.registerFunction(
             SkylarkNativeModule.class, function.getName(), function);
     }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java
index c844893..9d22708 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java
@@ -29,11 +29,11 @@
 import com.google.devtools.build.lib.packages.RuleClass;
 import com.google.devtools.build.lib.packages.RuleFactory;
 import com.google.devtools.build.lib.packages.Type.ConversionException;
+import com.google.devtools.build.lib.syntax.BaseFunction;
 import com.google.devtools.build.lib.syntax.BuildFileAST;
 import com.google.devtools.build.lib.syntax.BuiltinFunction;
 import com.google.devtools.build.lib.syntax.EvalException;
 import com.google.devtools.build.lib.syntax.FuncallExpression;
-import com.google.devtools.build.lib.syntax.Function;
 import com.google.devtools.build.lib.syntax.FunctionSignature;
 import com.google.devtools.build.lib.syntax.Label;
 import com.google.devtools.build.lib.syntax.Label.SyntaxException;
@@ -197,7 +197,7 @@
 
     RuleFactory ruleFactory = new RuleFactory(packageFactory.getRuleClassProvider());
     for (String ruleClass : ruleFactory.getRuleClassNames()) {
-      Function ruleFunction = newRuleFunction(ruleFactory, builder, ruleClass);
+      BaseFunction ruleFunction = newRuleFunction(ruleFactory, builder, ruleClass);
       workspaceEnv.update(ruleClass, ruleFunction);
     }
 
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/AbstractFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/AbstractFunction.java
deleted file mode 100644
index 7ed6d07..0000000
--- a/src/main/java/com/google/devtools/build/lib/syntax/AbstractFunction.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2014 Google Inc. 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 java.util.List;
-import java.util.Map;
-
-/**
- * Partial implementation of Function interface.
- */
-public abstract class AbstractFunction implements Function {
-
-  private final String name;
-
-  protected AbstractFunction(String name) {
-    this.name = name;
-  }
-
-  /**
-   * Returns the name of this function.
-   */
-  @Override
-  public String getName() {
-    return name;
-  }
-
-  @Override
-  public Class<?> getObjectType() {
-    return null;
-  }
-
-  @Override public String toString() {
-    return name;
-  }
-
-  /**
-   * Abstract implementation of Function that accepts no parameters.
-   */
-  public abstract static class NoArgFunction extends AbstractFunction {
-
-    public NoArgFunction(String name) {
-      super(name);
-    }
-
-    @Override
-    public Object call(List<Object> args, Map<String, Object> kwargs, FuncallExpression ast,
-        Environment env) throws EvalException, InterruptedException {
-      if (args.size() != 1 || !kwargs.isEmpty()) {
-        throw new EvalException(ast.getLocation(), "Invalid number of arguments (expected 0)");
-      }
-      return call(args.get(0), ast, env);
-    }
-
-    public abstract Object call(Object self, FuncallExpression ast, Environment env)
-        throws EvalException, InterruptedException;
-  }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java
index f1b148f..253e7a8 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java
@@ -58,7 +58,7 @@
 // Provide optimized argument frobbing depending of FunctionSignature and CallerSignature
 // (that FuncallExpression must supply), optimizing for the all-positional and all-keyword cases.
 // Also, use better pure maps to minimize map O(n) re-creation events when processing keyword maps.
-public abstract class BaseFunction implements Function {
+public abstract class BaseFunction {
 
   // The name of the function
   private final String name;
@@ -405,7 +405,6 @@
    * @return the value resulting from evaluating the function with the given arguments
    * @throws construction of EvalException-s containing source information.
    */
-  @Override
   public Object call(@Nullable List<Object> args,
       @Nullable Map<String, Object> kwargs,
       @Nullable FuncallExpression ast,
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
index a4a4bce..ea00506 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Environment.java
@@ -71,8 +71,8 @@
 
   protected final Map<String, Object> env = new HashMap<>();
 
-  // Functions with namespaces. Works only in the global environment.
-  protected final Map<Class<?>, Map<String, Function>> functions = new HashMap<>();
+  // BaseFunctions with namespaces. Works only in the global environment.
+  protected final Map<Class<?>, Map<String, BaseFunction>> functions = new HashMap<>();
 
   /**
    * The parent environment. For Skylark it's the global environment,
@@ -303,15 +303,15 @@
   /**
    * Registers a function with namespace to this global environment.
    */
-  public void registerFunction(Class<?> nameSpace, String name, Function function) {
+  public void registerFunction(Class<?> nameSpace, String name, BaseFunction function) {
     Preconditions.checkArgument(parent == null);
     if (!functions.containsKey(nameSpace)) {
-      functions.put(nameSpace, new HashMap<String, Function>());
+      functions.put(nameSpace, new HashMap<String, BaseFunction>());
     }
     functions.get(nameSpace).put(name, function);
   }
 
-  private Map<String, Function> getNamespaceFunctions(Class<?> nameSpace) {
+  private Map<String, BaseFunction> getNamespaceFunctions(Class<?> nameSpace) {
     if (disabledNameSpaces.contains(nameSpace)
         || (parent != null && parent.disabledNameSpaces.contains(nameSpace))) {
       return null;
@@ -326,8 +326,8 @@
   /**
    * Returns the function of the namespace of the given name or null of it does not exists.
    */
-  public Function getFunction(Class<?> nameSpace, String name) {
-    Map<String, Function> nameSpaceFunctions = getNamespaceFunctions(nameSpace);
+  public BaseFunction getFunction(Class<?> nameSpace, String name) {
+    Map<String, BaseFunction> nameSpaceFunctions = getNamespaceFunctions(nameSpace);
     return nameSpaceFunctions != null ? nameSpaceFunctions.get(name) : null;
   }
 
@@ -335,7 +335,7 @@
    * Returns the function names registered with the namespace.
    */
   public Set<String> getFunctionNames(Class<?> nameSpace) {
-    Map<String, Function> nameSpaceFunctions = getNamespaceFunctions(nameSpace);
+    Map<String, BaseFunction> nameSpaceFunctions = getNamespaceFunctions(nameSpace);
     return nameSpaceFunctions != null ? nameSpaceFunctions.keySet() : ImmutableSet.<String>of();
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
index bef2b09..ca73ea4 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java
@@ -14,6 +14,7 @@
 package com.google.devtools.build.lib.syntax;
 
 import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
@@ -134,7 +135,7 @@
    *         dictionary key) according to the rules of the Build language.
    */
   public static boolean isImmutable(Object o) {
-    if (o instanceof Map<?, ?> || o instanceof Function
+    if (o instanceof Map<?, ?> || o instanceof BaseFunction
         || o instanceof FilesetEntry || o instanceof GlobList<?>) {
       return false;
     } else if (o instanceof List<?>) {
@@ -282,7 +283,7 @@
       return "glob list";
     } else if (Map.class.isAssignableFrom(c)) {
       return "dict";
-    } else if (Function.class.isAssignableFrom(c)) {
+    } else if (BaseFunction.class.isAssignableFrom(c)) {
       return "function";
     } else if (c.equals(FilesetEntry.class)) {
       return "FilesetEntry";
@@ -371,8 +372,8 @@
       }
       buffer.append(")");
 
-    } else if (o instanceof Function) {
-      Function func = (Function) o;
+    } else if (o instanceof BaseFunction) {
+      BaseFunction func = (BaseFunction) o;
       buffer.append("<function " + func.getName() + ">");
 
     } else if (o instanceof FilesetEntry) {
@@ -504,8 +505,7 @@
    * Pretty-print values of 'o' separated by the separator.
    */
   public static String prettyPrintValues(String separator, Iterable<Object> o) {
-    return Joiner.on(separator).join(Iterables.transform(o,
-        new com.google.common.base.Function<Object, String>() {
+    return Joiner.on(separator).join(Iterables.transform(o, new Function<Object, String>() {
       @Override
       public String apply(Object input) {
         return prettyPrintValue(input);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
index f32dcdf..b996588 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java
@@ -420,7 +420,7 @@
 
   @SuppressWarnings("unchecked")
   private void evalArguments(ImmutableList.Builder<Object> posargs, Map<String, Object> kwargs,
-      Environment env, Function function)
+      Environment env, BaseFunction function)
       throws EvalException, InterruptedException {
     ArgConversion conversion = getArgConversion(function);
     ImmutableList.Builder<String> duplicates = new ImmutableList.Builder<>();
@@ -473,7 +473,7 @@
     Map<String, Object> kwargs = new HashMap<>();
 
     Object returnValue;
-    Function function;
+    BaseFunction function;
     if (obj != null) { // obj.func(...)
       Object objValue = obj.eval(env);
       // Strings, lists and dictionaries (maps) have functions that we want to use in MethodLibrary.
@@ -513,8 +513,8 @@
       }
     } else { // func(...)
       Object funcValue = func.eval(env);
-      if ((funcValue instanceof Function)) {
-        function = (Function) funcValue;
+      if ((funcValue instanceof BaseFunction)) {
+        function = (BaseFunction) funcValue;
         evalArguments(posargs, kwargs, env, function);
         returnValue = function.call(
             posargs.build(), ImmutableMap.<String, Object>copyOf(kwargs), this, env);
@@ -534,7 +534,7 @@
     return returnValue;
   }
 
-  private ArgConversion getArgConversion(Function function) {
+  private ArgConversion getArgConversion(BaseFunction function) {
     if (function == null) {
       // It means we try to call a Java function.
       return ArgConversion.FROM_SKYLARK;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Function.java b/src/main/java/com/google/devtools/build/lib/syntax/Function.java
deleted file mode 100644
index 5636a95..0000000
--- a/src/main/java/com/google/devtools/build/lib/syntax/Function.java
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2014 Google Inc. 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 java.util.List;
-import java.util.Map;
-
-/**
- * Function values in the BUILD language.
- *
- * <p>Each implementation of this interface defines a function in the BUILD language.
- *
- */
-public interface Function {
-
-  /**
-   * Implements the behavior of a call to a function with positional arguments
-   * "args" and keyword arguments "kwargs". The "ast" argument is provided to
-   * allow construction of EvalExceptions containing source information.
-   */
-  Object call(List<Object> args,
-              Map<String, Object> kwargs,
-              FuncallExpression ast,
-              Environment env)
-      throws EvalException, InterruptedException;
-
-  /**
-   * Returns the name of the function.
-   */
-  String getName();
-
-  // TODO(bazel-team): implement this for MethodLibrary functions as well.
-  /**
-   * Returns the type of the object on which this function is defined or null
-   * if this is a global function.
-   */
-  Class<?> getObjectType();
-}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MixedModeFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/MixedModeFunction.java
deleted file mode 100644
index 0248331..0000000
--- a/src/main/java/com/google/devtools/build/lib/syntax/MixedModeFunction.java
+++ /dev/null
@@ -1,248 +0,0 @@
-// Copyright 2014 Google Inc. 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.base.Joiner;
-import com.google.common.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.packages.Type.ConversionException;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Abstract implementation of Function for functions that accept a mixture of
- * positional and keyword parameters, as in Python.
- */
-public abstract class MixedModeFunction extends AbstractFunction {
-
-  // Nomenclature:
-  // "Parameters" are formal parameters of a function definition.
-  // "Arguments" are actual parameters supplied at the call site.
-
-  // A function signature, including defaults and types
-  // never null after it is configured
-  protected FunctionSignature.WithValues<Object, SkylarkType> signature;
-
-  // Number of regular named parameters (excluding *p and **p) in the
-  // equivalent Python function definition).
-  private final List<String> parameters;
-
-  // Number of leading "parameters" which are mandatory
-  private final int numMandatoryParameters;
-
-  // True if this function requires all arguments to be named
-  // TODO(bazel-team): replace this by a count of arguments before the * with optional arg,
-  // in the style Python 3 or PEP 3102.
-  private final boolean onlyNamedArguments;
-
-  // Location of the function definition, or null for builtin functions.
-  protected final Location location;
-
-  /**
-   * Constructs an instance of Function that supports Python-style mixed-mode
-   * parameter passing.
-   *
-   * @param parameters a list of named parameters
-   * @param numMandatoryParameters the number of leading parameters which are
-   *        considered mandatory; the remaining ones may be omitted, in which
-   *        case they will have the default value of null.
-   */
-  public MixedModeFunction(String name,
-                           Iterable<String> parameters,
-                           int numMandatoryParameters,
-                           boolean onlyNamedArguments) {
-    this(name, parameters, numMandatoryParameters, onlyNamedArguments, null);
-  }
-
-  protected MixedModeFunction(String name,
-                              Iterable<String> parameters,
-                              int numMandatoryParameters,
-                              boolean onlyNamedArguments,
-                              Location location) {
-    super(name);
-    this.parameters = ImmutableList.copyOf(parameters);
-    this.numMandatoryParameters = numMandatoryParameters;
-    this.onlyNamedArguments = onlyNamedArguments;
-    this.location = location;
-
-    // Fake a signature from the above
-    this.signature = FunctionSignature.WithValues.<Object, SkylarkType>create(
-        FunctionSignature.of(numMandatoryParameters, this.parameters.toArray(new String[0])));
-  }
-
-
-  /** Create a function using a signature with defaults */
-  public MixedModeFunction(String name,
-      FunctionSignature.WithValues<Object, SkylarkType> signature,
-      Location location) {
-    super(name);
-
-    // TODO(bazel-team): lift the following limitations, by actually implementing
-    // the full function call protocol.
-    FunctionSignature sig = signature.getSignature();
-    FunctionSignature.Shape shape = sig.getShape();
-    Preconditions.checkArgument(!shape.hasKwArg() && !shape.hasStarArg()
-        && shape.getNamedOnly() == 0, "no star, star-star or named-only parameters (for now)");
-
-    this.signature = signature;
-    this.parameters = ImmutableList.copyOf(sig.getNames());
-    this.numMandatoryParameters = shape.getMandatoryPositionals();
-    this.onlyNamedArguments = false;
-    this.location = location;
-  }
-
-  /** Create a function using a signature without defaults */
-  public MixedModeFunction(String name, FunctionSignature signature) {
-    this(name, FunctionSignature.WithValues.<Object, SkylarkType>create(signature), null);
-  }
-
-  // TODO(bazel-team): find a home for this function, maybe a better implementation.
-  private static <E> ArrayList<E> listDifference (List<E> plus, List<E> minus) {
-    final ArrayList<E> list = new ArrayList<>();
-    list.addAll(plus);
-    list.removeAll(minus);
-    return list;
-  }
-
-  @Override
-  public Object call(List<Object> args,
-                     Map<String, Object> kwargs,
-                     FuncallExpression ast,
-                     Environment env)
-      throws EvalException, InterruptedException {
-
-    // ast is null when called from Java (as there's no Skylark call site).
-    Location loc = ast == null ? location : ast.getLocation();
-    if (onlyNamedArguments && !args.isEmpty()) {
-      throw new EvalException(loc,
-          getSignature() + " does not accept positional arguments");
-    }
-
-    if (kwargs == null) {
-      kwargs = ImmutableMap.<String, Object>of();
-    }
-
-    int numParams = parameters.size();
-    int numArgs = args.size();
-    Object[] namedArguments = new Object[numParams];
-
-    // first, positional arguments:
-    if (numArgs > numParams) {
-      throw new EvalException(loc,
-          "too many positional arguments in call to " + getSignature());
-    }
-    for (int ii = 0; ii < numArgs; ++ii) {
-      namedArguments[ii] = args.get(ii);
-    }
-
-    // TODO(bazel-team): here, support *varargs splicing
-
-    // second, keyword arguments:
-    for (Map.Entry<String, Object> entry : kwargs.entrySet()) {
-      String keyword = entry.getKey();
-      int pos = parameters.indexOf(keyword);
-      if (pos == -1) {
-        List<String> unexpected =
-            listDifference(new ArrayList<>(kwargs.keySet()), parameters);
-        Collections.sort(unexpected); // issue stable error messages.
-        throw new EvalException(loc,
-            "unexpected keyword" + (unexpected.size() > 1 ? "s" : "") + " '"
-            + Joiner.on("', '").join(unexpected)
-            + "' in call to " + getSignature());
-      } else {
-        if (namedArguments[pos] != null) {
-          throw new EvalException(loc, getSignature()
-              + " got multiple values for keyword argument '" + keyword + "'");
-        }
-        namedArguments[pos] = kwargs.get(keyword);
-      }
-    }
-
-    // third, check mandatory parameters:
-    for (int ii = 0; ii < numMandatoryParameters; ++ii) {
-      if (namedArguments[ii] == null) {
-        throw new EvalException(loc,
-            getSignature() + " received insufficient arguments");
-      }
-    }
-
-    // fourth, fill in defaults from the signature, if any
-    List<Object> defaults = signature.getDefaultValues();
-    if (defaults != null) {
-      int jj = 0;
-      for (int ii = numMandatoryParameters; ii < numParams; ++ii) {
-        if (namedArguments[ii] == null) {
-          namedArguments[ii] = defaults.get(jj);
-        }
-        jj++;
-      }
-    }
-
-    try {
-      return call(namedArguments, ast, env);
-    } catch (ConversionException | IllegalArgumentException | IllegalStateException
-        | ClassCastException e) {
-      throw new EvalException(loc, e.getMessage());
-    }
-  }
-
-  /**
-   * Like Function.call, but generalised to support Python-style mixed-mode
-   * keyword and positional parameter passing.
-   *
-   * @param args an array of argument values corresponding to the list
-   *        of named parameters passed to the constructor.
-   */
-  protected Object call(Object[] args, FuncallExpression ast)
-      throws EvalException, ConversionException, InterruptedException {
-    throw new UnsupportedOperationException("Method not overridden");
-  }
-
-  /**
-   * Override this method instead of the one above, if you need to access
-   * the environment.
-   */
-  protected Object call(Object[] args, FuncallExpression ast, Environment env)
-      throws EvalException, ConversionException, InterruptedException {
-    return call(args, ast);
-  }
-
-  /**
-   * Render this object in the form of an equivalent Python function signature.
-   */
-  public String getSignature() {
-    StringBuilder sb = new StringBuilder();
-    sb.append(getName()).append('(');
-    int ii = 0;
-    int len = parameters.size();
-    for (; ii < len; ++ii) {
-      String parameter = parameters.get(ii);
-      if (ii > 0) {
-        sb.append(", ");
-      }
-      sb.append(parameter);
-      if (ii >= numMandatoryParameters) {
-        sb.append(" = null");
-      }
-    }
-    sb.append(')');
-    return sb.toString();
-  }
-
-}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java
index bff06d5..94b1917 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java
@@ -20,11 +20,11 @@
  */
 public class SkylarkCallbackFunction {
 
-  private final Function callback;
+  private final BaseFunction callback;
   private final FuncallExpression ast;
   private final SkylarkEnvironment funcallEnv;
 
-  public SkylarkCallbackFunction(Function callback, FuncallExpression ast,
+  public SkylarkCallbackFunction(BaseFunction callback, FuncallExpression ast,
       SkylarkEnvironment funcallEnv) {
     this.callback = callback;
     this.ast = ast;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java
index 11e3522..087bdc4 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java
@@ -123,7 +123,7 @@
     for (Entry<String, Object> entry : env.entrySet()) {
       newEnv.env.put(entry.getKey(), entry.getValue());
     }
-    for (Map.Entry<Class<?>, Map<String, Function>> functionMap : functions.entrySet()) {
+    for (Map.Entry<Class<?>, Map<String, BaseFunction>> functionMap : functions.entrySet()) {
       newEnv.functions.put(functionMap.getKey(), functionMap.getValue());
     }
     return newEnv;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkFunction.java
deleted file mode 100644
index c90a4ef..0000000
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkFunction.java
+++ /dev/null
@@ -1,254 +0,0 @@
-// Copyright 2014 Google Inc. 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.base.Preconditions;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.lib.events.Location;
-import com.google.devtools.build.lib.packages.Type.ConversionException;
-import com.google.devtools.build.lib.syntax.EvalException.EvalExceptionWithJavaCause;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.ExecutionException;
-
-/**
- * A function class for Skylark built in functions. Supports mandatory and optional arguments.
- * All usable arguments have to be specified. In case of ambiguous arguments (a parameter is
- * specified as positional and keyword arguments in the function call) an exception is thrown.
- */
-public abstract class SkylarkFunction extends BaseFunction {
-
-  private ImmutableList<String> parameters;
-  private ImmutableMap<String, SkylarkSignature.Param> parameterTypes;
-  private int mandatoryParamNum;
-  private boolean configured = false;
-  private Class<?> objectType;
-  private boolean onlyLoadingPhase;
-
-  /**
-   * Creates a SkylarkFunction with the given name.
-   */
-  public SkylarkFunction(String name) {
-    super(name);
-  }
-
-  /**
-   * Configures the parameter of this Skylark function using the annotation.
-   */
-  public void configure(SkylarkSignature annotation) {
-    Preconditions.checkState(!configured);
-    Preconditions.checkArgument(
-        getName().equals(annotation.name()), "%s != %s", getName(), annotation.name());
-    Preconditions.checkArgument(
-        annotation.optionalPositionals().length == 0 || annotation.mandatoryNamedOnly().length == 0,
-        "SkylarkFunction %s: forbidden simultaneous optionalPositionals and mandatoryNamedOnly",
-        getName());
-    Preconditions.checkArgument(
-        annotation.extraPositionals().length == 0 && annotation.extraKeywords().length == 0,
-        "SkylarkFunction %s: forbidden extra arguments", getName());
-    mandatoryParamNum = 0;
-    ImmutableList.Builder<String> paramListBuilder = ImmutableList.builder();
-    ImmutableMap.Builder<String, SkylarkSignature.Param> paramTypeBuilder = ImmutableMap.builder();
-    for (SkylarkSignature.Param param : annotation.mandatoryPositionals()) {
-      if (!param.name().equals("self")) {
-        paramListBuilder.add(param.name());
-        paramTypeBuilder.put(param.name(), param);
-        mandatoryParamNum++;
-      }
-    }
-    for (SkylarkSignature.Param param : annotation.optionalPositionals()) {
-      paramListBuilder.add(param.name());
-      paramTypeBuilder.put(param.name(), param);
-    }
-    for (SkylarkSignature.Param param : annotation.mandatoryNamedOnly()) {
-      paramListBuilder.add(param.name());
-      paramTypeBuilder.put(param.name(), param);
-      mandatoryParamNum++;
-    }
-    for (SkylarkSignature.Param param : annotation.optionalNamedOnly()) {
-      paramListBuilder.add(param.name());
-      paramTypeBuilder.put(param.name(), param);
-    }
-    parameters = paramListBuilder.build();
-    parameterTypes = paramTypeBuilder.build();
-    this.objectType = annotation.objectType().equals(Object.class) ? null : annotation.objectType();
-    this.onlyLoadingPhase = annotation.onlyLoadingPhase();
-    configured = true;
-  }
-
-  /**
-   * Returns true if the SkylarkFunction is configured.
-   */
-  public boolean isConfigured() {
-    return configured;
-  }
-
-  @Override
-  public Class<?> getObjectType() {
-    return objectType;
-  }
-
-  public boolean isOnlyLoadingPhase() {
-    return onlyLoadingPhase;
-  }
-
-  @Override
-  public Object call(List<Object> args,
-                     Map<String, Object> kwargs,
-                     FuncallExpression ast,
-                     Environment env)
-      throws EvalException, InterruptedException {
-    Preconditions.checkState(configured, "Function %s was not configured", getName());
-    try {
-      ImmutableMap.Builder<String, Object> arguments = new ImmutableMap.Builder<>();
-      if (objectType != null && !FuncallExpression.isNamespace(objectType)) {
-        args = new ArrayList<>(args); // args immutable, get a mutable copy.
-        arguments.put("self", args.remove(0));
-      }
-
-      int maxParamNum = parameters.size();
-      int paramNum = args.size() + kwargs.size();
-
-      if (paramNum < mandatoryParamNum) {
-        throw new EvalException(ast.getLocation(),
-            String.format("incorrect number of arguments (got %s, expected at least %s)",
-                paramNum, mandatoryParamNum));
-      } else if (paramNum > maxParamNum) {
-        throw new EvalException(ast.getLocation(),
-            String.format("incorrect number of arguments (got %s, expected at most %s)",
-                paramNum, maxParamNum));
-      }
-
-      for (int i = 0; i < mandatoryParamNum; i++) {
-        Preconditions.checkState(i < args.size() || kwargs.containsKey(parameters.get(i)),
-            String.format("missing mandatory parameter: %s", parameters.get(i)));
-      }
-
-      for (int i = 0; i < args.size(); i++) {
-        checkTypeAndAddArg(parameters.get(i), args.get(i), arguments, ast.getLocation());
-      }
-
-      for (Entry<String, Object> kwarg : kwargs.entrySet()) {
-        int idx = parameters.indexOf(kwarg.getKey());
-        if (idx < 0) {
-          throw new EvalException(ast.getLocation(),
-              String.format("unknown keyword argument: %s", kwarg.getKey()));
-        }
-        if (idx < args.size()) {
-          throw new EvalException(ast.getLocation(),
-              String.format("ambiguous argument: %s", kwarg.getKey()));
-        }
-        checkTypeAndAddArg(kwarg.getKey(), kwarg.getValue(), arguments, ast.getLocation());
-      }
-
-      return call(arguments.build(), ast, env);
-    } catch (ConversionException | IllegalArgumentException | IllegalStateException
-        | ClassCastException | ClassNotFoundException | ExecutionException e) {
-      if (e.getMessage() != null) {
-        throw new EvalException(ast.getLocation(), e.getMessage());
-      } else {
-        // TODO(bazel-team): ideally this shouldn't happen, however we need this for debugging
-        throw new EvalExceptionWithJavaCause(ast.getLocation(), e);
-      }
-    }
-  }
-
-  private void checkTypeAndAddArg(String paramName, Object value,
-      ImmutableMap.Builder<String, Object> arguments, Location loc) throws EvalException {
-    SkylarkSignature.Param param = parameterTypes.get(paramName);
-    if (param.callbackEnabled() && value instanceof Function) {
-      // If we pass a function as an argument we trust the Function implementation with the type
-      // check. It's OK since the function needs to be called manually anyway.
-      arguments.put(paramName, value);
-      return;
-    }
-    checkType(getName(), paramName, SkylarkType.of(param.type(), param.generic1()),
-        value, loc, param.doc());
-    arguments.put(paramName, value);
-  }
-
-  public static void checkType(String functionName, String paramName,
-      SkylarkType type, Object value, Location loc, String paramDoc) throws EvalException {
-    if (type != null && value != null) { // TODO(bazel-team): should we give a pass to NONE here?
-      if (!type.contains(value)) {
-        throw new EvalException(loc, String.format(
-            "expected %s for '%s' while calling %s but got %s instead: %s",
-            type, paramName, functionName, EvalUtils.getDataTypeName(value, true), value));
-      }
-    }
-  }
-
-  /**
-   * The actual function call. All positional and keyword arguments are put in the
-   * arguments map.
-   */
-  protected abstract Object call(
-      Map<String, Object> arguments, FuncallExpression ast, Environment env) throws EvalException,
-      ConversionException,
-      IllegalArgumentException,
-      IllegalStateException,
-      InterruptedException,
-      ClassCastException,
-      ClassNotFoundException,
-      ExecutionException;
-
-  /**
-   * An intermediate class to provide a simpler interface for Skylark functions.
-   */
-  public abstract static class SimpleSkylarkFunction extends SkylarkFunction {
-
-    public SimpleSkylarkFunction(String name) {
-      super(name);
-    }
-
-    @Override
-    protected final Object call(
-        Map<String, Object> arguments, FuncallExpression ast, Environment env) throws EvalException,
-        ConversionException,
-        IllegalArgumentException,
-        IllegalStateException,
-        ClassCastException,
-        ExecutionException {
-      return call(arguments, ast.getLocation());
-    }
-
-    /**
-     * The actual function call. All positional and keyword arguments are put in the
-     * arguments map.
-     */
-    protected abstract Object call(Map<String, Object> arguments, Location loc)
-        throws EvalException,
-        ConversionException,
-        IllegalArgumentException,
-        IllegalStateException,
-        ClassCastException,
-        ExecutionException;
-  }
-
-  // TODO(bazel-team): this is only used in MixedModeFunctions in MethodLibrary, migrate those
-  // to SkylarkFunction then remove this.
-  public static <TYPE> TYPE cast(Object elem, Class<TYPE> type, String what, Location loc)
-      throws EvalException {
-    try {
-      return type.cast(elem);
-    } catch (ClassCastException e) {
-      throw new EvalException(loc, String.format("expected %s for '%s' but got %s instead",
-          EvalUtils.getDataTypeNameFromClass(type), what, EvalUtils.getDataTypeName(elem)));
-    }
-  }
-}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
index f07fd61..b6c3767 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java
@@ -492,7 +492,7 @@
       return LIST;
     } else if (SkylarkNestedSet.class.isAssignableFrom(type)) {
       return SET;
-    } else if (Function.class.isAssignableFrom(type)) {
+    } else if (BaseFunction.class.isAssignableFrom(type)) {
       return new SkylarkFunctionType("unknown", TOP);
     } else {
       return Simple.of(type);
@@ -533,7 +533,7 @@
       }
     }
     @Override public Class<?> getType() {
-      return Function.class;
+      return BaseFunction.class;
     }
     @Override public String toString() {
       return (returnType == TOP || returnType == null ? "" : returnType + "-returning ")
@@ -542,7 +542,7 @@
 
     public boolean contains(Object value) {
       // This returns true a bit too much, not looking at the result type.
-      return value instanceof Function;
+      return value instanceof BaseFunction;
     }
 
     public static SkylarkFunctionType of(String name) {
@@ -839,7 +839,7 @@
    * Creates a SkylarkType from the SkylarkSignature annotation.
    */
   public static SkylarkType getReturnType(SkylarkSignature annotation) {
-    if (Function.class.isAssignableFrom(annotation.returnType())) {
+    if (BaseFunction.class.isAssignableFrom(annotation.returnType())) {
       return SkylarkFunctionType.of(annotation.name());
     } else {
       return Simple.of(annotation.returnType());
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java b/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java
deleted file mode 100644
index b45e951..0000000
--- a/src/test/java/com/google/devtools/build/lib/syntax/MixedModeFunctionTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2006-2015 Google Inc. 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 static com.google.common.truth.Truth.assertThat;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
-import com.google.common.collect.ImmutableList;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.Arrays;
-
-/**
- * Tests for {@link MixedModeFunction}.
- */
-@RunWith(JUnit4.class)
-public class MixedModeFunctionTest extends EvaluationTestCase {
-
-  /**
-   * Handy implementation of {@link MixedModeFunction} that just tuples up its args and returns
-   * them.
-   */
-  private static class TestingMixedModeFunction extends MixedModeFunction {
-    TestingMixedModeFunction(Iterable<String> parameters,
-                             int numMandatoryParameters,
-                             boolean onlyNamedArguments) {
-      super("mixed", parameters, numMandatoryParameters, onlyNamedArguments);
-    }
-    @Override
-    public Object call(Object[] namedParameters, FuncallExpression ast) {
-      return Arrays.asList(namedParameters);
-    }
-  }
-
-  private void checkMixedMode(Function func,
-                              String callExpression,
-                              String expectedOutput) throws Exception {
-    setUp();
-    update(func.getName(), func);
-
-    if (expectedOutput.charAt(0) == '[') { // a tuple => expected to pass
-      assertEquals(expectedOutput,
-                   eval(callExpression).toString());
-    } else { // expected to fail with an exception
-      try {
-        eval(callExpression);
-        fail();
-      } catch (EvalException e) {
-        assertThat(e).hasMessage(expectedOutput);
-      }
-    }
-  }
-
-  private static final String[] mixedModeExpressions = {
-    "mixed()",
-    "mixed(1)",
-    "mixed(1, 2)",
-    "mixed(1, 2, 3)",
-    "mixed(1, 2, wiz=3, quux=4)",
-    "mixed(foo=1)",
-    "mixed(foo=1, bar=2)",
-    "mixed(bar=2, foo=1)",
-    "mixed(2, foo=1)",
-    "mixed(bar=2, foo=1, wiz=3)",
-  };
-
-  public void checkMixedModeFunctions(boolean onlyNamedArguments,
-                                      String expectedSignature,
-                                      String[] expectedResults)
-      throws Exception {
-    MixedModeFunction func =
-        new TestingMixedModeFunction(ImmutableList.of("foo", "bar"), 1, onlyNamedArguments);
-
-    assertEquals(expectedSignature, func.getSignature());
-
-    for (int ii = 0; ii < mixedModeExpressions.length; ++ii) {
-      String expr = mixedModeExpressions[ii];
-      String expected = expectedResults[ii];
-      checkMixedMode(func, expr, expected);
-    }
-  }
-
-  @Test
-  public void testNoSurplusArguments() throws Exception {
-    checkMixedModeFunctions(false,
-                            "mixed(foo, bar = null)",
-                            new String[]
-      {
-        "mixed(foo, bar = null) received insufficient arguments",
-        "[1, null]",
-        "[1, 2]",
-        "too many positional arguments in call to mixed(foo, bar = null)",
-        "unexpected keywords 'quux', 'wiz' in call to mixed(foo, bar = null)",
-        "[1, null]",
-        "[1, 2]",
-        "[1, 2]",
-        "mixed(foo, bar = null) got multiple values for keyword"
-        + " argument 'foo'",
-        "unexpected keyword 'wiz' in call to mixed(foo, bar = null)",
-      });
-  }
-
-  @Test
-  public void testOnlyNamedArguments() throws Exception {
-    checkMixedModeFunctions(true,
-                            "mixed(foo, bar = null)",
-                            new String[]
-      {
-        "mixed(foo, bar = null) received insufficient arguments",
-        "mixed(foo, bar = null) does not accept positional arguments",
-        "mixed(foo, bar = null) does not accept positional arguments",
-        "mixed(foo, bar = null) does not accept positional arguments",
-        "mixed(foo, bar = null) does not accept positional arguments",
-        "[1, null]",
-        "[1, 2]",
-        "[1, 2]",
-        "mixed(foo, bar = null) does not accept positional arguments",
-        "unexpected keyword 'wiz' in call to mixed(foo, bar = null)",
-      });
-  }
-}