blob: ad6b54002a9a23c2014f20b9dbaae44111a6648d [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.query2;
15
Janak Ramakrishnancbe26342015-08-17 18:57:57 +000016import com.google.common.base.Function;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010017import com.google.common.base.Predicate;
Janak Ramakrishnanfe1056f2015-02-11 21:16:06 +000018import com.google.common.collect.ImmutableSet;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010019import com.google.common.collect.Iterables;
Janak Ramakrishnancbe26342015-08-17 18:57:57 +000020import com.google.common.collect.Maps;
Lukacs Berki6e91eb92015-09-21 09:12:37 +000021import com.google.devtools.build.lib.cmdline.Label;
Lukacs Berkia6434362015-09-15 13:56:14 +000022import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
Janak Ramakrishnane72d5222015-02-26 17:09:18 +000023import com.google.devtools.build.lib.cmdline.ResolvedTargets;
24import com.google.devtools.build.lib.cmdline.TargetParsingException;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010025import com.google.devtools.build.lib.events.EventHandler;
26import com.google.devtools.build.lib.graph.Digraph;
27import com.google.devtools.build.lib.graph.Node;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010028import com.google.devtools.build.lib.packages.Attribute;
29import com.google.devtools.build.lib.packages.NoSuchThingException;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010030import com.google.devtools.build.lib.packages.OutputFile;
31import com.google.devtools.build.lib.packages.Package;
32import com.google.devtools.build.lib.packages.Rule;
33import com.google.devtools.build.lib.packages.Target;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010034import com.google.devtools.build.lib.pkgcache.PackageProvider;
35import com.google.devtools.build.lib.pkgcache.TargetEdgeObserver;
36import com.google.devtools.build.lib.pkgcache.TargetPatternEvaluator;
37import com.google.devtools.build.lib.pkgcache.TargetProvider;
Janak Ramakrishnanfe1056f2015-02-11 21:16:06 +000038import com.google.devtools.build.lib.pkgcache.TransitivePackageLoader;
Miguel Alcon Pinto42984f32015-11-06 19:05:13 +000039import com.google.devtools.build.lib.query2.engine.Callback;
Miguel Alcon Pintob6510262015-12-10 17:50:15 +000040import com.google.devtools.build.lib.query2.engine.DigraphQueryEvalResult;
Janak Ramakrishnana46125c2015-02-11 16:51:37 +000041import com.google.devtools.build.lib.query2.engine.QueryEvalResult;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010042import com.google.devtools.build.lib.query2.engine.QueryException;
43import com.google.devtools.build.lib.query2.engine.QueryExpression;
Miguel Alcon Pinto42984f32015-11-06 19:05:13 +000044import com.google.devtools.build.lib.query2.engine.QueryUtil.AbstractUniquifier;
45import com.google.devtools.build.lib.query2.engine.QueryUtil.AggregateAllCallback;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010046import com.google.devtools.build.lib.query2.engine.SkyframeRestartQueryException;
Miguel Alcon Pinto42984f32015-11-06 19:05:13 +000047import com.google.devtools.build.lib.query2.engine.Uniquifier;
Nathan Harmatabc47f402016-07-13 16:22:30 +000048import com.google.devtools.build.lib.query2.engine.VariableContext;
Mark Schaller6df81792015-12-10 18:47:47 +000049import com.google.devtools.build.lib.util.Preconditions;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010050import com.google.devtools.build.lib.vfs.PathFragment;
Han-Wen Nienhuysc13c0022015-12-15 19:08:38 +000051import java.util.ArrayList;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010052import java.util.Collection;
Janak Ramakrishnanee6208b2016-01-07 20:17:41 +000053import java.util.HashMap;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010054import java.util.HashSet;
55import java.util.Iterator;
56import java.util.LinkedHashSet;
Han-Wen Nienhuysc13c0022015-12-15 19:08:38 +000057import java.util.List;
Janak Ramakrishnane72d5222015-02-26 17:09:18 +000058import java.util.Map;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010059import java.util.Set;
Miguel Alcon Pintob6510262015-12-10 17:50:15 +000060import java.util.concurrent.atomic.AtomicBoolean;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010061
62/**
63 * The environment of a Blaze query. Not thread-safe.
64 */
Janak Ramakrishnana46125c2015-02-11 16:51:37 +000065public class BlazeQueryEnvironment extends AbstractBlazeQueryEnvironment<Target> {
Janak Ramakrishnanfe1056f2015-02-11 21:16:06 +000066
67 private static final int MAX_DEPTH_FULL_SCAN_LIMIT = 20;
Janak Ramakrishnanee6208b2016-01-07 20:17:41 +000068 private final Map<String, Set<Target>> resolvedTargetPatterns = new HashMap<>();
Janak Ramakrishnane72d5222015-02-26 17:09:18 +000069 private final TargetPatternEvaluator targetPatternEvaluator;
Janak Ramakrishnanfe1056f2015-02-11 21:16:06 +000070 private final TransitivePackageLoader transitivePackageLoader;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010071 private final TargetProvider targetProvider;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010072 private final Digraph<Target> graph = new Digraph<>();
73 private final ErrorPrintingTargetEdgeErrorObserver errorObserver;
74 private final LabelVisitor labelVisitor;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010075 protected final int loadingPhaseThreads;
76
Janak Ramakrishnana46125c2015-02-11 16:51:37 +000077 private final BlazeTargetAccessor accessor = new BlazeTargetAccessor(this);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010078
79 /**
80 * Note that the correct operation of this class critically depends on the Reporter being a
81 * singleton object, shared by all cooperating classes contributing to Query.
82 * @param strictScope if true, fail the whole query if a label goes out of scope.
83 * @param loadingPhaseThreads the number of threads to use during loading
84 * the packages for the query.
85 * @param labelFilter a predicate that determines if a specific label is
86 * allowed to be visited during query execution. If it returns false,
87 * the query execution is stopped with an error message.
88 * @param settings a set of enabled settings
89 */
Janak Ramakrishnanfe1056f2015-02-11 21:16:06 +000090 BlazeQueryEnvironment(TransitivePackageLoader transitivePackageLoader,
91 PackageProvider packageProvider,
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +010092 TargetPatternEvaluator targetPatternEvaluator,
93 boolean keepGoing,
94 boolean strictScope,
95 int loadingPhaseThreads,
96 Predicate<Label> labelFilter,
97 EventHandler eventHandler,
98 Set<Setting> settings,
99 Iterable<QueryFunction> extraFunctions) {
Janak Ramakrishnane72d5222015-02-26 17:09:18 +0000100 super(keepGoing, strictScope, labelFilter, eventHandler, settings, extraFunctions);
101 this.targetPatternEvaluator = targetPatternEvaluator;
Janak Ramakrishnanfe1056f2015-02-11 21:16:06 +0000102 this.transitivePackageLoader = transitivePackageLoader;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100103 this.targetProvider = packageProvider;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100104 this.errorObserver = new ErrorPrintingTargetEdgeErrorObserver(this.eventHandler);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100105 this.loadingPhaseThreads = loadingPhaseThreads;
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100106 this.labelVisitor = new LabelVisitor(packageProvider, dependencyFilter);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100107 }
108
Mark Schaller6cebed62016-06-27 18:05:39 +0000109 /**
110 * Calling close is optional because {@link BlazeQueryEnvironment} has no resources that need
111 * manual management.
112 */
113 @Override
114 public void close() {}
115
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100116 @Override
Miguel Alcon Pintob6510262015-12-10 17:50:15 +0000117 public DigraphQueryEvalResult<Target> evaluateQuery(QueryExpression expr,
118 final Callback<Target> callback) throws QueryException, InterruptedException {
Janak Ramakrishnane72d5222015-02-26 17:09:18 +0000119 // Some errors are reported as QueryExceptions and others as ERROR events (if --keep_going). The
120 // result is set to have an error iff there were errors emitted during the query, so we reset
121 // errors here.
122 eventHandler.resetErrors();
Miguel Alcon Pintob6510262015-12-10 17:50:15 +0000123 final AtomicBoolean empty = new AtomicBoolean(true);
Janak Ramakrishnanee6208b2016-01-07 20:17:41 +0000124 resolvedTargetPatterns.clear();
Miguel Alcon Pintob6510262015-12-10 17:50:15 +0000125 QueryEvalResult queryEvalResult = super.evaluateQuery(expr, new Callback<Target>() {
126 @Override
127 public void process(Iterable<Target> partialResult)
128 throws QueryException, InterruptedException {
129 empty.compareAndSet(true, Iterables.isEmpty(partialResult));
130 callback.process(partialResult);
131 }
132 });
133 return new DigraphQueryEvalResult<>(queryEvalResult.getSuccess(), empty.get(), graph);
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100134 }
135
136 @Override
Janak Ramakrishnan0dbc1f92016-01-07 19:12:06 +0000137 public void getTargetsMatchingPattern(
Janak Ramakrishnan3c0adb22016-08-15 21:54:55 +0000138 QueryExpression caller, String pattern, Callback<Target> callback)
139 throws QueryException, InterruptedException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100140 // We can safely ignore the boolean error flag. The evaluateQuery() method above wraps the
141 // entire query computation in an error sensor.
142
Janak Ramakrishnancbe26342015-08-17 18:57:57 +0000143 Set<Target> targets = new LinkedHashSet<>(resolvedTargetPatterns.get(pattern));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100144
145 // Sets.filter would be more convenient here, but can't deal with exceptions.
146 Iterator<Target> targetIterator = targets.iterator();
147 while (targetIterator.hasNext()) {
148 Target target = targetIterator.next();
149 if (!validateScope(target.getLabel(), strictScope)) {
150 targetIterator.remove();
151 }
152 }
153
154 Set<PathFragment> packages = new HashSet<>();
155 for (Target target : targets) {
156 packages.add(target.getLabel().getPackageFragment());
157 }
158
159 Set<Target> result = new LinkedHashSet<>();
160 for (Target target : targets) {
161 result.add(getOrCreate(target));
162
163 // Preservation of graph order: it is important that targets obtained via
164 // a wildcard such as p:* are correctly ordered w.r.t. each other, so to
165 // ensure this, we add edges between any pair of directly connected
166 // targets in this set.
167 if (target instanceof OutputFile) {
168 OutputFile outputFile = (OutputFile) target;
169 if (targets.contains(outputFile.getGeneratingRule())) {
170 makeEdge(outputFile, outputFile.getGeneratingRule());
171 }
172 } else if (target instanceof Rule) {
173 Rule rule = (Rule) target;
174 for (Label label : rule.getLabels(dependencyFilter)) {
175 if (!packages.contains(label.getPackageFragment())) {
176 continue; // don't cause additional package loading
177 }
178 try {
179 if (!validateScope(label, strictScope)) {
180 continue; // Don't create edges to targets which are out of scope.
181 }
182 Target to = getTargetOrThrow(label);
183 if (targets.contains(to)) {
184 makeEdge(rule, to);
185 }
186 } catch (NoSuchThingException e) {
187 /* ignore */
188 } catch (InterruptedException e) {
189 throw new QueryException("interrupted");
190 }
191 }
192 }
193 }
Janak Ramakrishnan0dbc1f92016-01-07 19:12:06 +0000194 try {
195 callback.process(result);
196 } catch (InterruptedException e) {
197 throw new QueryException(caller, e.getMessage());
198 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100199 }
200
Ulf Adams3ab82f72015-09-04 12:10:53 +0000201 @Override
Janak Ramakrishnana41a5032015-02-06 21:27:27 +0000202 public Target getTarget(Label label) throws TargetNotFoundException, QueryException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100203 // Can't use strictScope here because we are expecting a target back.
204 validateScope(label, true);
205 try {
Janak Ramakrishnana41a5032015-02-06 21:27:27 +0000206 return getNode(getTargetOrThrow(label)).getLabel();
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100207 } catch (NoSuchThingException e) {
208 throw new TargetNotFoundException(e);
209 } catch (InterruptedException e) {
210 throw new QueryException("interrupted");
211 }
212 }
213
214 private Node<Target> getNode(Target target) {
215 return graph.createNode(target);
216 }
217
218 private Collection<Node<Target>> getNodes(Iterable<Target> target) {
219 Set<Node<Target>> result = new LinkedHashSet<>();
220 for (Target t : target) {
221 result.add(getNode(t));
222 }
223 return result;
224 }
225
226 @Override
227 public Target getOrCreate(Target target) {
228 return getNode(target).getLabel();
229 }
230
231 @Override
Janak Ramakrishnan73dd2302015-06-16 17:04:25 +0000232 public Collection<Target> getFwdDeps(Iterable<Target> targets) {
233 Set<Target> result = new HashSet<>();
234 for (Target target : targets) {
Janak Ramakrishnancda5b662015-06-18 23:46:36 +0000235 result.addAll(getTargetsFromNodes(getNode(target).getSuccessors()));
Janak Ramakrishnan73dd2302015-06-16 17:04:25 +0000236 }
237 return result;
238 }
239
240 @Override
Janak Ramakrishnan73dd2302015-06-16 17:04:25 +0000241 public Collection<Target> getReverseDeps(Iterable<Target> targets) {
242 Set<Target> result = new HashSet<>();
243 for (Target target : targets) {
Janak Ramakrishnancda5b662015-06-18 23:46:36 +0000244 result.addAll(getTargetsFromNodes(getNode(target).getPredecessors()));
Janak Ramakrishnan73dd2302015-06-16 17:04:25 +0000245 }
246 return result;
247 }
248
249 @Override
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100250 public Set<Target> getTransitiveClosure(Set<Target> targetNodes) {
251 for (Target node : targetNodes) {
252 checkBuilt(node);
253 }
254 return getTargetsFromNodes(graph.getFwdReachable(getNodes(targetNodes)));
255 }
256
257 /**
258 * Checks that the graph rooted at 'targetNode' has been completely built;
259 * fails if not. Callers of {@link #getTransitiveClosure} must ensure that
260 * {@link #buildTransitiveClosure} has been called before.
261 *
262 * <p>It would be inefficient and failure-prone to make getTransitiveClosure
263 * call buildTransitiveClosure directly. Also, it would cause
264 * nondeterministic behavior of the operators, since the set of packages
265 * loaded (and hence errors reported) would depend on the ordering details of
266 * the query operators' implementations.
267 */
268 private void checkBuilt(Target targetNode) {
269 Preconditions.checkState(
270 labelVisitor.hasVisited(targetNode.getLabel()),
271 "getTransitiveClosure(%s) called without prior call to buildTransitiveClosure()",
272 targetNode);
273 }
274
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100275 @Override
276 public void buildTransitiveClosure(QueryExpression caller,
277 Set<Target> targetNodes,
Janak Ramakrishnan89907392015-07-08 21:43:31 +0000278 int maxDepth) throws QueryException, InterruptedException {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100279 Set<Target> targets = targetNodes;
280 preloadTransitiveClosure(targets, maxDepth);
Janak Ramakrishnan89907392015-07-08 21:43:31 +0000281 labelVisitor.syncWithVisitor(eventHandler, targets, keepGoing,
282 loadingPhaseThreads, maxDepth, errorObserver, new GraphBuildingObserver());
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100283
284 if (errorObserver.hasErrors()) {
285 reportBuildFileError(caller, "errors were encountered while computing transitive closure");
286 }
287 }
288
289 @Override
290 public Set<Target> getNodesOnPath(Target from, Target to) {
291 return getTargetsFromNodes(graph.getShortestPath(getNode(from), getNode(to)));
292 }
293
Miguel Alcon Pinto42984f32015-11-06 19:05:13 +0000294 @Override
Nathan Harmatabc47f402016-07-13 16:22:30 +0000295 public void eval(QueryExpression expr, VariableContext<Target> context, Callback<Target> callback)
Miguel Alcon Pinto42984f32015-11-06 19:05:13 +0000296 throws QueryException, InterruptedException {
297 AggregateAllCallback<Target> aggregator = new AggregateAllCallback<>();
Nathan Harmatabc47f402016-07-13 16:22:30 +0000298 expr.eval(this, context, aggregator);
Miguel Alcon Pinto42984f32015-11-06 19:05:13 +0000299 callback.process(aggregator.getResult());
300 }
301
302 @Override
303 public Uniquifier<Target> createUniquifier() {
304 return new AbstractUniquifier<Target, Label>() {
305 @Override
306 protected Label extractKey(Target target) {
307 return target.getLabel();
308 }
309 };
310 }
311
Janak Ramakrishnanfe1056f2015-02-11 21:16:06 +0000312 private void preloadTransitiveClosure(Set<Target> targets, int maxDepth) throws QueryException {
313 if (maxDepth >= MAX_DEPTH_FULL_SCAN_LIMIT && transitivePackageLoader != null) {
314 // Only do the full visitation if "maxDepth" is large enough. Otherwise, the benefits of
315 // preloading will be outweighed by the cost of doing more work than necessary.
316 try {
317 transitivePackageLoader.sync(eventHandler, targets, ImmutableSet.<Label>of(), keepGoing,
318 loadingPhaseThreads, -1);
319 } catch (InterruptedException e) {
320 throw new QueryException("interrupted");
321 }
322 }
323 }
324
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100325 /**
326 * It suffices to synchronize the modifications of this.graph from within the
327 * GraphBuildingObserver, because that's the only concurrent part.
328 * Concurrency is always encapsulated within the evaluation of a single query
329 * operator (e.g. deps(), somepath(), etc).
330 */
331 private class GraphBuildingObserver implements TargetEdgeObserver {
332
333 @Override
334 public synchronized void edge(Target from, Attribute attribute, Target to) {
335 Preconditions.checkState(attribute == null ||
336 dependencyFilter.apply(((Rule) from), attribute),
337 "Disallowed edge from LabelVisitor: %s --> %s", from, to);
338 makeEdge(from, to);
339 }
340
341 @Override
342 public synchronized void node(Target node) {
343 graph.createNode(node);
344 }
345
346 @Override
347 public void missingEdge(Target target, Label to, NoSuchThingException e) {
348 // No - op.
349 }
350 }
351
352 private void makeEdge(Target from, Target to) {
353 graph.addEdge(from, to);
354 }
355
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100356 private Target getTargetOrThrow(Label label)
357 throws NoSuchThingException, SkyframeRestartQueryException, InterruptedException {
358 Target target = targetProvider.getTarget(eventHandler, label);
359 if (target == null) {
360 throw new SkyframeRestartQueryException();
361 }
362 return target;
363 }
364
365 // TODO(bazel-team): rename this to getDependentFiles when all implementations
366 // of QueryEnvironment is fixed.
367 @Override
Han-Wen Nienhuysc13c0022015-12-15 19:08:38 +0000368 public Set<Target> getBuildFiles(
369 final QueryExpression caller,
370 Set<Target> nodes,
371 boolean buildFiles,
372 boolean subincludes,
373 boolean loads)
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100374 throws QueryException {
375 Set<Target> dependentFiles = new LinkedHashSet<>();
376 Set<Package> seenPackages = new HashSet<>();
377 // Keep track of seen labels, to avoid adding a fake subinclude label that also exists as a
378 // real target.
379 Set<Label> seenLabels = new HashSet<>();
380
381 // Adds all the package definition files (BUILD files and build
382 // extensions) for package "pkg", to "buildfiles".
383 for (Target x : nodes) {
384 Package pkg = x.getPackage();
385 if (seenPackages.add(pkg)) {
Han-Wen Nienhuysc13c0022015-12-15 19:08:38 +0000386 if (buildFiles) {
387 addIfUniqueLabel(getNode(pkg.getBuildFile()), seenLabels, dependentFiles);
388 }
389
390 List<Label> extensions = new ArrayList<>();
391 if (subincludes) {
392 extensions.addAll(pkg.getSubincludeLabels());
393 }
394 if (loads) {
395 extensions.addAll(pkg.getSkylarkFileDependencies());
396 }
397
398 for (Label subinclude : extensions) {
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100399 addIfUniqueLabel(getSubincludeTarget(subinclude, pkg), seenLabels, dependentFiles);
400
401 // Also add the BUILD file of the subinclude.
Han-Wen Nienhuysc13c0022015-12-15 19:08:38 +0000402 if (buildFiles) {
403 try {
404 addIfUniqueLabel(
405 getSubincludeTarget(subinclude.getLocalTargetLabel("BUILD"), pkg),
406 seenLabels,
407 dependentFiles);
408
409 } catch (LabelSyntaxException e) {
410 throw new AssertionError("BUILD should always parse as a target name", e);
411 }
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100412 }
413 }
414 }
415 }
416 return dependentFiles;
417 }
418
Janak Ramakrishnancbe26342015-08-17 18:57:57 +0000419 private static final Function<ResolvedTargets<Target>, Set<Target>> RESOLVED_TARGETS_TO_TARGETS =
420 new Function<ResolvedTargets<Target>, Set<Target>>() {
421 @Override
422 public Set<Target> apply(ResolvedTargets<Target> resolvedTargets) {
423 return resolvedTargets.getTargets();
424 }
425 };
426
Ulf Adams3ab82f72015-09-04 12:10:53 +0000427 @Override
Janak Ramakrishnanee6208b2016-01-07 20:17:41 +0000428 protected void preloadOrThrow(QueryExpression caller, Collection<String> patterns)
429 throws TargetParsingException {
430 if (!resolvedTargetPatterns.keySet().containsAll(patterns)) {
431 try {
432 // Note that this may throw a RuntimeException if deps are missing in Skyframe and this is
433 // being called from within a SkyFunction.
434 resolvedTargetPatterns.putAll(
435 Maps.transformValues(
436 targetPatternEvaluator.preloadTargetPatterns(eventHandler, patterns, keepGoing),
437 RESOLVED_TARGETS_TO_TARGETS));
438 } catch (InterruptedException e) {
439 // TODO(bazel-team): Propagate the InterruptedException from here [skyframe-loading].
440 throw new TargetParsingException("interrupted");
441 }
Janak Ramakrishnane72d5222015-02-26 17:09:18 +0000442 }
443 }
444
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100445 private static void addIfUniqueLabel(Node<Target> node, Set<Label> labels, Set<Target> nodes) {
446 if (labels.add(node.getLabel().getLabel())) {
447 nodes.add(node.getLabel());
448 }
449 }
450
451 private Node<Target> getSubincludeTarget(final Label label, Package pkg) {
Mark Schallerb817e3f2015-06-04 17:14:18 +0000452 return getNode(new FakeSubincludeTarget(label, pkg));
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100453 }
454
455 @Override
456 public TargetAccessor<Target> getAccessor() {
457 return accessor;
458 }
459
Han-Wen Nienhuysd08b27f2015-02-25 16:45:20 +0100460 /** Given a set of target nodes, returns the targets. */
461 private static Set<Target> getTargetsFromNodes(Iterable<Node<Target>> input) {
462 Set<Target> result = new LinkedHashSet<>();
463 for (Node<Target> node : input) {
464 result.add(node.getLabel());
465 }
466 return result;
467 }
468}