blob: 4f11095490ac254933fc94b3ae2574fa3b7d2b40 [file] [log] [blame]
Damien Martin-Guillerezf88f4d82015-09-25 13:56:55 +00001// Copyright 2014 The Bazel Authors. All rights reserved.
Mark Schaller8ff5b3c2015-07-29 17:32:11 +00002//
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
Eric Fellheimere27d0632015-09-25 21:35:26 +000016import com.google.common.collect.ImmutableList;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000017import com.google.devtools.build.lib.cmdline.Label;
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000018import com.google.devtools.build.lib.collect.nestedset.NestedSet;
19import com.google.devtools.build.lib.events.EventHandler;
Eric Fellheimerb5c98842015-08-12 23:24:21 +000020import com.google.devtools.build.lib.packages.AspectDefinition;
Eric Fellheimerb5c98842015-08-12 23:24:21 +000021import com.google.devtools.build.lib.packages.Attribute;
Dmitry Lomov940ea072016-01-21 22:34:14 +000022import com.google.devtools.build.lib.packages.DependencyFilter;
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000023import com.google.devtools.build.lib.packages.NoSuchPackageException;
24import com.google.devtools.build.lib.packages.NoSuchTargetException;
Eric Fellheimere27d0632015-09-25 21:35:26 +000025import com.google.devtools.build.lib.packages.NoSuchThingException;
Dmitry Lomov6231d082015-11-02 17:17:20 +000026import com.google.devtools.build.lib.packages.Rule;
Mark Schaller24ed98d2015-10-21 17:47:51 +000027import com.google.devtools.build.lib.skyframe.TransitiveTraversalFunction.FirstErrorMessageAccumulator;
Mark Schaller6df81792015-12-10 18:47:47 +000028import com.google.devtools.build.lib.util.Preconditions;
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000029import com.google.devtools.build.skyframe.SkyKey;
30import com.google.devtools.build.skyframe.SkyValue;
31import com.google.devtools.build.skyframe.ValueOrException2;
Eric Fellheimere27d0632015-09-25 21:35:26 +000032import java.util.Collection;
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000033import java.util.Map.Entry;
Mark Schaller24ed98d2015-10-21 17:47:51 +000034import javax.annotation.Nullable;
35
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000036/**
37 * This class is like {@link TransitiveTargetFunction}, but the values it returns do not contain
Mark Schaller24ed98d2015-10-21 17:47:51 +000038 * {@link NestedSet}s. It performs the side-effects of {@link TransitiveTargetFunction} (i.e.,
39 * ensuring that transitive targets and their packages have been loaded). It evaluates to a
40 * {@link TransitiveTraversalValue} that contains the first error message it encountered, and a
41 * set of names of providers if the target is a rule.
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000042 */
Mark Schaller24ed98d2015-10-21 17:47:51 +000043public class TransitiveTraversalFunction
44 extends TransitiveBaseTraversalFunction<FirstErrorMessageAccumulator> {
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000045
46 @Override
47 SkyKey getKey(Label label) {
48 return TransitiveTraversalValue.key(label);
49 }
50
51 @Override
Mark Schaller24ed98d2015-10-21 17:47:51 +000052 FirstErrorMessageAccumulator processTarget(Label label, TargetAndErrorIfAny targetAndErrorIfAny) {
53 NoSuchTargetException errorIfAny = targetAndErrorIfAny.getErrorLoadingTarget();
54 String errorMessageIfAny = errorIfAny == null ? null : errorIfAny.getMessage();
55 return new FirstErrorMessageAccumulator(errorMessageIfAny);
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000056 }
57
58 @Override
Mark Schaller24ed98d2015-10-21 17:47:51 +000059 void processDeps(
60 FirstErrorMessageAccumulator accumulator,
61 EventHandler eventHandler,
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000062 TargetAndErrorIfAny targetAndErrorIfAny,
63 Iterable<Entry<SkyKey, ValueOrException2<NoSuchPackageException, NoSuchTargetException>>>
64 depEntries) {
Mark Schaller24ed98d2015-10-21 17:47:51 +000065 for (Entry<SkyKey, ValueOrException2<NoSuchPackageException, NoSuchTargetException>> entry :
66 depEntries) {
67 TransitiveTraversalValue transitiveTraversalValue;
68 try {
69 transitiveTraversalValue = (TransitiveTraversalValue) entry.getValue().get();
70 if (transitiveTraversalValue == null) {
71 continue;
72 }
73 } catch (NoSuchPackageException | NoSuchTargetException e) {
74 accumulator.maybeSet(e.getMessage());
75 continue;
76 }
77 String firstErrorMessage = transitiveTraversalValue.getFirstErrorMessage();
78 if (firstErrorMessage != null) {
79 accumulator.maybeSet(firstErrorMessage);
80 }
81 }
Mark Schaller8ff5b3c2015-07-29 17:32:11 +000082 }
83
Dmitry Lomov6231d082015-11-02 17:17:20 +000084 protected Collection<Label> getAspectLabels(Rule fromRule, Attribute attr, Label toLabel,
Eric Fellheimere27d0632015-09-25 21:35:26 +000085 ValueOrException2<NoSuchPackageException, NoSuchTargetException> toVal, Environment env) {
86 try {
87 if (toVal == null) {
88 return ImmutableList.of();
89 }
90 TransitiveTraversalValue traversalVal = (TransitiveTraversalValue) toVal.get();
91 if (traversalVal == null || traversalVal.getProviders() == null) {
92 return ImmutableList.of();
93 }
94 // Retrieve the providers of the dep from the TransitiveTraversalValue, so we can avoid
95 // issuing a dep on its defining Package.
Lukacs Berki549bfce2016-04-22 15:29:12 +000096 return AspectDefinition.visitAspectsIfRequired(fromRule, attr,
Dmitry Lomovb91d3922017-01-09 20:12:57 +000097 traversalVal.getProviders(),
Dmitry Lomov940ea072016-01-21 22:34:14 +000098 DependencyFilter.ALL_DEPS).values();
Eric Fellheimere27d0632015-09-25 21:35:26 +000099 } catch (NoSuchThingException e) {
100 // Do nothing. This error was handled when we computed the corresponding
101 // TransitiveTargetValue.
102 return ImmutableList.of();
103 }
104 }
105
Mark Schaller8ff5b3c2015-07-29 17:32:11 +0000106 @Override
Lukacs Berki549bfce2016-04-22 15:29:12 +0000107 SkyValue computeSkyValue(TargetAndErrorIfAny targetAndErrorIfAny,
108 FirstErrorMessageAccumulator accumulator) {
Mark Schaller24ed98d2015-10-21 17:47:51 +0000109 boolean targetLoadedSuccessfully = targetAndErrorIfAny.getErrorLoadingTarget() == null;
110 String firstErrorMessage = accumulator.getFirstErrorMessage();
111 return targetLoadedSuccessfully
112 ? TransitiveTraversalValue.forTarget(targetAndErrorIfAny.getTarget(), firstErrorMessage)
113 : TransitiveTraversalValue.unsuccessfulTransitiveTraversal(firstErrorMessage);
Mark Schaller8ff5b3c2015-07-29 17:32:11 +0000114 }
115
Mark Schaller6b6d8a92015-10-23 01:00:28 +0000116 @Override
117 TargetMarkerValue getTargetMarkerValue(SkyKey targetMarkerKey, Environment env)
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000118 throws NoSuchTargetException, NoSuchPackageException, InterruptedException {
Mark Schaller6b6d8a92015-10-23 01:00:28 +0000119 return TargetMarkerFunction.computeTargetMarkerValue(targetMarkerKey, env);
120 }
121
Mark Schaller24ed98d2015-10-21 17:47:51 +0000122 /**
123 * Keeps track of the first error message encountered while traversing itself and its
124 * dependencies.
Mark Schaller8ff5b3c2015-07-29 17:32:11 +0000125 */
Mark Schaller24ed98d2015-10-21 17:47:51 +0000126 static class FirstErrorMessageAccumulator {
Mark Schaller8ff5b3c2015-07-29 17:32:11 +0000127
Mark Schaller24ed98d2015-10-21 17:47:51 +0000128 @Nullable private String firstErrorMessage;
129
130 public FirstErrorMessageAccumulator(@Nullable String firstErrorMessage) {
131 this.firstErrorMessage = firstErrorMessage;
132 }
133
134 /** Remembers {@param errorMessage} if it is the first error message. */
135 void maybeSet(String errorMessage) {
136 Preconditions.checkNotNull(errorMessage);
137 if (firstErrorMessage == null) {
138 firstErrorMessage = errorMessage;
139 }
140 }
141
142 @Nullable
143 String getFirstErrorMessage() {
144 return firstErrorMessage;
145 }
Mark Schaller8ff5b3c2015-07-29 17:32:11 +0000146 }
147}