Allows Stardoc Binary to output aspect information as a proto output
Work toward https://github.com/bazelbuild/skydoc/issues/196.
PiperOrigin-RevId: 259836027
diff --git a/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java b/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
index 0c68293..e2ece22 100644
--- a/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
+++ b/src/main/java/com/google/devtools/build/docgen/SymbolFamilies.java
@@ -181,7 +181,8 @@
new FakeSkylarkAttrApi(),
new FakeSkylarkCommandLineApi(),
new FakeSkylarkNativeModuleApi(),
- new FakeSkylarkRuleFunctionsApi(Lists.newArrayList(), Lists.newArrayList()),
+ new FakeSkylarkRuleFunctionsApi(
+ Lists.newArrayList(), Lists.newArrayList(), Lists.newArrayList()),
new FakeStructProviderApi(),
new FakeOutputGroupInfoProvider(),
new FakeActionsInfoProvider(),
diff --git a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
index e867333..c379921 100644
--- a/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
+++ b/src/main/java/com/google/devtools/build/skydoc/SkydocMain.java
@@ -110,12 +110,14 @@
import com.google.devtools.build.skydoc.fakebuildapi.test.FakeAnalysisTestResultInfoProvider;
import com.google.devtools.build.skydoc.fakebuildapi.test.FakeCoverageCommon;
import com.google.devtools.build.skydoc.fakebuildapi.test.FakeTestingModule;
+import com.google.devtools.build.skydoc.rendering.AspectInfoWrapper;
import com.google.devtools.build.skydoc.rendering.DocstringParseException;
import com.google.devtools.build.skydoc.rendering.FunctionUtil;
import com.google.devtools.build.skydoc.rendering.MarkdownRenderer;
import com.google.devtools.build.skydoc.rendering.ProtoRenderer;
import com.google.devtools.build.skydoc.rendering.ProviderInfoWrapper;
import com.google.devtools.build.skydoc.rendering.RuleInfoWrapper;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AspectInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ProviderInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.UserDefinedFunctionInfo;
@@ -218,6 +220,7 @@
ImmutableMap.Builder<String, RuleInfo> ruleInfoMap = ImmutableMap.builder();
ImmutableMap.Builder<String, ProviderInfo> providerInfoMap = ImmutableMap.builder();
ImmutableMap.Builder<String, UserDefinedFunction> userDefinedFunctions = ImmutableMap.builder();
+ ImmutableMap.Builder<String, AspectInfo> aspectInfoMap = ImmutableMap.builder();
try {
new SkydocMain(new FilesystemFileAccessor(), skydocOptions.workspaceName, depRoots)
@@ -226,7 +229,8 @@
targetFileLabel,
ruleInfoMap,
providerInfoMap,
- userDefinedFunctions);
+ userDefinedFunctions,
+ aspectInfoMap);
} catch (StarlarkEvaluationException exception) {
System.err.println("Stardoc documentation generation failed: " + exception.getMessage());
System.exit(1);
@@ -244,6 +248,10 @@
userDefinedFunctions.build().entrySet().stream()
.filter(entry -> validSymbolName(symbolNames, entry.getKey()))
.collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue));
+ Map<String, AspectInfo> filteredAspectInfos =
+ aspectInfoMap.build().entrySet().stream()
+ .filter(entry -> validSymbolName(symbolNames, entry.getKey()))
+ .collect(ImmutableMap.toImmutableMap(Entry::getKey, Entry::getValue));
if (skydocOptions.outputFormat == OutputFormat.PROTO) {
try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(outputPath))) {
@@ -251,6 +259,7 @@
.appendRuleInfos(filteredRuleInfos.values())
.appendProviderInfos(filteredProviderInfos.values())
.appendUserDefinedFunctionInfos(filteredUserDefinedFunctions)
+ .appendAspectInfos(filteredAspectInfos.values())
.writeModuleInfo(out);
}
} else if (skydocOptions.outputFormat == OutputFormat.MARKDOWN) {
@@ -357,6 +366,9 @@
* @param userDefinedFunctionMap a map builder to be populated with user-defined functions. Keys
* are exported names of functions, and values are the {@link UserDefinedFunction} objects.
* For example, 'def my_function(foo):' is a function with key 'my_function'.
+ * @param aspectInfoMap a map builder to be populated with aspect definition information for named
+ * aspects. Keys are exported names of aspects, and values are the {@link AspectInfo} asepct
+ * descriptions. For example, 'my_aspect = aspect(...)' has key 'my_aspect'
* @throws InterruptedException if evaluation is interrupted
*/
public Environment eval(
@@ -364,14 +376,19 @@
Label label,
ImmutableMap.Builder<String, RuleInfo> ruleInfoMap,
ImmutableMap.Builder<String, ProviderInfo> providerInfoMap,
- ImmutableMap.Builder<String, UserDefinedFunction> userDefinedFunctionMap)
+ ImmutableMap.Builder<String, UserDefinedFunction> userDefinedFunctionMap,
+ ImmutableMap.Builder<String, AspectInfo> aspectInfoMap)
throws InterruptedException, IOException, LabelSyntaxException, EvalException,
StarlarkEvaluationException {
List<RuleInfoWrapper> ruleInfoList = new ArrayList<>();
List<ProviderInfoWrapper> providerInfoList = new ArrayList<>();
- Environment env = recursiveEval(semantics, label, ruleInfoList, providerInfoList);
+
+ List<AspectInfoWrapper> aspectInfoList = new ArrayList<>();
+
+ Environment env =
+ recursiveEval(semantics, label, ruleInfoList, providerInfoList, aspectInfoList);
Map<BaseFunction, RuleInfoWrapper> ruleFunctions =
ruleInfoList.stream()
@@ -382,6 +399,11 @@
providerInfoList.stream()
.collect(Collectors.toMap(ProviderInfoWrapper::getIdentifier, Functions.identity()));
+ Map<BaseFunction, AspectInfoWrapper> aspectFunctions =
+ aspectInfoList.stream()
+ .collect(
+ Collectors.toMap(AspectInfoWrapper::getIdentifierFunction, Functions.identity()));
+
// Sort the bindings so their ordering is deterministic.
TreeMap<String, Object> sortedBindings = new TreeMap<>(env.getGlobals().getExportedBindings());
@@ -406,6 +428,12 @@
FakeStructApi namespace = (FakeStructApi) envEntry.getValue();
putStructFields(namespaceName, namespace, userDefinedFunctionMap);
}
+ if (aspectFunctions.containsKey(envEntry.getValue())) {
+ AspectInfo.Builder aspectInfoBuild =
+ aspectFunctions.get(envEntry.getValue()).getAspectInfo();
+ AspectInfo aspectInfo = aspectInfoBuild.setAspectName(envEntry.getKey()).build();
+ aspectInfoMap.put(envEntry.getKey(), aspectInfo);
+ }
}
return env;
@@ -450,7 +478,8 @@
StarlarkSemantics semantics,
Label label,
List<RuleInfoWrapper> ruleInfoList,
- List<ProviderInfoWrapper> providerInfoList)
+ List<ProviderInfoWrapper> providerInfoList,
+ List<AspectInfoWrapper> aspectInfoList)
throws InterruptedException, IOException, LabelSyntaxException, StarlarkEvaluationException {
Path path = pathOfLabel(label);
@@ -473,7 +502,7 @@
try {
Environment importEnv =
- recursiveEval(semantics, relativeLabel, ruleInfoList, providerInfoList);
+ recursiveEval(semantics, relativeLabel, ruleInfoList, providerInfoList, aspectInfoList);
imports.put(anImport.getImportString(), new Extension(importEnv));
} catch (NoSuchFileException noSuchFileException) {
throw new StarlarkEvaluationException(
@@ -484,7 +513,8 @@
}
Environment env =
- evalSkylarkBody(semantics, buildFileAST, imports, ruleInfoList, providerInfoList);
+ evalSkylarkBody(
+ semantics, buildFileAST, imports, ruleInfoList, providerInfoList, aspectInfoList);
pending.remove(path);
env.mutability().freeze();
@@ -518,12 +548,16 @@
BuildFileAST buildFileAST,
Map<String, Extension> imports,
List<RuleInfoWrapper> ruleInfoList,
- List<ProviderInfoWrapper> providerInfoList)
+ List<ProviderInfoWrapper> providerInfoList,
+ List<AspectInfoWrapper> aspectInfoList)
throws InterruptedException, StarlarkEvaluationException {
Environment env =
createEnvironment(
- semantics, eventHandler, globalFrame(ruleInfoList, providerInfoList), imports);
+ semantics,
+ eventHandler,
+ globalFrame(ruleInfoList, providerInfoList, aspectInfoList),
+ imports);
if (!buildFileAST.exec(env, eventHandler)) {
throw new StarlarkEvaluationException("Starlark evaluation error");
@@ -543,14 +577,16 @@
* invocation information will be added
*/
private static GlobalFrame globalFrame(
- List<RuleInfoWrapper> ruleInfoList, List<ProviderInfoWrapper> providerInfoList) {
+ List<RuleInfoWrapper> ruleInfoList,
+ List<ProviderInfoWrapper> providerInfoList,
+ List<AspectInfoWrapper> aspectInfoList) {
TopLevelBootstrap topLevelBootstrap =
new TopLevelBootstrap(
new FakeBuildApiGlobals(),
new FakeSkylarkAttrApi(),
new FakeSkylarkCommandLineApi(),
new FakeSkylarkNativeModuleApi(),
- new FakeSkylarkRuleFunctionsApi(ruleInfoList, providerInfoList),
+ new FakeSkylarkRuleFunctionsApi(ruleInfoList, providerInfoList, aspectInfoList),
new FakeStructProviderApi(),
new FakeOutputGroupInfoProvider(),
new FakeActionsInfoProvider(),
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAspect.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAspect.java
index 7cd6e10..c24273b 100644
--- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAspect.java
+++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeSkylarkAspect.java
@@ -16,11 +16,22 @@
import com.google.devtools.build.lib.skylarkbuildapi.SkylarkAspectApi;
import com.google.devtools.build.lib.skylarkinterface.SkylarkPrinter;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.lib.syntax.FunctionSignature;
-/**
- * Fake implementation of {@link SkylarkAspectApi}.
- */
-public class FakeSkylarkAspect implements SkylarkAspectApi {
+/** Fake implementation of {@link SkylarkAspectApi}. */
+public class FakeSkylarkAspect extends BaseFunction implements SkylarkAspectApi {
+
+ /**
+ * Each fake is constructed with a unique name, controlled by this counter being the name suffix.
+ */
+ private static int idCounter = 0;
+
+ public FakeSkylarkAspect() {
+ super(
+ "AspectIdentifier" + idCounter++,
+ FunctionSignature.WithValues.create(FunctionSignature.KWARGS));
+ }
@Override
public void repr(SkylarkPrinter printer) {}
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 fa82b8a..c30ab1e 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
@@ -32,13 +32,16 @@
import com.google.devtools.build.lib.syntax.SkylarkDict;
import com.google.devtools.build.lib.syntax.SkylarkList;
import com.google.devtools.build.lib.syntax.SkylarkType;
+import com.google.devtools.build.skydoc.rendering.AspectInfoWrapper;
import com.google.devtools.build.skydoc.rendering.ProviderInfoWrapper;
import com.google.devtools.build.skydoc.rendering.RuleInfoWrapper;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AspectInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeType;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ProviderFieldInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ProviderInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
@@ -60,6 +63,8 @@
private final List<ProviderInfoWrapper> providerInfoList;
+ private final List<AspectInfoWrapper> aspectInfoList;
+
/**
* Constructor.
*
@@ -67,11 +72,16 @@
* will be added
* @param providerInfoList the list of {@link ProviderInfo} objects to which provider() invocation
* information will be added
+ * @param aspectInfoList the list of {@link AspectInfo} objects to which aspect() invocation
+ * information will be added
*/
public FakeSkylarkRuleFunctionsApi(
- List<RuleInfoWrapper> ruleInfoList, List<ProviderInfoWrapper> providerInfoList) {
+ List<RuleInfoWrapper> ruleInfoList,
+ List<ProviderInfoWrapper> providerInfoList,
+ List<AspectInfoWrapper> aspectInfoList) {
this.ruleInfoList = ruleInfoList;
this.providerInfoList = providerInfoList;
+ this.aspectInfoList = aspectInfoList;
}
@Override
@@ -138,7 +148,6 @@
Environment funcallEnv,
StarlarkContext context)
throws EvalException {
- List<AttributeInfo> attrInfos;
ImmutableMap.Builder<String, FakeDescriptor> attrsMapBuilder = ImmutableMap.builder();
if (attrs != null && attrs != Runtime.NONE) {
SkylarkDict<?, ?> attrsDict = (SkylarkDict<?, ?>) attrs;
@@ -146,7 +155,7 @@
}
attrsMapBuilder.put("name", IMPLICIT_NAME_ATTRIBUTE_DESCRIPTOR);
- attrInfos =
+ List<AttributeInfo> attrInfos =
attrsMapBuilder.build().entrySet().stream()
.filter(entry -> !entry.getKey().startsWith("_"))
.map(entry -> entry.getValue().asAttributeInfo(entry.getKey()))
@@ -186,7 +195,39 @@
Object attrs, SkylarkList<?> requiredAspectProvidersArg, SkylarkList<?> providesArg,
SkylarkList<?> fragments, SkylarkList<?> hostFragments, SkylarkList<?> toolchains, String doc,
FuncallExpression ast, Environment funcallEnv) throws EvalException {
- return new FakeSkylarkAspect();
+ FakeSkylarkAspect fakeAspect = new FakeSkylarkAspect();
+ ImmutableMap.Builder<String, FakeDescriptor> attrsMapBuilder = ImmutableMap.builder();
+ if (attrs != null && attrs != Runtime.NONE) {
+ SkylarkDict<?, ?> attrsDict = (SkylarkDict<?, ?>) attrs;
+ attrsMapBuilder.putAll(attrsDict.getContents(String.class, FakeDescriptor.class, "attrs"));
+ }
+
+ attrsMapBuilder.put("name", IMPLICIT_NAME_ATTRIBUTE_DESCRIPTOR);
+ List<AttributeInfo> attrInfos =
+ attrsMapBuilder.build().entrySet().stream()
+ .filter(entry -> !entry.getKey().startsWith("_"))
+ .map(entry -> entry.getValue().asAttributeInfo(entry.getKey()))
+ .collect(Collectors.toList());
+ attrInfos.sort(new AttributeNameComparator());
+
+ List<String> aspectAttrs = new ArrayList<>();
+ if (attributeAspects != null) {
+ aspectAttrs = attributeAspects.getContents(String.class, "aspectAttrs");
+ }
+
+ aspectAttrs =
+ aspectAttrs.stream().filter(entry -> !entry.startsWith("_")).collect(Collectors.toList());
+
+ // Only the Builder is passed to AspectInfoWrapper as the aspect name is not yet available.
+ AspectInfo.Builder aspectInfo =
+ AspectInfo.newBuilder()
+ .setDocString(doc)
+ .addAllAttribute(attrInfos)
+ .addAllAspectAttribute(aspectAttrs);
+
+ aspectInfoList.add(new AspectInfoWrapper(fakeAspect, ast.getLocation(), aspectInfo));
+
+ return fakeAspect;
}
/**
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/AspectInfoWrapper.java b/src/main/java/com/google/devtools/build/skydoc/rendering/AspectInfoWrapper.java
new file mode 100644
index 0000000..95d43e1
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/AspectInfoWrapper.java
@@ -0,0 +1,46 @@
+// Copyright 2019 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.skydoc.rendering;
+
+import com.google.devtools.build.lib.events.Location;
+import com.google.devtools.build.lib.syntax.BaseFunction;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AspectInfo;
+
+/** Stores information about a skylark aspect definition. */
+public class AspectInfoWrapper {
+ private final BaseFunction identifierFunction;
+ private final Location location;
+ // Only the Builder is passed to AspectInfoWrapper as the aspect name is not yet available.
+ private final AspectInfo.Builder aspectInfo;
+
+ public AspectInfoWrapper(
+ BaseFunction identifierFunction, Location location, AspectInfo.Builder aspectInfo) {
+ this.identifierFunction = identifierFunction;
+ this.location = location;
+ this.aspectInfo = aspectInfo;
+ }
+
+ public BaseFunction getIdentifierFunction() {
+ return identifierFunction;
+ }
+
+ public Location getLocation() {
+ return location;
+ }
+
+ public AspectInfo.Builder getAspectInfo() {
+ return aspectInfo;
+ }
+}
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/ProtoRenderer.java b/src/main/java/com/google/devtools/build/skydoc/rendering/ProtoRenderer.java
index 5048724..475b701 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/ProtoRenderer.java
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/ProtoRenderer.java
@@ -15,6 +15,7 @@
package com.google.devtools.build.skydoc.rendering;
import com.google.devtools.build.lib.syntax.UserDefinedFunction;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AspectInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ModuleInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ProviderInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.RuleInfo;
@@ -66,6 +67,14 @@
build.writeTo(outputStream);
}
+ /** Appends {@link AspectInfo} protos to a {@link ModuleInfo.Builder}. */
+ public ProtoRenderer appendAspectInfos(Collection<AspectInfo> aspectInfos) {
+ for (AspectInfo aspectInfo : aspectInfos) {
+ moduleInfo.addAspectInfo(aspectInfo);
+ }
+ return this;
+ }
+
public ModuleInfo.Builder getModuleInfo() {
return moduleInfo;
}
diff --git a/src/main/java/com/google/devtools/build/skydoc/rendering/proto/stardoc_output.proto b/src/main/java/com/google/devtools/build/skydoc/rendering/proto/stardoc_output.proto
index 9fc3be7..d8850bf 100644
--- a/src/main/java/com/google/devtools/build/skydoc/rendering/proto/stardoc_output.proto
+++ b/src/main/java/com/google/devtools/build/skydoc/rendering/proto/stardoc_output.proto
@@ -32,6 +32,8 @@
repeated ProviderInfo provider_info = 2;
repeated UserDefinedFunctionInfo func_info = 3;
+
+ repeated AspectInfo aspect_info = 4;
}
// Representation of a Starlark rule attribute type. These generally
@@ -141,3 +143,18 @@
// The fields of the provider.
repeated ProviderFieldInfo field_info = 3;
}
+
+// Representation of a Starlark aspect definition.
+message AspectInfo {
+ // The name of the aspect.
+ string aspect_name = 1;
+
+ // The documentation string of the aspect.
+ string doc_string = 2;
+
+ // The rule attributes along which the aspect propagates.
+ repeated string aspect_attribute = 3;
+
+ // The attributes of the aspect.
+ repeated AttributeInfo attribute = 4;
+}
diff --git a/src/test/java/com/google/devtools/build/skydoc/SkydocTest.java b/src/test/java/com/google/devtools/build/skydoc/SkydocTest.java
index 9917456..29ca936 100644
--- a/src/test/java/com/google/devtools/build/skydoc/SkydocTest.java
+++ b/src/test/java/com/google/devtools/build/skydoc/SkydocTest.java
@@ -31,6 +31,7 @@
import com.google.devtools.build.skydoc.rendering.DocstringParseException;
import com.google.devtools.build.skydoc.rendering.FunctionUtil;
import com.google.devtools.build.skydoc.rendering.ProtoRenderer;
+import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AspectInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.AttributeType;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ModuleInfo;
import com.google.devtools.build.skydoc.rendering.proto.StardocOutputProtos.ProviderInfo;
@@ -94,6 +95,7 @@
Label.parseAbsoluteUnchecked("//test:test.bzl"),
ImmutableMap.builder(),
ImmutableMap.builder(),
+ ImmutableMap.builder(),
ImmutableMap.builder()));
assertThat(expected).hasMessageThat().contains("Starlark evaluation error");
@@ -124,6 +126,7 @@
Label.parseAbsoluteUnchecked("//test:test.bzl"),
ruleInfoMap,
ImmutableMap.builder(),
+ ImmutableMap.builder(),
ImmutableMap.builder());
Map<String, RuleInfo> ruleInfos = ruleInfoMap.build();
assertThat(ruleInfos).hasSize(1);
@@ -148,12 +151,24 @@
.collect(Collectors.toList());
}
+ private static Iterable<String> getAttrNames(AspectInfo aspectInfo) {
+ return aspectInfo.getAttributeList().stream()
+ .map(attr -> attr.getName())
+ .collect(Collectors.toList());
+ }
+
private static Iterable<AttributeType> getAttrTypes(RuleInfo ruleInfo) {
return ruleInfo.getAttributeList().stream()
.map(attr -> attr.getType())
.collect(Collectors.toList());
}
+ private static Iterable<AttributeType> getAttrTypes(AspectInfo aspectInfo) {
+ return aspectInfo.getAttributeList().stream()
+ .map(attr -> attr.getType())
+ .collect(Collectors.toList());
+ }
+
@Test
public void testMultipleRuleNames() throws Exception {
scratch.file(
@@ -188,6 +203,7 @@
Label.parseAbsoluteUnchecked("//test:test.bzl"),
ruleInfoMap,
ImmutableMap.builder(),
+ ImmutableMap.builder(),
ImmutableMap.builder());
assertThat(ruleInfoMap.build().keySet()).containsExactly("rule_one", "rule_two");
@@ -231,6 +247,7 @@
Label.parseAbsoluteUnchecked("//test:main.bzl"),
ruleInfoMapBuilder,
ImmutableMap.builder(),
+ ImmutableMap.builder(),
ImmutableMap.builder());
Map<String, RuleInfo> ruleInfoMap = ruleInfoMapBuilder.build();
@@ -279,6 +296,7 @@
Label.parseAbsoluteUnchecked("//test:main.bzl"),
ruleInfoMapBuilder,
ImmutableMap.builder(),
+ ImmutableMap.builder(),
ImmutableMap.builder());
Map<String, RuleInfo> ruleInfoMap = ruleInfoMapBuilder.build();
@@ -307,6 +325,7 @@
Label.parseAbsoluteUnchecked("//test:main.bzl"),
ruleInfoMapBuilder,
ImmutableMap.builder(),
+ ImmutableMap.builder(),
ImmutableMap.builder());
Map<String, RuleInfo> ruleInfoMap = ruleInfoMapBuilder.build();
@@ -343,6 +362,7 @@
Label.parseAbsoluteUnchecked("//test:main.bzl"),
ImmutableMap.builder(),
ImmutableMap.builder(),
+ ImmutableMap.builder(),
ImmutableMap.builder()));
assertThat(expected).hasMessageThat().contains("cycle with test/main.bzl");
@@ -375,7 +395,8 @@
Label.parseAbsoluteUnchecked("//test:main.bzl"),
ImmutableMap.builder(),
ImmutableMap.builder(),
- functionInfoBuilder);
+ functionInfoBuilder,
+ ImmutableMap.builder());
UserDefinedFunction checkSourcesFn = functionInfoBuilder.build().get("check_sources");
DocstringParseException expected =
@@ -417,7 +438,8 @@
Label.parseAbsoluteUnchecked("//test:test.bzl"),
ImmutableMap.builder(),
ImmutableMap.builder(),
- funcInfoMap);
+ funcInfoMap,
+ ImmutableMap.builder());
Map<String, UserDefinedFunction> functions = funcInfoMap.build();
assertThat(functions).hasSize(1);
@@ -455,6 +477,7 @@
Label.parseAbsoluteUnchecked("//test:test.bzl"),
ImmutableMap.builder(),
providerInfoMap,
+ ImmutableMap.builder(),
ImmutableMap.builder());
Map<String, ProviderInfo> providers = providerInfoMap.build();
@@ -482,4 +505,46 @@
.map(field -> field.getDocString())
.collect(Collectors.toList());
}
+
+ @Test
+ public void testAspectInfo() throws Exception {
+ scratch.file(
+ "/test/test.bzl",
+ "def my_aspect_impl(ctx):\n"
+ + " return []\n"
+ + "\n"
+ + "my_aspect = aspect(\n"
+ + " implementation = my_aspect_impl,\n"
+ + " doc = \"This is my aspect. It does stuff.\",\n"
+ + " attr_aspects = [\"deps\"],\n"
+ + " attrs = {\n"
+ + " \"first\": attr.label(mandatory = True, allow_single_file = True),\n"
+ + " \"second\": attr.string_dict(mandatory = True),\n"
+ + " \"_third\": attr.label(mandatory = True, allow_single_file = True),\n"
+ + " },\n"
+ + ")");
+
+ ImmutableMap.Builder<String, AspectInfo> aspectInfoMap = ImmutableMap.builder();
+
+ skydocMain.eval(
+ StarlarkSemantics.DEFAULT_SEMANTICS,
+ Label.parseAbsoluteUnchecked("//test:test.bzl"),
+ ImmutableMap.builder(),
+ ImmutableMap.builder(),
+ ImmutableMap.builder(),
+ aspectInfoMap);
+ Map<String, AspectInfo> aspectInfos = aspectInfoMap.build();
+ assertThat(aspectInfos).hasSize(1);
+
+ ModuleInfo moduleInfo =
+ new ProtoRenderer().appendAspectInfos(aspectInfos.values()).getModuleInfo().build();
+ AspectInfo aspectInfo = moduleInfo.getAspectInfo(0);
+ assertThat(aspectInfo.getAspectName()).isEqualTo("my_aspect");
+ assertThat(aspectInfo.getDocString()).isEqualTo("This is my aspect. It does stuff.");
+ assertThat(getAttrNames(aspectInfo)).containsExactly("name", "first", "second").inOrder();
+ assertThat(getAttrTypes(aspectInfo))
+ .containsExactly(AttributeType.NAME, AttributeType.LABEL, AttributeType.STRING_DICT)
+ .inOrder();
+ assertThat(aspectInfo.getAspectAttributeList()).containsExactly("deps");
+ }
}