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());
}
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;
}
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);
}
}
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();
}
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));
}
Aggregations