private void visitRule( Rule rule, AspectDefinition aspect, AspectParameters aspectParameters, ListMultimap<Attribute, LabelAndConfiguration> labelMap, ListMultimap<Attribute, Dependency> outgoingEdges) { Preconditions.checkNotNull(labelMap); for (Map.Entry<Attribute, Collection<LabelAndConfiguration>> entry : labelMap.asMap().entrySet()) { Attribute attribute = entry.getKey(); for (LabelAndConfiguration dep : entry.getValue()) { Label label = dep.getLabel(); BuildConfiguration config = dep.getConfiguration(); Target toTarget; try { toTarget = getTarget(label); } catch (NoSuchThingException e) { throw new IllegalStateException( "not found: " + label + " from " + rule + " in " + attribute.getName()); } if (toTarget == null) { continue; } BuildConfiguration.TransitionApplier transitionApplier = config.getTransitionApplier(); if (config.useDynamicConfigurations() && config.isHostConfiguration() && !BuildConfiguration.usesNullConfiguration(toTarget)) { // This condition is needed because resolveLateBoundAttributes may switch config to // the host configuration, which is the only case DependencyResolver applies a // configuration transition outside of this method. We need to reflect that // transition in the results of this method, but config.evaluateTransition is hard-set // to return a NONE transition when the input is a host config. Since the outside // caller originally passed the *original* value of config (before the possible // switch), it can mistakenly interpret the result as a NONE transition from the // original value of config. This condition fixes that. Another fix would be to have // config.evaluateTransition return a HOST transition when the input config is a host, // but since this blemish is specific to DependencyResolver it seems best to keep the // fix here. // TODO(bazel-team): eliminate this special case by passing transitionApplier to // resolveLateBoundAttributes, so that method uses the same interface for transitions. transitionApplier.applyTransition(Attribute.ConfigurationTransition.HOST); } else { config.evaluateTransition(rule, attribute, toTarget, transitionApplier); } for (Dependency dependency : transitionApplier.getDependencies( label, requiredAspects(aspect, aspectParameters, attribute, toTarget, rule))) { outgoingEdges.put(entry.getKey(), dependency); } } } }