aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java18
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java58
-rw-r--r--src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkConstructor.java38
3 files changed, 74 insertions, 40 deletions
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 334634e3b9..6b614b381b 100644
--- a/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java
+++ b/src/main/java/com/google/devtools/build/docgen/SkylarkDocumentationCollector.java
@@ -20,6 +20,7 @@ import com.google.devtools.build.docgen.skylark.SkylarkBuiltinMethodDoc;
import com.google.devtools.build.docgen.skylark.SkylarkJavaMethodDoc;
import com.google.devtools.build.docgen.skylark.SkylarkModuleDoc;
import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable;
+import com.google.devtools.build.lib.skylarkinterface.SkylarkConstructor;
import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModuleCategory;
@@ -32,7 +33,6 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayDeque;
import java.util.Deque;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -120,10 +120,8 @@ final class SkylarkDocumentationCollector {
Map<String, SkylarkModuleDoc> modules) {
Set<Class<?>> done = new HashSet<>();
Deque<Class<?>> toProcess = new ArrayDeque<>();
- Map<Class<?>, SkylarkModule> annotations = new HashMap<>();
toProcess.addLast(firstClass);
- annotations.put(firstClass, firstModule);
while (!toProcess.isEmpty()) {
Class<?> c = toProcess.removeFirst();
@@ -143,7 +141,6 @@ final class SkylarkDocumentationCollector {
if (returnClass.isAnnotationPresent(SkylarkModule.class)
&& !done.contains(returnClass)) {
toProcess.addLast(returnClass);
- annotations.put(returnClass, returnClass.getAnnotation(SkylarkModule.class));
}
}
}
@@ -165,12 +162,21 @@ final class SkylarkDocumentationCollector {
private static void collectBuiltinMethods(
Map<String, SkylarkModuleDoc> modules, Class<?> moduleClass) {
- SkylarkModuleDoc module = getTopLevelModuleDoc(modules);
+ SkylarkModuleDoc topLevelModuleDoc = getTopLevelModuleDoc(modules);
ImmutableMap<Method, SkylarkCallable> methods =
FuncallExpression.collectSkylarkMethodsWithAnnotation(moduleClass);
for (Map.Entry<Method, SkylarkCallable> entry : methods.entrySet()) {
- module.addMethod(new SkylarkJavaMethodDoc("", entry.getKey(), entry.getValue()));
+ if (entry.getKey().isAnnotationPresent(SkylarkConstructor.class)) {
+ SkylarkConstructor constructorAnnotation =
+ entry.getKey().getAnnotation(SkylarkConstructor.class);
+ Class<?> objectClass = constructorAnnotation.objectType();
+ SkylarkModuleDoc module = getSkylarkModuleDoc(objectClass, modules);
+ module.addMethod(
+ new SkylarkJavaMethodDoc("", entry.getKey(), entry.getValue()));
+ } else {
+ topLevelModuleDoc.addMethod(new SkylarkJavaMethodDoc("", entry.getKey(), entry.getValue()));
+ }
}
}
}
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
index 985fbea325..a8ee1e007d 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/skylark/SkylarkRuleClassFunctions.java
@@ -74,6 +74,7 @@ import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
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.SkylarkConstructor;
import com.google.devtools.build.lib.skylarkinterface.SkylarkGlobalLibrary;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
import com.google.devtools.build.lib.skylarkinterface.SkylarkSignature;
@@ -1020,17 +1021,16 @@ public class SkylarkRuleClassFunctions {
ImmutableList.of(
SkylarkProvider.class, SkylarkDefinedAspect.class, SkylarkRuleFunction.class);
- @SkylarkSignature(
+ @SkylarkCallable(
name = "Label",
doc =
"Creates a Label referring to a BUILD target. Use "
+ "this function only when you want to give a default value for the label attributes. "
+ "The argument must refer to an absolute label. "
+ "Example: <br><pre class=language-python>Label(\"//tools:default\")</pre>",
- returnType = Label.class,
- objectType = Label.class,
parameters = {
- @Param(name = "label_string", type = String.class, doc = "the label string."),
+ @Param(name = "label_string", type = String.class, legacyNamed = true,
+ doc = "the label string."),
@Param(
name = "relative_to_caller_repository",
type = Boolean.class,
@@ -1050,36 +1050,26 @@ public class SkylarkRuleClassFunctions {
useLocation = true,
useEnvironment = true
)
- private static final BuiltinFunction label =
- new BuiltinFunction("Label") {
- @SuppressWarnings({"unchecked", "unused"})
- public Label invoke(
- String labelString, Boolean relativeToCallerRepository, Location loc, Environment env)
- throws EvalException {
- Label parentLabel = null;
- if (relativeToCallerRepository) {
- parentLabel = env.getCallerLabel();
- } else {
- parentLabel = env.getGlobals().getTransitiveLabel();
- }
- try {
- if (parentLabel != null) {
- LabelValidator.parseAbsoluteLabel(labelString);
- labelString = parentLabel.getRelative(labelString).getUnambiguousCanonicalForm();
- }
- return labelCache.get(labelString);
- } catch (LabelValidator.BadLabelException | LabelSyntaxException | ExecutionException e) {
- throw new EvalException(loc, "Illegal absolute label syntax: " + labelString);
- }
- }
- };
-
- // We want the Label ctor to show up under the Label documentation, but to be a "global
- // function." Thus, we create a global Label object here, which just points to the Skylark
- // function above.
- @SkylarkSignature(name = "Label",
- documented = false)
- private static final BuiltinFunction globalLabel = label;
+ @SkylarkConstructor(objectType = Label.class)
+ public Label label(
+ String labelString, Boolean relativeToCallerRepository, Location loc, Environment env)
+ throws EvalException {
+ Label parentLabel = null;
+ if (relativeToCallerRepository) {
+ parentLabel = env.getCallerLabel();
+ } else {
+ parentLabel = env.getGlobals().getTransitiveLabel();
+ }
+ try {
+ if (parentLabel != null) {
+ LabelValidator.parseAbsoluteLabel(labelString);
+ labelString = parentLabel.getRelative(labelString).getUnambiguousCanonicalForm();
+ }
+ return labelCache.get(labelString);
+ } catch (LabelValidator.BadLabelException | LabelSyntaxException | ExecutionException e) {
+ throw new EvalException(loc, "Illegal absolute label syntax: " + labelString);
+ }
+ }
@SkylarkSignature(
name = "FileType",
diff --git a/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkConstructor.java b/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkConstructor.java
new file mode 100644
index 0000000000..b785038da1
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/skylarkinterface/SkylarkConstructor.java
@@ -0,0 +1,38 @@
+// Copyright 2018 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 {@link SkylarkCallable}-annotated methods as representing top-level
+ * constructors for other Skylark objects. This is used only for documentation purposes.
+ *
+ * <p>For example, a "Foo" type skylark object might be constructable at the top level using
+ * a global callable "Foo()". One can annotate that callable with this annotation to ensure that
+ * the documentation for "Foo()" appears alongside the documentation for the Foo type, and not
+ * the available globals.
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface SkylarkConstructor {
+
+ /**
+ * The java class of the skylark type that this annotation's method is a constructor for.
+ */
+ Class<?> objectType();
+}