blob: 7343e6bf43364b7af147782938ab8ac384094378 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +01002//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package com.google.devtools.build.lib.analysis;
16
Carmi Grushkoeaaa9d0d2015-11-17 01:54:45 +000017import static com.google.devtools.build.lib.analysis.ExtraActionUtils.createExtraActionProvider;
18
tomlua155b532017-11-08 20:12:47 +010019import com.google.common.base.Preconditions;
tomlu39a0a382018-06-22 09:43:23 -070020import com.google.common.collect.ImmutableList;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010021import com.google.common.collect.ImmutableMap;
Carmi Grushko4076e442016-01-21 20:05:42 +000022import com.google.common.collect.ImmutableSet;
Rumou Duan33bab462016-04-25 17:55:12 +000023import com.google.devtools.build.lib.actions.ActionAnalysisMetadata;
tomlu39a0a382018-06-22 09:43:23 -070024import com.google.devtools.build.lib.actions.Actions;
25import com.google.devtools.build.lib.actions.Actions.GeneratingActions;
Dmitry Lomove2033b12015-08-19 16:57:49 +000026import com.google.devtools.build.lib.actions.Artifact;
tomlu39a0a382018-06-22 09:43:23 -070027import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
gregce130feba2020-02-06 13:55:08 -080028import com.google.devtools.build.lib.analysis.config.CoreOptions;
gregceeefc91c2020-06-19 13:33:43 -070029import com.google.devtools.build.lib.analysis.starlark.StarlarkApiProvider;
Dmitry Lomove2033b12015-08-19 16:57:49 +000030import com.google.devtools.build.lib.collect.nestedset.NestedSet;
31import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010032import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
adonovana11e2d02019-12-06 07:11:35 -080033import com.google.devtools.build.lib.packages.Info;
dslomovde965ac2017-07-31 21:07:51 +020034import com.google.devtools.build.lib.packages.Provider;
Kurt Alfred Kluever4192ca62022-07-05 06:30:29 -070035import com.google.errorprone.annotations.CanIgnoreReturnValue;
Googler94d35de2016-09-16 15:21:39 +000036import java.util.Arrays;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010037import java.util.Map;
Dmitry Lomove2033b12015-08-19 16:57:49 +000038import java.util.TreeMap;
Dmitry Lomove2033b12015-08-19 16:57:49 +000039import javax.annotation.Nullable;
adonovan450c7ad2020-09-14 13:00:21 -070040import net.starlark.java.eval.EvalException;
adonovana278c8f2021-01-11 08:34:20 -080041import net.starlark.java.eval.Starlark;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010042
43/**
44 * Extra information about a configured target computed on request of a dependent.
45 *
46 * <p>Analogous to {@link ConfiguredTarget}: contains a bunch of transitive info providers, which
Googler4e0a5cb2017-04-09 17:58:18 -040047 * are merged with the providers of the associated configured target before they are passed to the
48 * configured target factories that depend on the configured target to which this aspect is added.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010049 *
50 * <p>Aspects are created alongside configured targets on request from dependents.
Lukacs Berki2300cd62016-05-19 11:06:37 +000051 *
Googler4e0a5cb2017-04-09 17:58:18 -040052 * <p>For more information about aspects, see {@link
53 * com.google.devtools.build.lib.packages.AspectClass}.
Lukacs Berki2300cd62016-05-19 11:06:37 +000054 *
ulfjack26d0e492017-08-07 13:42:33 +020055 * @see com.google.devtools.build.lib.analysis.RuleConfiguredTargetFactory
Lukacs Berki2300cd62016-05-19 11:06:37 +000056 * @see com.google.devtools.build.lib.packages.AspectClass
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010057 */
58@Immutable
janakr6d185b82020-03-30 14:08:01 -070059public final class ConfiguredAspect implements ProviderCollection {
tomlu39a0a382018-06-22 09:43:23 -070060 private final ImmutableList<ActionAnalysisMetadata> actions;
tomlu39a0a382018-06-22 09:43:23 -070061 private final TransitiveInfoProviderMap providers;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010062
janakrf15d08d2020-04-22 12:53:03 -070063 private ConfiguredAspect(
64 ImmutableList<ActionAnalysisMetadata> actions, TransitiveInfoProviderMap providers) {
tomlu39a0a382018-06-22 09:43:23 -070065 this.actions = actions;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010066 this.providers = providers;
tomlu64416ce2018-10-02 12:46:08 -070067
gregce5c8a5f52020-05-13 10:35:36 -070068 // Initialize every StarlarkApiProvider
tomlu64416ce2018-10-02 12:46:08 -070069 for (int i = 0; i < providers.getProviderCount(); i++) {
70 Object obj = providers.getProviderInstanceAt(i);
gregce4893ee32020-04-27 11:53:54 -070071 if (obj instanceof StarlarkApiProvider) {
72 ((StarlarkApiProvider) obj).init(providers);
tomlu64416ce2018-10-02 12:46:08 -070073 }
74 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010075 }
76
tomlu39a0a382018-06-22 09:43:23 -070077 public ImmutableList<ActionAnalysisMetadata> getActions() {
78 return actions;
79 }
80
Googler94d35de2016-09-16 15:21:39 +000081 /** Returns the providers created by the aspect. */
82 public TransitiveInfoProviderMap getProviders() {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010083 return providers;
84 }
85
janakr6d185b82020-03-30 14:08:01 -070086 @Override
Dmitry Lomove2033b12015-08-19 16:57:49 +000087 @Nullable
Dmitry Lomov2473b9f2015-09-14 08:53:10 +000088 public <P extends TransitiveInfoProvider> P getProvider(Class<P> providerClass) {
dslomov211a3ba2017-05-16 00:21:22 +020089 AnalysisUtils.checkProvider(providerClass);
Googler94d35de2016-09-16 15:21:39 +000090 return providers.getProvider(providerClass);
Dmitry Lomove2033b12015-08-19 16:57:49 +000091 }
92
janakr6d185b82020-03-30 14:08:01 -070093 @Override
adonovana11e2d02019-12-06 07:11:35 -080094 public Info get(Provider.Key key) {
tomlu64416ce2018-10-02 12:46:08 -070095 return providers.get(key);
dslomovea7d4822017-05-03 13:01:27 +020096 }
97
janakr6d185b82020-03-30 14:08:01 -070098 @Override
dslomovea7d4822017-05-03 13:01:27 +020099 public Object get(String legacyKey) {
gregce773b95f2020-05-19 09:51:09 -0700100 if (OutputGroupInfo.STARLARK_NAME.equals(legacyKey)) {
101 return get(OutputGroupInfo.STARLARK_CONSTRUCTOR.getKey());
dslomovea7d4822017-05-03 13:01:27 +0200102 }
tomlu64416ce2018-10-02 12:46:08 -0700103 return providers.get(legacyKey);
dslomovea7d4822017-05-03 13:01:27 +0200104 }
105
Lukacs Berki549bfce2016-04-22 15:29:12 +0000106 public static ConfiguredAspect forAlias(ConfiguredAspect real) {
jhorvitzb6590822021-08-13 15:18:27 -0700107 return new ConfiguredAspect(real.actions, real.providers);
Lukacs Berki549bfce2016-04-22 15:29:12 +0000108 }
109
janakrf15d08d2020-04-22 12:53:03 -0700110 public static ConfiguredAspect forNonapplicableTarget() {
tomlu39a0a382018-06-22 09:43:23 -0700111 return new ConfiguredAspect(
tomlu39a0a382018-06-22 09:43:23 -0700112 ImmutableList.of(),
tomlu39a0a382018-06-22 09:43:23 -0700113 new TransitiveInfoProviderMapBuilder().add().build());
Dmitry Lomov6cd98972017-03-01 15:44:00 +0000114 }
115
janakrf15d08d2020-04-22 12:53:03 -0700116 public static Builder builder(RuleContext ruleContext) {
117 return new Builder(ruleContext);
dslomov99ea6b42017-04-25 17:46:17 +0200118 }
119
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100120 /**
Dmitry Lomovb487ac62015-11-09 13:09:12 +0000121 * Builder for {@link ConfiguredAspect}.
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100122 */
123 public static class Builder {
Googler4b7aae42017-05-04 17:16:09 -0400124 private final TransitiveInfoProviderMapBuilder providers =
125 new TransitiveInfoProviderMapBuilder();
Dmitry Lomove2033b12015-08-19 16:57:49 +0000126 private final Map<String, NestedSetBuilder<Artifact>> outputGroupBuilders = new TreeMap<>();
Carmi Grushkoeaaa9d0d2015-11-17 01:54:45 +0000127 private final RuleContext ruleContext;
jhorvitza44313a2021-08-18 17:59:02 -0700128
janakrf15d08d2020-04-22 12:53:03 -0700129 public Builder(RuleContext ruleContext) {
Carmi Grushkoeaaa9d0d2015-11-17 01:54:45 +0000130 this.ruleContext = ruleContext;
Dmitry Lomove2033b12015-08-19 16:57:49 +0000131 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100132
Kurt Alfred Kluever4192ca62022-07-05 06:30:29 -0700133 @CanIgnoreReturnValue
Googler94d35de2016-09-16 15:21:39 +0000134 public <T extends TransitiveInfoProvider> Builder addProvider(
135 Class<? extends T> providerClass, T provider) {
136 Preconditions.checkNotNull(provider);
137 checkProviderClass(providerClass);
138 providers.put(providerClass, provider);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100139 return this;
140 }
141
Googler94d35de2016-09-16 15:21:39 +0000142 /** Adds a provider to the aspect. */
Kurt Alfred Kluever4192ca62022-07-05 06:30:29 -0700143 @CanIgnoreReturnValue
Googler94d35de2016-09-16 15:21:39 +0000144 public Builder addProvider(TransitiveInfoProvider provider) {
145 Preconditions.checkNotNull(provider);
Googler4b7aae42017-05-04 17:16:09 -0400146 addProvider(TransitiveInfoProviderEffectiveClassHelper.get(provider), provider);
Googler94d35de2016-09-16 15:21:39 +0000147 return this;
148 }
149
jhorvitzb6590822021-08-13 15:18:27 -0700150 private static void checkProviderClass(Class<? extends TransitiveInfoProvider> providerClass) {
Googler94d35de2016-09-16 15:21:39 +0000151 Preconditions.checkNotNull(providerClass);
Googler94d35de2016-09-16 15:21:39 +0000152 }
153
154 /** Adds providers to the aspect. */
Kurt Alfred Kluever4192ca62022-07-05 06:30:29 -0700155 @CanIgnoreReturnValue
Googler94d35de2016-09-16 15:21:39 +0000156 public Builder addProviders(TransitiveInfoProviderMap providers) {
dslomovf6a7e5a2017-07-05 07:23:31 -0400157 this.providers.addAll(providers);
Googler94d35de2016-09-16 15:21:39 +0000158 return this;
159 }
160
161 /** Adds providers to the aspect. */
162 public Builder addProviders(TransitiveInfoProvider... providers) {
163 return addProviders(Arrays.asList(providers));
164 }
165
166 /** Adds providers to the aspect. */
Kurt Alfred Kluever4192ca62022-07-05 06:30:29 -0700167 @CanIgnoreReturnValue
Googler94d35de2016-09-16 15:21:39 +0000168 public Builder addProviders(Iterable<TransitiveInfoProvider> providers) {
169 for (TransitiveInfoProvider provider : providers) {
170 addProvider(provider);
Carmi Grushkob8f0e862015-11-23 23:26:15 +0000171 }
172 return this;
173 }
174
Kurt Alfred Kluever4192ca62022-07-05 06:30:29 -0700175 /** Adds a set of files to an output group. */
176 @CanIgnoreReturnValue
Dmitry Lomove2033b12015-08-19 16:57:49 +0000177 public Builder addOutputGroup(String name, NestedSet<Artifact> artifacts) {
jhorvitzb6590822021-08-13 15:18:27 -0700178 outputGroupBuilders
179 .computeIfAbsent(name, k -> NestedSetBuilder.stableOrder())
180 .addTransitive(artifacts);
Dmitry Lomove2033b12015-08-19 16:57:49 +0000181 return this;
182 }
183
Kurt Alfred Kluever4192ca62022-07-05 06:30:29 -0700184 @CanIgnoreReturnValue
gregce5c8a5f52020-05-13 10:35:36 -0700185 public Builder addStarlarkTransitiveInfo(String name, Object value) {
dslomovf6a7e5a2017-07-05 07:23:31 -0400186 providers.put(name, value);
Googler63ce8f22017-01-09 15:32:16 +0000187 return this;
188 }
189
Kurt Alfred Kluever4192ca62022-07-05 06:30:29 -0700190 @CanIgnoreReturnValue
gregce5c8a5f52020-05-13 10:35:36 -0700191 public Builder addStarlarkDeclaredProvider(Info declaredProvider) throws EvalException {
dslomovde965ac2017-07-31 21:07:51 +0200192 Provider constructor = declaredProvider.getProvider();
Vladimir Moskva6c28fe92017-03-03 12:55:08 +0000193 if (!constructor.isExported()) {
adonovana278c8f2021-01-11 08:34:20 -0800194 throw Starlark.errorf(
195 "aspect function returned an instance of a provider (defined at %s) that is not a"
196 + " global",
197 constructor.getLocation());
Vladimir Moskva6c28fe92017-03-03 12:55:08 +0000198 }
dslomov11da2202017-07-27 23:48:56 +0200199 addDeclaredProvider(declaredProvider);
Vladimir Moskva6c28fe92017-03-03 12:55:08 +0000200 return this;
201 }
202
adonovana11e2d02019-12-06 07:11:35 -0800203 private void addDeclaredProvider(Info declaredProvider) {
dslomov11da2202017-07-27 23:48:56 +0200204 providers.put(declaredProvider);
dslomovea7d4822017-05-03 13:01:27 +0200205 }
206
Kurt Alfred Kluever4192ca62022-07-05 06:30:29 -0700207 @CanIgnoreReturnValue
adonovana11e2d02019-12-06 07:11:35 -0800208 public Builder addNativeDeclaredProvider(Info declaredProvider) {
dslomovde965ac2017-07-31 21:07:51 +0200209 Provider constructor = declaredProvider.getProvider();
dslomovf9697342017-05-02 16:26:39 +0200210 Preconditions.checkState(constructor.isExported());
dslomov11da2202017-07-27 23:48:56 +0200211 addDeclaredProvider(declaredProvider);
dslomovf9697342017-05-02 16:26:39 +0200212 return this;
213 }
214
Googler7b649f92022-07-06 05:12:46 -0700215 @Nullable
michajlo3ad15802020-11-18 15:09:41 -0800216 public ConfiguredAspect build() throws ActionConflictException, InterruptedException {
Dmitry Lomove2033b12015-08-19 16:57:49 +0000217 if (!outputGroupBuilders.isEmpty()) {
218 ImmutableMap.Builder<String, NestedSet<Artifact>> outputGroups = ImmutableMap.builder();
219 for (Map.Entry<String, NestedSetBuilder<Artifact>> entry : outputGroupBuilders.entrySet()) {
220 outputGroups.put(entry.getKey(), entry.getValue().build());
221 }
222
gregce773b95f2020-05-19 09:51:09 -0700223 if (providers.contains(OutputGroupInfo.STARLARK_CONSTRUCTOR.getKey())) {
Dmitry Lomove2033b12015-08-19 16:57:49 +0000224 throw new IllegalStateException(
dslomov69c45f82017-12-14 11:15:43 -0500225 "OutputGroupInfo was provided explicitly; do not use addOutputGroup");
Dmitry Lomove2033b12015-08-19 16:57:49 +0000226 }
Googler92ce1152022-02-01 06:37:06 -0800227 addDeclaredProvider(new OutputGroupInfo(outputGroups.buildOrThrow()));
Dmitry Lomove2033b12015-08-19 16:57:49 +0000228 }
229
Carmi Grushko4076e442016-01-21 20:05:42 +0000230 addProvider(
jhorvitzb6590822021-08-13 15:18:27 -0700231 createExtraActionProvider(/*actionsWithoutExtraAction=*/ ImmutableSet.of(), ruleContext));
Carmi Grushkoeaaa9d0d2015-11-17 01:54:45 +0000232
tomlu39a0a382018-06-22 09:43:23 -0700233 AnalysisEnvironment analysisEnvironment = ruleContext.getAnalysisEnvironment();
janakr9790a3a2022-01-11 09:44:01 -0800234 GeneratingActions generatingActions;
235 try {
236 generatingActions =
237 Actions.assignOwnersAndFilterSharedActionsAndThrowActionConflict(
238 analysisEnvironment.getActionKeyContext(),
239 analysisEnvironment.getRegisteredActions(),
240 ruleContext.getOwner(),
241 /*outputFiles=*/ null);
242 } catch (Actions.ArtifactGeneratedByOtherRuleException e) {
243 ruleContext.ruleError(e.getMessage());
244 return null;
245 }
tomlu39a0a382018-06-22 09:43:23 -0700246
gregce405a9942020-04-27 09:55:04 -0700247 maybeAddRequiredConfigFragmentsProvider();
248
249 return new ConfiguredAspect(generatingActions.getActions(), providers.build());
250 }
251
252 /**
253 * Adds {@link RequiredConfigFragmentsProvider} if {@link
254 * CoreOptions#includeRequiredConfigFragmentsProvider} isn't {@link
255 * CoreOptions.IncludeConfigFragmentsEnum#OFF}.
256 *
jhorvitz7410c802020-07-22 11:55:07 -0700257 * <p>See {@link com.google.devtools.build.lib.analysis.config.RequiredFragmentsUtil} for a
258 * description of the meaning of this provider's content. That class contains methods that
jhorvitzca598d02021-09-10 11:32:54 -0700259 * populate the results of {@link RuleContext#getRequiredConfigFragments}.
gregce405a9942020-04-27 09:55:04 -0700260 */
261 private void maybeAddRequiredConfigFragmentsProvider() {
jhorvitz7410c802020-07-22 11:55:07 -0700262 if (ruleContext.shouldIncludeRequiredConfigFragmentsProvider()) {
jhorvitzca598d02021-09-10 11:32:54 -0700263 addProvider(ruleContext.getRequiredConfigFragments());
gregce130feba2020-02-06 13:55:08 -0800264 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100265 }
266 }
Carmi Grushko65ac3552015-08-21 16:43:26 +0000267}