diff options
author | 2015-06-05 07:20:55 +0000 | |
---|---|---|
committer | 2015-06-05 09:39:01 +0000 | |
commit | 14d905b5cce9a1bbc2911331809b03679b23dad1 (patch) | |
tree | eb97900e7011cf90503e8898297a69066029d977 /src/main/java/com/google/devtools/build/lib/query2 | |
parent | 8bc4352deaeb8d8b8afeaa68bd1a015d7731e0e0 (diff) |
Add --with_aspect_deps flag to blaze query. This flag should produce additional information about aspect dependencies when --output is set to {xml, proto}.
One quirk of this CL is that if BUILD files of direct dependencies are added both under <subinclude> and <load>. Any better ideas are appreciated.
As a drive-by fix, if for some reason a package reports the same label as a both subinclude and a Skylark dependency, it will only be reported once in the proto output.
RELNOTES[NEW]: added --with_aspect_deps to blaze query, that prints additional information about aspects of target when --output is set to {xml, proto, record}.
--
MOS_MIGRATED_REVID=95272042
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib/query2')
7 files changed, 281 insertions, 45 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/AspectResolver.java b/src/main/java/com/google/devtools/build/lib/query2/output/AspectResolver.java new file mode 100644 index 0000000000..7a560e886a --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/query2/output/AspectResolver.java @@ -0,0 +1,158 @@ +// Copyright 2014 Google Inc. 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.query2.output; + +import com.google.common.collect.Multimap; +import com.google.common.collect.Multimaps; +import com.google.devtools.build.lib.events.EventHandler; +import com.google.devtools.build.lib.packages.AspectDefinition; +import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.NoSuchPackageException; +import com.google.devtools.build.lib.packages.NoSuchThingException; +import com.google.devtools.build.lib.packages.Package; +import com.google.devtools.build.lib.packages.PackageIdentifier; +import com.google.devtools.build.lib.packages.Rule; +import com.google.devtools.build.lib.packages.Target; +import com.google.devtools.build.lib.pkgcache.PackageProvider; +import com.google.devtools.build.lib.syntax.Label; +import com.google.devtools.build.lib.util.BinaryPredicate; + +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.annotation.Nullable; + +/** Utility class that determines additional dependencies of a target from its aspects. */ +public class AspectResolver { + private final PackageProvider packageProvider; + private final EventHandler eventHandler; + + public AspectResolver(PackageProvider packageProvider, EventHandler eventHandler) { + this.packageProvider = packageProvider; + this.eventHandler = eventHandler; + } + + /** + * Compute additional dependencies of target from aspects. This method is going to load direct + * deps of target to determine their types. Returns map of attributes and corresponding label + * values. + */ + Map<Attribute, Collection<Label>> computeAspectDependenciesWithAttributes(Target target) + throws InterruptedException { + Map<Attribute, Collection<Label>> aspectDependencies = new LinkedHashMap<>(); + if (target instanceof Rule) { + Multimap<Attribute, Label> transitions = + ((Rule) target).getTransitions(Rule.NO_NODEP_ATTRIBUTES); + for (Entry<Attribute, Label> entry : transitions.entries()) { + Target toTarget; + try { + toTarget = packageProvider.getTarget(eventHandler, entry.getValue()); + Map<Attribute, Collection<Label>> deps = Multimaps.asMap( + AspectDefinition.visitAspectsIfRequired(target, entry.getKey(), toTarget)); + aspectDependencies.putAll(deps); + } catch (NoSuchThingException e) { + // Do nothing. One of target direct deps has an error. The dependency on the BUILD file + // (or one of the files included in it) will be reported in the query result of :BUILD. + } + } + } + return aspectDependencies; + } + + /** + * Compute additional dependencies of target from aspects. This method is going to load direct + * deps of target to determine their types. Returns set of labels. + */ + Set<Label> computeAspectDependencies(Target target) throws InterruptedException { + Set<Label> labels = new LinkedHashSet<Label>(); + for (Collection<Label> labelCollection : + computeAspectDependenciesWithAttributes(target).values()) { + labels.addAll(labelCollection); + } + return labels; + } + + /** The way aspect dependencies for a BUILD file are calculated. */ + enum BuildFileDependencyMode { + + /** Return all the subincluded files that may affect the package. */ + SUBINCLUDE { + @Override + protected Collection<Label> getDependencies(Package pkg) { + return pkg.getSubincludeLabels(); + } + }, + + /** Return all Skylark files that may affect the package. */ + SKYLARK { + @Override + protected Collection<Label> getDependencies(Package pkg) { + return pkg.getSkylarkFileDependencies(); + } + }; + + protected abstract Collection<Label> getDependencies(Package pkg); + }; + + Set<Label> computeBuildFileDependencies(Package pkg, BuildFileDependencyMode mode) + throws InterruptedException { + Set<Label> result = new LinkedHashSet<>(); + result.addAll(mode.getDependencies(pkg)); + + Set<PackageIdentifier> dependentPackages = new LinkedHashSet<>(); + // First compute with packages can possibly affect the aspect attributes of this package: + // Iterate over all rules... + for (Target target : pkg.getTargets()) { + + if (!(target instanceof Rule)) { + continue; + } + + // ...figure out which direct dependencies can possibly have aspects attached to them... + Multimap<Attribute, Label> depsWithPossibleAspects = ((Rule) target).getTransitions( + new BinaryPredicate<Rule, Attribute>() { + @Override + public boolean apply(@Nullable Rule rule, @Nullable Attribute attribute) { + return !attribute.getAspects().isEmpty(); + } + }); + + // ...and add the package of the aspect. + for (Label depLabel : depsWithPossibleAspects.values()) { + dependentPackages.add(depLabel.getPackageIdentifier()); + } + } + + // Then add all the subinclude labels of the packages thus found to the result. + for (PackageIdentifier packageIdentifier : dependentPackages) { + try { + result.add(Label.create(packageIdentifier, "BUILD")); + Package dependentPackage = packageProvider.getPackage(eventHandler, packageIdentifier); + result.addAll(mode.getDependencies(dependentPackage)); + } catch (NoSuchPackageException e) { + // If the package is not found, just add its BUILD file, which is already done above. + // Hopefully this error is not raised when there is a syntax error in a subincluded file + // or something. + } catch (Label.SyntaxException e) { + throw new IllegalStateException(e); + } + } + + return result; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java index c51fc81e90..0cfcceac5b 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java +++ b/src/main/java/com/google/devtools/build/lib/query2/output/GraphOutputFormatter.java @@ -42,7 +42,8 @@ class GraphOutputFormatter extends OutputFormatter { } @Override - public void output(QueryOptions options, Digraph<Target> result, PrintStream out) { + public void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectProvider) { this.graphNodeStringLimit = options.graphNodeStringLimit; this.graphFactored = options.graphFactored; diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java index e8247c540a..e47fcb70da 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java +++ b/src/main/java/com/google/devtools/build/lib/query2/output/OutputFormatter.java @@ -144,8 +144,8 @@ public abstract class OutputFormatter implements Serializable { * Format the result (a set of target nodes implicitly ordered according to * the graph maintained by the QueryEnvironment), and print it to "out". */ - public abstract void output(QueryOptions options, Digraph<Target> result, PrintStream out) - throws IOException; + public abstract void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectProvider) throws IOException, InterruptedException; /** * Unordered output formatter (wrt. dependency ordering). @@ -157,8 +157,8 @@ public abstract class OutputFormatter implements Serializable { * subgraph extraction step before presenting the query results. */ public interface UnorderedFormatter { - void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) - throws IOException; + void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out, + AspectResolver aspectResolver) throws IOException, InterruptedException; } /** @@ -184,7 +184,8 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) { + public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out, + AspectResolver aspectResolver) { for (Target target : result) { if (showKind) { out.print(target.getTargetKind()); @@ -195,10 +196,11 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void output(QueryOptions options, Digraph<Target> result, PrintStream out) { + public void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectResolver) { Iterable<Target> ordered = Iterables.transform( result.getTopologicalOrder(new TargetOrdering()), EXTRACT_NODE_LABEL); - outputUnordered(options, ordered, out); + outputUnordered(options, ordered, out, aspectResolver); } } @@ -224,7 +226,8 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) { + public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out, + AspectResolver aspectResolver) { Set<String> packageNames = Sets.newTreeSet(); for (Target target : result) { packageNames.add(target.getLabel().getPackageName()); @@ -235,10 +238,11 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void output(QueryOptions options, Digraph<Target> result, PrintStream out) { + public void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectResolver) { Iterable<Target> ordered = Iterables.transform( result.getTopologicalOrder(new TargetOrdering()), EXTRACT_NODE_LABEL); - outputUnordered(options, ordered, out); + outputUnordered(options, ordered, out, aspectResolver); } } @@ -256,7 +260,8 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) { + public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out, + AspectResolver aspectResolver) { for (Target target : result) { Location location = target.getLocation(); out.println(location.print() + ": " + target.getTargetKind() + " " + target.getLabel()); @@ -264,10 +269,11 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void output(QueryOptions options, Digraph<Target> result, PrintStream out) { + public void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectResolver) { Iterable<Target> ordered = Iterables.transform( result.getTopologicalOrder(new TargetOrdering()), EXTRACT_NODE_LABEL); - outputUnordered(options, ordered, out); + outputUnordered(options, ordered, out, aspectResolver); } } @@ -310,7 +316,8 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) { + public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out, + AspectResolver aspectResolver) { Set<Label> printed = new HashSet<>(); for (Target target : result) { Rule rule = target.getAssociatedRule(); @@ -323,10 +330,11 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void output(QueryOptions options, Digraph<Target> result, PrintStream out) { + public void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectResolver) { Iterable<Target> ordered = Iterables.transform( result.getTopologicalOrder(new TargetOrdering()), EXTRACT_NODE_LABEL); - outputUnordered(options, ordered, out); + outputUnordered(options, ordered, out, aspectResolver); } } @@ -347,7 +355,8 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void output(QueryOptions options, Digraph<Target> result, PrintStream out) { + public void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectResolver) { // getRoots() isn't defined for cyclic graphs, so in order to handle // cycles correctly, we need work on the strong component graph, as // cycles should be treated a "clump" of nodes all on the same rank. @@ -397,7 +406,8 @@ public abstract class OutputFormatter implements Serializable { } @Override - public void output(QueryOptions options, Digraph<Target> result, PrintStream out) { + public void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectResolver) { // In order to handle cycles correctly, we need work on the strong // component graph, as cycles should be treated a "clump" of nodes all on // the same rank. Graphs may contain cycles because there are errors in BUILD files. diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java index e7d9d21aef..77761efbea 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java +++ b/src/main/java/com/google/devtools/build/lib/query2/output/ProtoOutputFormatter.java @@ -19,6 +19,7 @@ import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target. import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target.Discriminator.RULE; import static com.google.devtools.build.lib.query2.proto.proto2api.Build.Target.Discriminator.SOURCE_FILE; +import com.google.common.collect.Lists; import com.google.devtools.build.lib.graph.Digraph; import com.google.devtools.build.lib.packages.Attribute; import com.google.devtools.build.lib.packages.EnvironmentGroup; @@ -30,6 +31,7 @@ import com.google.devtools.build.lib.packages.ProtoUtils; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.query2.FakeSubincludeTarget; +import com.google.devtools.build.lib.query2.output.AspectResolver.BuildFileDependencyMode; import com.google.devtools.build.lib.query2.output.OutputFormatter.UnorderedFormatter; import com.google.devtools.build.lib.query2.proto.proto2api.Build; import com.google.devtools.build.lib.syntax.Label; @@ -38,6 +40,13 @@ import com.google.devtools.build.lib.util.BinaryPredicate; import java.io.IOException; import java.io.PrintStream; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.annotation.Nullable; /** * An output formatter that outputs a protocol buffer representation @@ -54,6 +63,7 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo private BinaryPredicate<Rule, Attribute> dependencyFilter; private boolean relativeLocations = false; + @Nullable protected AspectResolver aspectResolver = null; // null if aspect deps are not required protected void setDependencyFilter(QueryOptions options) { this.dependencyFilter = OutputFormatter.getDependencyFilter(options); @@ -65,10 +75,10 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo } @Override - public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) - throws IOException { + public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out, + AspectResolver aspectResolver) throws IOException, InterruptedException { relativeLocations = options.relativeLocations; - + this.aspectResolver = aspectResolver; setDependencyFilter(options); Build.QueryResult.Builder queryResult = Build.QueryResult.newBuilder(); @@ -80,9 +90,9 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo } @Override - public void output(QueryOptions options, Digraph<Target> result, PrintStream out) - throws IOException { - outputUnordered(options, result.getLabels(), out); + public void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectResolver) throws IOException, InterruptedException { + outputUnordered(options, result.getLabels(), out, aspectResolver); } /** @@ -91,14 +101,16 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo * output targets. * @param target The query target being converted to a protocol buffer. */ - private void addTarget(Build.QueryResult.Builder queryResult, Target target) { + private void addTarget(Build.QueryResult.Builder queryResult, Target target) + throws InterruptedException { queryResult.addTarget(toTargetProtoBuffer(target)); } /** * Converts a logical Target object into a Target protobuffer. */ - protected Build.Target toTargetProtoBuffer(Target target) { + protected Build.Target toTargetProtoBuffer(Target target) + throws InterruptedException { Build.Target.Builder targetPb = Build.Target.newBuilder(); String location = getLocation(target, relativeLocations); @@ -127,6 +139,22 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo .setStringValue(env.getTransitiveFileContentHashCode())); } + if (aspectResolver != null) { + Map<Attribute, Collection<Label>> aspectsDependencies = + aspectResolver.computeAspectDependenciesWithAttributes(target); + // Add information about additional attributes from aspects. + for (Entry<Attribute, Collection<Label>> entry : aspectsDependencies.entrySet()) { + PackageSerializer.addAttributeToProto(rulePb, entry.getKey(), + Lists.<Object>newArrayList(entry.getValue()), null, false, false); + } + // Add all deps from aspects as rule inputs of current target. + for (Collection<Label> labelCollection : aspectsDependencies.values()) { + for (Label label : labelCollection) { + rulePb.addRuleInput(label.toString()); + } + } + } + // Include explicit elements for all direct inputs and outputs of a rule; // this goes beyond what is available from the attributes above, since it // may also (depending on options) include implicit outputs, @@ -166,11 +194,17 @@ public class ProtoOutputFormatter extends OutputFormatter implements UnorderedFo .setName(label.toString()); if (inputFile.getName().equals("BUILD")) { - for (Label subinclude : inputFile.getPackage().getSubincludeLabels()) { - input.addSubinclude(subinclude.toString()); - } - - for (Label skylarkFileDep : inputFile.getPackage().getSkylarkFileDependencies()) { + Set<Label> subincludeLabels = new LinkedHashSet<>(); + subincludeLabels.addAll(aspectResolver == null + ? inputFile.getPackage().getSubincludeLabels() + : aspectResolver.computeBuildFileDependencies( + inputFile.getPackage(), BuildFileDependencyMode.SUBINCLUDE)); + subincludeLabels.addAll(aspectResolver == null + ? inputFile.getPackage().getSkylarkFileDependencies() + : aspectResolver.computeBuildFileDependencies( + inputFile.getPackage(), BuildFileDependencyMode.SKYLARK)); + + for (Label skylarkFileDep : subincludeLabels) { input.addSubinclude(skylarkFileDep.toString()); } diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/QueryOptions.java b/src/main/java/com/google/devtools/build/lib/query2/output/QueryOptions.java index 52d897ea69..417981ec2e 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/output/QueryOptions.java +++ b/src/main/java/com/google/devtools/build/lib/query2/output/QueryOptions.java @@ -137,6 +137,13 @@ public class QueryOptions extends OptionsBase { + "across machines.") public boolean relativeLocations; + @Option(name = "aspect_deps", + defaultValue = "false", + category = "query", + help = "If true, the dependencies from aspects should be added to targets. By default, this " + + "information about aspects is missing when --output is set to xml, proto or record.") + public boolean withAspectDeps; + /** * Return the current options as a set of QueryEnvironment settings. */ diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/QueryOutputUtils.java b/src/main/java/com/google/devtools/build/lib/query2/output/QueryOutputUtils.java index 6443ee4687..078b937a55 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/output/QueryOutputUtils.java +++ b/src/main/java/com/google/devtools/build/lib/query2/output/QueryOutputUtils.java @@ -31,14 +31,14 @@ public class QueryOutputUtils { } public static void output(QueryOptions queryOptions, QueryEvalResult<Target> result, - OutputFormatter formatter, PrintStream outputStream) - throws IOException { + OutputFormatter formatter, PrintStream outputStream, AspectResolver aspectResolver) + throws IOException, InterruptedException { if (orderResults(queryOptions, formatter)) { formatter.output(queryOptions, ((BlazeQueryEvalResult<Target>) result).getResultGraph(), - outputStream); + outputStream, aspectResolver); } else { ((UnorderedFormatter) formatter).outputUnordered(queryOptions, result.getResultSet(), - outputStream); + outputStream, aspectResolver); } } } diff --git a/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java b/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java index 68eaefd4d2..4d3dca8c8a 100644 --- a/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java +++ b/src/main/java/com/google/devtools/build/lib/query2/output/XmlOutputFormatter.java @@ -25,6 +25,7 @@ import com.google.devtools.build.lib.packages.PackageGroup; import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.query2.FakeSubincludeTarget; +import com.google.devtools.build.lib.query2.output.AspectResolver.BuildFileDependencyMode; import com.google.devtools.build.lib.syntax.FilesetEntry; import com.google.devtools.build.lib.syntax.Label; import com.google.devtools.build.lib.util.BinaryPredicate; @@ -40,6 +41,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import javax.annotation.Nullable; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; @@ -58,6 +60,7 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor private boolean xmlLineNumbers; private boolean showDefaultValues; private boolean relativeLocations; + @Nullable private AspectResolver aspectResolver; // Null if aspect dependencies are not needed private BinaryPredicate<Rule, Attribute> dependencyFilter; @Override @@ -66,12 +69,13 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor } @Override - public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out) { + public void outputUnordered(QueryOptions options, Iterable<Target> result, PrintStream out, + AspectResolver aspectResolver) throws InterruptedException { this.xmlLineNumbers = options.xmlLineNumbers; this.showDefaultValues = options.xmlShowDefaultValues; this.relativeLocations = options.relativeLocations; this.dependencyFilter = OutputFormatter.getDependencyFilter(options); - + this.aspectResolver = aspectResolver; Document doc; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); @@ -98,10 +102,11 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor } @Override - public void output(QueryOptions options, Digraph<Target> result, PrintStream out) { + public void output(QueryOptions options, Digraph<Target> result, PrintStream out, + AspectResolver aspectResolver) throws InterruptedException { Iterable<Target> ordered = Iterables.transform( result.getTopologicalOrder(new TargetOrdering()), OutputFormatter.EXTRACT_NODE_LABEL); - outputUnordered(options, ordered, out); + outputUnordered(options, ordered, out, aspectResolver); } /** @@ -114,8 +119,10 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor * - 'name' attribute is target's label. * - 'location' attribute is consistent with output of --output location. * - rule attributes are represented in the DOM structure. + * @throws InterruptedException */ - private Element createTargetElement(Document doc, Target target) { + private Element createTargetElement(Document doc, Target target) + throws InterruptedException { Element elem; if (target instanceof Rule) { Rule rule = (Rule) target; @@ -139,6 +146,13 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor inputElem.setAttribute("name", label.toString()); elem.appendChild(inputElem); } + if (aspectResolver != null) { + for (Label label : aspectResolver.computeAspectDependencies(target)) { + Element inputElem = doc.createElement("rule-input"); + inputElem.setAttribute("name", label.toString()); + elem.appendChild(inputElem); + } + } for (OutputFile outputFile: rule.getOutputFiles()) { Element outputElem = doc.createElement("rule-output"); outputElem.setAttribute("name", outputFile.getLabel().toString()); @@ -233,16 +247,28 @@ class XmlOutputFormatter extends OutputFormatter implements OutputFormatter.Unor } } - private void addSubincludedFilesToElement(Document doc, Element parent, InputFile inputFile) { - for (Label subinclude : inputFile.getPackage().getSubincludeLabels()) { + private void addSubincludedFilesToElement(Document doc, Element parent, InputFile inputFile) + throws InterruptedException { + Iterable<Label> dependencies = aspectResolver == null + ? inputFile.getPackage().getSubincludeLabels() + : aspectResolver.computeBuildFileDependencies( + inputFile.getPackage(), BuildFileDependencyMode.SUBINCLUDE); + + for (Label subinclude : dependencies) { Element elem = doc.createElement("subinclude"); elem.setAttribute("name", subinclude.toString()); parent.appendChild(elem); } } - private void addSkylarkFilesToElement(Document doc, Element parent, InputFile inputFile) { - for (Label skylarkFileDep : inputFile.getPackage().getSkylarkFileDependencies()) { + private void addSkylarkFilesToElement(Document doc, Element parent, InputFile inputFile) + throws InterruptedException { + Iterable<Label> dependencies = aspectResolver == null + ? inputFile.getPackage().getSkylarkFileDependencies() + : aspectResolver.computeBuildFileDependencies( + inputFile.getPackage(), BuildFileDependencyMode.SKYLARK); + + for (Label skylarkFileDep : dependencies) { Element elem = doc.createElement("load"); elem.setAttribute("name", skylarkFileDep.toString()); parent.appendChild(elem); |