Chromium Code Reviews| Index: sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| diff --git a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| index c5580a901ed1204142842aef2aa577a07c13b84b..9efb562ebce68367eb5cc68bb8a32ce011d34406 100644 |
| --- a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| +++ b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| @@ -193,27 +193,10 @@ class BacktrackingSolver { |
| while (!_selected.isEmpty) { |
| // Look for a relevant selection to jump back to. |
| - for (var i = _selected.length - 1; i >= 0; i--) { |
| - // Can't jump to a package that has no more alternatives. |
| - if (_selected[i].length == 1) continue; |
| - |
| - var selected = _selected[i].first; |
| - |
| - // If we find the package itself that failed, jump to it. |
| - if (selected.name == failure.package) { |
| - logSolve('jump to selected package ${failure.package}'); |
| - _selected.removeRange(i + 1, _selected.length); |
| - break; |
| - } |
| - |
| - // See if this package directly or indirectly depends on [package]. |
| - var path = _getDependencyPath(selected, failure.package); |
| - if (path != null) { |
| - logSolve('backjump to ${selected.name} because it depends on ' |
| - '${failure.package} by $path'); |
| - _selected.removeRange(i + 1, _selected.length); |
| - break; |
| - } |
| + if (failure.mayHaveTransitiveCause) { |
|
nweiz
2013/04/30 22:00:29
I don't understand this distinction. Why can't sou
Bob Nystrom
2013/05/01 01:06:15
After putting on my thinking cap, I've got a clean
|
| + _backjumpToDependency(failure.package); |
| + } else { |
| + _backjumpToPackage(failure.dependencies); |
| } |
| // Advance past the current version of the leaf-most package. |
| @@ -232,6 +215,47 @@ class BacktrackingSolver { |
| return false; |
| } |
| + /// Backjumps to the most recently selected package in [dependencies]. Does |
| + /// not consider dependent or related packages. This is used for failures |
| + /// like [SourceMismatchException] where one of the packages explicitly in |
| + /// that list is known to be a direct cause of the failure. |
| + void _backjumpToPackage(Iterable<Dependency> dependencies) { |
| + for (var i = _selected.length - 1; i >= 0; i--) { |
| + var selected = _selected[i].first; |
| + |
| + for (var dep in dependencies) { |
| + if (selected.name == dep.dep.name) { |
| + logSolve('backjump to ${selected.name} because it caused conflict'); |
| + _selected.removeRange(i + 1, _selected.length); |
| + return; |
| + } |
| + } |
| + } |
| + } |
| + |
| + /// Backjumps to the most recently selected package that directly or |
| + /// indirectly depends on [package]. This is used for failures like |
| + /// [NoVersionException] where we failed to find a version for [package] and |
| + /// any package along the dependency graph leading to it could have caused |
| + /// that failure. |
| + void _backjumpToDependency(String package) { |
| + for (var i = _selected.length - 1; i >= 0; i--) { |
| + // Can't jump to a package that has no more alternatives. |
| + if (_selected[i].length == 1) continue; |
| + |
| + var selected = _selected[i].first; |
| + |
| + // See if this package directly or indirectly depends on [package]. |
| + var path = _getDependencyPath(selected, package); |
| + if (path != null) { |
| + logSolve('backjump to ${selected.name} because it depends on ' |
| + '${package} by $path'); |
|
nweiz
2013/04/30 22:00:29
indentation
Bob Nystrom
2013/05/01 01:06:15
Done.
|
| + _selected.removeRange(i + 1, _selected.length); |
| + return; |
| + } |
| + } |
| + } |
| + |
| /// Determines if [depender] has a direct or indirect dependency on |
| /// [dependent] based on the currently selected versions of all packages. |
| /// Returns a string describing the dependency chain if it does, or `null` if |