use of com.google.devtools.build.lib.packages.Aspect 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.Aspect in project bazel by bazelbuild.
the class PreciseAspectResolver method computeBuildFileDependencies.
@Override
public Set<Label> computeBuildFileDependencies(Package pkg, BuildFileDependencyMode mode) throws InterruptedException {
Set<Label> result = new LinkedHashSet<>();
result.addAll(mode.getDependencies(pkg));
Set<PackageIdentifier> dependentPackages = new LinkedHashSet<>();
// Iterate over all rules...
for (Target target : pkg.getTargets()) {
if (!(target instanceof Rule)) {
continue;
}
// ...figure out which direct dependencies can possibly have aspects attached to them...
Multimap<Attribute, Label> depsWithPossibleAspects = ((Rule) target).getTransitions(new BinaryPredicate<Rule, Attribute>() {
@Override
public boolean apply(@Nullable Rule rule, Attribute attribute) {
for (Aspect aspectWithParameters : attribute.getAspects(rule)) {
if (!aspectWithParameters.getDefinition().getAttributes().isEmpty()) {
return true;
}
}
return false;
}
});
// ...and add the package of the aspect.
for (Label depLabel : depsWithPossibleAspects.values()) {
dependentPackages.add(depLabel.getPackageIdentifier());
}
}
// Then add all the subinclude labels of the packages thus found to the result.
for (PackageIdentifier packageIdentifier : dependentPackages) {
try {
result.add(Label.create(packageIdentifier, "BUILD"));
Package dependentPackage = packageProvider.getPackage(eventHandler, packageIdentifier);
result.addAll(mode.getDependencies(dependentPackage));
} catch (NoSuchPackageException e) {
// If the package is not found, just add its BUILD file, which is already done above.
// Hopefully this error is not raised when there is a syntax error in a subincluded file
// or something.
} catch (LabelSyntaxException e) {
throw new IllegalStateException(e);
}
}
return result;
}
use of com.google.devtools.build.lib.packages.Aspect in project bazel by bazelbuild.
the class ConservativeAspectResolver method computeAspectDependencies.
@Override
public ImmutableMultimap<Attribute, Label> computeAspectDependencies(Target target, DependencyFilter dependencyFilter) throws InterruptedException {
if (!(target instanceof Rule)) {
return ImmutableMultimap.of();
}
Rule rule = (Rule) target;
Multimap<Attribute, Label> result = LinkedHashMultimap.create();
for (Attribute attribute : rule.getAttributes()) {
for (Aspect aspect : attribute.getAspects(rule)) {
AspectDefinition.addAllAttributesOfAspect(rule, result, aspect, dependencyFilter);
}
}
return ImmutableMultimap.copyOf(result);
}
use of com.google.devtools.build.lib.packages.Aspect in project bazel by bazelbuild.
the class AspectCollection method deduplicateAspects.
/**
* Deduplicate aspects in path.
*
* @throws AspectCycleOnPathException if an aspect occurs twice on the path and
* the second occurrence sees a different set of aspects.
*/
private static LinkedHashMap<AspectDescriptor, Aspect> deduplicateAspects(Iterable<Aspect> aspectPath) throws AspectCycleOnPathException {
LinkedHashMap<AspectDescriptor, Aspect> aspectMap = new LinkedHashMap<>();
ArrayList<Aspect> seenAspects = new ArrayList<>();
for (Aspect aspect : aspectPath) {
if (!aspectMap.containsKey(aspect.getDescriptor())) {
aspectMap.put(aspect.getDescriptor(), aspect);
seenAspects.add(aspect);
} else {
validateDuplicateAspect(aspect, seenAspects);
}
}
return aspectMap;
}
use of com.google.devtools.build.lib.packages.Aspect in project bazel by bazelbuild.
the class DependencyResolver method requiredAspects.
private AspectCollection requiredAspects(Iterable<Aspect> aspectPath, AttributeAndOwner attributeAndOwner, final Target target, Rule originalRule) throws InconsistentAspectOrderException {
if (!(target instanceof Rule)) {
return AspectCollection.EMPTY;
}
if (attributeAndOwner.ownerAspect != null) {
// Do not propagate aspects along aspect attributes.
return AspectCollection.EMPTY;
}
ImmutableList.Builder<Aspect> filteredAspectPath = ImmutableList.builder();
ImmutableSet.Builder<AspectDescriptor> visibleAspects = ImmutableSet.builder();
Attribute attribute = attributeAndOwner.attribute;
collectOriginatingAspects(originalRule, attribute, (Rule) target, filteredAspectPath, visibleAspects);
collectPropagatingAspects(aspectPath, attribute, (Rule) target, filteredAspectPath, visibleAspects);
try {
return AspectCollection.create(filteredAspectPath.build(), visibleAspects.build());
} catch (AspectCycleOnPathException e) {
throw new InconsistentAspectOrderException(originalRule, attribute, target, e);
}
}
Aggregations