Search in sources :

Example 1 with NativeAspectClass

use of com.google.devtools.build.lib.packages.NativeAspectClass 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 2 with NativeAspectClass

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

the class BuildView method update.

@ThreadCompatible
public AnalysisResult update(LoadingResult loadingResult, BuildConfigurationCollection configurations, List<String> aspects, Options viewOptions, TopLevelArtifactContext topLevelOptions, ExtendedEventHandler eventHandler, EventBus eventBus) throws ViewCreationFailedException, InterruptedException {
    LOG.info("Starting analysis");
    pollInterruptedStatus();
    skyframeBuildView.resetEvaluatedConfiguredTargetKeysSet();
    Collection<Target> targets = loadingResult.getTargets();
    eventBus.post(new AnalysisPhaseStartedEvent(targets));
    skyframeBuildView.setConfigurations(configurations);
    // Determine the configurations.
    List<TargetAndConfiguration> topLevelTargetsWithConfigs = nodesForTopLevelTargets(configurations, targets, eventHandler);
    List<ConfiguredTargetKey> topLevelCtKeys = Lists.transform(topLevelTargetsWithConfigs, new Function<TargetAndConfiguration, ConfiguredTargetKey>() {

        @Override
        public ConfiguredTargetKey apply(TargetAndConfiguration node) {
            return new ConfiguredTargetKey(node.getLabel(), node.getConfiguration());
        }
    });
    List<AspectValueKey> aspectKeys = new ArrayList<>();
    for (String aspect : aspects) {
        // Syntax: label%aspect
        int delimiterPosition = aspect.indexOf('%');
        if (delimiterPosition >= 0) {
            // TODO(jfield): For consistency with Skylark loads, the aspect should be specified
            // as an absolute path. Also, we probably need to do at least basic validation of
            // path well-formedness here.
            String bzlFileLoadLikeString = aspect.substring(0, delimiterPosition);
            if (!bzlFileLoadLikeString.startsWith("//") && !bzlFileLoadLikeString.startsWith("@")) {
                // "Legacy" behavior of '--aspects' parameter.
                bzlFileLoadLikeString = new PathFragment("/" + bzlFileLoadLikeString).toString();
                if (bzlFileLoadLikeString.endsWith(".bzl")) {
                    bzlFileLoadLikeString = bzlFileLoadLikeString.substring(0, bzlFileLoadLikeString.length() - ".bzl".length());
                }
            }
            SkylarkImport skylarkImport;
            try {
                skylarkImport = SkylarkImports.create(bzlFileLoadLikeString);
            } catch (SkylarkImportSyntaxException e) {
                throw new ViewCreationFailedException(String.format("Invalid aspect '%s': %s", aspect, e.getMessage()), e);
            }
            String skylarkFunctionName = aspect.substring(delimiterPosition + 1);
            for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
                if (!(targetSpec.getTarget() instanceof Rule)) {
                    continue;
                }
                aspectKeys.add(AspectValue.createSkylarkAspectKey(targetSpec.getLabel(), // aspect and the base target while the top-level configuration is untrimmed.
                targetSpec.getConfiguration(), targetSpec.getConfiguration(), skylarkImport, skylarkFunctionName));
            }
        } else {
            final NativeAspectClass aspectFactoryClass = ruleClassProvider.getNativeAspectClassMap().get(aspect);
            if (aspectFactoryClass != null) {
                for (TargetAndConfiguration targetSpec : topLevelTargetsWithConfigs) {
                    if (!(targetSpec.getTarget() instanceof Rule)) {
                        continue;
                    }
                    // For invoking top-level aspects, use the top-level configuration for both the
                    // aspect and the base target while the top-level configuration is untrimmed.
                    BuildConfiguration configuration = targetSpec.getConfiguration();
                    aspectKeys.add(AspectValue.createAspectKey(targetSpec.getLabel(), configuration, new AspectDescriptor(aspectFactoryClass, AspectParameters.EMPTY), configuration));
                }
            } else {
                throw new ViewCreationFailedException("Aspect '" + aspect + "' is unknown");
            }
        }
    }
    skyframeExecutor.injectWorkspaceStatusData(loadingResult.getWorkspaceName());
    SkyframeAnalysisResult skyframeAnalysisResult;
    try {
        skyframeAnalysisResult = skyframeBuildView.configureTargets(eventHandler, topLevelCtKeys, aspectKeys, eventBus, viewOptions.keepGoing, viewOptions.loadingPhaseThreads);
        setArtifactRoots(skyframeAnalysisResult.getPackageRoots());
    } finally {
        skyframeBuildView.clearInvalidatedConfiguredTargets();
    }
    int numTargetsToAnalyze = topLevelTargetsWithConfigs.size();
    int numSuccessful = skyframeAnalysisResult.getConfiguredTargets().size();
    if (0 < numSuccessful && numSuccessful < numTargetsToAnalyze) {
        String msg = String.format("Analysis succeeded for only %d of %d top-level targets", numSuccessful, numTargetsToAnalyze);
        eventHandler.handle(Event.info(msg));
        LOG.info(msg);
    }
    AnalysisResult result = createResult(eventHandler, loadingResult, topLevelOptions, viewOptions, skyframeAnalysisResult);
    LOG.info("Finished analysis");
    return result;
}
Also used : SkylarkImportSyntaxException(com.google.devtools.build.lib.syntax.SkylarkImports.SkylarkImportSyntaxException) SkyframeAnalysisResult(com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult) ArrayList(java.util.ArrayList) PathFragment(com.google.devtools.build.lib.vfs.PathFragment) SkyframeAnalysisResult(com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult) SkylarkImport(com.google.devtools.build.lib.syntax.SkylarkImport) BuildConfiguration(com.google.devtools.build.lib.analysis.config.BuildConfiguration) Target(com.google.devtools.build.lib.packages.Target) AspectValueKey(com.google.devtools.build.lib.skyframe.AspectValue.AspectValueKey) NativeAspectClass(com.google.devtools.build.lib.packages.NativeAspectClass) AspectDescriptor(com.google.devtools.build.lib.packages.AspectDescriptor) Rule(com.google.devtools.build.lib.packages.Rule) ConfiguredTargetKey(com.google.devtools.build.lib.skyframe.ConfiguredTargetKey) ThreadCompatible(com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible)

Example 3 with NativeAspectClass

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

the class AspectCollectionTest method createAspect.

/**
   * Creates an aspect wiht a class named {@code className} advertizing a provider
   * {@code className} that requires any of providers {@code requiredAspects}.
   */
private Aspect createAspect(final String className, String... requiredAspects) {
    ImmutableList.Builder<ImmutableSet<SkylarkProviderIdentifier>> requiredProvidersBuilder = ImmutableList.builder();
    for (String requiredAspect : requiredAspects) {
        requiredProvidersBuilder.add(ImmutableSet.of((SkylarkProviderIdentifier.forLegacy(requiredAspect))));
    }
    final ImmutableList<ImmutableSet<SkylarkProviderIdentifier>> requiredProviders = requiredProvidersBuilder.build();
    return Aspect.forNative(new NativeAspectClass() {

        @Override
        public String getName() {
            return className;
        }

        @Override
        public AspectDefinition getDefinition(AspectParameters aspectParameters) {
            return AspectDefinition.builder(this).requireAspectsWithProviders(requiredProviders).advertiseProvider(ImmutableList.of(SkylarkProviderIdentifier.forLegacy(className))).build();
        }
    });
}
Also used : NativeAspectClass(com.google.devtools.build.lib.packages.NativeAspectClass) AspectParameters(com.google.devtools.build.lib.packages.AspectParameters) ImmutableSet(com.google.common.collect.ImmutableSet) ImmutableList(com.google.common.collect.ImmutableList) AspectDefinition(com.google.devtools.build.lib.packages.AspectDefinition)

Aggregations

NativeAspectClass (com.google.devtools.build.lib.packages.NativeAspectClass)3 ImmutableList (com.google.common.collect.ImmutableList)2 AspectDescriptor (com.google.devtools.build.lib.packages.AspectDescriptor)2 Rule (com.google.devtools.build.lib.packages.Rule)2 Target (com.google.devtools.build.lib.packages.Target)2 ImmutableSet (com.google.common.collect.ImmutableSet)1 ConfiguredAspect (com.google.devtools.build.lib.analysis.ConfiguredAspect)1 ConfiguredAspectFactory (com.google.devtools.build.lib.analysis.ConfiguredAspectFactory)1 ConfiguredTarget (com.google.devtools.build.lib.analysis.ConfiguredTarget)1 InconsistentAspectOrderException (com.google.devtools.build.lib.analysis.DependencyResolver.InconsistentAspectOrderException)1 MergedConfiguredTarget (com.google.devtools.build.lib.analysis.MergedConfiguredTarget)1 DuplicateException (com.google.devtools.build.lib.analysis.MergedConfiguredTarget.DuplicateException)1 TargetAndConfiguration (com.google.devtools.build.lib.analysis.TargetAndConfiguration)1 BuildConfiguration (com.google.devtools.build.lib.analysis.config.BuildConfiguration)1 ConfigMatchingProvider (com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider)1 InvalidConfigurationException (com.google.devtools.build.lib.analysis.config.InvalidConfigurationException)1 Label (com.google.devtools.build.lib.cmdline.Label)1 ThreadCompatible (com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadCompatible)1 Aspect (com.google.devtools.build.lib.packages.Aspect)1 AspectDefinition (com.google.devtools.build.lib.packages.AspectDefinition)1