diff options
author | 2015-04-22 16:52:13 +0000 | |
---|---|---|
committer | 2015-04-23 09:11:04 +0000 | |
commit | 95b0d0cc209fbff23938910c12f84bdbef73eb68 (patch) | |
tree | 6697e7e1bf0fdcd25bd931b69804aa315e551b2d /src/main/java/com | |
parent | c857853cb0c0e4f13fd7890dec0d4d734c947932 (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')
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()); |