Skip to content

Commit 2fc18a8

Browse files
lberkicopybara-github
authored andcommitted
Implement attr.dormant_label() and attr.dormant_label_list().
This required some ancillary work: 1. Implementing an experimental flag behind which I can put these 2. Implementing the DormantDependency data structure so that dormant attributes can be represented in Starlark 3. Deciding the Starlark API for dormant labels Other than (3), this change is mostly boilerplate and plumbing. RELNOTES: None. PiperOrigin-RevId: 671387069 Change-Id: I4aca5e36085a6d1d3320191e3892611f6c6e09a4
1 parent 737168a commit 2fc18a8

File tree

13 files changed

+382
-2
lines changed

13 files changed

+382
-2
lines changed

src/main/java/com/google/devtools/build/lib/analysis/BUILD

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,7 @@ java_library(
305305
":constraints/supported_environments",
306306
":constraints/supported_environments_provider",
307307
":dependency_kind",
308+
":dormant_dependency",
308309
":exec_group_collection",
309310
":extra/extra_action_info_file_write_action",
310311
":extra_action_artifacts_provider",
@@ -2601,6 +2602,16 @@ java_library(
26012602
],
26022603
)
26032604

2605+
java_library(
2606+
name = "dormant_dependency",
2607+
srcs = ["DormantDependency.java"],
2608+
deps = [
2609+
"//src/main/java/com/google/devtools/build/lib/cmdline",
2610+
"//src/main/java/net/starlark/java/annot",
2611+
"//src/main/java/net/starlark/java/eval",
2612+
],
2613+
)
2614+
26042615
java_library(
26052616
name = "starlark/starlark_late_bound_default",
26062617
srcs = ["starlark/StarlarkLateBoundDefault.java"],

src/main/java/com/google/devtools/build/lib/analysis/DependencyResolutionHelpers.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,8 @@ private static void resolveAttributes(
372372
|| type == BuildType.OUTPUT_LIST
373373
|| type == BuildType.NODEP_LABEL
374374
|| type == BuildType.NODEP_LABEL_LIST
375+
|| type == BuildType.DORMANT_LABEL
376+
|| type == BuildType.DORMANT_LABEL_LIST
375377
|| type == BuildType.GENQUERY_SCOPE_TYPE
376378
|| type == BuildType.GENQUERY_SCOPE_TYPE_LIST) {
377379
// These types invoke visitLabels() so that they are reported in "bazel query" but do not
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright 2024 The Bazel Authors. All rights reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.devtools.build.lib.analysis;
16+
17+
import com.google.devtools.build.lib.cmdline.Label;
18+
import net.starlark.java.annot.StarlarkMethod;
19+
import net.starlark.java.eval.Printer;
20+
import net.starlark.java.eval.StarlarkValue;
21+
22+
/**
23+
* Not an actual dependency, but the possibility of one.
24+
*
25+
* <p>Dormant attributes result in an instance of this object for each possible dependency edge. It
26+
* can then be passed up the dependency graph and turned into an actual dependency ("materialized")
27+
* by rules in the reverse transitive closure.
28+
*/
29+
public record DormantDependency(Label label) implements StarlarkValue {
30+
@Override
31+
public void repr(Printer printer) {
32+
printer.append("<dormant dependency label='");
33+
printer.append(label.toString());
34+
printer.append("'>");
35+
}
36+
37+
@StarlarkMethod(name = "label", doc = "TBD")
38+
public Label getLabel() {
39+
return label;
40+
}
41+
42+
@Override
43+
public boolean isImmutable() {
44+
return true;
45+
}
46+
47+
@Override
48+
public String toString() {
49+
return "<dormant dependency " + label.toString() + ">";
50+
}
51+
}

src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttrModule.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,39 @@ public Descriptor labelListAttribute(
710710
return new Descriptor("label_list", attribute);
711711
}
712712

713+
@Override
714+
public StarlarkAttrModuleApi.Descriptor dormantLabelAttribute(
715+
Object defaultValue, Object doc, Boolean mandatory, StarlarkThread thread)
716+
throws EvalException {
717+
checkContext(thread, "attr.dormant_label()");
718+
719+
ImmutableAttributeFactory attribute =
720+
createAttributeFactory(
721+
BuildType.DORMANT_LABEL,
722+
Starlark.toJavaOptional(doc, String.class),
723+
optionMap(DEFAULT_ARG, defaultValue, MANDATORY_ARG, mandatory),
724+
thread,
725+
"dormant_label");
726+
return new Descriptor("dormant_label", attribute);
727+
}
728+
729+
@Override
730+
public StarlarkAttrModuleApi.Descriptor dormantLabelListAttribute(
731+
Boolean allowEmpty, Object defaultValue, Object doc, Boolean mandatory, StarlarkThread thread)
732+
throws EvalException {
733+
checkContext(thread, "attr.dormant_label_list()");
734+
Map<String, Object> kwargs =
735+
optionMap(DEFAULT_ARG, defaultValue, MANDATORY_ARG, mandatory, ALLOW_EMPTY_ARG, allowEmpty);
736+
ImmutableAttributeFactory attribute =
737+
createAttributeFactory(
738+
BuildType.DORMANT_LABEL_LIST,
739+
Starlark.toJavaOptional(doc, String.class),
740+
kwargs,
741+
thread,
742+
"dormant_label_list");
743+
return new Descriptor("dormant_label_list", attribute);
744+
}
745+
713746
@Override
714747
public Descriptor labelKeyedStringDictAttribute(
715748
Boolean allowEmpty,

src/main/java/com/google/devtools/build/lib/analysis/starlark/StarlarkAttributesCollection.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@
1313
// limitations under the License.
1414
package com.google.devtools.build.lib.analysis.starlark;
1515

16+
import static com.google.common.collect.ImmutableList.toImmutableList;
17+
1618
import com.google.common.collect.ImmutableMap;
1719
import com.google.devtools.build.lib.actions.Artifact;
1820
import com.google.devtools.build.lib.analysis.AliasProvider;
1921
import com.google.devtools.build.lib.analysis.AspectContext;
22+
import com.google.devtools.build.lib.analysis.DormantDependency;
2023
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
2124
import com.google.devtools.build.lib.analysis.PrerequisiteArtifacts;
2225
import com.google.devtools.build.lib.analysis.PrerequisitesCollection;
@@ -208,6 +211,26 @@ public void addAttribute(Attribute a, Object val) {
208211
return;
209212
}
210213

214+
if (type == BuildType.DORMANT_LABEL) {
215+
if (val == null) {
216+
attrBuilder.put(skyname, Starlark.NONE);
217+
} else {
218+
DormantDependency dormantDep = new DormantDependency(BuildType.DORMANT_LABEL.cast(val));
219+
attrBuilder.put(skyname, dormantDep);
220+
}
221+
return;
222+
}
223+
224+
if (type == BuildType.DORMANT_LABEL_LIST) {
225+
StarlarkList<DormantDependency> dormantDeps =
226+
StarlarkList.immutableCopyOf(
227+
BuildType.DORMANT_LABEL_LIST.cast(val).stream()
228+
.map(DormantDependency::new)
229+
.collect(toImmutableList()));
230+
attrBuilder.put(skyname, dormantDeps);
231+
return;
232+
}
233+
211234
// TODO(b/140636597): Remove the LABEL_DICT_UNARY special case of this conditional
212235
// LABEL_DICT_UNARY was previously not treated as a dependency-bearing type, and was put into
213236
// Starlark as a Map<String, Label>; this special case preserves that behavior temporarily.

src/main/java/com/google/devtools/build/lib/packages/AttributeFormatter.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
package com.google.devtools.build.lib.packages;
1515

1616
import static com.google.devtools.build.lib.packages.BuildType.DISTRIBUTIONS;
17+
import static com.google.devtools.build.lib.packages.BuildType.DORMANT_LABEL;
18+
import static com.google.devtools.build.lib.packages.BuildType.DORMANT_LABEL_LIST;
1719
import static com.google.devtools.build.lib.packages.BuildType.GENQUERY_SCOPE_TYPE;
1820
import static com.google.devtools.build.lib.packages.BuildType.GENQUERY_SCOPE_TYPE_LIST;
1921
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
@@ -213,7 +215,8 @@ private static void writeAttributeValueToBuilder(
213215
} else if (type == LABEL
214216
|| type == NODEP_LABEL
215217
|| type == OUTPUT
216-
|| type == GENQUERY_SCOPE_TYPE) {
218+
|| type == GENQUERY_SCOPE_TYPE
219+
|| type == DORMANT_LABEL) {
217220
builder.setStringValue(labelPrinter.toString((Label) value));
218221
} else if (type == STRING_LIST || type == DISTRIBUTIONS) {
219222
for (Object entry : (Collection<?>) value) {
@@ -222,7 +225,8 @@ private static void writeAttributeValueToBuilder(
222225
} else if (type == LABEL_LIST
223226
|| type == NODEP_LABEL_LIST
224227
|| type == OUTPUT_LIST
225-
|| type == GENQUERY_SCOPE_TYPE_LIST) {
228+
|| type == GENQUERY_SCOPE_TYPE_LIST
229+
|| type == DORMANT_LABEL_LIST) {
226230
for (Label entry : (Collection<Label>) value) {
227231
builder.addStringListValue(labelPrinter.toString(entry));
228232
}

src/main/java/com/google/devtools/build/lib/packages/BuildType.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ public final class BuildType {
8181
@SerializationConstant
8282
public static final ListType<Label> NODEP_LABEL_LIST = ListType.create(NODEP_LABEL);
8383

84+
@SerializationConstant
85+
public static final Type<Label> DORMANT_LABEL =
86+
new LabelType(LabelClass.GENQUERY_SCOPE_REFERENCE);
87+
88+
@SerializationConstant
89+
public static final ListType<Label> DORMANT_LABEL_LIST = ListType.create(DORMANT_LABEL);
90+
8491
/**
8592
* This is a label type that causes dependencies, but the dependencies are NOT to be configured.
8693
* Does not say anything about whether the attribute of this type is itself configurable.

src/main/java/com/google/devtools/build/lib/packages/ProtoUtils.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
package com.google.devtools.build.lib.packages;
1616

1717
import static com.google.devtools.build.lib.packages.BuildType.DISTRIBUTIONS;
18+
import static com.google.devtools.build.lib.packages.BuildType.DORMANT_LABEL;
19+
import static com.google.devtools.build.lib.packages.BuildType.DORMANT_LABEL_LIST;
1820
import static com.google.devtools.build.lib.packages.BuildType.GENQUERY_SCOPE_TYPE;
1921
import static com.google.devtools.build.lib.packages.BuildType.GENQUERY_SCOPE_TYPE_LIST;
2022
import static com.google.devtools.build.lib.packages.BuildType.LABEL;
@@ -55,6 +57,8 @@ public class ProtoUtils {
5557
.put(GENQUERY_SCOPE_TYPE, Discriminator.LABEL)
5658
.put(GENQUERY_SCOPE_TYPE_LIST, Discriminator.LABEL_LIST)
5759
.put(NODEP_LABEL_LIST, Discriminator.STRING_LIST)
60+
.put(DORMANT_LABEL, Discriminator.LABEL_LIST)
61+
.put(DORMANT_LABEL_LIST, Discriminator.STRING_LIST)
5862
.put(STRING, Discriminator.STRING)
5963
.put(STRING_NO_INTERN, Discriminator.STRING)
6064
.put(STRING_LIST, Discriminator.STRING_LIST)

src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,18 @@ public final class BuildLanguageOptions extends OptionsBase {
751751
help = "Enable experimental rule extension API and subrule APIs")
752752
public boolean experimentalRuleExtensionApi;
753753

754+
@Option(
755+
name = "experimental_dormant_deps",
756+
defaultValue = "false",
757+
documentationCategory = OptionDocumentationCategory.STARLARK_SEMANTICS,
758+
effectTags = {OptionEffectTag.BUILD_FILE_SEMANTICS},
759+
metadataTags = {OptionMetadataTag.EXPERIMENTAL},
760+
help =
761+
" If set to true, attr.label(materializer=), attr(for_dependency_resolution=),"
762+
+ " attr.dormant_label(), attr.dormant_label_list() and"
763+
+ " rule(for_dependency_resolution=) are allowed.")
764+
public boolean experimentalDormantDeps;
765+
754766
@Option(
755767
name = "incompatible_enable_deprecated_label_apis",
756768
defaultValue = "true",
@@ -877,6 +889,7 @@ public StarlarkSemantics toStarlarkSemantics() {
877889
INCOMPATIBLE_DISABLE_TARGET_DEFAULT_PROVIDER_FIELDS,
878890
incompatibleDisableTargetDefaultProviderFields)
879891
.setBool(EXPERIMENTAL_RULE_EXTENSION_API, experimentalRuleExtensionApi)
892+
.setBool(EXPERIMENTAL_DORMANT_DEPS, experimentalDormantDeps)
880893
.setBool(INCOMPATIBLE_ENABLE_DEPRECATED_LABEL_APIS, enableDeprecatedLabelApis)
881894
.setBool(
882895
INCOMPATIBLE_STOP_EXPORTING_BUILD_FILE_PATH, incompatibleStopExportingBuildFilePath)
@@ -975,6 +988,7 @@ public StarlarkSemantics toStarlarkSemantics() {
975988
public static final String INCOMPATIBLE_DISABLE_TARGET_DEFAULT_PROVIDER_FIELDS =
976989
"-incompatible_disable_target_default_provider_fields";
977990
public static final String EXPERIMENTAL_RULE_EXTENSION_API = "-experimental_rule_extension_api";
991+
public static final String EXPERIMENTAL_DORMANT_DEPS = "-experimental_dormant_deps";
978992
public static final String INCOMPATIBLE_ENABLE_DEPRECATED_LABEL_APIS =
979993
"+incompatible_enable_deprecated_label_apis";
980994
public static final String INCOMPATIBLE_STOP_EXPORTING_BUILD_FILE_PATH =

src/main/java/com/google/devtools/build/lib/query2/query/output/ProtoOutputFormatter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public class ProtoOutputFormatter extends AbstractUnorderedFormatter {
9393
Type.STRING,
9494
BuildType.LABEL,
9595
BuildType.NODEP_LABEL,
96+
BuildType.DORMANT_LABEL,
9697
BuildType.OUTPUT,
9798
Type.BOOLEAN,
9899
BuildType.TRISTATE,
@@ -508,6 +509,7 @@ private static Object getFlattenedAttributeValues(Type<?> attrType, Rule rule, A
508509
if (attrType == Types.STRING_LIST
509510
|| attrType == BuildType.LABEL_LIST
510511
|| attrType == BuildType.NODEP_LABEL_LIST
512+
|| attrType == BuildType.DORMANT_LABEL_LIST
511513
|| attrType == BuildType.OUTPUT_LIST
512514
|| attrType == BuildType.DISTRIBUTIONS
513515
|| attrType == Types.INTEGER_LIST) {

0 commit comments

Comments
 (0)