Improve AttributeImplementationTest to generate correct dependencies.
@@ -28,6 +28,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
/**
@@ -112,11 +113,11 @@ public class BuildRuleWithDefaultsBuilder extends BuildRuleBuilder {
Predicate<RuleClass> allowedRuleClasses = attribute.getAllowedRuleClassesPredicate();
if (allowedRuleClasses != Predicates.<RuleClass>alwaysFalse()) {
// See if there is an applicable rule among the already enqueued rules
- BuildRuleBuilder referencedRuleBuilder = getFirstApplicableRule(allowedRuleClasses);
+ BuildRuleBuilder referencedRuleBuilder = getFirstApplicableRule(attribute);
if (referencedRuleBuilder != null) {
label = ":" + referencedRuleBuilder.ruleName;
} else {
- RuleClass referencedRuleClass = getFirstApplicableRuleClass(allowedRuleClasses);
+ RuleClass referencedRuleClass = getFirstApplicableRuleClass(attribute);
if (referencedRuleClass != null) {
// Generate a rule with the appropriate ruleClass and a label for it in
// the original rule
@@ -135,25 +136,46 @@ public class BuildRuleWithDefaultsBuilder extends BuildRuleBuilder {
return this;
}
- private BuildRuleBuilder getFirstApplicableRule(Predicate<RuleClass> allowedRuleClasses) {
- // There is no direct way to get the set of allowedRuleClasses from the Attribute
- // The Attribute API probably should not be modified for sole testing purposes
- for (Map.Entry<String, BuildRuleBuilder> entry : generateRules.entrySet()) {
- if (allowedRuleClasses.apply(ruleClassMap.get(entry.getKey()))) {
- return entry.getValue();
- }
+ private boolean doesRuleClassMatch(Attribute attribute, RuleClass ruleClass) {
+ // The rule class isn't in the allowed list.
+ if (!attribute.getAllowedRuleClassesPredicate().apply(ruleClass)) {
+ return false;
}
- return null;
+
+ // Does this rule class have the correct providers?
+ if (!attribute.getRequiredProviders().acceptsAny()) {
+ // This attribute requires specific providers, so ignore any rule that claims to have every
+ // provider.
+ if (ruleClass.getAdvertisedProviders().canHaveAnyProvider()) {
+ return false;
}
- private RuleClass getFirstApplicableRuleClass(Predicate<RuleClass> allowedRuleClasses) {
- // See comments in getFirstApplicableRule(Predicate<RuleClass> allowedRuleClasses)
- for (RuleClass ruleClass : ruleClassMap.values()) {
- if (allowedRuleClasses.apply(ruleClass)) {
- return ruleClass;
+ if (!attribute.getRequiredProviders().isSatisfiedBy(ruleClass.getAdvertisedProviders())) {
+ return false;
}
}
- return null;
+
+ // Default to accept if nothing else prevents.
+ return true;
+ }
+
+ private BuildRuleBuilder getFirstApplicableRule(Attribute attribute) {
+ // There is no direct way to get the set of allowedRuleClasses from the Attribute
+ // The Attribute API probably should not be modified for sole testing purposes
+ Optional<BuildRuleBuilder> result =
+ generateRules.entrySet().stream()
+ .filter(entry -> doesRuleClassMatch(attribute, ruleClassMap.get(entry.getKey())))
+ .map(Map.Entry::getValue)
+ .findFirst();
+ return result.orElse(null);
+ }
+
+ private RuleClass getFirstApplicableRuleClass(Attribute attribute) {
+ Optional<RuleClass> result =
+ ruleClassMap.values().stream()
+ .filter(ruleClass -> doesRuleClassMatch(attribute, ruleClass))
+ .findFirst();
+ return result.orElse(null);
}
public BuildRuleWithDefaultsBuilder populateStringListAttribute(Attribute attribute) {
