Index: sdk/lib/_internal/pub/lib/src/package_graph.dart |
diff --git a/sdk/lib/_internal/pub/lib/src/package_graph.dart b/sdk/lib/_internal/pub/lib/src/package_graph.dart |
index 14913787b95be9a5c9a70ad98a672c5762a03332..4470e51bc6ae1abde3ab918cfe87ebd080e38719 100644 |
--- a/sdk/lib/_internal/pub/lib/src/package_graph.dart |
+++ b/sdk/lib/_internal/pub/lib/src/package_graph.dart |
@@ -7,6 +7,7 @@ library pub.package_graph; |
import 'entrypoint.dart'; |
import 'lock_file.dart'; |
import 'package.dart'; |
+import 'utils.dart'; |
/// A holistic view of the entire transitive dependency graph for an entrypoint. |
/// |
@@ -24,5 +25,26 @@ class PackageGraph { |
/// All transitive dependencies of the entrypoint (including itself). |
final Map<String, Package> packages; |
+ /// A map of transitive dependencies for each package. |
+ Map<String, Set<Package>> _transitiveDependencies; |
+ |
PackageGraph(this.entrypoint, this.lockFile, this.packages); |
+ |
+ /// Returns all transitive dependencies of [package]. |
+ /// |
+ /// For the entrypoint this returns all packages in [packages], which includes |
+ /// dev and override. For any other package, it ignores dev and override |
+ /// dependencies. |
+ Set<Package> transitiveDependencies(String package) { |
+ if (package == entrypoint.root.name) return packages.values.toSet(); |
+ |
+ if (_transitiveDependencies == null) { |
+ var closure = transitiveClosure(mapMap(packages, |
+ value: (_, package) => package.dependencies.map((dep) => dep.name))); |
+ _transitiveDependencies = mapMap(closure, |
+ value: (_, names) => names.map((name) => packages[name]).toSet()); |
+ } |
+ |
+ return _transitiveDependencies[package]; |
+ } |
} |