bazel syntax: delete SkylarkSignature and its machinery
We lose documentation of True and False
and the long-deprecated PACKAGE_NAME and REPOSITORY_NAME.
This is no great loss.
BEGIN_PUBLIC
bazel syntax: delete SkylarkSignature
END_PUBLIC
PiperOrigin-RevId: 279401209
diff --git a/src/main/java/com/google/devtools/build/docgen/ApiExporter.java b/src/main/java/com/google/devtools/build/docgen/ApiExporter.java
index c9743ba..427baf69 100644
--- a/src/main/java/com/google/devtools/build/docgen/ApiExporter.java
+++ b/src/main/java/com/google/devtools/build/docgen/ApiExporter.java
@@ -151,8 +151,7 @@
private static Value.Builder valueFromMethodDescriptor(MethodDescriptor descriptor) {
SkylarkSignatureProcessor.SignatureInfo info =
- SkylarkSignatureProcessor.getSignatureForCallable(
- descriptor.getName(), descriptor, null, null);
+ SkylarkSignatureProcessor.getSignatureForCallable(descriptor);
return collectFunctionInfo(descriptor.getName(), info.signature, info.defaultValues);
}
diff --git a/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java b/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java
index a876bec..8cad380 100644
--- a/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java
+++ b/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java
@@ -15,7 +15,6 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
-import com.google.devtools.build.docgen.skylark.SkylarkBuiltinMethodDoc;
import com.google.devtools.build.docgen.skylark.SkylarkConstructorMethodDoc;
import com.google.devtools.build.docgen.skylark.SkylarkJavaMethodDoc;
import com.google.devtools.build.docgen.skylark.SkylarkModuleDoc;
@@ -24,10 +23,8 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.CallUtils;
-import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.TreeMap;
@@ -80,8 +77,6 @@
if (candidateClass.isAnnotationPresent(SkylarkGlobalLibrary.class)) {
collectGlobalLibraryMethods(candidateClass, modules);
}
- // Use of SkylarkSignature fields is deprecated, but not all uses have been migrated.
- collectSkylarkSignatureFunctions(candidateClass, modules);
}
// 3. Add all constructors.
@@ -218,31 +213,6 @@
}
}
- /**
- * Adds {@link SkylarkBuiltinMethodDoc} entries to the top level module, one for
- * each @SkylarkSignature-annotated field defined in the given {@code moduleClass}.
- *
- * <p>Note that use of SkylarkSignature fields is deprecated, but not all uses have been migrated.
- */
- private static void collectSkylarkSignatureFunctions(
- Class<?> moduleClass, Map<String, SkylarkModuleDoc> modules) {
-
- SkylarkModuleDoc topLevelModuleDoc = getTopLevelModuleDoc(modules);
-
- // Collect any fields annotated with @SkylarkSignature, even if the class isn't
- // annotated.
- for (Field field : moduleClass.getDeclaredFields()) {
- if (field.isAnnotationPresent(SkylarkSignature.class)) {
- SkylarkSignature skylarkSignature = field.getAnnotation(SkylarkSignature.class);
- Preconditions.checkState(skylarkSignature.objectType() == Object.class);
-
- topLevelModuleDoc.addMethod(
- new SkylarkBuiltinMethodDoc(
- getTopLevelModuleDoc(modules), skylarkSignature, field.getType()));
- }
- }
- }
-
private static void collectConstructor(
Map<String, SkylarkModuleDoc> modules,
Class<?> moduleClass,
diff --git a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkBuiltinMethodDoc.java b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkBuiltinMethodDoc.java
deleted file mode 100644
index 5c0ba8e..0000000
--- a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkBuiltinMethodDoc.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.docgen.skylark;
-
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
-import com.google.devtools.build.lib.syntax.BaseFunction;
-import com.google.devtools.build.lib.syntax.EvalUtils;
-import java.util.List;
-
-/** A class representing a Skylark built-in object or method. */
-@Deprecated
-public final class SkylarkBuiltinMethodDoc extends SkylarkMethodDoc {
- private final SkylarkModuleDoc module;
- private final SkylarkSignature annotation;
- private final Class<?> fieldClass;
- private List<SkylarkParamDoc> params;
-
- public SkylarkBuiltinMethodDoc(SkylarkModuleDoc module, SkylarkSignature annotation,
- Class<?> fieldClass) {
- this.module = module;
- this.annotation = annotation;
- this.fieldClass = fieldClass;
- this.params =
- SkylarkDocUtils.determineParams(
- this,
- withoutSelfParam(annotation),
- annotation.extraPositionals(),
- annotation.extraKeywords());
- }
-
- @Override
- public boolean isDeprecated() {
- return false;
- }
-
- public SkylarkSignature getAnnotation() {
- return annotation;
- }
-
- @Override
- public boolean documented() {
- return annotation.documented();
- }
-
- @Override
- public String getName() {
- return annotation.name();
- }
-
- @Override
- public String getDocumentation() {
- return SkylarkDocUtils.substituteVariables(annotation.doc());
- }
-
- /**
- * Returns a string representing the method signature with links to the types if
- * available.
- *
- * <p>If the built-in method is a function, the construct the method signature. Otherwise,
- * return a string containing the return type of the method.
- */
- @Override
- public String getSignature() {
- if (BaseFunction.class.isAssignableFrom(fieldClass)) {
- return getSignature(module.getName(), annotation);
- }
- if (!annotation.returnType().equals(Object.class)) {
- return getTypeAnchor(annotation.returnType());
- }
- return "";
- }
-
- @Override
- public String getReturnType() {
- return EvalUtils.getDataTypeNameFromClass(annotation.returnType());
- }
-
- @Override
- public Boolean isCallable() {
- return BaseFunction.class.isAssignableFrom(fieldClass);
- }
-
- @Override
- public List<SkylarkParamDoc> getParams() {
- return params;
- }
-}
diff --git a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java
index 12072d2..d2f8d39 100644
--- a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java
+++ b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkDoc.java
@@ -19,8 +19,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
-import com.google.devtools.build.lib.syntax.CallUtils;
import com.google.devtools.build.lib.syntax.EvalUtils;
import com.google.devtools.build.lib.syntax.Runtime.NoneType;
import com.google.devtools.build.lib.syntax.SkylarkList;
@@ -83,22 +81,6 @@
}
// Omit self parameter from parameters in class methods.
- protected static Param[] withoutSelfParam(SkylarkSignature annotation) {
- Param[] params = annotation.parameters();
- if (params.length > 0
- && !params[0].named()
- && (params[0].defaultValue() != null && params[0].defaultValue().isEmpty())
- && params[0].positional()
- && annotation.objectType() != Object.class
- && !CallUtils.isNamespace(annotation.objectType())) {
- // Skip the self parameter, which is the first mandatory positional parameter.
- return Arrays.copyOfRange(params, 1, params.length);
- } else {
- return params;
- }
- }
-
- // Omit self parameter from parameters in class methods.
protected static Param[] withoutSelfParam(SkylarkCallable annotation, Method method) {
Param[] params = annotation.parameters();
if (params.length > 0) {
diff --git a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkMethodDoc.java b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkMethodDoc.java
index d7c2057..d40d643 100644
--- a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkMethodDoc.java
+++ b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkMethodDoc.java
@@ -18,7 +18,6 @@
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
@@ -115,37 +114,6 @@
getTypeAnchor(method.getReturnType()), fullyQualifiedMethodName, args);
}
- protected String getSignature(String objectName, SkylarkSignature method) {
- List<String> argList = new ArrayList<>();
- boolean named = false;
- for (Param param : withoutSelfParam(method)) {
- if (param.named() && !param.positional() && !named) {
- named = true;
- if (!method.extraPositionals().name().isEmpty()) {
- argList.add("*" + method.extraPositionals().name());
- }
- if (!argList.isEmpty()) {
- argList.add("*");
- }
- }
- argList.add(formatParameter(param));
- }
- if (!named && !method.extraPositionals().name().isEmpty()) {
- argList.add("*" + method.extraPositionals().name());
- }
- if (!method.extraKeywords().name().isEmpty()) {
- argList.add("**" + method.extraKeywords().name());
- }
- String args = "(" + Joiner.on(", ").join(argList) + ")";
- if (!objectName.equals(TOP_LEVEL_ID)) {
- return String.format("%s %s.%s%s\n",
- getTypeAnchor(method.returnType()), objectName, method.name(), args);
- } else {
- return String.format("%s %s%s\n",
- getTypeAnchor(method.returnType()), method.name(), args);
- }
- }
-
private String formatParameter(Param param) {
String defaultValue = param.defaultValue();
String name = param.name();
diff --git a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkModuleDoc.java b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkModuleDoc.java
index 999f583..4a59a17 100644
--- a/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkModuleDoc.java
+++ b/src/main/java/com/google/devtools/build/docgen/skylark/SkylarkModuleDoc.java
@@ -20,24 +20,20 @@
import com.google.common.collect.Multimap;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.skylarkinterface.StarlarkDeprecated;
import java.text.Collator;
import java.util.Collection;
import java.util.Locale;
-import java.util.Map;
import java.util.TreeMap;
import javax.annotation.Nullable;
/**
* A class representing documentation for a Skylark built-in object with its {@link SkylarkModule}
- * annotation and with the {@link SkylarkCallable} methods and {@link SkylarkSignature} fields it
- * documents.
+ * annotation and with the {@link SkylarkCallable} methods it documents.
*/
public final class SkylarkModuleDoc extends SkylarkDoc {
private final SkylarkModule module;
private final Class<?> classObject;
- private final Map<String, SkylarkBuiltinMethodDoc> builtinMethodMap;
private final Multimap<String, SkylarkJavaMethodDoc> javaMethods;
private TreeMap<String, SkylarkMethodDoc> methodMap;
private final String title;
@@ -48,7 +44,6 @@
this.module = Preconditions.checkNotNull(
module, "Class has to be annotated with SkylarkModule: %s", classObject);
this.classObject = classObject;
- this.builtinMethodMap = new TreeMap<>(Collator.getInstance(Locale.US));
this.methodMap = new TreeMap<>(Collator.getInstance(Locale.US));
this.javaMethods = HashMultimap.<String, SkylarkJavaMethodDoc>create();
this.deprecated = classObject.isAnnotationPresent(StarlarkDeprecated.class);
@@ -91,11 +86,6 @@
javaConstructor = method;
}
- public void addMethod(SkylarkBuiltinMethodDoc method) {
- methodMap.put(method.getName(), method);
- builtinMethodMap.put(method.getName(), method);
- }
-
public void addMethod(SkylarkJavaMethodDoc method) {
if (!method.documented()) {
return;
@@ -126,10 +116,6 @@
return javaMethods.isEmpty();
}
- public Map<String, SkylarkBuiltinMethodDoc> getBuiltinMethods() {
- return builtinMethodMap;
- }
-
public Collection<SkylarkMethodDoc> getJavaMethods() {
ImmutableList.Builder<SkylarkMethodDoc> returnedMethods = ImmutableList.builder();
if (javaConstructor != null) {
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 cc83cea..6d65a73 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
@@ -57,7 +57,6 @@
import com.google.devtools.build.lib.syntax.NodeVisitor;
import com.google.devtools.build.lib.syntax.ParserInput;
import com.google.devtools.build.lib.syntax.Runtime;
-import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
import com.google.devtools.build.lib.syntax.SkylarkUtils;
import com.google.devtools.build.lib.syntax.SkylarkUtils.Phase;
import com.google.devtools.build.lib.syntax.Starlark;
@@ -141,10 +140,8 @@
/** Update the predeclared environment of WORKSPACE files. */
void updateWorkspace(ImmutableMap.Builder<String, Object> env);
- /**
- * Returns the extra functions needed to be added to the Skylark native module.
- */
- ImmutableList<BaseFunction> nativeModuleFunctions();
+ /** Update the environment of the native module. */
+ void updateNative(ImmutableMap.Builder<String, Object> env);
/**
* Returns the extra arguments to the {@code package()} statement.
@@ -904,10 +901,8 @@
builder.putAll(SkylarkNativeModule.BINDINGS_FOR_BUILD_FILES);
builder.putAll(ruleFunctions);
builder.put("package", newPackageFunction(packageArguments));
- for (EnvironmentExtension extension : environmentExtensions) {
- for (BaseFunction function : extension.nativeModuleFunctions()) {
- builder.put(function.getName(), function);
- }
+ for (EnvironmentExtension ext : environmentExtensions) {
+ ext.updateNative(builder);
}
return StructProvider.STRUCT.create(builder.build(), "no native function or rule '%s'");
}
@@ -1148,10 +1143,6 @@
return true;
}
- static {
- SkylarkSignatureProcessor.configureSkylarkFunctions(PackageFactory.class);
- }
-
/**
* checkBuildSyntax checks the syntax tree of a BUILD (not .bzl) file. If it discovers a 'def',
* 'if', or 'for' statement, or a f(*args) or f(**kwargs) call, it reports an event to handler and
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
index 1302309..2bbfd58 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
@@ -1319,10 +1319,6 @@
CustomExitCodePublisher.setAbruptExitStatusFileDir(
serverDirectories.getOutputBase().getPathString());
- // Most static initializers for @SkylarkSignature-containing classes have already run by this
- // point, but this will pick up the stragglers.
- initSkylarkBuiltinsRegistry();
-
AutoProfiler.setClock(runtime.getClock());
BugReport.setRuntime(runtime);
BlazeDirectories directories =
@@ -1341,38 +1337,6 @@
return runtime;
}
- /**
- * Configures the Skylark builtins registry.
- *
- * <p>Any class containing {@link SkylarkSignature}-annotated fields should call
- * {@link SkylarkSignatureProcessor#configureSkylarkFunctions} on itself. This serves two
- * purposes: 1) it initializes those fields for use, and 2) it registers them with the Skylark
- * builtins registry object
- * ({@link com.google.devtools.build.lib.syntax.Runtime#getBuiltinRegistry}). Unfortunately
- * there's some technical debt here: The registry object is static and the registration occurs
- * inside static initializer blocks.
- *
- * <p>The registry supports concurrent read/write access, but read access is not actually
- * efficient (lockless) until write access is disallowed by calling its
- * {@link com.google.devtools.build.lib.syntax.Runtime.BuiltinRegistry#freeze freeze} method.
- * We want to freeze before the build begins, but not before all classes have had a chance to run
- * their static initializers.
- *
- * <p>Therefore, this method first ensures that the initializers have run, and then explicitly
- * freezes the registry. It ensures initialization by calling a no-op static method on the class.
- * Only classes whose initializers have been observed to cause {@code BuiltinRegistry} to throw an
- * exception need to be included here, since that indicates that their initialization did not
- * happen by this point in time.
- *
- * <p>Unit tests don't need to worry about registry freeze exceptions, since the registry isn't
- * frozen at all for them. They just pay the cost of extra synchronization on every access.
- */
- private static void initSkylarkBuiltinsRegistry() {
- // Currently no classes need to be initialized here. The hook's still here because it's
- // possible it may be needed again in the future.
- com.google.devtools.build.lib.syntax.Runtime.getBuiltinRegistry().freeze();
- }
-
private static String maybeGetPidString() {
Integer pid = maybeForceJNIByGettingPid(null);
return pid == null ? "" : "pid " + pid + " and ";
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkinterface/Param.java b/src/main/java/com/google/devtools/build/lib/skylarkinterface/Param.java
index f44bcbf..c56be4b 100644
--- a/src/main/java/com/google/devtools/build/lib/skylarkinterface/Param.java
+++ b/src/main/java/com/google/devtools/build/lib/skylarkinterface/Param.java
@@ -106,11 +106,11 @@
/**
* If this true, {@link #named} should be treated as true.
*
- * <p>This indicates this parameter is part of a {@link SkylarkCallable} method which
- * was migrated from {@link SkylarkSignature}. Due to a pre-migration bug, all parameters were
- * treated as if {@link #named} was true, even if it was false. To prevent breakages during
- * migration, the interpreter can continue to treat these parameters as named. This is distinct
- * from {@link #named}, however, so that a bulk fix/cleanup will be easier later.
+ * <p>This indicates this parameter is part of a {@link SkylarkCallable} method which was migrated
+ * from {@code SkylarkSignature}. Due to a pre-migration bug, all parameters were treated as if
+ * {@link #named} was true, even if it was false. To prevent breakages during migration, the
+ * interpreter can continue to treat these parameters as named. This is distinct from {@link
+ * #named}, however, so that a bulk fix/cleanup will be easier later.
*/
// TODO(b/77902276): Remove this after a bulk cleanup/fix.
boolean legacyNamed() default false;
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkSignature.java b/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkSignature.java
deleted file mode 100644
index 5942b68..0000000
--- a/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkSignature.java
+++ /dev/null
@@ -1,120 +0,0 @@
-// Copyright 2014 The Bazel Authors. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-package com.google.devtools.build.lib.skylarkinterface;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * An annotation to mark built-in keyword argument methods accessible from Skylark.
- *
- * <p>Use this annotation around a {@link com.google.devtools.build.lib.syntax.BuiltinFunction}. The
- * annotated function should expect the arguments described by {@link #parameters()}, {@link
- * #extraPositionals()}, and {@link #extraKeywords()}. It should also expect the following
- * extraneous arguments:
- *
- * <ul>
- * <li>{@link com.google.devtools.build.lib.events.Location} if {@link #useLocation()} is true.
- * <li>{@link com.google.devtools.build.lib.syntax.Node} if {@link #useAst()} is true.
- * <li>{@link com.google.devtools.build.lib.syntax.StarlarkThread} if {@link #useStarlarkThread()}
- * )} is true.
- * </ul>
- */
-@Target({ElementType.FIELD})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface SkylarkSignature {
-
- // TODO(bazel-team): parse most everything from single string specifying the signature
- // in Skylark syntax, e.g.: signature = "foo(a: string, b: ListOf(int)) -> NoneType"
- // String signature() default "";
-
- /**
- * Name of the method as exposed to Skylark.
- */
- String name();
-
- /**
- * General documentation block of the method. See the skylark documentation at
- * http://www.bazel.build/docs/skylark/.
- */
- String doc() default "";
-
- /**
- * List of parameters for calling this method. Named only parameters are expected to be last.
- */
- Param[] parameters() default {};
-
- /**
- * Defines a catch all positional parameters. By default, it is an error to define more
- * positional parameters that specified but by defining an extraPositionals argument, one can
- * catch those. See python's <code>*args</code>
- * (http://thepythonguru.com/python-args-and-kwargs/).
- */
- Param extraPositionals() default @Param(name = "");
-
- /**
- * Defines a catch all named parameters. By default, it is an error to define more
- * named parameters that specified but by defining an extraKeywords argument, one can catch those.
- * See python's <code>**kwargs</code> (http://thepythonguru.com/python-args-and-kwargs/).
- */
- Param extraKeywords() default @Param(name = "");
-
- /**
- * Set <code>documented</code> to <code>false</code> if this method should not be mentioned
- * in the documentation of Skylark. This is generally used for experimental APIs or duplicate
- * methods already documented on another call.
- */
- boolean documented() default true;
-
- /**
- * Type of the object associated to that function. If this field is
- * <code>Object.class</code>, then the function will be considered as an object method.
- * For example, to add a function to the string object, set it to <code>String.class</code>.
- */
- Class<?> objectType() default Object.class;
-
- /**
- * Return type of the function. Use {@link com.google.devtools.build.lib.syntax.Runtime.NoneType}
- * for a void function.
- */
- Class<?> returnType() default Object.class;
-
- /**
- * Fake return type of the function. Used by the documentation generator for documenting
- * deprecated functions (documentation for this type is generated, even if it's not the real
- * return type).
- */
- Class<?> documentationReturnType() default Object.class;
-
- // TODO(bazel-team): determine this way whether to accept mutable Lists
- // boolean mutableLists() default false;
-
- /**
- * If true the location of the call site will be passed as an argument of the annotated function.
- */
- boolean useLocation() default false;
-
- /**
- * If true the AST of the call site will be passed as an argument of the annotated function.
- */
- boolean useAst() default false;
-
- /**
- * If true the ({@link com.google.devtools.build.lib.syntax.StarlarkThread}) will be passed as an
- * argument of the annotated function.
- */
- boolean useStarlarkThread() default false;
-}
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 9b6db90..fb42720 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
@@ -488,7 +488,8 @@
// implementation, so this statement does not clobber the
// enforcedArgumentTypes computed by getSignatureForCallable.
// Still it is hard to explain what the configure method does.
- // TODO(adonovan): eliminate SkylarkSignature then simplify.
+
+ // TODO(adonovan): simplify now that SkylarkSignature is gone.
this.enforcedArgumentTypes = this.paramTypes;
}
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BuiltinFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/BuiltinFunction.java
index 39de391..74c91e4 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BuiltinFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BuiltinFunction.java
@@ -21,12 +21,10 @@
import com.google.devtools.build.lib.profiler.ProfilerTask;
import com.google.devtools.build.lib.profiler.SilentCloseable;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.syntax.SkylarkType.SkylarkFunctionType;
import com.google.devtools.build.lib.syntax.StarlarkThread.LexicalFrame;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.NoSuchElementException;
@@ -169,28 +167,6 @@
}
/**
- * Configure the reflection mechanism. Called by signature processor for BuiltinFunctions already
- * created.
- */
- final void configureFromAnnotation(SkylarkSignature annotation) {
- Preconditions.checkState(!isConfigured()); // must not be configured yet
- this.enforcedArgumentTypes = new ArrayList<>();
-
- this.returnType = annotation.returnType();
-
- // Appends to getEnforcedArgumentTypes() and paramDoc as a side effect.
- SkylarkSignatureProcessor.SignatureInfo info =
- SkylarkSignatureProcessor.getSignatureForCallable(
- getName(), annotation, /*paramDoc=*/ new ArrayList<>(), this.enforcedArgumentTypes);
- this.signature = info.signature;
- this.paramTypes = info.types;
- this.defaultValues = info.defaultValues;
-
- this.objectType = annotation.objectType() == Object.class ? null : annotation.objectType();
- configure();
- }
-
- /**
* Configure the reflection mechanism. Called directly by constructor for BuiltinFunctions created
* with a signature, and called after annotation processing for other BuiltinFunctions.
*/
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java b/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java
index c29a393..056231d 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/CallUtils.java
@@ -234,7 +234,8 @@
/**
* Returns a {@link BuiltinCallable} representing a {@link SkylarkCallable}-annotated instance
- * method of a given object with the given Java method name.
+ * method of a given object with the given Starlark field name (not necessarily the same as the
+ * Java method name).
*/
// TODO(adonovan): replace with EvalUtils.getAttr, once the latter doesn't require
// a Thread and Location.
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/FunctionSignature.java b/src/main/java/com/google/devtools/build/lib/syntax/FunctionSignature.java
index 705ad35..c00a452 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/FunctionSignature.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/FunctionSignature.java
@@ -410,7 +410,7 @@
return of(0, 0, numMandatory, false, false, names);
}
- /** Invalid signature from Parser or from SkylarkSignature annotations */
+ /** Invalid signature from Parser or from SkylarkCallable annotation. */
static class SignatureException extends Exception {
private final Parameter parameter;
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/Runtime.java b/src/main/java/com/google/devtools/build/lib/syntax/Runtime.java
index b17969b..7ef24e9 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/Runtime.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/Runtime.java
@@ -23,7 +23,6 @@
import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import java.util.HashMap;
import java.util.Map;
@@ -36,14 +35,6 @@
private Runtime() {}
- // (for documentation only)
- @SkylarkSignature(name = "True", returnType = Boolean.class, doc = "The Boolean true value.")
- private static final Boolean TRUE = true;
-
- // (for documentation only)
- @SkylarkSignature(name = "False", returnType = Boolean.class, doc = "The Boolean false value.")
- private static final Boolean FALSE = false;
-
/** There should be only one instance of this type to allow "== None" tests. */
@SkylarkModule(
name = "NoneType",
@@ -75,6 +66,9 @@
}
}
+ /* The Starlark None value. */
+ public static final NoneType NONE = new NoneType();
+
/** Marker for unbound variables in cases where neither Java null nor Skylark None is suitable. */
@Immutable
public static final class UnboundMarker implements SkylarkValue {
@@ -96,54 +90,8 @@
}
}
- @SkylarkSignature(
- name = "<unbound>",
- returnType = UnboundMarker.class,
- documented = false,
- doc = "Marker for unbound values in cases where neither Starlark None nor Java null can do.")
public static final UnboundMarker UNBOUND = new UnboundMarker();
- @SkylarkSignature(name = "None", returnType = NoneType.class,
- doc = "Literal for the None value.")
- public static final NoneType NONE = new NoneType();
-
- // (for documentation only)
- @SkylarkSignature(
- name = "PACKAGE_NAME",
- returnType = String.class,
- doc =
- "<b>Deprecated. Use <a href=\"native.html#package_name\">package_name()</a> instead.</b>"
- + " The name of the package being evaluated. For example, in the BUILD file"
- + " <code>some/package/BUILD</code>, its value will be <code>some/package</code>. If"
- + " the BUILD file calls a function defined in a .bzl file, PACKAGE_NAME will match"
- + " the caller BUILD file package. In .bzl files, do not access PACKAGE_NAME at the"
- + " file-level (outside of functions), either directly or by calling a function at"
- + " the file-level that accesses PACKAGE_NAME (PACKAGE_NAME is only defined during"
- + " BUILD file evaluation).Here is an example of a .bzl file:<br><pre"
- + " class=language-python># a = PACKAGE_NAME # not allowed outside functions\n"
- + "def extension():\n"
- + " return PACKAGE_NAME</pre>In this case, <code>extension()</code> can be called"
- + " from a BUILD file (even indirectly), but not in a file-level expression in the"
- + " .bzl file. When implementing a rule, use <a"
- + " href=\"ctx.html#label\">ctx.label</a> to know where the rule comes from. ")
- private final String unusedPackageName = "PACKAGE_NAME";
-
- // (for documentation only)
- @SkylarkSignature(
- name = "REPOSITORY_NAME",
- returnType = String.class,
- doc =
- "<b>Deprecated. Use <a href=\"native.html#repository_name\">repository_name()</a> "
- + "instead.</b> The name of the repository the rule or build extension is called "
- + "from. "
- + "For example, in packages that are called into existence by the WORKSPACE stanza "
- + "<code>local_repository(name='local', path=...)</code> it will be set to "
- + "<code>@local</code>. In packages in the main repository, it will be set to "
- + "<code>@</code>. It can only be accessed in functions (transitively) called from "
- + "BUILD files, i.e. it follows the same restrictions as "
- + "<a href=\"#PACKAGE_NAME\">PACKAGE_NAME</a>.")
- private final String unusedRepositoryName = "REPOSITORY_NAME";
-
/**
* Returns the canonical class representing the namespace associated with the given class, i.e.,
* the class under which builtins should be registered.
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
index a974b32..d484339 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSignatureProcessor.java
@@ -17,8 +17,6 @@
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
-import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -27,8 +25,7 @@
import javax.annotation.Nullable;
/**
- * This class defines utilities to process @SkylarkSignature annotations
- * to configure a given field.
+ * This class defines utilities to process @SkylarkCallable annotations to configure a given field.
*/
public class SkylarkSignatureProcessor {
@@ -55,71 +52,24 @@
}
}
- /**
- * Extracts signature information from a {@link SkylarkCallable}-annotated method.
- *
- * @param name the name of the function
- * @param descriptor the method descriptor
- * @param paramDoc an optional list into which to store documentation strings
- * @param enforcedTypesList an optional list into which to store effective types to enforce
- */
- public static SignatureInfo getSignatureForCallable(
- String name,
- MethodDescriptor descriptor,
- @Nullable List<String> paramDoc,
- @Nullable List<SkylarkType> enforcedTypesList) {
-
+ /** Extracts signature information from a {@link SkylarkCallable}-annotated method descriptor. */
+ public static SignatureInfo getSignatureForCallable(MethodDescriptor descriptor) {
SkylarkCallable annotation = descriptor.getAnnotation();
- // TODO(cparsons): Validate these properties with the annotation processor instead.
- Preconditions.checkArgument(name.equals(annotation.name()),
- "%s != %s", name, annotation.name());
boolean documented = annotation.documented();
if (annotation.doc().isEmpty() && documented) {
- throw new RuntimeException(String.format("function %s is undocumented", name));
+ throw new IllegalStateException(
+ String.format("function %s is undocumented", annotation.name()));
}
return getSignatureForCallableImpl(
- name,
+ annotation.name(),
documented,
annotation.parameters(),
annotation.extraPositionals(),
annotation.extraKeywords(),
- paramDoc,
- enforcedTypesList);
- }
-
- /**
- * Extracts signature information from a {@link SkylarkSignature} annotation.
- *
- * @param name the name of the function
- * @param annotation the annotation
- * @param paramDoc an optional list into which to store documentation strings
- * @param enforcedTypesList an optional list into which to store effective types to enforce
- */
- // NB: the two arguments paramDoc and enforcedTypesList are used to "return" extra values via
- // side-effects, and that's ugly
- // TODO(bazel-team): use AutoValue to declare a value type to use as return value?
- static SignatureInfo getSignatureForCallable(
- String name,
- SkylarkSignature annotation,
- @Nullable List<String> paramDoc,
- @Nullable List<SkylarkType> enforcedTypesList) {
-
- Preconditions.checkArgument(name.equals(annotation.name()),
- "%s != %s", name, annotation.name());
- boolean documented = annotation.documented();
- if (annotation.doc().isEmpty() && documented) {
- throw new RuntimeException(String.format("function %s is undocumented", name));
- }
- return getSignatureForCallableImpl(
- name,
- documented,
- annotation.parameters(),
- annotation.extraPositionals(),
- annotation.extraKeywords(),
- paramDoc,
- enforcedTypesList);
+ /*paramDoc=*/ null,
+ /*enforcedTypesList=*/ null);
}
private static boolean isParamNamed(Param param) {
@@ -336,60 +286,11 @@
} catch (Exception e) {
throw new RuntimeException(
String.format(
- "Exception while processing @SkylarkSignature.Param %s, default value %s",
+ "Exception while processing @Param %s, default value %s",
paramName, paramDefaultValue),
e);
}
}
}
- /**
- * Processes all {@link SkylarkSignature}-annotated fields in a class.
- *
- * <p>This includes registering these fields as builtins using {@link Runtime}, and for {@link
- * BuiltinFunction} instances, calling {@link BuiltinFunction#configure(SkylarkSignature)}. The
- * fields will be picked up by reflection even if they are not public.
- *
- * <p>This function should be called once per class, before the builtins registry is frozen. In
- * practice, this is usually called from the class's own static initializer block. E.g., a class
- * {@code Foo} containing {@code @SkylarkSignature} annotations would end with {@code static {
- * SkylarkSignatureProcessor.configureSkylarkFunctions(Foo.class); }}.
- *
- * <p><b>If you see exceptions from {@link Runtime.BuiltinRegistry} here:</b> Be sure the class's
- * static initializer has in fact been called before the registry was frozen. In Bazel, see {@link
- * com.google.devtools.build.lib.runtime.BlazeRuntime#initSkylarkBuiltinsRegistry}.
- */
- public static void configureSkylarkFunctions(Class<?> type) {
- Runtime.BuiltinRegistry builtins = Runtime.getBuiltinRegistry();
- for (Field field : type.getDeclaredFields()) {
- if (field.isAnnotationPresent(SkylarkSignature.class)) {
- // The annotated fields are often private, but we need access them.
- field.setAccessible(true);
- SkylarkSignature annotation = field.getAnnotation(SkylarkSignature.class);
- Object value = null;
- try {
- value =
- Preconditions.checkNotNull(
- field.get(null),
- "Error while trying to configure %s.%s: its value is null",
- type,
- field);
- builtins.registerBuiltin(type, field.getName(), value);
- if (BuiltinFunction.class.isAssignableFrom(field.getType())) {
- BuiltinFunction function = (BuiltinFunction) value;
- if (!function.isConfigured()) {
- function.configureFromAnnotation(annotation);
- }
- Class<?> nameSpace = function.getObjectType();
- if (nameSpace != null) {
- builtins.registerFunction(nameSpace, function);
- }
- }
- } catch (IllegalAccessException e) {
- throw new RuntimeException(String.format(
- "Error while trying to configure %s.%s (value %s)", type, field, value), e);
- }
- }
- }
- }
}
diff --git a/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java b/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java
index 2d89c1a..b789291 100644
--- a/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java
+++ b/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java
@@ -83,6 +83,14 @@
undocumentedItems.add(varname);
}
}
+
+ // These constants are currently undocumented.
+ // If they need documentation, the easiest approach would be
+ // to hard-code it in SkylarkDocumentationCollector.
+ undocumentedItems.remove("True");
+ undocumentedItems.remove("False");
+ undocumentedItems.remove("None");
+
assertWithMessage("Undocumented items: " + undocumentedItems)
.that(undocumentedItems)
.containsExactlyElementsIn(DEPRECATED_UNDOCUMENTED_TOP_LEVEL_SYMBOLS);
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/RuntimeTest.java b/src/test/java/com/google/devtools/build/lib/syntax/RuntimeTest.java
index 06e68ba..6f1fb52 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/RuntimeTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/RuntimeTest.java
@@ -28,14 +28,15 @@
@RunWith(JUnit4.class)
public final class RuntimeTest {
- private static final BuiltinFunction DUMMY_FUNC = new BuiltinFunction("dummyFunc") {
- // This would normally be done by @SkylarkSignature annotation and configure(), but a simple
- // stub suffices.
- @Override
- public Class<?> getObjectType() {
- return DummyType.class;
- }
- };
+ private static final BuiltinFunction DUMMY_FUNC =
+ new BuiltinFunction("dummyFunc") {
+ // This would normally be done by @SkylarkCallable annotation and configure(), but a simple
+ // stub suffices.
+ @Override
+ public Class<?> getObjectType() {
+ return DummyType.class;
+ }
+ };
private static class DummyType implements SkylarkValue {
@Override
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
index a7da512..ec4a25e 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -32,8 +32,8 @@
import com.google.devtools.build.lib.skylarkinterface.Param;
import com.google.devtools.build.lib.skylarkinterface.ParamType;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
-import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
import com.google.devtools.build.lib.skylarkinterface.SkylarkValue;
import com.google.devtools.build.lib.syntax.SkylarkList.MutableList;
import com.google.devtools.build.lib.syntax.StarlarkSemantics.FlagIdentifier;
@@ -48,6 +48,7 @@
/** Tests of Starlark evaluation. */
// This test uses 'extends' to make a copy of EvaluationTest whose
// mode is overridden to SKYLARK, changing various environmental parameters.
+@SkylarkGlobalLibrary // required for @SkylarkCallable-annotated methods
@RunWith(JUnit4.class)
public final class SkylarkEvaluationTest extends EvaluationTest {
@@ -71,29 +72,21 @@
}
}
- @SkylarkSignature(name = "foobar", returnType = String.class, documented = false)
- static BuiltinFunction foobar = new BuiltinFunction("foobar") {
- public String invoke() throws EvalException {
- return "foobar";
- }
- };
+ @SkylarkCallable(name = "foobar", documented = false)
+ public String foobar() {
+ return "foobar";
+ }
- @SkylarkSignature(
- name = "interrupted_function",
- returnType = Runtime.NoneType.class,
- documented = false)
- static BuiltinFunction interruptedFunction =
- new BuiltinFunction("interrupted_function") {
- public Runtime.NoneType invoke() throws InterruptedException {
- throw new InterruptedException();
- }
- };
+ @SkylarkCallable(name = "interrupted_function", documented = false)
+ public Runtime.NoneType interruptedFunction() throws InterruptedException {
+ throw new InterruptedException();
+ }
+
+ private static final NativeProvider<NativeInfoMock> CONSTRUCTOR =
+ new NativeProvider<NativeInfoMock>(NativeInfoMock.class, "native_info_mock") {};
@SkylarkModule(name = "Mock", doc = "")
- static class NativeInfoMock extends NativeInfo {
-
- private static final NativeProvider<NativeInfoMock> CONSTRUCTOR =
- new NativeProvider<NativeInfoMock>(NativeInfoMock.class, "native_info_mock") {};
+ class NativeInfoMock extends NativeInfo {
public NativeInfoMock() {
super(CONSTRUCTOR);
@@ -110,8 +103,8 @@
}
@SkylarkCallable(name = "struct_field_callable", documented = false, structField = true)
- public BuiltinFunction structFieldCallable() {
- return foobar;
+ public BuiltinCallable structFieldCallable() {
+ return CallUtils.getBuiltinCallable(SkylarkEvaluationTest.this, "foobar");
}
@SkylarkCallable(
@@ -126,7 +119,7 @@
}
@SkylarkModule(name = "Mock", doc = "")
- static class Mock implements SkylarkValue {
+ class Mock implements SkylarkValue {
@SkylarkCallable(
name = "MockFn",
selfCall = true,
@@ -171,9 +164,10 @@
+ (sem != null)
+ ")";
}
+
@SkylarkCallable(name = "struct_field_callable", documented = false, structField = true)
- public BuiltinFunction structFieldCallable() {
- return foobar;
+ public Object structFieldCallable() {
+ return CallUtils.getBuiltinCallable(SkylarkEvaluationTest.this, "foobar");
}
@SkylarkCallable(name = "interrupted_struct_field", documented = false, structField = true)
@@ -521,7 +515,7 @@
}
@SkylarkModule(name = "MockSubClass", doc = "")
- static final class MockSubClass extends Mock implements MockInterface {
+ final class MockSubClass extends Mock implements MockInterface {
@Override
public Boolean isEmpty(String str) {
return str.isEmpty();
@@ -1298,8 +1292,6 @@
@Test
public void testStructAccessAsFuncall() throws Exception {
- foobar.configureFromAnnotation(
- getClass().getDeclaredField("foobar").getAnnotation(SkylarkSignature.class));
new SkylarkTest()
.update("mock", new Mock())
.setUp("v = mock.struct_field_callable()")
@@ -1314,9 +1306,7 @@
@Test
public void testCallingInterruptedFunction() throws Exception {
- interruptedFunction.configureFromAnnotation(
- getClass().getDeclaredField("interruptedFunction").getAnnotation(SkylarkSignature.class));
- update("interrupted_function", interruptedFunction);
+ update("interrupted_function", CallUtils.getBuiltinCallable(this, "interrupted_function"));
assertThrows(InterruptedException.class, () -> eval("interrupted_function()"));
}