blob: 02f41f7edf3ca94de579a8fba64744c5db156092 [file] [log] [blame]
/*
* Copyright 2013-present Facebook, Inc.
*
* 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.facebook.buck.rules;
import com.facebook.buck.graph.AbstractBreadthFirstTraversal;
import com.facebook.buck.graph.DefaultDirectedAcyclicGraph;
import com.facebook.buck.graph.DirectedAcyclicGraph;
import com.facebook.buck.graph.MutableDirectedGraph;
import com.google.common.base.Predicate;
import com.google.common.collect.ImmutableSet;
public class BuildRuleDependencyVisitors {
private BuildRuleDependencyVisitors() {
}
/**
* Given dependencies in inputs builds graph of transitive dependencies filtering them by
* instanceOf T.
*
* @param inputs initial dependencies from which to build transitive closure
* @param filter predicate to determine whether a node should be included
* @param traverse predicate to determine whether this node should be traversed
* @param <T> class to fitler on
* @return filtered BuildRule DAG of transitive dependencies
*
* @see com.facebook.buck.rules.BuildRule
*/
public static <T> DirectedAcyclicGraph<BuildRule> getBuildRuleDirectedGraphFilteredBy(
final Iterable<? extends BuildRule> inputs,
final Predicate<Object> filter,
final Predicate<Object> traverse) {
// Build up a graph of the inputs and their transitive dependencies, we'll use the graph
// to topologically sort the dependencies.
final MutableDirectedGraph<BuildRule> graph = new MutableDirectedGraph<>();
AbstractBreadthFirstTraversal<BuildRule> visitor =
new AbstractBreadthFirstTraversal<BuildRule>(inputs) {
@Override
public ImmutableSet<BuildRule> visit(BuildRule rule) {
if (filter.apply(rule)) {
graph.addNode(rule);
for (BuildRule dep : rule.getDeps()) {
if (traverse.apply(dep) && filter.apply(dep)) {
graph.addEdge(rule, dep);
}
}
}
return traverse.apply(rule) ? rule.getDeps() : ImmutableSet.<BuildRule>of();
}
};
visitor.start();
return new DefaultDirectedAcyclicGraph<>(graph);
}
public static ImmutableSet<BuildRule> maybeVisitAllDeps(BuildRule rule, boolean visitDeps) {
return visitDeps ? rule.getDeps() : ImmutableSet.<BuildRule>of();
}
}