Skip to content

Commit 7a537ca

Browse files
fmeumcopybara-github
authored andcommitted
Fix visibility check at definition for aspects
With `--incompatible_visibility_private_attributes_at_definition`, the visibility of aspects (and aspects on aspects) into their implicit dependencies is now checked relative to the aspect's, not the rule's definition. This requires ensuring the precedence of aspect on aspect attributes over those of the underlying aspect in `DependencyResolutionHelper`, which was hinted at by a comment but not realized. Closes #19442. PiperOrigin-RevId: 567333681 Change-Id: I167c45fea8535e0f35c0298ca1cb9f845c9fe2d2
1 parent b7678af commit 7a537ca

File tree

4 files changed

+419
-5
lines changed

4 files changed

+419
-5
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,7 @@ java_library(
654654
"//src/main/java/com/google/devtools/build/lib/packages",
655655
"//src/main/java/com/google/devtools/build/lib/packages/semantics",
656656
"//src/main/java/com/google/devtools/build/lib/skyframe:configured_target_and_data",
657+
"//third_party:guava",
657658
],
658659
)
659660

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

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

16+
import static com.google.common.base.Preconditions.checkNotNull;
1617
import static com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper.attributeOrNull;
1718

1819
import com.google.devtools.build.lib.analysis.AliasProvider.TargetMode;
1920
import com.google.devtools.build.lib.analysis.RuleContext.PrerequisiteValidator;
2021
import com.google.devtools.build.lib.analysis.configuredtargets.PackageGroupConfiguredTarget;
2122
import com.google.devtools.build.lib.cmdline.Label;
2223
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
24+
import com.google.devtools.build.lib.packages.Aspect;
2325
import com.google.devtools.build.lib.packages.Attribute;
2426
import com.google.devtools.build.lib.packages.FunctionSplitTransitionAllowlist;
2527
import com.google.devtools.build.lib.packages.InputFile;
2628
import com.google.devtools.build.lib.packages.NonconfigurableAttributeMapper;
2729
import com.google.devtools.build.lib.packages.RawAttributeMapper;
2830
import com.google.devtools.build.lib.packages.Rule;
2931
import com.google.devtools.build.lib.packages.RuleClass;
32+
import com.google.devtools.build.lib.packages.StarlarkAspectClass;
3033
import com.google.devtools.build.lib.packages.Type;
3134
import com.google.devtools.build.lib.packages.semantics.BuildLanguageOptions;
3235
import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
@@ -105,16 +108,33 @@ private void validateDirectPrerequisiteVisibility(
105108
if (!toolCheckAtDefinition
106109
|| !attribute.isImplicit()
107110
|| attribute.getName().equals(RuleClass.CONFIG_SETTING_DEPS_ATTRIBUTE)
108-
|| rule.getRuleClassObject().getRuleDefinitionEnvironmentLabel() == null) {
111+
|| !context.isStarlarkRuleOrAspect()) {
109112
// Default check: The attribute must be visible from the target.
110113
if (!context.isVisible(prerequisite.getConfiguredTarget())) {
111114
handleVisibilityConflict(context, prerequisite, rule.getLabel());
112115
}
113116
} else {
114-
// For implicit attributes, check if the prerequisite is visible from the location of the
115-
// rule definition
116-
Label implicitDefinition = rule.getRuleClassObject().getRuleDefinitionEnvironmentLabel();
117-
if (!RuleContext.isVisible(implicitDefinition, prerequisite.getConfiguredTarget())) {
117+
// For implicit attributes of Starlark rules or aspects, check if the prerequisite is visible
118+
// from the location of the definition that declares the attribute. Only perform this check
119+
// for the current aspect.
120+
Label implicitDefinition = null;
121+
Aspect mainAspect = context.getMainAspect();
122+
if (mainAspect != null) {
123+
// Only verify visibility of implicit dependencies of the current aspect. Implicit
124+
// dependencies of other aspects as well as the rule itself are checked when they are
125+
// evaluated.
126+
if (mainAspect.getDefinition().getAttributes().containsKey(attrName)) {
127+
StarlarkAspectClass aspectClass = (StarlarkAspectClass) mainAspect.getAspectClass();
128+
// Never null since we already checked that the aspect is Starlark-defined.
129+
implicitDefinition = checkNotNull(aspectClass.getExtensionLabel());
130+
}
131+
} else {
132+
// Never null since we already checked that the rule is a Starlark rule.
133+
implicitDefinition =
134+
checkNotNull(rule.getRuleClassObject().getRuleDefinitionEnvironmentLabel());
135+
}
136+
if (implicitDefinition != null
137+
&& !RuleContext.isVisible(implicitDefinition, prerequisite.getConfiguredTarget())) {
118138
handleVisibilityConflict(context, prerequisite, implicitDefinition);
119139
}
120140
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
import com.google.devtools.build.lib.packages.Rule;
8282
import com.google.devtools.build.lib.packages.RuleClass;
8383
import com.google.devtools.build.lib.packages.RuleClass.ConfiguredTargetFactory.RuleErrorException;
84+
import com.google.devtools.build.lib.packages.StarlarkAspectClass;
8485
import com.google.devtools.build.lib.packages.StarlarkProviderWrapper;
8586
import com.google.devtools.build.lib.packages.SymbolGenerator;
8687
import com.google.devtools.build.lib.packages.Target;
@@ -2031,6 +2032,20 @@ public boolean isVisible(TransitiveInfoCollection prerequisite) {
20312032
return RuleContext.isVisible(target.getAssociatedRule(), prerequisite);
20322033
}
20332034

2035+
@Nullable
2036+
Aspect getMainAspect() {
2037+
return Streams.findLast(aspects.stream()).orElse(null);
2038+
}
2039+
2040+
boolean isStarlarkRuleOrAspect() {
2041+
Aspect mainAspect = getMainAspect();
2042+
if (mainAspect != null) {
2043+
return mainAspect.getAspectClass() instanceof StarlarkAspectClass;
2044+
} else {
2045+
return getRule().getRuleClassObject().getRuleDefinitionEnvironmentLabel() != null;
2046+
}
2047+
}
2048+
20342049
private void validateDirectPrerequisiteFileTypes(
20352050
ConfiguredTargetAndData prerequisite, Attribute attribute) {
20362051
if (attribute.isSkipAnalysisTimeFileTypeCheck()) {

0 commit comments

Comments
 (0)