Skip to content

Commit

Permalink
starlark_doc_extract: expose providers' custom init callback in extra…
Browse files Browse the repository at this point in the history
…cted docs

Note that init's signature may have little relation to the list of fields of
the constructed provider, so exposing a full StarlarkFunctionInfo for the init
is appropriate.

Working towards bazelbuild/stardoc#182

PiperOrigin-RevId: 559112284
Change-Id: I5a4821cde492676553a40400ff1e7831a069294f
  • Loading branch information
tetromino authored and Copybara-Service committed Aug 22, 2023
1 parent fb504ee commit bf5504a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@

package com.google.devtools.build.lib.packages;


import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
Expand Down Expand Up @@ -306,8 +304,10 @@ public StarlarkCallable createRawConstructor() {
return new RawConstructor(this);
}

/**
* Returns the provider's custom initializer callback, or null if the provider doesn't have one.
*/
@Nullable
@VisibleForTesting
public StarlarkCallable getInit() {
return init;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,8 @@ private void maybeVisit(
protected void visitRule(String qualifiedName, StarlarkRuleFunction value)
throws ExtractionException {}

protected void visitProvider(String qualifiedName, StarlarkProvider value) {}
protected void visitProvider(String qualifiedName, StarlarkProvider value)
throws ExtractionException {}

protected void visitFunction(String qualifiedName, StarlarkFunction value)
throws ExtractionException {}
Expand Down Expand Up @@ -376,7 +377,8 @@ protected void visitRule(String qualifiedName, StarlarkRuleFunction ruleFunction
}

@Override
protected void visitProvider(String qualifiedName, StarlarkProvider provider) {
protected void visitProvider(String qualifiedName, StarlarkProvider provider)
throws ExtractionException {
ProviderInfo.Builder providerInfoBuilder = ProviderInfo.newBuilder();
// Record the name under which this symbol is made accessible, which may differ from the
// symbol's exported name.
Expand Down Expand Up @@ -408,6 +410,22 @@ protected void visitProvider(String qualifiedName, StarlarkProvider provider) {
}
}
}
// TODO(b/276733504): if init is a dict-returning native method (e.g. `dict`), do we document
// it? (This is very unlikely to be useful at present, and would require parsing annotations
// on the native method.)
if (provider.getInit() instanceof StarlarkFunction) {
try {
providerInfoBuilder.setInit(
StarlarkFunctionInfoExtractor.fromNameAndFunction(
qualifiedName,
(StarlarkFunction) provider.getInit(),
/* withOriginKey= */ true,
labelRenderer));
} catch (DocstringParseException e) {
throw new ExtractionException(e);
}
}

moduleInfoBuilder.addProviderInfo(providerInfoBuilder);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,14 @@ message ProviderInfo {
// The fields of the provider.
repeated ProviderFieldInfo field_info = 3;

// Note: legacy Stardoc (0.5.x and earlier) does not set any fields below.

// The module where and the name under which the provider was originally
// declared.
//
// Note: legacy Stardoc (0.5.x and earlier) does not set this field.
OriginKey origin_key = 4;

// The provider's init callback.
StarlarkFunctionInfo init = 5;
}

// Representation of a Starlark aspect definition.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,60 @@ public void providerFields() throws Exception {
.build());
}

@Test
public void providerInit() throws Exception {
Module module =
exec(
"def _my_info_init(x_value, y_value = 0):",
" '''MyInfo constructor",
"",
" Args:",
" x_value: my x value",
" y_value: my y value",
" '''",
" return {'x': x_value, 'y': y_value}",
"",
"_MyInfo, _new_my_info = provider(",
" doc = '''My provider''',",
" fields = ['x', 'y'],",
" init = _my_info_init,",
")",
"",
"namespace = struct(",
" MyInfo = _MyInfo,",
")");
ModuleInfo moduleInfo = getExtractor().extractFrom(module);
assertThat(moduleInfo.getProviderInfoList())
.containsExactly(
ProviderInfo.newBuilder()
.setProviderName("namespace.MyInfo")
.setDocString("My provider")
.addFieldInfo(ProviderFieldInfo.newBuilder().setName("x"))
.addFieldInfo(ProviderFieldInfo.newBuilder().setName("y"))
.setInit(
StarlarkFunctionInfo.newBuilder()
.setFunctionName("namespace.MyInfo")
.setDocString("MyInfo constructor")
.addParameter(
FunctionParamInfo.newBuilder()
.setName("x_value")
.setDocString("my x value")
.setMandatory(true)
.build())
.addParameter(
FunctionParamInfo.newBuilder()
.setName("y_value")
.setDocString("my y value")
.setDefaultValue("0")
.build())
.setOriginKey(
OriginKey.newBuilder()
.setName("_my_info_init")
.setFile(fakeLabelString)))
.setOriginKey(OriginKey.newBuilder().setName("_MyInfo").setFile(fakeLabelString))
.build());
}

@Test
public void ruleDocstring() throws Exception {
Module module =
Expand Down

0 comments on commit bf5504a

Please sign in to comment.