blob: 9141619dd0fac8375cb15fa1949426b5807545b2 [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.
14package com.google.devtools.build.lib.skyframe;
15
emilyguo91c1f9f2022-02-28 11:39:38 -080016import com.google.devtools.build.lib.bugreport.BugReport;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000017import com.google.devtools.build.lib.cmdline.Label;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010018import com.google.devtools.build.lib.collect.nestedset.NestedSet;
19import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
Mark Schaller6b6d8a92015-10-23 01:00:28 +000020import com.google.devtools.build.lib.events.Event;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010021import com.google.devtools.build.lib.events.EventHandler;
nharmataf2b26ad2019-03-06 09:37:00 -080022import com.google.devtools.build.lib.packages.AdvertisedProviderSet;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010023import com.google.devtools.build.lib.packages.NoSuchPackageException;
24import com.google.devtools.build.lib.packages.NoSuchTargetException;
Eric Fellheimerb5c98842015-08-12 23:24:21 +000025import com.google.devtools.build.lib.packages.NoSuchThingException;
Janak Ramakrishnan0a4c6e42015-09-17 00:37:58 +000026import com.google.devtools.build.lib.packages.Package;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010027import com.google.devtools.build.lib.packages.Rule;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010028import com.google.devtools.build.lib.packages.Target;
Mark Schaller6b6d8a92015-10-23 01:00:28 +000029import com.google.devtools.build.lib.packages.TargetUtils;
Mark Schallerb25759c2015-07-29 17:09:18 +000030import com.google.devtools.build.lib.skyframe.TransitiveTargetFunction.TransitiveTargetValueBuilder;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010031import com.google.devtools.build.skyframe.SkyKey;
32import com.google.devtools.build.skyframe.SkyValue;
emilyguo91c1f9f2022-02-28 11:39:38 -080033import com.google.devtools.build.skyframe.SkyframeLookupResult;
Mark Schallerb25759c2015-07-29 17:09:18 +000034import javax.annotation.Nullable;
35
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010036/**
37 * This class builds transitive Target values such that evaluating a Target value is similar to
38 * running it through the LabelVisitor.
39 */
jhorvitz0ace4c72021-10-04 15:20:52 -070040final class TransitiveTargetFunction
Mark Schallerb25759c2015-07-29 17:09:18 +000041 extends TransitiveBaseTraversalFunction<TransitiveTargetValueBuilder> {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010042
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010043 @Override
ulfjackdc73a1d2017-10-30 07:05:53 -040044 Label argumentFromKey(SkyKey key) {
45 return ((TransitiveTargetKey) key).getLabel();
46 }
47
48 @Override
Mark Schallerb25759c2015-07-29 17:09:18 +000049 SkyKey getKey(Label label) {
ulfjackdc73a1d2017-10-30 07:05:53 -040050 return TransitiveTargetKey.of(label);
Marian Loburfdd788e2015-03-25 09:36:28 +000051 }
52
Mark Schallerb25759c2015-07-29 17:09:18 +000053 @Override
janakr8cd101d2020-11-16 13:12:58 -080054 TransitiveTargetValueBuilder processTarget(TargetAndErrorIfAny targetAndErrorIfAny) {
Mark Schallerb25759c2015-07-29 17:09:18 +000055 Target target = targetAndErrorIfAny.getTarget();
56 boolean packageLoadedSuccessfully = targetAndErrorIfAny.isPackageLoadedSuccessfully();
janakr8cd101d2020-11-16 13:12:58 -080057 return new TransitiveTargetValueBuilder(target, packageLoadedSuccessfully);
Greg Estren531fc042015-05-26 22:37:44 +000058 }
59
Mark Schallerb25759c2015-07-29 17:09:18 +000060 @Override
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +000061 void processDeps(
62 TransitiveTargetValueBuilder builder,
63 EventHandler eventHandler,
Mark Schallerb25759c2015-07-29 17:09:18 +000064 TargetAndErrorIfAny targetAndErrorIfAny,
emilyguo91c1f9f2022-02-28 11:39:38 -080065 SkyframeLookupResult depEntries,
66 Iterable<? extends SkyKey> depKeys) {
Mark Schallerb25759c2015-07-29 17:09:18 +000067 boolean successfulTransitiveLoading = builder.isSuccessfulTransitiveLoading();
68 Target target = targetAndErrorIfAny.getTarget();
Mark Schallerb25759c2015-07-29 17:09:18 +000069
emilyguo91c1f9f2022-02-28 11:39:38 -080070 for (SkyKey skyKey : depKeys) {
71 Label depLabel = ((TransitiveTargetKey) skyKey).getLabel();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010072 TransitiveTargetValue transitiveTargetValue;
73 try {
emilyguo91c1f9f2022-02-28 11:39:38 -080074 transitiveTargetValue =
75 (TransitiveTargetValue)
76 depEntries.getOrThrow(
77 skyKey, NoSuchPackageException.class, NoSuchTargetException.class);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010078 } catch (NoSuchPackageException | NoSuchTargetException e) {
79 successfulTransitiveLoading = false;
Mark Schallerb25759c2015-07-29 17:09:18 +000080 maybeReportErrorAboutMissingEdge(target, depLabel, e, eventHandler);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010081 continue;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010082 }
emilyguo91c1f9f2022-02-28 11:39:38 -080083 if (transitiveTargetValue == null) {
84 BugReport.sendBugReport(
85 new IllegalStateException(
86 "TransitiveTargetValue " + skyKey + " was missing, this should never happen"));
87 continue;
88 }
Mark Schallerb25759c2015-07-29 17:09:18 +000089 builder.getTransitiveTargets().addTransitive(transitiveTargetValue.getTransitiveTargets());
janakr8cd101d2020-11-16 13:12:58 -080090 if (transitiveTargetValue.encounteredLoadingError()) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010091 successfulTransitiveLoading = false;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010092 if (transitiveTargetValue.getErrorLoadingTarget() != null) {
93 maybeReportErrorAboutMissingEdge(target, depLabel,
Mark Schallerb25759c2015-07-29 17:09:18 +000094 transitiveTargetValue.getErrorLoadingTarget(), eventHandler);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010095 }
96 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010097 }
jhorvitz0ace4c72021-10-04 15:20:52 -070098
Mark Schallerb25759c2015-07-29 17:09:18 +000099 builder.setSuccessfulTransitiveLoading(successfulTransitiveLoading);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100100 }
101
102 @Override
Googler3e1bf5c2019-11-04 12:41:49 -0800103 public SkyValue computeSkyValue(
104 TargetAndErrorIfAny targetAndErrorIfAny, TransitiveTargetValueBuilder builder) {
Mark Schallerb25759c2015-07-29 17:09:18 +0000105 NoSuchTargetException errorLoadingTarget = targetAndErrorIfAny.getErrorLoadingTarget();
Mark Schallerb25759c2015-07-29 17:09:18 +0000106 return builder.build(errorLoadingTarget);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100107 }
108
nharmataf2b26ad2019-03-06 09:37:00 -0800109 @Nullable
Googler119b15f2016-07-22 19:22:48 +0000110 @Override
nharmataf2b26ad2019-03-06 09:37:00 -0800111 protected AdvertisedProviderSet getAdvertisedProviderSet(
emilyguo91c1f9f2022-02-28 11:39:38 -0800112 Label toLabel, SkyValue toVal, Environment env) throws InterruptedException {
Eric Fellheimere27d0632015-09-25 21:35:26 +0000113 SkyKey packageKey = PackageValue.key(toLabel.getPackageIdentifier());
nharmataf2b26ad2019-03-06 09:37:00 -0800114 Target toTarget;
Eric Fellheimere27d0632015-09-25 21:35:26 +0000115 try {
116 PackageValue pkgValue =
117 (PackageValue) env.getValueOrThrow(packageKey, NoSuchPackageException.class);
118 if (pkgValue == null) {
nharmataf2b26ad2019-03-06 09:37:00 -0800119 return null;
Eric Fellheimerb5c98842015-08-12 23:24:21 +0000120 }
Eric Fellheimere27d0632015-09-25 21:35:26 +0000121 Package pkg = pkgValue.getPackage();
122 if (pkg.containsErrors()) {
nharmataf2b26ad2019-03-06 09:37:00 -0800123 // Do nothing interesting. This error was handled when we computed the corresponding
Eric Fellheimere27d0632015-09-25 21:35:26 +0000124 // TransitiveTargetValue.
nharmataf2b26ad2019-03-06 09:37:00 -0800125 return null;
Eric Fellheimere27d0632015-09-25 21:35:26 +0000126 }
nharmataf2b26ad2019-03-06 09:37:00 -0800127 toTarget = pkgValue.getPackage().getTarget(toLabel.getName());
Eric Fellheimere27d0632015-09-25 21:35:26 +0000128 } catch (NoSuchThingException e) {
nharmataf2b26ad2019-03-06 09:37:00 -0800129 // Do nothing interesting. This error was handled when we computed the corresponding
Eric Fellheimere27d0632015-09-25 21:35:26 +0000130 // TransitiveTargetValue.
nharmataf2b26ad2019-03-06 09:37:00 -0800131 return null;
Eric Fellheimerb5c98842015-08-12 23:24:21 +0000132 }
nharmataf2b26ad2019-03-06 09:37:00 -0800133 if (!(toTarget instanceof Rule)) {
134 // Aspect can be declared only for Rules.
135 return null;
136 }
137 return ((Rule) toTarget).getRuleClassObject().getAdvertisedProviders();
Eric Fellheimer85fe0612015-08-18 21:09:54 +0000138 }
139
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000140 private static void maybeReportErrorAboutMissingEdge(
lberki231d77d2019-01-03 11:18:11 -0800141 Target target, Label depLabel, NoSuchThingException e, EventHandler eventHandler) {
Mark Schaller6b6d8a92015-10-23 01:00:28 +0000142 if (e instanceof NoSuchTargetException) {
143 NoSuchTargetException nste = (NoSuchTargetException) e;
144 if (depLabel.equals(nste.getLabel())) {
145 eventHandler.handle(
146 Event.error(
147 TargetUtils.getLocationMaybe(target),
148 TargetUtils.formatMissingEdge(target, depLabel, e)));
149 }
150 } else if (e instanceof NoSuchPackageException) {
151 NoSuchPackageException nspe = (NoSuchPackageException) e;
152 if (nspe.getPackageId().equals(depLabel.getPackageIdentifier())) {
153 eventHandler.handle(
154 Event.error(
155 TargetUtils.getLocationMaybe(target),
156 TargetUtils.formatMissingEdge(target, depLabel, e)));
157 }
158 }
159 }
160
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100161 /**
Mark Schallerb25759c2015-07-29 17:09:18 +0000162 * Holds values accumulated across the given target and its transitive dependencies for the
163 * purpose of constructing a {@link TransitiveTargetValue}.
164 *
165 * <p>Note that this class is mutable! The {@code successfulTransitiveLoading} property is
166 * initialized with the {@code packageLoadedSuccessfully} constructor parameter, and may be
167 * modified if a transitive dependency is found to be in error.
168 */
169 static class TransitiveTargetValueBuilder {
170 private boolean successfulTransitiveLoading;
Mark Schallerb25759c2015-07-29 17:09:18 +0000171 private final NestedSetBuilder<Label> transitiveTargets;
Mark Schallerb25759c2015-07-29 17:09:18 +0000172
janakr8cd101d2020-11-16 13:12:58 -0800173 public TransitiveTargetValueBuilder(Target target, boolean packageLoadedSuccessfully) {
Mark Schallerb25759c2015-07-29 17:09:18 +0000174 this.transitiveTargets = NestedSetBuilder.stableOrder();
Mark Schallerb25759c2015-07-29 17:09:18 +0000175 this.successfulTransitiveLoading = packageLoadedSuccessfully;
Mark Schallerb25759c2015-07-29 17:09:18 +0000176 transitiveTargets.add(target.getLabel());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100177 }
178
Mark Schallerb25759c2015-07-29 17:09:18 +0000179 public NestedSetBuilder<Label> getTransitiveTargets() {
180 return transitiveTargets;
181 }
182
Mark Schallerb25759c2015-07-29 17:09:18 +0000183 public boolean isSuccessfulTransitiveLoading() {
184 return successfulTransitiveLoading;
185 }
186
187 public void setSuccessfulTransitiveLoading(boolean successfulTransitiveLoading) {
188 this.successfulTransitiveLoading = successfulTransitiveLoading;
189 }
190
191 public SkyValue build(@Nullable NoSuchTargetException errorLoadingTarget) {
Mark Schallerb25759c2015-07-29 17:09:18 +0000192 NestedSet<Label> loadedTargets = transitiveTargets.build();
Mark Schallerb25759c2015-07-29 17:09:18 +0000193 return successfulTransitiveLoading
jhorvitz0ace4c72021-10-04 15:20:52 -0700194 ? TransitiveTargetValue.successfulTransitiveLoading(loadedTargets)
195 : TransitiveTargetValue.unsuccessfulTransitiveLoading(loadedTargets, errorLoadingTarget);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100196 }
197 }
198}