| Index: utils/pub/solver/backtracking_solver.dart
|
| diff --git a/utils/pub/solver/backtracking_solver.dart b/utils/pub/solver/backtracking_solver.dart
|
| index 0a583e2f6077cac765d207b3bf92181ea04d19de..83a43605a2c0e93e3829bcae103ae5ca0ffb3bc1 100644
|
| --- a/utils/pub/solver/backtracking_solver.dart
|
| +++ b/utils/pub/solver/backtracking_solver.dart
|
| @@ -175,7 +175,7 @@ class BacktrackingVersionSolver extends VersionSolver {
|
| return true;
|
| }
|
|
|
| - logSolve('${previous} is last version, backtracking');
|
| + logSolve('$previous is last version, backtracking');
|
|
|
| // That package has no more versions, so pop it and try the next one.
|
| _selected.removeLast();
|
| @@ -189,40 +189,35 @@ class BacktrackingVersionSolver extends VersionSolver {
|
| /// Returns a string describing the dependency chain if it does, or `null` if
|
| /// there is no dependency.
|
| String _getDependencyPath(PackageId depender, String dependent) {
|
| + // TODO(rnystrom): This is O(n^2) where n is the number of selected
|
| + // packages. Could store the reverse dependency graph to address that. If
|
| + // we do that, we need to make sure it gets correctly rolled back when
|
| + // backtracking occurs.
|
| var visited = new Set<String>();
|
| - var resultPath;
|
| - var currentPath = '${depender.name}';
|
|
|
| - walkDeps(PackageId package) {
|
| - if (visited.contains(package.name)) return false;
|
| + walkDeps(PackageId package, String currentPath) {
|
| + if (visited.contains(package.name)) return null;
|
| visited.add(package.name);
|
|
|
| var pubspec = cache.getCachedPubspec(package);
|
| - if (pubspec == null) return false;
|
| + if (pubspec == null) return null;
|
|
|
| for (var dep in pubspec.dependencies) {
|
| - var previousPath = currentPath;
|
| - currentPath = '$currentPath -> ${dep.name}';
|
| -
|
| - if (dep.name == dependent) {
|
| - resultPath = currentPath;
|
| - return true;
|
| - }
|
| + if (dep.name == dependent) return currentPath;
|
|
|
| var selected = getSelected(dep.name);
|
| // Ignore unselected dependencies. We haven't traversed into them yet,
|
| // so they can't affect backjumping.
|
| if (selected == null) continue;
|
|
|
| - if (walkDeps(selected)) return true;
|
| -
|
| - currentPath = previousPath;
|
| + var depPath = walkDeps(selected, '$currentPath -> ${dep.name}');
|
| + if (depPath != null) return depPath;
|
| }
|
|
|
| - return false;
|
| + return null;
|
| }
|
|
|
| - return walkDeps(depender) ? resultPath : null;
|
| + return walkDeps(depender, depender.name);
|
| }
|
|
|
| /// Logs [message] in the context of the current selected packages. If
|
| @@ -232,13 +227,8 @@ class BacktrackingVersionSolver extends VersionSolver {
|
| if (_selected.isEmpty) {
|
| message = "* start at root";
|
| } else {
|
| - var versions = _selected.last.map((id) => id.version).toList();
|
| - if (versions.length > 5) {
|
| - versions = versions.take(5).join(', ') + '...';
|
| - } else {
|
| - versions = versions.join(', ');
|
| - }
|
| - message = "* select ${_selected.last.first} (from $versions)";
|
| + var count = _selected.last.length;
|
| + message = "* select ${_selected.last.first} ($count versions)";
|
| }
|
| } else {
|
| // Otherwise, indent it under the current selected package.
|
| @@ -327,6 +317,8 @@ class Traverser {
|
| // If it fails for any reason, just treat that as no versions. This
|
| // will sort this reference higher so that we can traverse into it
|
| // and report the error more properly.
|
| + log.solver("Could not get versions for $ref:\n$error\n\n"
|
| + "${getAttachedStackTrace(error)}");
|
| return new Pair<PackageRef, int>(ref, 0);
|
| });
|
| }
|
| @@ -366,6 +358,8 @@ class Traverser {
|
| // Move onto the next package if we've traversed all of these references.
|
| if (refs.isEmpty) return _traversePackage();
|
|
|
| + // Pump the event loop to flatten the stack trace and workaround #9583.
|
| + // If that bug is fixed, this can be Future.sync() instead.
|
| return new Future(() {
|
| var ref = refs.removeFirst();
|
|
|
|
|