aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Nathan Harmata <nharmata@google.com>2016-04-05 19:49:43 +0000
committerGravatar Lukacs Berki <lberki@google.com>2016-04-07 11:40:36 +0000
commit351475627b9e94e5afdf472cbf465f49c433a25e (patch)
tree464c30ffd1bf8b023fef87d8d2549d956c859d9f
parenteb89cccfd3aff746b59da3feb31eb3ae528ce909 (diff)
Make non-empty attribute checks happen during analysis of the target in question, rather than during loading of the target's package. This way a target's package won't be in error if e.g. an unrelated target has empty 'srcs'.
-- MOS_MIGRATED_REVID=119079777
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/RuleClass.java41
-rw-r--r--src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java4
-rw-r--r--src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java62
-rw-r--r--src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java5
5 files changed, 31 insertions, 92 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
index 706d986193..5eac0d686a 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleContext.java
@@ -158,6 +158,7 @@ public final class RuleContext extends TargetContext
private RuleContext(
Builder builder,
+ AttributeMap attributes,
ListMultimap<String, ConfiguredTarget> targetMap,
ListMultimap<String, ConfiguredFilesetEntry> filesetEntryMap,
Set<ConfigMatchingProvider> configConditions,
@@ -172,8 +173,7 @@ public final class RuleContext extends TargetContext
this.targetMap = targetMap;
this.filesetEntryMap = filesetEntryMap;
this.configConditions = configConditions;
- this.attributes =
- ConfiguredAttributeMapper.of(builder.rule, configConditions);
+ this.attributes = attributes;
this.features = getEnabledFeatures();
this.ruleClassNameForLogging = ruleClassNameForLogging;
this.aspectAttributes = aspectAttributes;
@@ -1306,11 +1306,14 @@ public final class RuleContext extends TargetContext
Preconditions.checkNotNull(prerequisiteMap);
Preconditions.checkNotNull(configConditions);
Preconditions.checkNotNull(visibility);
+ AttributeMap attributes = ConfiguredAttributeMapper.of(rule, configConditions);
+ validateAttributes(attributes);
ListMultimap<String, ConfiguredTarget> targetMap = createTargetMap();
ListMultimap<String, ConfiguredFilesetEntry> filesetEntryMap =
createFilesetEntryMap(rule, configConditions);
return new RuleContext(
this,
+ attributes,
targetMap,
filesetEntryMap,
configConditions,
@@ -1319,6 +1322,10 @@ public final class RuleContext extends TargetContext
aspectAttributes != null ? aspectAttributes : ImmutableMap.<String, Attribute>of());
}
+ private void validateAttributes(AttributeMap attributes) {
+ rule.getRuleClassObject().checkAttributesNonEmpty(rule, reporter, attributes);
+ }
+
Builder setVisibility(NestedSet<PackageSpecification> visibility) {
this.visibility = visibility;
return this;
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
index 9accac3899..ed2ad3064c 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java
@@ -1401,7 +1401,6 @@ public final class RuleClass {
boolean explicit = attributeValues.isAttributeExplicitlySpecified(attributeName);
setRuleAttributeValue(rule, eventHandler, attr, nativeAttributeValue, explicit);
definedAttrIndices.set(attrIndex);
- checkAttrValNonEmpty(rule, eventHandler, attributeValue, attr);
}
return definedAttrIndices;
}
@@ -1457,7 +1456,6 @@ public final class RuleClass {
attrsWithComputedDefaults.add(attr);
} else {
Object defaultValue = getAttributeNoncomputedDefaultValue(attr, pkgBuilder);
- checkAttrValNonEmpty(rule, eventHandler, defaultValue, attr);
rule.setAttributeValue(attr, defaultValue, /*explicit=*/ false);
checkAllowedValues(rule, attr, eventHandler);
}
@@ -1500,26 +1498,27 @@ public final class RuleClass {
/*explicit=*/false);
}
- private void checkAttrValNonEmpty(
- Rule rule, EventHandler eventHandler, Object attributeValue, Attribute attr) {
- if (!attr.isNonEmpty()) {
- return;
- }
-
- boolean isEmpty = false;
-
- if (attributeValue instanceof SkylarkList) {
- isEmpty = ((SkylarkList) attributeValue).isEmpty();
- } else if (attributeValue instanceof List<?>) {
- isEmpty = ((List<?>) attributeValue).isEmpty();
- } else if (attributeValue instanceof Map<?, ?>) {
- isEmpty = ((Map<?, ?>) attributeValue).isEmpty();
- }
+ public void checkAttributesNonEmpty(
+ Rule rule, RuleErrorConsumer ruleErrorConsumer, AttributeMap attributes) {
+ for (String attributeName : attributes.getAttributeNames()) {
+ Attribute attr = attributes.getAttributeDefinition(attributeName);
+ if (!attr.isNonEmpty()) {
+ continue;
+ }
+ Object attributeValue = attributes.get(attributeName, attr.getType());
+
+ boolean isEmpty = false;
+ if (attributeValue instanceof SkylarkList) {
+ isEmpty = ((SkylarkList) attributeValue).isEmpty();
+ } else if (attributeValue instanceof List<?>) {
+ isEmpty = ((List<?>) attributeValue).isEmpty();
+ } else if (attributeValue instanceof Map<?, ?>) {
+ isEmpty = ((Map<?, ?>) attributeValue).isEmpty();
+ }
- if (isEmpty) {
- rule.reportError(rule.getLabel() + ": non empty attribute '" + attr.getName()
- + "' in '" + name + "' rule '" + rule.getLabel() + "' has to have at least one value",
- eventHandler);
+ if (isEmpty) {
+ ruleErrorConsumer.attributeError(attr.getName(), "attribute must be non empty");
+ }
}
}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 541356f75f..abb7a79772 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -1449,8 +1449,8 @@ public abstract class BuildViewTestCase extends FoundationTestCase {
}
protected String getErrorMsgNonEmptyList(String attrName, String ruleType, String ruleName) {
- return "non empty attribute '" + attrName + "' in '" + ruleType
- + "' rule '" + ruleName + "' has to have at least one value";
+ return "in " + attrName + " attribute of " + ruleType + " rule " + ruleName + ": attribute "
+ + "must be non empty";
}
protected String getErrorMsgMandatoryMissing(String attrName, String ruleType) {
diff --git a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
index 93ca76a9b3..36d539a6ec 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/RuleClassTest.java
@@ -613,68 +613,6 @@ public class RuleClassTest extends PackageLoadingTestCase {
attributes.get("my-sorted-stringlist-attr", Type.STRING_LIST));
}
- @Test
- public void testNonEmptyGood() throws Exception {
- RuleClass mneRuleClass = setupNonEmpty(
- attr("list1", LABEL_LIST).mandatory().legacyAllowAnyFileType().build(),
- attr("list2", LABEL_LIST).nonEmpty().legacyAllowAnyFileType().build(),
- attr("list3", STRING_LIST).nonEmpty().build());
-
- Map<String, Object> attributeValues = new LinkedHashMap<>();
- attributeValues.put("list1", Lists.newArrayList());
- attributeValues.put("list2", Lists.newArrayList(":nodup1", ":nodup2"));
- attributeValues.put("list3", Lists.newArrayList("val1", "val2"));
-
- createRule(mneRuleClass, "ruleTestMNE", attributeValues, testRuleLocation);
- }
-
- @Test
- public void testNonEmptyFail() throws Exception {
- RuleClass mandNonEmptyRuleClass = setupNonEmpty(
- attr("list", LABEL_LIST).nonEmpty().legacyAllowAnyFileType().build());
-
- Map<String, Object> attributeValues = new LinkedHashMap<>();
- attributeValues.put("list", Lists.newArrayList());
-
- reporter.removeHandler(failFastHandler);
- createRule(mandNonEmptyRuleClass, "ruleTestMNE", attributeValues, testRuleLocation);
-
- assertSame(1, eventCollector.count());
- assertContainsEvent(getErrorMsgNonEmptyList(
- "list", "ruleMNE", "//testpackage:ruleTestMNE"));
- }
-
- private RuleClass setupNonEmpty(Attribute... attributes) {
- RuleClass mandNonEmptyRuleClass = new RuleClass(
- "ruleMNE", false, false, false, false, false, false,
- ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
- PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
- ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
- MissingFragmentPolicy.FAIL_ANALYSIS, true, attributes);
- return mandNonEmptyRuleClass;
- }
-
- @Test
- public void testNonEmptyWrongDefVal() throws Exception {
- List<Label> emptyList = ImmutableList.of();
- RuleClass mandNonEmptyRuleClass = new RuleClass(
- "ruleMNE", false, false, false, false, false, false,
- ImplicitOutputsFunction.NONE, RuleClass.NO_CHANGE, DUMMY_CONFIGURED_TARGET_FACTORY,
- PredicatesWithMessage.<Rule>alwaysTrue(), PREFERRED_DEPENDENCY_PREDICATE,
- ImmutableSet.<Class<?>>of(), null, NO_EXTERNAL_BINDINGS, null, ImmutableSet.<Class<?>>of(),
- MissingFragmentPolicy.FAIL_ANALYSIS, true, attr("list", LABEL_LIST)
- .nonEmpty().legacyAllowAnyFileType().value(emptyList).build());
-
- Map<String, Object> attributeValues = new LinkedHashMap<>();
- reporter.removeHandler(failFastHandler);
- createRule(mandNonEmptyRuleClass, "ruleTestMNE", attributeValues, testRuleLocation);
-
- assertSame(1, eventCollector.count());
-
- assertContainsEvent(getErrorMsgNonEmptyList(
- "list", "ruleMNE", "//testpackage:ruleTestMNE"));
- }
-
private Rule createRule(RuleClass ruleClass, String name, Map<String, Object> attributeValues,
Location location) throws LabelSyntaxException, InterruptedException {
Package.Builder pkgBuilder = createDummyPackageBuilder();
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
index 1a0c5d9877..7af31eccd8 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
@@ -276,9 +276,4 @@ public abstract class PackageLoadingTestCase extends FoundationTestCase {
skyframeExecutor.invalidateFilesUnderPathForTesting(
reporter, ModifiedFileSet.EVERYTHING_MODIFIED, rootDirectory);
}
-
- protected String getErrorMsgNonEmptyList(String attrName, String ruleType, String ruleName) {
- return "non empty attribute '" + attrName + "' in '" + ruleType
- + "' rule '" + ruleName + "' has to have at least one value";
- }
}