Add attribute information to skydoc output
RELNOTES: None.
PiperOrigin-RevId: 204147228
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java
index 9b1081b..4260032 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkRuleFunctionsApi.java
@@ -14,7 +14,7 @@
package com.google.devtools.build.skydoc.fakebuildapi;
-import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.events.Location;
import com.google.devtools.build.lib.skylarkbuildapi.FileApi;
@@ -29,10 +29,11 @@
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
+import com.google.devtools.build.skydoc.fakebuildapi.FakeDescriptor.Type;
import com.google.devtools.build.skydoc.rendering.AttributeInfo;
import com.google.devtools.build.skydoc.rendering.RuleInfo;
+import java.util.Comparator;
import java.util.List;
-import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
@@ -44,6 +45,8 @@
*/
public class FakeSkylarkRuleFunctionsApi implements SkylarkRuleFunctionsApi<FileApi> {
+ private static final FakeDescriptor IMPLICIT_NAME_ATTRIBUTE_DESCRIPTOR =
+ new FakeDescriptor(Type.STRING, "A unique name for this rule.", true);
private final List<RuleInfo> ruleInfoList;
/**
@@ -69,20 +72,22 @@
Boolean executionPlatformConstraintsAllowed, SkylarkList<?> execCompatibleWith,
FuncallExpression ast, Environment funcallEnv) throws EvalException {
List<AttributeInfo> attrInfos;
- // TODO(cparsons): Include implicit "Name" attribute.
+ ImmutableMap.Builder<String, FakeDescriptor> attrsMapBuilder = ImmutableMap.builder();
if (attrs != null && attrs != Runtime.NONE) {
SkylarkDict<?, ?> attrsDict = (SkylarkDict<?, ?>) attrs;
- Map<String, FakeDescriptor> attrsMap =
- attrsDict.getContents(String.class, FakeDescriptor.class, "attrs");
- // TODO(cparsons): Include better attribute details. For example, attribute type.
- attrInfos = attrsMap.entrySet().stream()
- .map(entry -> new AttributeInfo(entry.getKey(), entry.getValue().getDocString()))
- .sorted((o1, o2) -> o1.getName().compareTo(o2.getName()))
- .collect(Collectors.toList());
- } else {
- attrInfos = ImmutableList.of();
+ attrsMapBuilder.putAll(attrsDict.getContents(String.class, FakeDescriptor.class, "attrs"));
}
+ attrsMapBuilder.put("name", IMPLICIT_NAME_ATTRIBUTE_DESCRIPTOR);
+ attrInfos = attrsMapBuilder.build().entrySet().stream()
+ .map(entry -> new AttributeInfo(
+ entry.getKey(),
+ entry.getValue().getDocString(),
+ entry.getValue().getType().getDescription(),
+ entry.getValue().isMandatory()))
+ .collect(Collectors.toList());
+ attrInfos.sort(new AttributeNameComparator());
+
RuleDefinitionIdentifier functionIdentifier = new RuleDefinitionIdentifier();
ruleInfoList.add(new RuleInfo(functionIdentifier, ast.getLocation(), doc, attrInfos));
@@ -128,4 +133,22 @@
return this == other;
}
}
+
+ /**
+ * A comparator for {@link AttributeInfo} objects which sorts by attribute name alphabetically,
+ * except that any attribute named "name" is placed first.
+ */
+ private static class AttributeNameComparator implements Comparator<AttributeInfo> {
+
+ @Override
+ public int compare(AttributeInfo o1, AttributeInfo o2) {
+ if (o1.getName().equals("name")) {
+ return o2.getName().equals("name") ? 0 : -1;
+ } else if (o2.getName().equals("name")) {
+ return 1;
+ } else {
+ return o1.getName().compareTo(o2.getName());
+ }
+ }
+ }
}