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)",
- });
- }
-}