@Nullable
  @Override
  public SkyValue compute(SkyKey skyKey, Environment env)
      throws SkyFunctionException, InterruptedException {
    ImmutableMap<Action, ConflictException> badActions = PrecomputedValue.BAD_ACTIONS.get(env);
    ConfiguredTargetValue ctValue =
        (ConfiguredTargetValue)
            env.getValue(ConfiguredTargetValue.key((ConfiguredTargetKey) skyKey.argument()));
    SkyframeDependencyResolver resolver =
        buildViewProvider.getSkyframeBuildView().createDependencyResolver(env);
    if (env.valuesMissing()) {
      return null;
    }

    for (Action action : ctValue.getActions()) {
      if (badActions.containsKey(action)) {
        throw new ActionConflictFunctionException(badActions.get(action));
      }
    }

    ConfiguredTarget ct = ctValue.getConfiguredTarget();
    TargetAndConfiguration ctgValue =
        new TargetAndConfiguration(ct.getTarget(), ct.getConfiguration());

    Set<ConfigMatchingProvider> configConditions =
        getConfigurableAttributeConditions(ctgValue, env);
    if (configConditions == null) {
      return null;
    }

    ListMultimap<Attribute, Dependency> deps;
    try {
      BuildConfiguration hostConfiguration =
          buildViewProvider.getSkyframeBuildView().getHostConfiguration(ct.getConfiguration());
      deps =
          resolver.dependentNodeMap(
              ctgValue, hostConfiguration, /*aspect=*/ null, configConditions);
      if (ct.getConfiguration() != null && ct.getConfiguration().useDynamicConfigurations()) {
        deps =
            ConfiguredTargetFunction.trimConfigurations(
                env, ctgValue, deps, hostConfiguration, ruleClassProvider);
      }
    } catch (EvalException e) {
      throw new PostConfiguredTargetFunctionException(e);
    } catch (ConfiguredTargetFunction.DependencyEvaluationException e) {
      throw new PostConfiguredTargetFunctionException(e);
    }

    env.getValues(Iterables.transform(deps.values(), TO_KEYS));
    if (env.valuesMissing()) {
      return null;
    }

    return new PostConfiguredTargetValue(ct);
  }
Пример #2
0
  @Nullable
  @Override
  public SkyValue compute(SkyKey skyKey, Environment env)
      throws AspectFunctionException, InterruptedException {
    SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
    NestedSetBuilder<Package> transitivePackages = NestedSetBuilder.stableOrder();
    NestedSetBuilder<Label> transitiveRootCauses = NestedSetBuilder.stableOrder();
    AspectKey key = (AspectKey) skyKey.argument();
    ConfiguredAspectFactory aspectFactory;
    if (key.getAspectClass() instanceof NativeAspectClass<?>) {
      aspectFactory =
          (ConfiguredAspectFactory) ((NativeAspectClass<?>) key.getAspectClass()).newInstance();
    } else if (key.getAspectClass() instanceof SkylarkAspectClass) {
      SkylarkAspectClass skylarkAspectClass = (SkylarkAspectClass) key.getAspectClass();
      SkylarkAspect skylarkAspect;
      try {
        skylarkAspect =
            loadSkylarkAspect(
                env, skylarkAspectClass.getExtensionLabel(), skylarkAspectClass.getExportedName());
      } catch (AspectCreationException e) {
        throw new AspectFunctionException(e);
      }
      if (skylarkAspect == null) {
        return null;
      }

      aspectFactory = new SkylarkAspectFactory(skylarkAspect.getName(), skylarkAspect);
    } else {
      throw new IllegalStateException();
    }

    // Keep this in sync with the same code in ConfiguredTargetFunction.
    PackageValue packageValue =
        (PackageValue) env.getValue(PackageValue.key(key.getLabel().getPackageIdentifier()));
    if (packageValue == null) {
      return null;
    }
    Package pkg = packageValue.getPackage();
    if (pkg.containsErrors()) {
      throw new AspectFunctionException(
          new BuildFileContainsErrorsException(key.getLabel().getPackageIdentifier()));
    }
    Target target;
    try {
      target = pkg.getTarget(key.getLabel().getName());
    } catch (NoSuchTargetException e) {
      throw new AspectFunctionException(e);
    }

    if (!(target instanceof Rule)) {
      throw new AspectFunctionException(
          new AspectCreationException("aspects must be attached to rules"));
    }

    final ConfiguredTargetValue configuredTargetValue;
    try {
      configuredTargetValue =
          (ConfiguredTargetValue)
              env.getValueOrThrow(
                  ConfiguredTargetValue.key(key.getLabel(), key.getConfiguration()),
                  ConfiguredValueCreationException.class);
    } catch (ConfiguredValueCreationException e) {
      throw new AspectFunctionException(new AspectCreationException(e.getRootCauses()));
    }
    if (configuredTargetValue == null) {
      // TODO(bazel-team): remove this check when top-level targets also use dynamic configurations.
      // Right now the key configuration may be dynamic while the original target's configuration
      // is static, resulting in a Skyframe cache miss even though the original target is, in fact,
      // precomputed.
      return null;
    }
    RuleConfiguredTarget associatedTarget =
        (RuleConfiguredTarget) configuredTargetValue.getConfiguredTarget();
    if (associatedTarget == null) {
      return null;
    }

    SkyframeDependencyResolver resolver = view.createDependencyResolver(env);

    TargetAndConfiguration ctgValue = new TargetAndConfiguration(target, key.getConfiguration());
    try {
      // Get the configuration targets that trigger this rule's configurable attributes.
      Set<ConfigMatchingProvider> configConditions =
          ConfiguredTargetFunction.getConfigConditions(
              target, env, resolver, ctgValue, transitivePackages, transitiveRootCauses);
      if (configConditions == null) {
        // Those targets haven't yet been resolved.
        return null;
      }

      ListMultimap<Attribute, ConfiguredTarget> depValueMap =
          ConfiguredTargetFunction.computeDependencies(
              env,
              resolver,
              ctgValue,
              key.getAspect(),
              configConditions,
              ruleClassProvider,
              view.getHostConfiguration(ctgValue.getConfiguration()),
              transitivePackages,
              transitiveRootCauses);
      if (depValueMap == null) {
        return null;
      }
      if (!transitiveRootCauses.isEmpty()) {
        throw new AspectFunctionException(
            new AspectCreationException("Loading failed", transitiveRootCauses.build()));
      }

      return createAspect(
          env,
          key,
          aspectFactory,
          associatedTarget,
          configConditions,
          depValueMap,
          transitivePackages);
    } catch (DependencyEvaluationException e) {
      if (e.getCause() instanceof ConfiguredValueCreationException) {
        ConfiguredValueCreationException cause = (ConfiguredValueCreationException) e.getCause();
        throw new AspectFunctionException(
            new AspectCreationException(cause.getMessage(), cause.getAnalysisRootCause()));
      } else {
        // Cast to InvalidConfigurationException as a consistency check. If you add any
        // DependencyEvaluationException constructors, you may need to change this code, too.
        InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
        throw new AspectFunctionException(new AspectCreationException(cause.getMessage()));
      }
    } catch (AspectCreationException e) {
      throw new AspectFunctionException(e);
    }
  }