diff options
Diffstat (limited to 'src/main/java/com')
29 files changed, 521 insertions, 323 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java index 3d47a22739..f60eb63562 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/BuildView.java @@ -68,7 +68,7 @@ import com.google.devtools.build.lib.rules.test.CoverageReportActionFactory.Cove import com.google.devtools.build.lib.rules.test.InstrumentedFilesProvider; import com.google.devtools.build.lib.skyframe.ActionLookupValue; import com.google.devtools.build.lib.skyframe.AspectValue; -import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey; +import com.google.devtools.build.lib.skyframe.AspectValue.AspectValueKey; import com.google.devtools.build.lib.skyframe.ConfiguredTargetKey; import com.google.devtools.build.lib.skyframe.CoverageReportValue; import com.google.devtools.build.lib.skyframe.SkyframeAnalysisResult; @@ -451,7 +451,7 @@ public class BuildView { } }); - List<AspectKey> aspectKeys = new ArrayList<>(); + List<AspectValueKey> aspectKeys = new ArrayList<>(); for (String aspect : aspects) { // Syntax: label%aspect @@ -478,8 +478,8 @@ public class BuildView { } } else { @SuppressWarnings("unchecked") - final Class<? extends ConfiguredAspectFactory> aspectFactoryClass = - (Class<? extends ConfiguredAspectFactory>) + final Class<? extends ConfiguredNativeAspectFactory> aspectFactoryClass = + (Class<? extends ConfiguredNativeAspectFactory>) ruleClassProvider.getAspectFactoryMap().get(aspect); if (aspectFactoryClass != null) { for (ConfiguredTargetKey targetSpec : targetSpecs) { diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspectFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspectFactory.java index 7c24768e81..667164001b 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspectFactory.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredAspectFactory.java @@ -13,16 +13,21 @@ // limitations under the License. package com.google.devtools.build.lib.analysis; -import com.google.devtools.build.lib.packages.AspectFactory; +import com.google.devtools.build.lib.packages.AspectParameters; /** - * Instantiation of {@link AspectFactory} with the actual types. - * - * <p>This is needed because {@link AspectFactory} is needed in the {@code packages} package to - * do loading phase things properly and to be able to specify them on attributes, but the actual - * classes are in the {@code view} package, which is not available there. + * Creates the Skyframe node of an aspect. */ -public interface ConfiguredAspectFactory - extends AspectFactory<ConfiguredTarget, RuleContext, Aspect> { - +public interface ConfiguredAspectFactory { + /** + * Creates the aspect based on the configured target of the associated rule. + * + * @param base the configured target of the associated rule + * @param context the context of the associated configured target plus all the attributes the + * aspect itself has defined + * @param parameters information from attributes of the rule that have requested this + * aspect + */ + Aspect create(ConfiguredTarget base, RuleContext context, AspectParameters parameters) + throws InterruptedException; } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredNativeAspectFactory.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredNativeAspectFactory.java new file mode 100644 index 0000000000..e315141029 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredNativeAspectFactory.java @@ -0,0 +1,28 @@ +// Copyright 2015 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.analysis; + +import com.google.devtools.build.lib.packages.NativeAspectClass; + +/** + * A union of {@link ConfiguredAspectFactory} and + * {@link com.google.devtools.build.lib.packages.NativeAspectClass.NativeAspectFactory} + * All native aspect classes should implement this interface. + * + */ +public interface ConfiguredNativeAspectFactory + extends ConfiguredAspectFactory, NativeAspectClass.NativeAspectFactory { + +} diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java index 36d497fdbe..9d0cd4c706 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java @@ -34,8 +34,8 @@ import com.google.devtools.build.lib.cmdline.LabelSyntaxException; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.graph.Digraph; import com.google.devtools.build.lib.graph.Node; -import com.google.devtools.build.lib.packages.AspectFactory; import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.NativeAspectClass.NativeAspectFactory; import com.google.devtools.build.lib.packages.RuleClass; import com.google.devtools.build.lib.packages.RuleClassProvider; import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; @@ -90,7 +90,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { private final Map<String, RuleClass> ruleClassMap = new HashMap<>(); private final Map<String, Class<? extends RuleDefinition>> ruleDefinitionMap = new HashMap<>(); - private final Map<String, Class<? extends AspectFactory<?, ?, ?>>> aspectFactoryMap = + private final Map<String, Class<? extends NativeAspectFactory>> aspectFactoryMap = new HashMap<>(); private final Map<Class<? extends RuleDefinition>, RuleClass> ruleMap = new HashMap<>(); private final Map<Class<? extends RuleDefinition>, RuleDefinition> ruleDefinitionInstanceCache = @@ -140,7 +140,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { } public Builder addAspectFactory( - String name, Class<? extends AspectFactory<?, ?, ?>> configuredAspectFactoryClass) { + String name, Class<? extends ConfiguredNativeAspectFactory> configuredAspectFactoryClass) { aspectFactoryMap.put(name, configuredAspectFactoryClass); return this; @@ -291,7 +291,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { /** * Maps aspect name to the aspect factory meta class. */ - private final ImmutableMap<String, Class<? extends AspectFactory<?, ?, ?>>> aspectFactoryMap; + private final ImmutableMap<String, Class<? extends NativeAspectFactory>> aspectFactoryMap; /** * The configuration options that affect the behavior of the rules. @@ -319,7 +319,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { String runfilesPrefix, ImmutableMap<String, RuleClass> ruleClassMap, ImmutableMap<String, Class<? extends RuleDefinition>> ruleDefinitionMap, - ImmutableMap<String, Class<? extends AspectFactory<?, ?, ?>>> aspectFactoryMap, + ImmutableMap<String, Class<? extends NativeAspectFactory>> aspectFactoryMap, String defaultWorkspaceFile, ImmutableList<BuildInfoFactory> buildInfoFactories, ImmutableList<Class<? extends FragmentOptions>> configurationOptions, @@ -361,7 +361,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider { } @Override - public Map<String, Class<? extends AspectFactory<?, ?, ?>>> getAspectFactoryMap() { + public Map<String, Class<? extends NativeAspectFactory>> getAspectFactoryMap() { return aspectFactoryMap; } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java index 8d77bee428..a18902b5dc 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/DependencyResolver.java @@ -27,7 +27,6 @@ import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.collect.ImmutableSortedKeyListMultimap; import com.google.devtools.build.lib.packages.AspectClass; import com.google.devtools.build.lib.packages.AspectDefinition; -import com.google.devtools.build.lib.packages.AspectFactory; import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.Attribute.LateBoundDefault; @@ -560,11 +559,11 @@ public abstract class DependencyResolver { RuleClass ruleClass = ((Rule) target).getRuleClassObject(); ImmutableSet.Builder<AspectWithParameters> result = ImmutableSet.builder(); for (AspectWithParameters candidateClass : aspectCandidates) { - ConfiguredAspectFactory candidate = - (ConfiguredAspectFactory) AspectFactory.Util.create(candidateClass.getAspectClass()); + AspectClass aspectClass = candidateClass.getAspectClass(); if (Sets.difference( - candidate.getDefinition().getRequiredProviders(), - ruleClass.getAdvertisedProviders()).isEmpty()) { + aspectClass.getDefinition().getRequiredProviders(), + ruleClass.getAdvertisedProviders()) + .isEmpty()) { result.add(candidateClass); } } @@ -581,8 +580,8 @@ public abstract class DependencyResolver { Set<AspectWithParameters> aspectCandidates = new LinkedHashSet<>(); for (Map.Entry<AspectClass, AspectParameters> aspectWithParameters : attribute.getAspectsWithParameters(originalRule).entrySet()) { - aspectCandidates.add( - new AspectWithParameters(aspectWithParameters.getKey(), aspectWithParameters.getValue())); + AspectClass key = aspectWithParameters.getKey(); + aspectCandidates.add(new AspectWithParameters(key, aspectWithParameters.getValue())); } if (aspectDefinition != null) { for (AspectClass aspect : aspectDefinition.getAttributeAspects().get(attribute.getName())) { diff --git a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java index d8614597a4..14ef1550af 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/RuleConfiguredTarget.java @@ -130,14 +130,12 @@ public final class RuleConfiguredTarget extends AbstractConfiguredTarget { providers.addAll(base.providers.keySet()); // Merge output group providers. - List<OutputGroupProvider> outputGroupProviders = - getAllProviders(base, aspects, OutputGroupProvider.class); - OutputGroupProvider mergedOutputGroupProvider = OutputGroupProvider.merge(outputGroupProviders); + OutputGroupProvider mergedOutputGroupProvider = + OutputGroupProvider.merge(getAllProviders(base, aspects, OutputGroupProvider.class)); // Merge Skylark providers. - List<SkylarkProviders> skylarkProviders = - getAllProviders(base, aspects, SkylarkProviders.class); - SkylarkProviders mergedSkylarkProviders = SkylarkProviders.merge(skylarkProviders); + SkylarkProviders mergedSkylarkProviders = + SkylarkProviders.merge(getAllProviders(base, aspects, SkylarkProviders.class)); // Validate that all other providers are only provided once. for (Aspect aspect : aspects) { @@ -174,7 +172,7 @@ public final class RuleConfiguredTarget extends AbstractConfiguredTarget { builder.put(OutputGroupProvider.class, mergedOutputGroupProvider); } if (mergedSkylarkProviders != null) { - builder.put(SkylarkProviders.class, skylarkProviders); + builder.put(SkylarkProviders.class, mergedSkylarkProviders); } this.providers = builder.build(); } diff --git a/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java b/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java index c01100b26d..c01e10d0c6 100644 --- a/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java @@ -25,7 +25,7 @@ import com.google.devtools.build.lib.actions.Root; import com.google.devtools.build.lib.analysis.AnalysisUtils; import com.google.devtools.build.lib.analysis.Aspect; import com.google.devtools.build.lib.analysis.Aspect.Builder; -import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory; +import com.google.devtools.build.lib.analysis.ConfiguredNativeAspectFactory; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; @@ -70,7 +70,7 @@ import javax.annotation.Nullable; /** * Generates ide-build information for Android Studio. */ -public class AndroidStudioInfoAspect implements ConfiguredAspectFactory { +public class AndroidStudioInfoAspect implements ConfiguredNativeAspectFactory { public static final String NAME = "AndroidStudioInfoAspect"; // Output groups. diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java b/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java index 9c829221b1..834379cfe3 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/AspectClass.java @@ -17,7 +17,13 @@ package com.google.devtools.build.lib.packages; /** * A class of aspects. * - * <p>This interface serves as a factory for {@link AspectFactory}. + * <p>This interface serves as a factory for {@code AspectFactory}. + * {@code AspectFactory} type argument is a placeholder for + * a {@link com.google.devtools.build.lib.analysis.ConfiguredAspectFactory}, which is + * an analysis-phase class. All loading-phase code uses {@code AspectClass<?>}, + * whereas analysis-phase code uses {@code AspectClass<ConfiguredAspectFactory>}. + * The latter is what all real implementations of this interface should implement. + * */ public interface AspectClass { @@ -26,8 +32,5 @@ public interface AspectClass { */ String getName(); - /** - * Instantiates an {@link AspectFactory} for this aspect class. - */ - AspectFactory<?, ?, ?> newInstance(); + AspectDefinition getDefinition(); } diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java index a9c75d7811..7c5fa83ed3 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java +++ b/src/main/java/com/google/devtools/build/lib/packages/AspectDefinition.java @@ -22,6 +22,7 @@ import com.google.common.collect.LinkedHashMultimap; import com.google.common.collect.Multimap; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.packages.NativeAspectClass.NativeAspectFactory; import com.google.devtools.build.lib.util.BinaryPredicate; import java.util.LinkedHashMap; @@ -145,14 +146,13 @@ public final class AspectDefinition { LinkedHashMultimap<Attribute, Label> result = LinkedHashMultimap.create(); for (AspectClass candidateClass : attribute.getAspects()) { - AspectFactory<?, ?, ?> candidate = AspectFactory.Util.create(candidateClass); // Check if target satisfies condition for this aspect (has to provide all required // TransitiveInfoProviders) if (!advertisedProviders.containsAll( - candidate.getDefinition().getRequiredProviderNames())) { + candidateClass.getDefinition().getRequiredProviderNames())) { continue; } - addAllAttributesOfAspect((Rule) from, result, candidate.getDefinition(), Rule.ALL_DEPS); + addAllAttributesOfAspect((Rule) from, result, candidateClass.getDefinition(), Rule.ALL_DEPS); } return ImmutableMultimap.copyOf(result); } @@ -214,21 +214,38 @@ public final class AspectDefinition { * by direct dependencies through attribute {@code attribute} on the target associated with this * aspect. * - * <p>Note that {@code AspectFactory} instances are expected in the second argument, but we - * cannot reference that interface here. + * <p>Note that {@code ConfiguredAspectFactory} instances are expected in the second argument, + * but we cannot reference that interface here. */ @SafeVarargs public final Builder attributeAspect( - String attribute, Class<? extends AspectFactory<?, ?, ?>>... aspectFactories) { + String attribute, Class<? extends NativeAspectFactory>... aspectFactories) { Preconditions.checkNotNull(attribute); - for (Class<? extends AspectFactory<?, ?, ?>> aspectFactory : aspectFactories) { - this.attributeAspects.put( - attribute, new NativeAspectClass(Preconditions.checkNotNull(aspectFactory))); + for (Class<? extends NativeAspectFactory> aspectFactory : aspectFactories) { + this + .attributeAspect( + attribute, new NativeAspectClass<>(Preconditions.checkNotNull(aspectFactory))); } return this; } /** + * Declares that this aspect depends on the given {@link AspectClass} provided + * by direct dependencies through attribute {@code attribute} on the target associated with this + * aspect. + * + * <p>Note that {@code ConfiguredAspectFactory} instances are expected in the second argument, + * but we cannot reference that interface here. + */ + public final Builder attributeAspect(String attribute, AspectClass aspectClass) { + Preconditions.checkNotNull(attribute); + + this.attributeAspects.put(attribute, Preconditions.checkNotNull(aspectClass)); + + return this; + } + + /** * Adds an attribute to the aspect. * * <p>Since aspects do not appear in BUILD files, the attribute must be either implicit diff --git a/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java b/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java deleted file mode 100644 index bbc1fea1fd..0000000000 --- a/src/main/java/com/google/devtools/build/lib/packages/AspectFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.packages; - -/** - * Creates the Skyframe node of an aspect. - * - * <p>Also has a reference to the definition of the aspect. - */ -public interface AspectFactory<TConfiguredTarget, TRuleContext, TAspect> { - /** - * Creates the aspect based on the configured target of the associated rule. - * - * @param base the configured target of the associated rule - * @param context the context of the associated configured target plus all the attributes the - * aspect itself has defined - * @param parameters information from attributes of the rule that have requested this - * aspect - */ - TAspect create(TConfiguredTarget base, TRuleContext context, AspectParameters parameters) - throws InterruptedException; - - /** - * Returns the definition of the aspect. - */ - AspectDefinition getDefinition(); - - /** - * Dummy wrapper class for utility methods because interfaces cannot even have static ones. - */ - public static final class Util { - private Util() { - // Should never be instantiated - } - - public static AspectFactory<?, ?, ?> create(AspectClass aspectClass) { - // TODO(bazel-team): This should be cached somehow, because this method is invoked quite often - - return aspectClass.newInstance(); - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java index 63a1a3c517..b501579c44 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/Attribute.java +++ b/src/main/java/com/google/devtools/build/lib/packages/Attribute.java @@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableSet; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.packages.NativeAspectClass.NativeAspectFactory; import com.google.devtools.build.lib.syntax.ClassObject; import com.google.devtools.build.lib.syntax.ClassObject.SkylarkClassObject; import com.google.devtools.build.lib.syntax.EvalException; @@ -701,7 +702,7 @@ public final class Attribute implements Comparable<Attribute> { * Asserts that a particular aspect probably needs to be computed for all direct dependencies * through this attribute. */ - public Builder<TYPE> aspect(Class<? extends AspectFactory<?, ?, ?>> aspect) { + public <T extends NativeAspectFactory> Builder<TYPE> aspect(Class<T> aspect) { Function<Rule, AspectParameters> noParameters = new Function<Rule, AspectParameters>() { @Override public AspectParameters apply(Rule input) { @@ -717,9 +718,9 @@ public final class Attribute implements Comparable<Attribute> { * * @param evaluator function that extracts aspect parameters from rule. */ - public Builder<TYPE> aspect(Class<? extends AspectFactory<?, ?, ?>> aspect, - Function<Rule, AspectParameters> evaluator) { - this.aspects.add(new RuleAspect(new NativeAspectClass(aspect), evaluator)); + public <T extends NativeAspectFactory> Builder<TYPE> aspect( + Class<T> aspect, Function<Rule, AspectParameters> evaluator) { + this.aspects.add(new RuleAspect(new NativeAspectClass<T>(aspect), evaluator)); return this; } diff --git a/src/main/java/com/google/devtools/build/lib/packages/NativeAspectClass.java b/src/main/java/com/google/devtools/build/lib/packages/NativeAspectClass.java index 66360c152b..7477ea0184 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/NativeAspectClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/NativeAspectClass.java @@ -18,12 +18,13 @@ package com.google.devtools.build.lib.packages; * A class of aspects that are implemented natively in Bazel. * * <p>This class just wraps a {@link java.lang.Class} implementing the - * aspect factory. All wrappers of the same class are + * aspect factory. All wrappers of the same class are equal. */ -public final class NativeAspectClass implements AspectClass { - private final Class<? extends AspectFactory<?, ?, ?>> nativeClass; +public final class NativeAspectClass<T extends NativeAspectClass.NativeAspectFactory> + implements AspectClass { + private final Class<? extends T> nativeClass; - public NativeAspectClass(Class<? extends AspectFactory<?, ?, ?>> nativeClass) { + public NativeAspectClass(Class<? extends T> nativeClass) { this.nativeClass = nativeClass; } @@ -33,7 +34,11 @@ public final class NativeAspectClass implements AspectClass { } @Override - public AspectFactory<?, ?, ?> newInstance() { + public AspectDefinition getDefinition() { + return newInstance().getDefinition(); + } + + public T newInstance() { try { return nativeClass.newInstance(); } catch (Exception e) { @@ -53,4 +58,14 @@ public final class NativeAspectClass implements AspectClass { } return nativeClass.equals(((NativeAspectClass) obj).nativeClass); } + + /** + * Every native aspect should implement this interface. + */ + public interface NativeAspectFactory { + /** + * Returns the definition of the aspect. + */ + AspectDefinition getDefinition(); + } } diff --git a/src/main/java/com/google/devtools/build/lib/packages/Rule.java b/src/main/java/com/google/devtools/build/lib/packages/Rule.java index df1cb5e9b5..9825e2df06 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/Rule.java +++ b/src/main/java/com/google/devtools/build/lib/packages/Rule.java @@ -692,9 +692,8 @@ public final class Rule implements Target { LinkedHashMultimap<Attribute, Label> labels = LinkedHashMultimap.create(); for (Attribute attribute : this.getAttributes()) { for (AspectClass candidateClass : attribute.getAspects()) { - AspectFactory<?, ?, ?> candidate = AspectFactory.Util.create(candidateClass); - AspectDefinition.addAllAttributesOfAspect(Rule.this, labels, - candidate.getDefinition(), predicate); + AspectDefinition.addAllAttributesOfAspect( + Rule.this, labels, candidateClass.getDefinition(), predicate); } } return labels.values(); diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java index e50645e431..db69c2494f 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java @@ -15,6 +15,7 @@ package com.google.devtools.build.lib.packages; import com.google.devtools.build.lib.events.EventHandler; +import com.google.devtools.build.lib.packages.NativeAspectClass.NativeAspectFactory; import com.google.devtools.build.lib.syntax.Environment; import com.google.devtools.build.lib.syntax.Environment.Extension; import com.google.devtools.build.lib.syntax.Mutability; @@ -45,11 +46,6 @@ public interface RuleClassProvider { Map<String, RuleClass> getRuleClassMap(); /** - * Returns a map from aspect names to aspect factory objects. - */ - Map<String, Class<? extends AspectFactory<?, ?, ?>>> getAspectFactoryMap(); - - /** * Returns a new Skylark Environment instance for rule creation. * Implementations need to be thread safe. * Be sure to close() the mutability before you return the results of said evaluation. @@ -65,6 +61,11 @@ public interface RuleClassProvider { @Nullable Map<PathFragment, Extension> importMap); /** + * Returns a map from aspect names to aspect factory objects. + */ + Map<String, Class<? extends NativeAspectFactory>> getAspectFactoryMap(); + + /** * Returns the default content of the WORKSPACE file. * * <p>Used to provide external dependencies for built-in rules. Rules defined here can be diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/ConservativeAspectResolver.java b/src/main/java/com/google/devtools/build/lib/query2/output/ConservativeAspectResolver.java index c9f2321519..7404126739 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/output/ConservativeAspectResolver.java +++ b/src/main/java/com/google/devtools/build/lib/query2/output/ConservativeAspectResolver.java @@ -20,7 +20,6 @@ import com.google.common.collect.Multimap; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.packages.AspectClass; import com.google.devtools.build.lib.packages.AspectDefinition; -import com.google.devtools.build.lib.packages.AspectFactory; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.Target; @@ -44,10 +43,7 @@ public class ConservativeAspectResolver implements AspectResolver { for (Attribute attribute : ((Rule) target).getAttributes()) { for (AspectClass aspectFactory : attribute.getAspects()) { AspectDefinition.addAllAttributesOfAspect( - (Rule) target, - result, - AspectFactory.Util.create(aspectFactory).getDefinition(), - Rule.ALL_DEPS); + (Rule) target, result, aspectFactory.getDefinition(), Rule.ALL_DEPS); } } diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/PreciseAspectResolver.java b/src/main/java/com/google/devtools/build/lib/query2/output/PreciseAspectResolver.java index 4a22d49591..011cd9c3d5 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/output/PreciseAspectResolver.java +++ b/src/main/java/com/google/devtools/build/lib/query2/output/PreciseAspectResolver.java @@ -22,7 +22,6 @@ import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.events.EventHandler; import com.google.devtools.build.lib.packages.AspectClass; import com.google.devtools.build.lib.packages.AspectDefinition; -import com.google.devtools.build.lib.packages.AspectFactory; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.packages.NoSuchThingException; @@ -97,10 +96,7 @@ public class PreciseAspectResolver implements AspectResolver { @Override public boolean apply(@Nullable Rule rule, @Nullable Attribute attribute) { for (AspectClass aspectClass : attribute.getAspects()) { - if (!AspectFactory.Util.create(aspectClass) - .getDefinition() - .getAttributes() - .isEmpty()) { + if (!aspectClass.getDefinition().getAttributes().isEmpty()) { return true; } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java index ddfe3ff7e5..b27fb45227 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java +++ b/src/main/java/com/google/devtools/build/lib/rules/SkylarkRuleClassFunctions.java @@ -28,6 +28,7 @@ import static com.google.devtools.build.lib.syntax.Type.STRING; import static com.google.devtools.build.lib.syntax.Type.STRING_LIST; import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Preconditions; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -40,7 +41,11 @@ import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.RunUnder; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.cmdline.LabelSyntaxException; +import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; import com.google.devtools.build.lib.events.Location; +import com.google.devtools.build.lib.packages.AspectClass; +import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.Attribute.ConfigurationTransition; import com.google.devtools.build.lib.packages.Attribute.LateBoundLabel; @@ -83,6 +88,7 @@ import com.google.devtools.build.lib.vfs.PathFragment; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ExecutionException; /** @@ -336,12 +342,26 @@ public class SkylarkRuleClassFunctions { returnType = SkylarkAspect.class, documented = false, // TODO(dslomov): Experimental, document later. mandatoryPositionals = {@Param(name = "implementation", type = BaseFunction.class)}, + optionalPositionals = { + @Param( + name = "attr_aspects", + type = SkylarkList.class, + generic1 = String.class, + defaultValue = "[]" + ) + }, useEnvironment = true ) private static final BuiltinFunction aspect = new BuiltinFunction("aspect") { - public SkylarkAspect invoke(BaseFunction implementation, Environment funcallEnv) { - return new SkylarkAspect(implementation, funcallEnv); + public SkylarkAspect invoke( + BaseFunction implementation, SkylarkList attributeAspects, Environment funcallEnv) + throws ConversionException { + ImmutableList.Builder<String> builder = ImmutableList.<String>builder(); + for (Object attributeAspect : attributeAspects) { + builder.add(STRING.convert(attributeAspect, "")); + } + return new SkylarkAspect(implementation, builder.build(), funcallEnv); } }; @@ -399,14 +419,20 @@ public class SkylarkRuleClassFunctions { } } - public static void exportRuleFunctions(Environment env, PathFragment skylarkFile) { + public static void exportRuleFunctionsAndAspects(Environment env, PackageIdentifier skylarkFile) { for (String name : env.getGlobals().getDirectVariableNames()) { try { Object value = env.lookup(name); if (value instanceof RuleFunction) { RuleFunction function = (RuleFunction) value; if (function.skylarkFile == null) { - function.export(skylarkFile, name); + function.export(skylarkFile.getPackageFragment(), name); + } + } + if (value instanceof SkylarkAspect) { + SkylarkAspect skylarkAspect = (SkylarkAspect) value; + if (!skylarkAspect.isExported()) { + skylarkAspect.export(skylarkFile, name); } } } catch (NoSuchVariableException e) { @@ -539,10 +565,16 @@ public class SkylarkRuleClassFunctions { */ public static class SkylarkAspect implements SkylarkValue { private final BaseFunction implementation; + private final ImmutableList<String> attributeAspects; private final Environment funcallEnv; + private Exported exported; - public SkylarkAspect(BaseFunction implementation, Environment funcallEnv) { + public SkylarkAspect( + BaseFunction implementation, + ImmutableList<String> attributeAspects, + Environment funcallEnv) { this.implementation = implementation; + this.attributeAspects = attributeAspects; this.funcallEnv = funcallEnv; } @@ -550,6 +582,10 @@ public class SkylarkRuleClassFunctions { return implementation; } + public ImmutableList<String> getAttributeAspects() { + return attributeAspects; + } + public Environment getFuncallEnv() { return funcallEnv; } @@ -564,5 +600,100 @@ public class SkylarkRuleClassFunctions { Printer.append(buffer, "Aspect:"); implementation.write(buffer, quotationMark); } + + public String getName() { + return exported != null ? exported.toString() : "<skylark aspect>"; + } + + void export(PackageIdentifier extensionFile, String name) { + this.exported = new Exported(extensionFile, name); + } + + public boolean isExported() { + return exported != null; + } + + private PackageIdentifier getExtensionFile() { + Preconditions.checkArgument(isExported()); + return exported.extensionFile; + } + + private String getExportedName() { + Preconditions.checkArgument(isExported()); + return exported.name; + } + + @Immutable + private static class Exported { + private final PackageIdentifier extensionFile; + private final String name; + + public Exported(PackageIdentifier extensionFile, String name) { + this.extensionFile = extensionFile; + this.name = name; + } + + public String toString() { + return extensionFile.toString() + "%" + name; + } + } + } + + /** + * Implementation of an aspect class defined in Skylark. + */ + @Immutable + public static final class SkylarkAspectClass implements AspectClass { + private final AspectDefinition aspectDefinition; + private final PackageIdentifier extensionFile; + private final String exportedName; + + public SkylarkAspectClass(SkylarkAspect skylarkAspect) { + Preconditions.checkArgument(skylarkAspect.isExported(), "Skylark aspects must be exported"); + AspectDefinition.Builder builder = new AspectDefinition.Builder(skylarkAspect.getName()); + for (String attributeAspect : skylarkAspect.getAttributeAspects()) { + builder.attributeAspect(attributeAspect, this); + } + this.aspectDefinition = builder.build(); + + this.extensionFile = skylarkAspect.getExtensionFile(); + this.exportedName = skylarkAspect.getExportedName(); + } + + @Override + public String getName() { + return aspectDefinition.getName(); + } + + @Override + public AspectDefinition getDefinition() { + return aspectDefinition; + } + + public PackageIdentifier getExtensionFile() { + return extensionFile; + } + + public String getExportedName() { + return exportedName; + } + + public int hashCode() { + return Objects.hash(extensionFile, exportedName); + } + + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof SkylarkAspectClass)) { + return false; + } + + SkylarkAspectClass that = (SkylarkAspectClass) other; + return Objects.equals(this.extensionFile, that.extensionFile) + && Objects.equals(this.exportedName, that.exportedName); + } + } } diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverlinkAspect.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverlinkAspect.java index ca2a64891c..e3e0856d28 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverlinkAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidNeverlinkAspect.java @@ -15,7 +15,7 @@ package com.google.devtools.build.lib.rules.android; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.analysis.Aspect; -import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory; +import com.google.devtools.build.lib.analysis.ConfiguredNativeAspectFactory; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; @@ -38,7 +38,7 @@ import java.util.List; * <p>One would think that using the compile time classpath would be enough, but alas, those are * ijars, */ -public class AndroidNeverlinkAspect implements ConfiguredAspectFactory { +public class AndroidNeverlinkAspect implements ConfiguredNativeAspectFactory { public static final String NAME = "AndroidNeverlinkAspect"; private static final ImmutableList<String> ATTRIBUTES = ImmutableList.of( diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java index 8eff14704d..7d7ff0581c 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/AbstractJ2ObjcProtoAspect.java @@ -19,7 +19,7 @@ import static com.google.devtools.build.lib.rules.objc.J2ObjcSource.SourceType; import com.google.common.collect.ImmutableList; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.analysis.Aspect; -import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory; +import com.google.devtools.build.lib.analysis.ConfiguredNativeAspectFactory; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; @@ -49,7 +49,7 @@ import com.google.devtools.build.lib.vfs.PathFragment; * by this class and provided by proto_library will be exported all the way to objc_binary for ObjC * compilation and linking into the final application bundle. */ -public abstract class AbstractJ2ObjcProtoAspect implements ConfiguredAspectFactory { +public abstract class AbstractJ2ObjcProtoAspect implements ConfiguredNativeAspectFactory { public static final String NAME = "J2ObjcProtoAspect"; public AspectDefinition getDefinition() { diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java index 84427d46f8..9fc55ccf67 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java +++ b/src/main/java/com/google/devtools/build/lib/rules/objc/J2ObjcAspect.java @@ -25,7 +25,7 @@ import com.google.devtools.build.lib.Constants; import com.google.devtools.build.lib.actions.Artifact; import com.google.devtools.build.lib.actions.ParameterFile; import com.google.devtools.build.lib.analysis.Aspect; -import com.google.devtools.build.lib.analysis.ConfiguredAspectFactory; +import com.google.devtools.build.lib.analysis.ConfiguredNativeAspectFactory; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.RuleConfiguredTarget.Mode; import com.google.devtools.build.lib.analysis.RuleContext; @@ -54,7 +54,7 @@ import java.util.List; /** * J2ObjC transpilation aspect for Java rules. */ -public class J2ObjcAspect implements ConfiguredAspectFactory { +public class J2ObjcAspect implements ConfiguredNativeAspectFactory { public static final String NAME = "J2ObjcAspect"; /** * Adds the attribute aspect args to the given AspectDefinition.Builder. diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java index 57dc717f00..13764f62dc 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectFunction.java @@ -25,21 +25,21 @@ import com.google.devtools.build.lib.analysis.RuleConfiguredTarget; import com.google.devtools.build.lib.analysis.TargetAndConfiguration; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.analysis.config.ConfigMatchingProvider; +import com.google.devtools.build.lib.cmdline.PackageIdentifier; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.events.StoredEventHandler; -import com.google.devtools.build.lib.packages.AspectFactory; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException; +import com.google.devtools.build.lib.packages.NativeAspectClass; import com.google.devtools.build.lib.packages.NoSuchTargetException; import com.google.devtools.build.lib.packages.Package; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.RuleClassProvider; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.rules.SkylarkRuleClassFunctions.SkylarkAspect; +import com.google.devtools.build.lib.rules.SkylarkRuleClassFunctions.SkylarkAspectClass; import com.google.devtools.build.lib.skyframe.ASTFileLookupValue.ASTLookupInputException; import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey; -import com.google.devtools.build.lib.skyframe.AspectValue.NativeAspectKey; -import com.google.devtools.build.lib.skyframe.AspectValue.SkylarkAspectKey; import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.DependencyEvaluationException; import com.google.devtools.build.lib.skyframe.SkyframeExecutor.BuildViewProvider; import com.google.devtools.build.lib.syntax.Type.ConversionException; @@ -55,30 +55,38 @@ import javax.annotation.Nullable; /** * The Skyframe function that generates aspects. */ -public final class AspectFunction<T extends AspectKey> implements SkyFunction { +public final class AspectFunction implements SkyFunction { private final BuildViewProvider buildViewProvider; private final RuleClassProvider ruleClassProvider; - private final AspectFactoryCreator<T> aspectFactoryCreator; - public static AspectFunction<NativeAspectKey> createNativeAspectFunction( - BuildViewProvider buildViewProvider, RuleClassProvider ruleClassProvider) { - return new AspectFunction<>( - buildViewProvider, ruleClassProvider, new NativeAspectFactoryCreator()); + public AspectFunction(BuildViewProvider buildViewProvider, RuleClassProvider ruleClassProvider) { + this.buildViewProvider = buildViewProvider; + this.ruleClassProvider = ruleClassProvider; } - public static AspectFunction<SkylarkAspectKey> createSkylarkAspectFunction( - BuildViewProvider buildViewProvider, RuleClassProvider ruleClassProvider) { - return new AspectFunction<>( - buildViewProvider, ruleClassProvider, new SkylarkAspectFactoryCreator()); - } + /** + * Load Skylark aspect from an extension file. Is to be called from a SkyFunction. + * + * @return {@code null} if dependencies cannot be satisfied. + */ + @Nullable + public static SkylarkAspect loadSkylarkAspect( + Environment env, PackageIdentifier extensionFile, String skylarkValueName) + throws ASTLookupInputException, ConversionException { + SkyKey importFileKey; + importFileKey = SkylarkImportLookupValue.key(extensionFile); + SkylarkImportLookupValue skylarkImportLookupValue = + (SkylarkImportLookupValue) env.getValue(importFileKey); + if (skylarkImportLookupValue == null) { + return null; + } - private AspectFunction( - BuildViewProvider buildViewProvider, - RuleClassProvider ruleClassProvider, - AspectFactoryCreator<T> aspectFactoryCreator) { - this.buildViewProvider = buildViewProvider; - this.ruleClassProvider = ruleClassProvider; - this.aspectFactoryCreator = aspectFactoryCreator; + Object skylarkValue = skylarkImportLookupValue.getEnvironmentExtension().get(skylarkValueName); + if (!(skylarkValue instanceof SkylarkAspect)) { + throw new ConversionException( + skylarkValueName + " from " + extensionFile.toString() + " is not an aspect"); + } + return (SkylarkAspect) skylarkValue; } @Nullable @@ -88,7 +96,28 @@ public final class AspectFunction<T extends AspectKey> implements SkyFunction { SkyframeBuildView view = buildViewProvider.getSkyframeBuildView(); NestedSetBuilder<Package> transitivePackages = NestedSetBuilder.stableOrder(); AspectKey key = (AspectKey) skyKey.argument(); - ConfiguredAspectFactory aspectFactory = aspectFactoryCreator.createAspectFactory(skyKey, env); + ConfiguredAspectFactory aspectFactory; + if (key.getAspect() instanceof NativeAspectClass<?>) { + aspectFactory = + (ConfiguredAspectFactory) ((NativeAspectClass<?>) key.getAspect()).newInstance(); + } else if (key.getAspect() instanceof SkylarkAspectClass) { + SkylarkAspectClass skylarkAspectClass = (SkylarkAspectClass) key.getAspect(); + SkylarkAspect skylarkAspect; + try { + skylarkAspect = + loadSkylarkAspect( + env, skylarkAspectClass.getExtensionFile(), skylarkAspectClass.getExportedName()); + } catch (ASTLookupInputException | ConversionException e) { + throw new AspectFunctionException(skyKey, e); + } + if (skylarkAspect == null) { + return null; + } + + aspectFactory = new SkylarkAspectFactory(skylarkAspect.getName(), skylarkAspect); + } else { + throw new IllegalStateException(); + } PackageValue packageValue = (PackageValue) env.getValue(PackageValue.key(key.getLabel().getPackageIdentifier())); @@ -148,9 +177,15 @@ public final class AspectFunction<T extends AspectKey> implements SkyFunction { } ListMultimap<Attribute, ConfiguredTarget> depValueMap = - ConfiguredTargetFunction.computeDependencies(env, resolver, ctgValue, - aspectFactory.getDefinition(), key.getParameters(), configConditions, - ruleClassProvider, view.getHostConfiguration(ctgValue.getConfiguration()), + ConfiguredTargetFunction.computeDependencies( + env, + resolver, + ctgValue, + key.getAspect().getDefinition(), + key.getParameters(), + configConditions, + ruleClassProvider, + view.getHostConfiguration(ctgValue.getConfiguration()), transitivePackages); return createAspect( @@ -247,57 +282,4 @@ public final class AspectFunction<T extends AspectKey> implements SkyFunction { } } - /** - * Factory for {@link ConfiguredAspectFactory} given a particular kind of {@link AspectKey}. - */ - private interface AspectFactoryCreator<T extends AspectKey> { - ConfiguredAspectFactory createAspectFactory(SkyKey skyKey, Environment env) - throws AspectFunctionException; - } - - /** - * Factory for native aspects. - */ - private static class NativeAspectFactoryCreator implements AspectFactoryCreator<NativeAspectKey> { - - @Override - public ConfiguredAspectFactory createAspectFactory(SkyKey skyKey, Environment env) { - NativeAspectKey key = (NativeAspectKey) skyKey.argument(); - return (ConfiguredAspectFactory) AspectFactory.Util.create(key.getAspect()); - } - } - - /** - * Factory for Skylark aspects. - */ - private static class SkylarkAspectFactoryCreator - implements AspectFactoryCreator<SkylarkAspectKey> { - - @Override - public ConfiguredAspectFactory createAspectFactory(SkyKey skyKey, Environment env) - throws AspectFunctionException { - SkylarkAspectKey skylarkAspectKey = (SkylarkAspectKey) skyKey.argument(); - SkyKey importFileKey; - try { - importFileKey = SkylarkImportLookupValue.key(skylarkAspectKey.getExtensionFile()); - } catch (ASTLookupInputException e) { - throw new AspectFunctionException(skyKey, e); - } - SkylarkImportLookupValue skylarkImportLookupValue = - (SkylarkImportLookupValue) env.getValue(importFileKey); - if (skylarkImportLookupValue == null) { - return null; - } - Object skylarkValue = skylarkImportLookupValue - .getEnvironmentExtension() - .get(skylarkAspectKey.getSkylarkValueName()); - if (!(skylarkValue instanceof SkylarkAspect)) { - throw new AspectFunctionException( - new ConversionException(skylarkAspectKey.getSkylarkValueName() + " from " - + skylarkAspectKey.getExtensionFile().toString() + " is not an aspect")); - } - SkylarkAspect skylarkAspect = (SkylarkAspect) skylarkValue; - return new SkylarkAspectFactory(skylarkAspectKey.getSkylarkValueName(), skylarkAspect); - } - } } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/AspectValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/AspectValue.java index 336056fad1..318b6683be 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/AspectValue.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/AspectValue.java @@ -15,7 +15,6 @@ package com.google.devtools.build.lib.skyframe; import com.google.common.base.Objects; -import com.google.common.base.Preconditions; import com.google.devtools.build.lib.actions.Action; import com.google.devtools.build.lib.analysis.Aspect; import com.google.devtools.build.lib.analysis.AspectWithParameters; @@ -38,65 +37,59 @@ import javax.annotation.Nullable; public final class AspectValue extends ActionLookupValue { /** - * A base class for a key representing an aspect applied to a particular target. + * A base class for keys that have AspectValue as a Sky value. */ - public abstract static class AspectKey extends ActionLookupKey { - protected final Label label; - protected final BuildConfiguration configuration; - - protected AspectKey(Label label, BuildConfiguration configuration) { - this.label = label; - this.configuration = configuration; - } - - @Override - public Label getLabel() { - return label; - } - - public abstract AspectParameters getParameters(); + public abstract static class AspectValueKey extends ActionLookupKey { public abstract String getDescription(); - - public BuildConfiguration getConfiguration() { - return configuration; - } } /** - * The key of an action that is generated by a native aspect. + * A base class for a key representing an aspect applied to a particular target. */ - public static final class NativeAspectKey extends AspectKey { + public static final class AspectKey extends AspectValueKey { + private final Label label; + private final BuildConfiguration configuration; private final AspectWithParameters aspect; + private final String aspectName; - private NativeAspectKey( + protected AspectKey( Label label, BuildConfiguration configuration, - AspectClass aspectClass , + AspectClass aspectClass, AspectParameters parameters) { - super(label, configuration); - Preconditions.checkNotNull(parameters); + this.label = label; + this.configuration = configuration; + this.aspectName = aspectClass.getName(); this.aspect = new AspectWithParameters(aspectClass, parameters); } + @Override + SkyFunctionName getType() { + return SkyFunctions.ASPECT; + } + + + @Override + public Label getLabel() { + return label; + } + public AspectClass getAspect() { return aspect.getAspectClass(); } - @Override @Nullable public AspectParameters getParameters() { return aspect.getParameters(); } - @Override public String getDescription() { return String.format("%s of %s", aspect.getAspectClass().getName(), getLabel()); } - @Override - SkyFunctionName getType() { - return SkyFunctions.NATIVE_ASPECT; + public BuildConfiguration getConfiguration() { + return configuration; } @Override @@ -110,11 +103,11 @@ public final class AspectValue extends ActionLookupValue { return true; } - if (!(other instanceof NativeAspectKey)) { + if (!(other instanceof AspectKey)) { return false; } - NativeAspectKey that = (NativeAspectKey) other; + AspectKey that = (AspectKey) other; return Objects.equal(label, that.label) && Objects.equal(configuration, that.configuration) && Objects.equal(aspect, that.aspect); @@ -129,20 +122,30 @@ public final class AspectValue extends ActionLookupValue { } /** - * The key of an action that is generated by a skylark aspect. + * The key for a skylark aspect. */ - public static class SkylarkAspectKey extends AspectKey { + public static class SkylarkAspectLoadingKey extends AspectValueKey { + + private final Label targetLabel; + private final BuildConfiguration targetConfiguration; private final PackageIdentifier extensionFile; - private final String skylarkFunctionName; + private final String skylarkValueName; - private SkylarkAspectKey( + private SkylarkAspectLoadingKey( Label targetLabel, BuildConfiguration targetConfiguration, PackageIdentifier extensionFile, String skylarkFunctionName) { - super(targetLabel, targetConfiguration); + this.targetLabel = targetLabel; + this.targetConfiguration = targetConfiguration; + this.extensionFile = extensionFile; - this.skylarkFunctionName = skylarkFunctionName; + this.skylarkValueName = skylarkFunctionName; + } + + @Override + SkyFunctionName getType() { + return SkyFunctions.LOAD_SKYLARK_ASPECT; } public PackageIdentifier getExtensionFile() { @@ -150,24 +153,20 @@ public final class AspectValue extends ActionLookupValue { } public String getSkylarkValueName() { - return skylarkFunctionName; + return skylarkValueName; } - @Override - public AspectParameters getParameters() { - return AspectParameters.EMPTY; + public Label getTargetLabel() { + return targetLabel; } - @Override - public String getDescription() { - // Skylark aspects are referred to on command line with <file>%<value name> - return String.format( - "%s%%%s of %s", extensionFile.toString(), skylarkFunctionName, getLabel()); + public BuildConfiguration getTargetConfiguration() { + return targetConfiguration; } - @Override - SkyFunctionName getType() { - return SkyFunctions.SKYLARK_ASPECT; + public String getDescription() { + // Skylark aspects are referred to on command line with <file>%<value ame> + return String.format("%s%%%s of %s", extensionFile.toString(), skylarkValueName, targetLabel); } } @@ -215,24 +214,25 @@ public final class AspectValue extends ActionLookupValue { AspectClass aspectFactory, AspectParameters additionalConfiguration) { return new SkyKey( - SkyFunctions.NATIVE_ASPECT, - new NativeAspectKey(label, configuration, aspectFactory, additionalConfiguration)); + SkyFunctions.ASPECT, + new AspectKey(label, configuration, aspectFactory, additionalConfiguration)); } - public static SkyKey key(AspectKey aspectKey) { + public static SkyKey key(AspectValueKey aspectKey) { return new SkyKey(aspectKey.getType(), aspectKey); } - public static NativeAspectKey createAspectKey( + public static AspectKey createAspectKey( Label label, BuildConfiguration configuration, AspectClass aspectFactory) { - return new NativeAspectKey(label, configuration, aspectFactory, AspectParameters.EMPTY); + return new AspectKey(label, configuration, aspectFactory, AspectParameters.EMPTY); } - public static SkylarkAspectKey createSkylarkAspectKey( + public static SkylarkAspectLoadingKey createSkylarkAspectKey( Label targetLabel, BuildConfiguration targetConfiguration, - PackageIdentifier bzlFile, - String skylarkFunctionName) { - return new SkylarkAspectKey(targetLabel, targetConfiguration, bzlFile, skylarkFunctionName); + PackageIdentifier skylarkFile, + String skylarkExportName) { + return new SkylarkAspectLoadingKey( + targetLabel, targetConfiguration, skylarkFile, skylarkExportName); } } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java index 237feea9d7..4493229290 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ConfiguredTargetFunction.java @@ -47,7 +47,6 @@ import com.google.devtools.build.lib.events.Event; import com.google.devtools.build.lib.events.StoredEventHandler; import com.google.devtools.build.lib.packages.AspectClass; import com.google.devtools.build.lib.packages.AspectDefinition; -import com.google.devtools.build.lib.packages.AspectFactory; import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.BuildFileContainsErrorsException; @@ -510,7 +509,8 @@ final class ConfiguredTargetFunction implements SkyFunction { } ConfiguredTarget depConfiguredTarget = configuredTargetMap.get(depKey); for (AspectWithParameters depAspect : dep.getAspects()) { - if (!aspectMatchesConfiguredTarget(depConfiguredTarget, depAspect.getAspectClass())) { + AspectClass depAspectClass = depAspect.getAspectClass(); + if (!aspectMatchesConfiguredTarget(depConfiguredTarget, depAspectClass)) { continue; } @@ -522,11 +522,12 @@ final class ConfiguredTargetFunction implements SkyFunction { // The configured target should have been created in resolveConfiguredTargetDependencies() throw new IllegalStateException(e); } catch (NoSuchThingException e) { - AspectFactory<?, ?, ?> depAspectFactory = - AspectFactory.Util.create(depAspect.getAspectClass()); throw new AspectCreationException( - String.format("Evaluation of aspect %s on %s failed: %s", - depAspectFactory.getDefinition().getName(), dep.getLabel(), e.toString())); + String.format( + "Evaluation of aspect %s on %s failed: %s", + depAspectClass.getDefinition().getName(), + dep.getLabel(), + e.toString())); } if (aspectValue == null) { @@ -550,7 +551,7 @@ final class ConfiguredTargetFunction implements SkyFunction { private static boolean aspectMatchesConfiguredTarget( ConfiguredTarget dep, AspectClass aspectClass) { - AspectDefinition aspectDefinition = AspectFactory.Util.create(aspectClass).getDefinition(); + AspectDefinition aspectDefinition = aspectClass.getDefinition(); for (Class<?> provider : aspectDefinition.getRequiredProviders()) { if (dep.getProvider(provider.asSubclass(TransitiveInfoProvider.class)) == null) { return false; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java index ee3d395841..b04121163e 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyFunctions.java @@ -65,8 +65,9 @@ public final class SkyFunctions { SkyFunctionName.create("CONFIGURED_TARGET"); public static final SkyFunctionName POST_CONFIGURED_TARGET = SkyFunctionName.create("POST_CONFIGURED_TARGET"); - public static final SkyFunctionName NATIVE_ASPECT = SkyFunctionName.create("NATIVE_ASPECT"); - public static final SkyFunctionName SKYLARK_ASPECT = SkyFunctionName.create("SKYLARK_ASPECT"); + public static final SkyFunctionName ASPECT = SkyFunctionName.create("ASPECT"); + public static final SkyFunctionName LOAD_SKYLARK_ASPECT = + SkyFunctionName.create("LOAD_SKYLARK_ASPECT"); public static final SkyFunctionName TARGET_COMPLETION = SkyFunctionName.create("TARGET_COMPLETION"); public static final SkyFunctionName ASPECT_COMPLETION = diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java index f7a85e6902..e1dc3a025a 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeBuildView.java @@ -63,7 +63,7 @@ import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.pkgcache.LoadingPhaseRunner; import com.google.devtools.build.lib.skyframe.ActionLookupValue.ActionLookupKey; import com.google.devtools.build.lib.skyframe.AspectFunction.AspectCreationException; -import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey; +import com.google.devtools.build.lib.skyframe.AspectValue.AspectValueKey; import com.google.devtools.build.lib.skyframe.BuildInfoCollectionValue.BuildInfoKeyAndConfig; import com.google.devtools.build.lib.skyframe.ConfiguredTargetFunction.ConfiguredValueCreationException; import com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.ConflictException; @@ -238,7 +238,7 @@ public final class SkyframeBuildView { public SkyframeAnalysisResult configureTargets( EventHandler eventHandler, List<ConfiguredTargetKey> values, - List<AspectKey> aspectKeys, + List<AspectValueKey> aspectKeys, EventBus eventBus, boolean keepGoing) throws InterruptedException, ViewCreationFailedException { @@ -253,7 +253,7 @@ public final class SkyframeBuildView { Collection<AspectValue> goodAspects = Lists.newArrayListWithCapacity(values.size()); NestedSetBuilder<Package> packages = NestedSetBuilder.stableOrder(); - for (AspectKey aspectKey : aspectKeys) { + for (AspectValueKey aspectKey : aspectKeys) { AspectValue value = (AspectValue) result.get(AspectValue.key(aspectKey)); if (value == null) { // Skip aspects that couldn't be applied to targets. @@ -320,8 +320,8 @@ public final class SkyframeBuildView { "Analysis of target '" + ConfiguredTargetValue.extractLabel(topLevel) + "' failed; build aborted"; - } else if (topLevel.argument() instanceof AspectKey) { - AspectKey aspectKey = (AspectKey) topLevel.argument(); + } else if (topLevel.argument() instanceof AspectValueKey) { + AspectValueKey aspectKey = (AspectValueKey) topLevel.argument(); errorMsg = "Analysis of aspect '" + aspectKey.getDescription() + "' failed; build aborted"; } else { assert false; diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java index 1b5dfd8468..f13505b3d4 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java @@ -92,7 +92,7 @@ import com.google.devtools.build.lib.pkgcache.PackageManager; import com.google.devtools.build.lib.pkgcache.PathPackageLocator; import com.google.devtools.build.lib.pkgcache.TransitivePackageLoader; import com.google.devtools.build.lib.profiler.AutoProfiler; -import com.google.devtools.build.lib.skyframe.AspectValue.AspectKey; +import com.google.devtools.build.lib.skyframe.AspectValue.AspectValueKey; import com.google.devtools.build.lib.skyframe.DirtinessCheckerUtils.FileDirtinessChecker; import com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.ActionCompletedReceiver; import com.google.devtools.build.lib.skyframe.SkyframeActionExecutor.ProgressSupplier; @@ -351,12 +351,8 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { map.put(SkyFunctions.TRANSITIVE_TRAVERSAL, new TransitiveTraversalFunction()); map.put(SkyFunctions.CONFIGURED_TARGET, new ConfiguredTargetFunction(new BuildViewProvider(), ruleClassProvider)); - map.put( - SkyFunctions.NATIVE_ASPECT, - AspectFunction.createNativeAspectFunction(new BuildViewProvider(), ruleClassProvider)); - map.put( - SkyFunctions.SKYLARK_ASPECT, - AspectFunction.createSkylarkAspectFunction(new BuildViewProvider(), ruleClassProvider)); + map.put(SkyFunctions.ASPECT, new AspectFunction(new BuildViewProvider(), ruleClassProvider)); + map.put(SkyFunctions.LOAD_SKYLARK_ASPECT, new ToplevelSkylarkAspectFunction()); map.put(SkyFunctions.POST_CONFIGURED_TARGET, new PostConfiguredTargetFunction(new BuildViewProvider(), ruleClassProvider)); map.put(SkyFunctions.BUILD_CONFIGURATION, @@ -1320,13 +1316,16 @@ public abstract class SkyframeExecutor implements WalkableGraphFactory { } /** Configures a given set of configured targets. */ - public EvaluationResult<ActionLookupValue> configureTargets(EventHandler eventHandler, - List<ConfiguredTargetKey> values, List<AspectKey> aspectKeys, boolean keepGoing) - throws InterruptedException { + public EvaluationResult<ActionLookupValue> configureTargets( + EventHandler eventHandler, + List<ConfiguredTargetKey> values, + List<AspectValueKey> aspectKeys, + boolean keepGoing) + throws InterruptedException { checkActive(); List<SkyKey> keys = new ArrayList<>(ConfiguredTargetValue.keys(values)); - for (AspectKey aspectKey : aspectKeys) { + for (AspectValueKey aspectKey : aspectKeys) { keys.add(AspectValue.key(aspectKey)); } // Make sure to not run too many analysis threads. This can cause memory thrashing. diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java index 916803a795..c8775c97c3 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkAspectFactory.java @@ -21,7 +21,6 @@ import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.RuleContext; import com.google.devtools.build.lib.analysis.SkylarkProviderValidationUtil; import com.google.devtools.build.lib.events.Location; -import com.google.devtools.build.lib.packages.AspectDefinition; import com.google.devtools.build.lib.packages.AspectParameters; import com.google.devtools.build.lib.rules.SkylarkRuleClassFunctions.SkylarkAspect; import com.google.devtools.build.lib.rules.SkylarkRuleContext; @@ -37,11 +36,11 @@ import com.google.devtools.build.lib.syntax.Mutability; public class SkylarkAspectFactory implements ConfiguredAspectFactory { private final String name; - private final SkylarkAspect aspectFunction; + private final SkylarkAspect skylarkAspect; - public SkylarkAspectFactory(String name, SkylarkAspect aspectFunction) { + public SkylarkAspectFactory(String name, SkylarkAspect skylarkAspect) { this.name = name; - this.aspectFunction = aspectFunction; + this.skylarkAspect = skylarkAspect; } @Override @@ -58,14 +57,14 @@ public class SkylarkAspectFactory implements ConfiguredAspectFactory { Environment env = Environment.builder(mutability) .setSkylark() - .setGlobals(aspectFunction.getFuncallEnv().getGlobals()) + .setGlobals(skylarkAspect.getFuncallEnv().getGlobals()) .setEventHandler(ruleContext.getAnalysisEnvironment().getEventHandler()) .build(); // NB: loading phase functions are not available: this is analysis already, // so we do *not* setLoadingPhase(). Object aspectSkylarkObject; try { aspectSkylarkObject = - aspectFunction + skylarkAspect .getImplementation() .call( ImmutableList.<Object>of(base, skylarkRuleContext), @@ -105,12 +104,7 @@ public class SkylarkAspectFactory implements ConfiguredAspectFactory { .registerPhantomFuncall( String.format("%s(...)", name), base.getTarget().getAssociatedRule().getLocation(), - aspectFunction.getImplementation()); + skylarkAspect.getImplementation()); } } - - @Override - public AspectDefinition getDefinition() { - return new AspectDefinition.Builder(name).build(); - } } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java index c0c72f05e2..bba850b316 100644 --- a/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java +++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunction.java @@ -177,7 +177,7 @@ public class SkylarkImportLookupFunction implements SkyFunction { // Skylark UserDefinedFunction-s in that file will share this function definition Environment, // which will be frozen by the time it is returned by createExtension. - Extension extension = createExtension(ast, file, importMap, env); + Extension extension = createExtension(ast, pkgId, importMap, env); return new SkylarkImportLookupValue( extension, new SkylarkFileDependency(label, fileDependencies.build())); @@ -229,26 +229,27 @@ public class SkylarkImportLookupFunction implements SkyFunction { */ private Extension createExtension( BuildFileAST ast, - PathFragment file, + PackageIdentifier packageIdentifier, Map<PathFragment, Extension> importMap, Environment env) - throws InterruptedException, SkylarkImportLookupFunctionException { + throws InterruptedException, SkylarkImportLookupFunctionException { StoredEventHandler eventHandler = new StoredEventHandler(); // TODO(bazel-team): this method overestimates the changes which can affect the // Skylark RuleClass. For example changes to comments or unused functions can modify the hash. // A more accurate - however much more complicated - way would be to calculate a hash based on // the transitive closure of the accessible AST nodes. - try (Mutability mutability = Mutability.create("importing %s", file)) { + try (Mutability mutability = Mutability.create("importing %s", packageIdentifier)) { com.google.devtools.build.lib.syntax.Environment extensionEnv = ruleClassProvider.createSkylarkRuleClassEnvironment( mutability, eventHandler, ast.getContentHashCode(), importMap) .setupOverride("native", packageFactory.getNativeModule()); ast.exec(extensionEnv, eventHandler); - SkylarkRuleClassFunctions.exportRuleFunctions(extensionEnv, file); + SkylarkRuleClassFunctions.exportRuleFunctionsAndAspects(extensionEnv, packageIdentifier); Event.replayEventsOn(env.getListener(), eventHandler.getEvents()); if (eventHandler.hasErrors()) { - throw new SkylarkImportLookupFunctionException(SkylarkImportFailedException.errors(file)); + throw new SkylarkImportLookupFunctionException( + SkylarkImportFailedException.errors(packageIdentifier.getPackageFragment())); } return new Extension(extensionEnv); } diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelSkylarkAspectFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelSkylarkAspectFunction.java new file mode 100644 index 0000000000..fabb1bb058 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/skyframe/ToplevelSkylarkAspectFunction.java @@ -0,0 +1,85 @@ +// Copyright 2015 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.devtools.build.lib.skyframe; + +import com.google.devtools.build.lib.cmdline.PackageIdentifier; +import com.google.devtools.build.lib.packages.AspectParameters; +import com.google.devtools.build.lib.rules.SkylarkRuleClassFunctions.SkylarkAspect; +import com.google.devtools.build.lib.rules.SkylarkRuleClassFunctions.SkylarkAspectClass; +import com.google.devtools.build.lib.skyframe.ASTFileLookupValue.ASTLookupInputException; +import com.google.devtools.build.lib.skyframe.AspectValue.SkylarkAspectLoadingKey; +import com.google.devtools.build.lib.syntax.Type.ConversionException; +import com.google.devtools.build.skyframe.SkyFunction; +import com.google.devtools.build.skyframe.SkyFunctionException; +import com.google.devtools.build.skyframe.SkyKey; +import com.google.devtools.build.skyframe.SkyValue; + +import javax.annotation.Nullable; + +/** + * SkyFunction to load aspects from Skylark extensions and calculate their values. + * + * Used for loading top-level aspects. At top level, in + * {@link com.google.devtools.build.lib.analysis.BuildView}, we cannot invoke two SkyFunctions + * one aftre another, so BuildView call this function to do the work. + */ +public class ToplevelSkylarkAspectFunction implements SkyFunction { + + @Nullable + @Override + public SkyValue compute(SkyKey skyKey, Environment env) + throws LoadSkylarkAspectFunctionException, InterruptedException { + SkylarkAspectLoadingKey aspectLoadingKey = (SkylarkAspectLoadingKey) skyKey.argument(); + String skylarkValueName = aspectLoadingKey.getSkylarkValueName(); + PackageIdentifier extensionFile = aspectLoadingKey.getExtensionFile(); + SkylarkAspect skylarkAspect = null; + try { + skylarkAspect = AspectFunction.loadSkylarkAspect(env, extensionFile, skylarkValueName); + } catch (ASTLookupInputException | ConversionException e) { + throw new LoadSkylarkAspectFunctionException(e, skyKey); + } + if (skylarkAspect == null) { + return null; + } + SkyKey aspectKey = + AspectValue.key( + aspectLoadingKey.getTargetLabel(), + aspectLoadingKey.getTargetConfiguration(), + new SkylarkAspectClass(skylarkAspect), + AspectParameters.EMPTY); + + return env.getValue(aspectKey); + } + + @Nullable + @Override + public String extractTag(SkyKey skyKey) { + return null; + } + + /** + * Exceptions thrown from ToplevelSkylarkAspectFunction. + */ + public class LoadSkylarkAspectFunctionException extends SkyFunctionException { + + public LoadSkylarkAspectFunctionException(Exception cause, SkyKey childKey) { + super(cause, childKey); + } + + public LoadSkylarkAspectFunctionException(Exception cause) { + super(cause, Transience.PERSISTENT); + } + } +} |