Search in sources :

Example 1 with AspectDescriptor

use of com.google.devtools.build.lib.packages.AspectDescriptor in project bazel by bazelbuild.

the class AspectCollection method create.

/**
   *  Creates an {@link AspectCollection} from an ordered list of aspects and
   *  a set of visible aspects.
   *
   *  The order of aspects is reverse to the order in which they originated, with
   *  the earliest originating occurring last in the list.
   */
public static AspectCollection create(Iterable<Aspect> aspectPath, Set<AspectDescriptor> visibleAspects) throws AspectCycleOnPathException {
    LinkedHashMap<AspectDescriptor, Aspect> aspectMap = deduplicateAspects(aspectPath);
    LinkedHashMap<AspectDescriptor, ArrayList<AspectDescriptor>> deps = new LinkedHashMap<>();
    // deps[aspect] contains all aspects that 'aspect' needs, in reverse order.
    for (Entry<AspectDescriptor, Aspect> aspect : ImmutableList.copyOf(aspectMap.entrySet()).reverse()) {
        boolean needed = visibleAspects.contains(aspect.getKey());
        for (AspectDescriptor depAspectDescriptor : deps.keySet()) {
            if (depAspectDescriptor.equals(aspect.getKey())) {
                continue;
            }
            Aspect depAspect = aspectMap.get(depAspectDescriptor);
            if (depAspect.getDefinition().getRequiredProvidersForAspects().isSatisfiedBy(aspect.getValue().getDefinition().getAdvertisedProviders())) {
                deps.get(depAspectDescriptor).add(aspect.getKey());
                needed = true;
            }
        }
        if (needed && !deps.containsKey(aspect.getKey())) {
            deps.put(aspect.getKey(), new ArrayList<AspectDescriptor>());
        }
    }
    // Record only the needed aspects from all aspects, in correct order.
    ImmutableList<AspectDescriptor> neededAspects = ImmutableList.copyOf(deps.keySet()).reverse();
    // Calculate visible aspect paths.
    HashMap<AspectDescriptor, AspectDeps> aspectPaths = new HashMap<>();
    ImmutableSet.Builder<AspectDeps> visibleAspectPaths = ImmutableSet.builder();
    for (AspectDescriptor visibleAspect : visibleAspects) {
        visibleAspectPaths.add(buildAspectDeps(visibleAspect, aspectPaths, deps));
    }
    return new AspectCollection(ImmutableSet.copyOf(neededAspects), visibleAspectPaths.build());
}
Also used : LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Aspect(com.google.devtools.build.lib.packages.Aspect) LinkedHashMap(java.util.LinkedHashMap) ImmutableSet(com.google.common.collect.ImmutableSet) AspectDescriptor(com.google.devtools.build.lib.packages.AspectDescriptor)

Example 2 with AspectDescriptor

use of com.google.devtools.build.lib.packages.AspectDescriptor in project bazel by bazelbuild.

the class AbstractAction method getExtraActionInfo.

@Override
public ExtraActionInfo.Builder getExtraActionInfo() {
    ActionOwner owner = getOwner();
    ExtraActionInfo.Builder result = ExtraActionInfo.newBuilder().setOwner(owner.getLabel().toString()).setId(getKey()).setMnemonic(getMnemonic());
    Iterable<AspectDescriptor> aspectDescriptors = owner.getAspectDescriptors();
    AspectDescriptor lastAspect = null;
    for (AspectDescriptor aspectDescriptor : aspectDescriptors) {
        ExtraActionInfo.AspectDescriptor.Builder builder = ExtraActionInfo.AspectDescriptor.newBuilder().setAspectName(aspectDescriptor.getAspectClass().getName());
        for (Entry<String, Collection<String>> entry : aspectDescriptor.getParameters().getAttributes().asMap().entrySet()) {
            builder.putAspectParameters(entry.getKey(), ExtraActionInfo.AspectDescriptor.StringList.newBuilder().addAllValue(entry.getValue()).build());
        }
        lastAspect = aspectDescriptor;
    }
    if (lastAspect != null) {
        result.setAspectName(lastAspect.getAspectClass().getName());
        for (Map.Entry<String, Collection<String>> entry : lastAspect.getParameters().getAttributes().asMap().entrySet()) {
            result.putAspectParameters(entry.getKey(), ExtraActionInfo.StringList.newBuilder().addAllValue(entry.getValue()).build());
        }
    }
    return result;
}
Also used : AspectDescriptor(com.google.devtools.build.lib.packages.AspectDescriptor) Collection(java.util.Collection) Map(java.util.Map) ExtraActionInfo(com.google.devtools.build.lib.actions.extra.ExtraActionInfo)

Example 3 with AspectDescriptor

use of com.google.devtools.build.lib.packages.AspectDescriptor in project bazel by bazelbuild.

the class AspectFunction method compute.

@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;
    Aspect aspect;
    if (key.getAspectClass() instanceof NativeAspectClass) {
        NativeAspectClass nativeAspectClass = (NativeAspectClass) key.getAspectClass();
        aspectFactory = (ConfiguredAspectFactory) nativeAspectClass;
        aspect = Aspect.forNative(nativeAspectClass, key.getParameters());
    } 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);
        aspect = Aspect.forSkylark(skylarkAspect.getAspectClass(), skylarkAspect.getDefinition(key.getParameters()), key.getParameters());
    } 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)) {
        env.getListener().handle(Event.error(target.getLocation(), String.format("%s is attached to %s %s but aspects must be attached to rules", aspect.getAspectClass().getName(), target.getTargetKind(), target.getName())));
        throw new AspectFunctionException(new AspectCreationException("aspects must be attached to rules"));
    }
    ConfiguredTargetValue configuredTargetValue;
    try {
        configuredTargetValue = (ConfiguredTargetValue) env.getValueOrThrow(ConfiguredTargetValue.key(key.getLabel(), key.getBaseConfiguration()), ConfiguredValueCreationException.class);
    } catch (ConfiguredValueCreationException e) {
        throw new AspectFunctionException(new AspectCreationException(e.getRootCauses()));
    }
    if (configuredTargetValue == null) {
        // precomputed.
        return null;
    }
    if (configuredTargetValue.getConfiguredTarget() == null) {
        return null;
    }
    if (configuredTargetValue.getConfiguredTarget().getProvider(AliasProvider.class) != null) {
        return createAliasAspect(env, target, aspect, key, configuredTargetValue.getConfiguredTarget());
    }
    ConfiguredTarget associatedTarget = configuredTargetValue.getConfiguredTarget();
    ImmutableList.Builder<Aspect> aspectPathBuilder = ImmutableList.builder();
    if (!key.getBaseKeys().isEmpty()) {
        // We transitively collect all required aspects to reduce the number of restarts.
        // Semantically it is enough to just request key.getBaseKeys().
        ImmutableMap<AspectDescriptor, SkyKey> aspectKeys = getSkyKeysForAspects(key.getBaseKeys());
        Map<SkyKey, SkyValue> values = env.getValues(aspectKeys.values());
        if (env.valuesMissing()) {
            return null;
        }
        try {
            associatedTarget = getBaseTargetAndCollectPath(associatedTarget, key.getBaseKeys(), values, aspectPathBuilder);
        } catch (DuplicateException e) {
            env.getListener().handle(Event.error(associatedTarget.getTarget().getLocation(), e.getMessage()));
            throw new AspectFunctionException(new AspectCreationException(e.getMessage(), associatedTarget.getLabel()));
        }
    }
    aspectPathBuilder.add(aspect);
    SkyframeDependencyResolver resolver = view.createDependencyResolver(env);
    // When getting the dependencies of this hybrid aspect+base target, use the aspect's
    // configuration. The configuration of the aspect will always be a superset of the target's
    // (dynamic configuration mode: target is part of the aspect's config fragment requirements;
    // static configuration mode: target is the same configuration as the aspect), so the fragments
    // required by all dependencies (both those of the aspect and those of the base target)
    // will be present this way.
    TargetAndConfiguration originalTargetAndAspectConfiguration = new TargetAndConfiguration(target, key.getAspectConfiguration());
    ImmutableList<Aspect> aspectPath = aspectPathBuilder.build();
    try {
        // Get the configuration targets that trigger this rule's configurable attributes.
        ImmutableMap<Label, ConfigMatchingProvider> configConditions = ConfiguredTargetFunction.getConfigConditions(target, env, resolver, originalTargetAndAspectConfiguration, transitivePackages, transitiveRootCauses);
        if (configConditions == null) {
            // Those targets haven't yet been resolved.
            return null;
        }
        OrderedSetMultimap<Attribute, ConfiguredTarget> depValueMap;
        try {
            depValueMap = ConfiguredTargetFunction.computeDependencies(env, resolver, originalTargetAndAspectConfiguration, aspectPath, configConditions, ruleClassProvider, view.getHostConfiguration(originalTargetAndAspectConfiguration.getConfiguration()), transitivePackages, transitiveRootCauses);
        } catch (ConfiguredTargetFunctionException e) {
            throw new AspectCreationException(e.getMessage());
        }
        if (depValueMap == null) {
            return null;
        }
        if (!transitiveRootCauses.isEmpty()) {
            throw new AspectFunctionException(new AspectCreationException("Loading failed", transitiveRootCauses.build()));
        }
        return createAspect(env, key, aspectPath, aspect, aspectFactory, associatedTarget, key.getAspectConfiguration(), 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 if (e.getCause() instanceof InconsistentAspectOrderException) {
            InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause();
            throw new AspectFunctionException(new AspectCreationException(cause.getMessage()));
        } 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);
    }
}
Also used : AspectKey(com.google.devtools.build.lib.skyframe.AspectValue.AspectKey) Attribute(com.google.devtools.build.lib.packages.Attribute) ImmutableList(com.google.common.collect.ImmutableList) Label(com.google.devtools.build.lib.cmdline.Label) SkylarkAspect(com.google.devtools.build.lib.packages.SkylarkAspect) ConfiguredAspect(com.google.devtools.build.lib.analysis.ConfiguredAspect) Aspect(com.google.devtools.build.lib.packages.Aspect) DependencyEvaluationException(com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.DependencyEvaluationException) InvalidConfigurationException(com.google.devtools.build.lib.analysis.config.InvalidConfigurationException) SkyValue(com.google.devtools.build.skyframe.SkyValue) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) MergedConfiguredTarget(com.google.devtools.build.lib.analysis.MergedConfiguredTarget) Target(com.google.devtools.build.lib.packages.Target) AliasProvider(com.google.devtools.build.lib.rules.AliasProvider) ConfiguredAspectFactory(com.google.devtools.build.lib.analysis.ConfiguredAspectFactory) NativeAspectClass(com.google.devtools.build.lib.packages.NativeAspectClass) NoSuchTargetException(com.google.devtools.build.lib.packages.NoSuchTargetException) SkylarkAspect(com.google.devtools.build.lib.packages.SkylarkAspect) AspectDescriptor(com.google.devtools.build.lib.packages.AspectDescriptor) SkyKey(com.google.devtools.build.skyframe.SkyKey) BuildFileContainsErrorsException(com.google.devtools.build.lib.packages.BuildFileContainsErrorsException) ConfiguredTarget(com.google.devtools.build.lib.analysis.ConfiguredTarget) MergedConfiguredTarget(com.google.devtools.build.lib.analysis.MergedConfiguredTarget) ConfiguredValueCreationException(com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ConfiguredValueCreationException) InconsistentAspectOrderException(com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException) TargetAndConfiguration(com.google.devtools.build.lib.analysis.TargetAndConfiguration) SkylarkAspectClass(com.google.devtools.build.lib.packages.SkylarkAspectClass) DuplicateException(com.google.devtools.build.lib.analysis.MergedConfiguredTarget.DuplicateException) ConfiguredTargetFunctionException(com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ConfiguredTargetFunctionException) ConfigMatchingProvider(com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider) Package(com.google.devtools.build.lib.packages.Package) Rule(com.google.devtools.build.lib.packages.Rule) Nullable(javax.annotation.Nullable)

Example 4 with AspectDescriptor

use of com.google.devtools.build.lib.packages.AspectDescriptor in project bazel by bazelbuild.

the class ExtraActionSpec method getActionId.

/**
   * Creates a unique id for the action shadowed by this extra_action.
   *
   * We need to have a unique id for the extra_action to use. We build this
   * from the owner's  label and the shadowed action id (which is only
   * guaranteed to be unique per target). Together with the subfolder
   * matching the original target's package name, we believe this is enough
   * of a uniqueness guarantee.
   */
@VisibleForTesting
public static String getActionId(ActionOwner owner, Action action) {
    Fingerprint f = new Fingerprint();
    f.addString(owner.getLabel().toString());
    ImmutableList<AspectDescriptor> aspectDescriptors = owner.getAspectDescriptors();
    f.addInt(aspectDescriptors.size());
    for (AspectDescriptor aspectDescriptor : aspectDescriptors) {
        f.addString(aspectDescriptor.getDescription());
    }
    f.addString(action.getKey());
    return f.hexDigestAndReset();
}
Also used : Fingerprint(com.google.devtools.build.lib.util.Fingerprint) AspectDescriptor(com.google.devtools.build.lib.packages.AspectDescriptor) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 5 with AspectDescriptor

use of com.google.devtools.build.lib.packages.AspectDescriptor in project bazel by bazelbuild.

the class DependencyResolverTest method hasAspectsRequiredByAspect.

@Test
public void hasAspectsRequiredByAspect() throws Exception {
    setRulesAvailableInTests(new TestAspects.BaseRule(), new TestAspects.SimpleRule());
    pkg("a", "simple(name='a', foo=[':b'])", "simple(name='b', foo=[])");
    OrderedSetMultimap<Attribute, Dependency> map = dependentNodeMap("//a:a", TestAspects.ATTRIBUTE_ASPECT);
    assertDep(map, "foo", "//a:b", new AspectDescriptor(TestAspects.ATTRIBUTE_ASPECT));
}
Also used : Attribute(com.google.devtools.build.lib.packages.Attribute) AspectDescriptor(com.google.devtools.build.lib.packages.AspectDescriptor) TestAspects(com.google.devtools.build.lib.analysis.util.TestAspects) Test(org.junit.Test)

Aggregations

AspectDescriptor (com.google.devtools.build.lib.packages.AspectDescriptor)21 Test (org.junit.Test)8 Aspect (com.google.devtools.build.lib.packages.Aspect)5 Attribute (com.google.devtools.build.lib.packages.Attribute)5 SkyKey (com.google.devtools.build.skyframe.SkyKey)5 ImmutableList (com.google.common.collect.ImmutableList)4 BuildConfiguration (com.google.devtools.build.lib.analysis.config.BuildConfiguration)4 AspectDeps (com.google.devtools.build.lib.analysis.AspectCollection.AspectDeps)3 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)3 MergedConfiguredTarget (com.google.devtools.build.lib.analysis.MergedConfiguredTarget)3 TestAspects (com.google.devtools.build.lib.analysis.util.TestAspects)3 Label (com.google.devtools.build.lib.cmdline.Label)3 Rule (com.google.devtools.build.lib.packages.Rule)3 ArrayList (java.util.ArrayList)3 HashMap (java.util.HashMap)3 LinkedHashMap (java.util.LinkedHashMap)3 ImmutableSet (com.google.common.collect.ImmutableSet)2 ConfiguredAspect (com.google.devtools.build.lib.analysis.ConfiguredAspect)2 Dependency (com.google.devtools.build.lib.analysis.Dependency)2 DuplicateException (com.google.devtools.build.lib.analysis.MergedConfiguredTarget.DuplicateException)2