use of com.google.devtools.build.lib.packages.BuildType.Selector in project bazel by bazelbuild.
the class AggregatingAttributeMapper method visitConfigurableAttribute.
/**
* Determines all possible values a configurable attribute can take. Do not call this method
* unless really necessary (see TODO comment inside).
*
* @param selectors the selectors that make up this attribute assignment (in order)
* @param boundSelectorPaths paths that have already been chosen from previous selectors in an
* earlier recursive call of this method. For example, given
* <pre>cmd = select({':a': 'w', ':b': 'x'}) + select({':a': 'y', ':b': 'z'})</pre>
* the only possible values for <code>cmd</code> are <code>"wy"</code> and <code>"xz"</code>.
* This is because the selects have the same conditions, so whatever matches the first also
* matches the second. Note that this doesn't work for selects with overlapping but
* <i>different</i> key sets. That's because of key specialization (see
* {@link com.google.devtools.build.lib.analysis.ConfiguredAttributeMapper} - if the
* second select also included a condition <code>':c'</code> that includes both the flags
* in <code>':a'</code> and <code>':b'</code>, <code>':c'</code> would be chosen over
* them both.
* @param type the type of this attribute
* @param currentValueSoFar the partial value produced so far from earlier calls to this method
* @param valuesBuilder output container for full values this attribute can take
*/
private <T> void visitConfigurableAttribute(List<Selector<T>> selectors, BoundSelectorPaths boundSelectorPaths, Type<T> type, T currentValueSoFar, ImmutableList.Builder<T> valuesBuilder) {
if (selectors.isEmpty()) {
if (currentValueSoFar != null) {
// Null values arise when a None is used as the value of a Selector for a type without a
// default value.
// TODO(gregce): visitAttribute should probably convey that an unset attribute is possible.
// Therefore we need to actually handle null values here.
valuesBuilder.add(currentValueSoFar);
}
} else {
Selector<T> firstSelector = selectors.get(0);
List<Selector<T>> remainingSelectors = selectors.subList(1, selectors.size());
Map<Label, T> firstSelectorEntries = firstSelector.getEntries();
Label boundKey = boundSelectorPaths.getChosenKey(firstSelectorEntries.keySet());
if (boundKey != null) {
// If we've already followed some path from a previous selector with the same exact
// conditions as this one, we only need to visit that path (since the same key will
// match both selectors).
T boundValue = firstSelectorEntries.get(boundKey);
visitConfigurableAttribute(remainingSelectors, boundSelectorPaths, type, currentValueSoFar == null ? boundValue : type.concat(ImmutableList.of(currentValueSoFar, boundValue)), valuesBuilder);
} else {
// Otherwise, we need to iterate over all possible paths.
for (Map.Entry<Label, T> selectorBranch : firstSelectorEntries.entrySet()) {
// Bind this particular path for later selectors using the same conditions.
boundSelectorPaths.bind(firstSelectorEntries.keySet(), selectorBranch.getKey());
visitConfigurableAttribute(remainingSelectors, boundSelectorPaths, type, currentValueSoFar == null ? selectorBranch.getValue() : type.concat(ImmutableList.of(currentValueSoFar, selectorBranch.getValue())), valuesBuilder);
// Unbind the path (so when we pop back up the recursive stack we can rebind it to new
// values if we visit this selector again).
boundSelectorPaths.unbind(firstSelectorEntries.keySet());
}
}
}
}
use of com.google.devtools.build.lib.packages.BuildType.Selector in project bazel by bazelbuild.
the class AttributeFormatter method writeSelectorListToBuilder.
private static void writeSelectorListToBuilder(Build.Attribute.Builder attrPb, Type<?> type, SelectorList<?> selectorList) {
Build.Attribute.SelectorList.Builder selectorListBuilder = Build.Attribute.SelectorList.newBuilder();
selectorListBuilder.setType(ProtoUtils.getDiscriminatorFromType(type));
for (Selector<?> selector : selectorList.getSelectors()) {
Build.Attribute.Selector.Builder selectorBuilder = Build.Attribute.Selector.newBuilder().setNoMatchError(selector.getNoMatchError()).setHasDefaultValue(selector.hasDefault());
// entries' order is preserved from the sorting performed by the SelectorValue constructor.
for (Entry<Label, ?> entry : selector.getEntries().entrySet()) {
Label condition = entry.getKey();
Builder selectorEntryBuilder = SelectorEntry.newBuilder().setLabel(condition.toString()).setIsDefaultValue(!selector.isValueSet(condition));
Object conditionValue = entry.getValue();
if (conditionValue != null) {
writeAttributeValueToBuilder(new SelectorEntryBuilderAdapter(selectorEntryBuilder), type, conditionValue);
}
selectorBuilder.addEntries(selectorEntryBuilder);
}
selectorListBuilder.addElements(selectorBuilder);
}
attrPb.setSelectorList(selectorListBuilder);
}
Aggregations