From 9edc821c0b444411fb18c0ddb005988a983c645e Mon Sep 17 00:00:00 2001 From: Greg Estren Date: Mon, 9 Feb 2015 21:38:59 +0000 Subject: Configurable attributes: allow multiple matches so long as one is a specialization of the other (e.g. {"foo=bar"} and {"foo=bar", "baz=bug"}. The most precise one wins. RELNOTES: When two configurable attribute conditions match and one is a specialization of the other, the most precise match is chosen. -- MOS_MIGRATED_REVID=85921611 --- .../lib/analysis/ConfiguredAttributeMapper.java | 31 ++++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) (limited to 'src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAttributeMapper.java') diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAttributeMapper.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAttributeMapper.java index 84029b2046..67ff7a23c7 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAttributeMapper.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAttributeMapper.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.analysis; import com.google.common.base.Preconditions; +import com.google.common.base.Verify; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider; @@ -102,25 +103,33 @@ public class ConfiguredAttributeMapper extends AbstractAttributeMapper { return super.get(attributeName, type); } - // We expect exactly one of this attribute's conditions to match (including the default - // condition, if specified). Throw an exception if our expectations aren't met. - Label matchingCondition = null; + ConfigMatchingProvider matchingCondition = null; T matchingValue = null; // Find the matching condition and record its value (checking for duplicates). for (Map.Entry entry : selector.getEntries().entrySet()) { - Label curCondition = entry.getKey(); - if (Type.Selector.isReservedLabel(curCondition)) { + Label selectorKey = entry.getKey(); + if (Type.Selector.isReservedLabel(selectorKey)) { continue; - } else if (Preconditions.checkNotNull(configConditions.get(curCondition)).matches()) { - if (matchingCondition != null) { + } + + ConfigMatchingProvider curCondition = Verify.verifyNotNull(configConditions.get(selectorKey)); + + if (curCondition.matches()) { + if (matchingCondition == null || curCondition.refines(matchingCondition)) { + // A match is valid if either this is the *only* condition that matches or this is a + // more "precise" specification of another matching condition (in which case we choose + // the most precise one). + matchingCondition = curCondition; + matchingValue = entry.getValue(); + } else if (matchingCondition.refines(curCondition)) { + // The originally matching conditions is more precise, so keep that one. + } else { throw new EvalException(rule.getAttributeLocation(attributeName), - "Both " + matchingCondition.toString() + " and " + curCondition.toString() + "Both " + matchingCondition.label() + " and " + curCondition.label() + " match configurable attribute \"" + attributeName + "\" in " + getLabel() - + ". At most one match is allowed"); + + ". Multiple matches are not allowed unless one is a specialization of the other"); } - matchingCondition = curCondition; - matchingValue = entry.getValue(); } } -- cgit v1.2.3