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..24f4282ef24888fb9a9e687e91e5eefe36e28d1f 100644 |
| --- a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| +++ b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart |
| @@ -192,29 +192,7 @@ class BacktrackingSolver { |
| var dependers = failure.dependencies.map((dep) => dep.depender).toSet(); |
| 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; |
| - } |
| - } |
| + _backjump(failure); |
| // Advance past the current version of the leaf-most package. |
| var previous = _selected.last.removeFirst(); |
| @@ -232,6 +210,40 @@ class BacktrackingSolver { |
| return false; |
| } |
| + /// Walks the selected packages from most to least recent to determine which |
| + /// ones can be ignored and jumped over by the backtracker. The only packages |
| + /// we need to backtrack to are ones that have other versions to try and that |
| + /// led (possibly indirectly) to the failure. Everything else can be skipped. |
| + void _backjump(SolveFailure failure) { |
| + for (var i = _selected.length - 1; i >= 0; i--) { |
| + var selected = _selected[i].first; |
|
nweiz
2013/05/01 01:17:52
Might be nice to add a comment or assertion here e
Bob Nystrom
2013/05/01 01:38:57
Done.
|
| + |
| + // If the package has no more versions, we can jump over it. |
| + if (_selected[i].length == 1) continue; |
| + |
| + // If we get to the package that failed, stop there. |
| + if (selected.name == failure.package) { |
| + logSolve('backjump to failed package ${selected.name}'); |
| + _selected.removeRange(i + 1, _selected.length); |
| + return; |
| + } |
| + |
| + // If we get to a package that depends on the failing package, try stop |
| + // there. |
| + var path = _getDependencyPath(selected, failure.package); |
| + if (path != null) { |
| + logSolve('backjump to ${selected.name} because it depends on ' |
| + '${failure.package} along $path'); |
| + _selected.removeRange(i + 1, _selected.length); |
| + return; |
| + } |
| + } |
| + |
| + // If we got here, every selection can be jumped over (except for the first |
| + // root package one). |
| + _selected.removeRange(1, _selected.length); |
|
nweiz
2013/05/01 01:17:52
I'm not 100% clear what's going on here. How did w
Bob Nystrom
2013/05/01 01:38:57
Added some comments.
|
| + } |
| + |
| /// 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 |
| @@ -594,7 +606,7 @@ void _validateSdkConstraint(Pubspec pubspec) { |
| if (pubspec.environment.sdkVersion.allows(sdk.version)) return; |
| - throw new CouldNotSolveException( |
| + throw new BadSdkVersionException(pubspec.name, |
| 'Package ${pubspec.name} requires SDK version ' |
| '${pubspec.environment.sdkVersion} but the current SDK is ' |
| '${sdk.version}.'); |