Exemplo n.º 1
0
 private static Set<AspectWithParameters> extractAspectCandidates(
     AspectDefinition aspectDefinition,
     AspectParameters aspectParameters,
     Attribute attribute,
     Rule originalRule) {
   // The order of this set will be deterministic. This is necessary because this order eventually
   // influences the order in which aspects are merged into the main configured target, which in
   // turn influences which aspect takes precedence if two emit the same provider (maybe this
   // should be an error)
   Set<AspectWithParameters> aspectCandidates = new LinkedHashSet<>();
   for (Map.Entry<Class<? extends AspectFactory<?, ?, ?>>, AspectParameters> aspectWithParameters :
       attribute.getAspectsWithParameters(originalRule).entrySet()) {
     aspectCandidates.add(
         new AspectWithParameters(
             aspectWithParameters.getKey().asSubclass(ConfiguredAspectFactory.class),
             aspectWithParameters.getValue()));
   }
   if (aspectDefinition != null) {
     for (Class<? extends AspectFactory<?, ?, ?>> aspect :
         aspectDefinition.getAttributeAspects().get(attribute.getName())) {
       aspectCandidates.add(
           new AspectWithParameters(
               aspect.asSubclass(ConfiguredAspectFactory.class), aspectParameters));
     }
   }
   return aspectCandidates;
 }
Exemplo n.º 2
0
  @Override
  public ImmutableMultimap<Attribute, Label> computeAspectDependencies(Target target)
      throws InterruptedException {
    if (!(target instanceof Rule)) {
      return ImmutableMultimap.of();
    }

    Multimap<Attribute, Label> result = LinkedHashMultimap.create();
    for (Attribute attribute : ((Rule) target).getAttributes()) {
      for (Class<? extends AspectFactory<?, ?, ?>> aspectFactory : attribute.getAspects()) {
        AspectDefinition.addAllAttributesOfAspect(
            (Rule) target,
            result,
            AspectFactory.Util.create(aspectFactory).getDefinition(),
            Rule.ALL_DEPS);
      }
    }

    return ImmutableMultimap.copyOf(result);
  }
Exemplo n.º 3
0
  private ListMultimap<Attribute, LabelAndConfiguration> resolveAttributes(
      Rule rule,
      AspectDefinition aspect,
      BuildConfiguration configuration,
      BuildConfiguration hostConfiguration,
      Set<ConfigMatchingProvider> configConditions)
      throws EvalException, InterruptedException {
    ConfiguredAttributeMapper attributeMap = ConfiguredAttributeMapper.of(rule, configConditions);
    attributeMap.validateAttributes();
    List<Attribute> attributes;
    if (aspect == null) {
      attributes = rule.getRuleClassObject().getAttributes();
    } else {
      attributes = new ArrayList<>();
      attributes.addAll(rule.getRuleClassObject().getAttributes());
      if (aspect != null) {
        attributes.addAll(aspect.getAttributes().values());
      }
    }

    ImmutableSortedKeyListMultimap.Builder<Attribute, LabelAndConfiguration> result =
        ImmutableSortedKeyListMultimap.builder();

    resolveExplicitAttributes(rule, configuration, attributeMap, result);
    resolveImplicitAttributes(rule, configuration, attributeMap, attributes, result);
    resolveLateBoundAttributes(
        rule, configuration, hostConfiguration, attributeMap, attributes, result);

    // Add the rule's visibility labels (which may come from the rule or from package defaults).
    addExplicitDeps(
        result, rule, "visibility", rule.getVisibility().getDependencyLabels(), configuration);

    // Add package default constraints when the rule doesn't explicitly declare them.
    //
    // Note that this can have subtle implications for constraint semantics. For example: say that
    // package defaults declare compatibility with ':foo' and rule R declares compatibility with
    // ':bar'. Does that mean that R is compatible with [':foo', ':bar'] or just [':bar']? In other
    // words, did R's author intend to add additional compatibility to the package defaults or to
    // override them? More severely, what if package defaults "restrict" support to just [':baz']?
    // Should R's declaration signify [':baz'] + ['bar'], [ORIGINAL_DEFAULTS] + ['bar'], or
    // something else?
    //
    // Rather than try to answer these questions with possibly confusing logic, we take the
    // simple approach of assigning the rule's "restriction" attribute to the rule-declared value if
    // it exists, else the package defaults value (and likewise for "compatibility"). This may not
    // always provide what users want, but it makes it easy for them to understand how rule
    // declarations and package defaults intermix (and how to refactor them to get what they want).
    //
    // An alternative model would be to apply the "rule declaration" / "rule class defaults"
    // relationship, i.e. the rule class' "compatibility" and "restriction" declarations are merged
    // to generate a set of default environments, then the rule's declarations are independently
    // processed on top of that. This protects against obscure coupling behavior between
    // declarations from wildly different places (e.g. it offers clear answers to the examples posed
    // above). But within the scope of a single package it seems better to keep the model simple and
    // make the user responsible for resolving ambiguities.
    if (!rule.isAttributeValueExplicitlySpecified(RuleClass.COMPATIBLE_ENVIRONMENT_ATTR)) {
      addExplicitDeps(
          result,
          rule,
          RuleClass.COMPATIBLE_ENVIRONMENT_ATTR,
          rule.getPackage().getDefaultCompatibleWith(),
          configuration);
    }
    if (!rule.isAttributeValueExplicitlySpecified(RuleClass.RESTRICTED_ENVIRONMENT_ATTR)) {
      addExplicitDeps(
          result,
          rule,
          RuleClass.RESTRICTED_ENVIRONMENT_ATTR,
          rule.getPackage().getDefaultRestrictedTo(),
          configuration);
    }

    return result.build();
  }