aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com
diff options
context:
space:
mode:
authorGravatar Francois-Rene Rideau <tunes@google.com>2015-04-22 16:52:13 +0000
committerGravatar Laszlo Csomor <laszlocsomor@google.com>2015-04-23 09:11:04 +0000
commit95b0d0cc209fbff23938910c12f84bdbef73eb68 (patch)
tree6697e7e1bf0fdcd25bd931b69804aa315e551b2d /src/main/java/com
parentc857853cb0c0e4f13fd7890dec0d4d734c947932 (diff)
Remove old Skylark Function hierarchy
Last step in refactoring of Skylark builtin functions. -- MOS_MIGRATED_REVID=91796746
Diffstat (limited to 'src/main/java/com')
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/MethodLibrary.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/PackageFactory.java13
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/RuleClass.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleConfiguredTargetBuilder.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/runtime/BlazeModule.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/AbstractFunction.java68
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/BaseFunction.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Environment.java16
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/EvalUtils.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/FuncallExpression.java10
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/Function.java49
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/MixedModeFunction.java248
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkCallbackFunction.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkEnvironment.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkFunction.java254
-rw-r--r--src/main/java/com/google/devtools/build/lib/syntax/SkylarkType.java8
19 files changed, 74 insertions, 695 deletions
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 9d7faa82da..55d5bb5758 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.common.collect.Ordering;
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.Environment;
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 @@ public class MethodLibrary {
+ "</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 @@ public class MethodLibrary {
}
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 @@ public class MethodLibrary {
* 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 b4d4a6df17..4d7b71f19b 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.EvalException;
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 @@ public final class PackageFactory {
/**
* 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 @@ public final class PackageFactory {
* 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 @@ public final class PackageFactory {
* 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 @@ public final class PackageFactory {
* 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 @@ public final class PackageFactory {
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 c604fff3e2..93a0165d45 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.common.collect.Ordering;
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 @@ public final class RuleClass {
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 @@ public final class RuleClass {
/**
* 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 @@ public final class RuleClass {
/**
* 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 @@ public final class RuleClass {
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 @@ public final class RuleClass {
/**
* 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 14bdcd7bbc..10a567467a 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.Environment.NoSuchVariableException;
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 @@ public class SkylarkRuleClassFunctions {
"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 @@ public class SkylarkRuleClassFunctions {
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 @@ public class SkylarkRuleClassFunctions {
}
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 f848f91c2e..08d313a8c4 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.collect.nestedset.NestedSetBuilder;
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 @@ public final class SkylarkRuleConfiguredTargetBuilder {
* 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 @@ public final class SkylarkRuleConfiguredTargetBuilder {
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 a5ddf3d15e..1385647615 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.DiffAwareness;
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 @@ public abstract class BlazeModule {
}
@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 cd997ec8f7..60c80a04ba 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.PackageIdentifier.RepositoryName;
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 @@ import java.util.Map;
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 @@ public class SkylarkImportLookupFunction implements SkyFunction {
.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 c8448930b2..9d2270864c 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.PackageFactory;
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 @@ public class WorkspaceFileFunction implements SkyFunction {
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 7ed6d078b0..0000000000
--- 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 f1b148f442..253e7a8603 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 @@ import javax.annotation.Nullable;
// 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 @@ public abstract class BaseFunction implements Function {
* @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 a4a4bce771..ea0050698c 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 @@ public class Environment {
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 @@ public class Environment {
/**
* 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 @@ public class Environment {
/**
* 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 @@ public class Environment {
* 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 bef2b09c90..ca73ea4455 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 @@ public abstract class EvalUtils {
* 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 @@ public abstract class EvalUtils {
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 @@ public abstract class EvalUtils {
}
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 @@ public abstract class EvalUtils {
* 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 f32dcdf9ce..b996588822 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 @@ public final class FuncallExpression extends Expression {
@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 @@ public final class FuncallExpression extends Expression {
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 @@ public final class FuncallExpression extends Expression {
}
} 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 @@ public final class FuncallExpression extends Expression {
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 5636a957b1..0000000000
--- 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 024833120d..0000000000
--- 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 bff06d5348..94b1917ab6 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 @@ import com.google.common.collect.ImmutableList;
*/
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 11e35227b7..087bdc448d 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 @@ public class SkylarkEnvironment extends Environment implements Serializable {
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 c90a4efbeb..0000000000
--- 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 f07fd61914..b6c3767e42 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 @@ public abstract class SkylarkType {
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 @@ public abstract class SkylarkType {
}
}
@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 abstract class SkylarkType {
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 @@ public abstract class SkylarkType {
* 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());