Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// A back-tracking depth-first solver. Attempts to find the best solution for | 5 /// A back-tracking depth-first solver. Attempts to find the best solution for |
| 6 /// a root package's transitive dependency graph, where a "solution" is a set | 6 /// a root package's transitive dependency graph, where a "solution" is a set |
| 7 /// of concrete package versions. A valid solution will select concrete | 7 /// of concrete package versions. A valid solution will select concrete |
| 8 /// versions for every package reached from the root package's dependency graph, | 8 /// versions for every package reached from the root package's dependency graph, |
| 9 /// and each of those packages will fit the version constraints placed on it. | 9 /// and each of those packages will fit the version constraints placed on it. |
| 10 /// | 10 /// |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 67 /// | 67 /// |
| 68 /// The solver tries versions in depth-first order, so only the last queue in | 68 /// The solver tries versions in depth-first order, so only the last queue in |
| 69 /// the list will have items removed from it. When a new constraint is placed | 69 /// the list will have items removed from it. When a new constraint is placed |
| 70 /// on an already-selected package, and that constraint doesn't match the | 70 /// on an already-selected package, and that constraint doesn't match the |
| 71 /// selected version, that will cause the current solution to fail and | 71 /// selected version, that will cause the current solution to fail and |
| 72 /// trigger backtracking. | 72 /// trigger backtracking. |
| 73 final _selected = <Queue<PackageId>>[]; | 73 final _selected = <Queue<PackageId>>[]; |
| 74 | 74 |
| 75 /// The number of possible solutions that have been attempted. | 75 /// The number of possible solutions that have been attempted. |
| 76 int get attemptedSolutions => _attemptedSolutions; | 76 int get attemptedSolutions => _attemptedSolutions; |
| 77 var _attemptedSolutions = 0; | 77 var _attemptedSolutions = 1; |
| 78 | 78 |
| 79 BacktrackingVersionSolver(SourceRegistry sources, Package root, | 79 BacktrackingVersionSolver(SourceRegistry sources, Package root, |
| 80 LockFile lockFile, List<String> useLatest) | 80 LockFile lockFile, List<String> useLatest) |
| 81 : super(sources, root, lockFile, useLatest); | 81 : super(sources, root, lockFile, useLatest); |
| 82 | 82 |
| 83 void forceLatestVersion(String package) { | 83 void forceLatestVersion(String package) { |
| 84 _forceLatest.add(package); | 84 _forceLatest.add(package); |
| 85 } | 85 } |
| 86 | 86 |
| 87 Future<List<PackageId>> runSolver() => _traverseSolution(); | 87 Future<List<PackageId>> runSolver() => _traverseSolution(); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 115 /// `null` if it isn't in the lockfile (or has been unlocked). | 115 /// `null` if it isn't in the lockfile (or has been unlocked). |
| 116 PackageId getLocked(String package) => lockFile.packages[package]; | 116 PackageId getLocked(String package) => lockFile.packages[package]; |
| 117 | 117 |
| 118 /// Traverses the root package's dependency graph using the current potential | 118 /// Traverses the root package's dependency graph using the current potential |
| 119 /// solution. If successful, completes to the solution. If not, backtracks | 119 /// solution. If successful, completes to the solution. If not, backtracks |
| 120 /// to the most recently selected version of a package and tries the next | 120 /// to the most recently selected version of a package and tries the next |
| 121 /// version of it. If there are no more versions, continues to backtrack to | 121 /// version of it. If there are no more versions, continues to backtrack to |
| 122 /// previous selections, and so on. If there is nothing left to backtrack to, | 122 /// previous selections, and so on. If there is nothing left to backtrack to, |
| 123 /// completes to the last failure that occurred. | 123 /// completes to the last failure that occurred. |
| 124 Future<List<PackageId>> _traverseSolution() { | 124 Future<List<PackageId>> _traverseSolution() { |
| 125 _attemptedSolutions++; | |
| 126 | |
| 127 return new Traverser(this).traverse().catchError((error) { | 125 return new Traverser(this).traverse().catchError((error) { |
| 128 if (error is! SolveFailure) throw error; | 126 if (error is! SolveFailure) throw error; |
| 129 | 127 |
| 130 if (_backtrack(error)) return _traverseSolution(); | 128 if (_backtrack(error)) { |
| 129 _attemptedSolutions++; | |
|
nweiz
2013/04/16 23:52:32
Why is this moving in here? Won't this just decrem
Bob Nystrom
2013/04/17 17:28:44
This handles a weird little corner case. If the ro
| |
| 130 return _traverseSolution(); | |
| 131 } | |
| 131 | 132 |
| 132 // All out of solutions, so fail. | 133 // All out of solutions, so fail. |
| 133 throw error; | 134 throw error; |
| 134 }); | 135 }); |
| 135 } | 136 } |
| 136 | 137 |
| 137 /// Backtracks from the current failed solution and determines the next | 138 /// Backtracks from the current failed solution and determines the next |
| 138 /// solution to try. If possible, it will backjump based on the cause of the | 139 /// solution to try. If possible, it will backjump based on the cause of the |
| 139 /// [failure] to minize backtracking. Otherwise, it will simply backtrack to | 140 /// [failure] to minize backtracking. Otherwise, it will simply backtrack to |
| 140 /// the next possible solution. | 141 /// the next possible solution. |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 300 | 301 |
| 301 var id = _packages.removeFirst(); | 302 var id = _packages.removeFirst(); |
| 302 | 303 |
| 303 // Don't visit the same package twice. | 304 // Don't visit the same package twice. |
| 304 if (_visited.contains(id)) { | 305 if (_visited.contains(id)) { |
| 305 return _traversePackage(); | 306 return _traversePackage(); |
| 306 } | 307 } |
| 307 _visited.add(id); | 308 _visited.add(id); |
| 308 | 309 |
| 309 return _solver.cache.getPubspec(id).then((pubspec) { | 310 return _solver.cache.getPubspec(id).then((pubspec) { |
| 311 validateSdkConstraint(pubspec); | |
| 312 | |
| 310 var refs = pubspec.dependencies.toList(); | 313 var refs = pubspec.dependencies.toList(); |
| 311 | 314 |
| 312 // Include dev dependencies of the root package. | 315 // Include dev dependencies of the root package. |
| 313 if (id.isRoot) refs.addAll(pubspec.devDependencies); | 316 if (id.isRoot) refs.addAll(pubspec.devDependencies); |
| 314 | 317 |
| 315 // Given a package ref, returns a future that completes to a pair of the | 318 // Given a package ref, returns a future that completes to a pair of the |
| 316 // ref and the number of versions available for it. | 319 // ref and the number of versions available for it. |
| 317 getNumVersions(PackageRef ref) { | 320 getNumVersions(PackageRef ref) { |
| 318 // There is only ever one version of the root package. | 321 // There is only ever one version of the root package. |
| 319 if (ref.isRoot) { | 322 if (ref.isRoot) { |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 533 | 536 |
| 534 var required = _getRequired(name); | 537 var required = _getRequired(name); |
| 535 if (required != null) { | 538 if (required != null) { |
| 536 if (package.source.name != required.ref.source.name) return null; | 539 if (package.source.name != required.ref.source.name) return null; |
| 537 if (!package.descriptionEquals(required.ref)) return null; | 540 if (!package.descriptionEquals(required.ref)) return null; |
| 538 } | 541 } |
| 539 | 542 |
| 540 return package; | 543 return package; |
| 541 } | 544 } |
| 542 } | 545 } |
| OLD | NEW |