Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(466)

Side by Side Diff: sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart

Issue 14685002: Backjump on a source or description mismatch. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Revise. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/pub/lib/src/solver/version_solver.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 /// Backtracks from the current failed solution and determines the next 185 /// Backtracks from the current failed solution and determines the next
186 /// solution to try. If possible, it will backjump based on the cause of the 186 /// solution to try. If possible, it will backjump based on the cause of the
187 /// [failure] to minize backtracking. Otherwise, it will simply backtrack to 187 /// [failure] to minize backtracking. Otherwise, it will simply backtrack to
188 /// the next possible solution. 188 /// the next possible solution.
189 /// 189 ///
190 /// Returns `true` if there is a new solution to try. 190 /// Returns `true` if there is a new solution to try.
191 bool _backtrack(SolveFailure failure) { 191 bool _backtrack(SolveFailure failure) {
192 var dependers = failure.dependencies.map((dep) => dep.depender).toSet(); 192 var dependers = failure.dependencies.map((dep) => dep.depender).toSet();
193 193
194 while (!_selected.isEmpty) { 194 while (!_selected.isEmpty) {
195 // Look for a relevant selection to jump back to. 195 _backjump(failure);
196 for (var i = _selected.length - 1; i >= 0; i--) {
197 // Can't jump to a package that has no more alternatives.
198 if (_selected[i].length == 1) continue;
199
200 var selected = _selected[i].first;
201
202 // If we find the package itself that failed, jump to it.
203 if (selected.name == failure.package) {
204 logSolve('jump to selected package ${failure.package}');
205 _selected.removeRange(i + 1, _selected.length);
206 break;
207 }
208
209 // See if this package directly or indirectly depends on [package].
210 var path = _getDependencyPath(selected, failure.package);
211 if (path != null) {
212 logSolve('backjump to ${selected.name} because it depends on '
213 '${failure.package} by $path');
214 _selected.removeRange(i + 1, _selected.length);
215 break;
216 }
217 }
218 196
219 // Advance past the current version of the leaf-most package. 197 // Advance past the current version of the leaf-most package.
220 var previous = _selected.last.removeFirst(); 198 var previous = _selected.last.removeFirst();
221 if (!_selected.last.isEmpty) { 199 if (!_selected.last.isEmpty) {
222 logSolve(); 200 logSolve();
223 return true; 201 return true;
224 } 202 }
225 203
226 logSolve('$previous is last version, backtracking'); 204 logSolve('$previous is last version, backtracking');
227 205
228 // That package has no more versions, so pop it and try the next one. 206 // That package has no more versions, so pop it and try the next one.
229 _selected.removeLast(); 207 _selected.removeLast();
230 } 208 }
231 209
232 return false; 210 return false;
233 } 211 }
234 212
213 /// Walks the selected packages from most to least recent to determine which
214 /// ones can be ignored and jumped over by the backtracker. The only packages
215 /// we need to backtrack to are ones that have other versions to try and that
216 /// led (possibly indirectly) to the failure. Everything else can be skipped.
217 void _backjump(SolveFailure failure) {
218 for (var i = _selected.length - 1; i >= 0; i--) {
219 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.
220
221 // If the package has no more versions, we can jump over it.
222 if (_selected[i].length == 1) continue;
223
224 // If we get to the package that failed, stop there.
225 if (selected.name == failure.package) {
226 logSolve('backjump to failed package ${selected.name}');
227 _selected.removeRange(i + 1, _selected.length);
228 return;
229 }
230
231 // If we get to a package that depends on the failing package, try stop
232 // there.
233 var path = _getDependencyPath(selected, failure.package);
234 if (path != null) {
235 logSolve('backjump to ${selected.name} because it depends on '
236 '${failure.package} along $path');
237 _selected.removeRange(i + 1, _selected.length);
238 return;
239 }
240 }
241
242 // If we got here, every selection can be jumped over (except for the first
243 // root package one).
244 _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.
245 }
246
235 /// Determines if [depender] has a direct or indirect dependency on 247 /// Determines if [depender] has a direct or indirect dependency on
236 /// [dependent] based on the currently selected versions of all packages. 248 /// [dependent] based on the currently selected versions of all packages.
237 /// Returns a string describing the dependency chain if it does, or `null` if 249 /// Returns a string describing the dependency chain if it does, or `null` if
238 /// there is no dependency. 250 /// there is no dependency.
239 String _getDependencyPath(PackageId depender, String dependent) { 251 String _getDependencyPath(PackageId depender, String dependent) {
240 // TODO(rnystrom): This is O(n^2) where n is the number of selected 252 // TODO(rnystrom): This is O(n^2) where n is the number of selected
241 // packages. Could store the reverse dependency graph to address that. If 253 // packages. Could store the reverse dependency graph to address that. If
242 // we do that, we need to make sure it gets correctly rolled back when 254 // we do that, we need to make sure it gets correctly rolled back when
243 // backtracking occurs. 255 // backtracking occurs.
244 var visited = new Set<String>(); 256 var visited = new Set<String>();
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 /// with the current SDK. Throws a [SolverFailure] if not. 599 /// with the current SDK. Throws a [SolverFailure] if not.
588 void _validateSdkConstraint(Pubspec pubspec) { 600 void _validateSdkConstraint(Pubspec pubspec) {
589 // If the user is running a continouous build of the SDK, just disable SDK 601 // If the user is running a continouous build of the SDK, just disable SDK
590 // constraint checking entirely. The actual version number you get is 602 // constraint checking entirely. The actual version number you get is
591 // impossibly old and not correct. We'll just assume users on continuous 603 // impossibly old and not correct. We'll just assume users on continuous
592 // know what they're doing. 604 // know what they're doing.
593 if (sdk.isBleedingEdge) return; 605 if (sdk.isBleedingEdge) return;
594 606
595 if (pubspec.environment.sdkVersion.allows(sdk.version)) return; 607 if (pubspec.environment.sdkVersion.allows(sdk.version)) return;
596 608
597 throw new CouldNotSolveException( 609 throw new BadSdkVersionException(pubspec.name,
598 'Package ${pubspec.name} requires SDK version ' 610 'Package ${pubspec.name} requires SDK version '
599 '${pubspec.environment.sdkVersion} but the current SDK is ' 611 '${pubspec.environment.sdkVersion} but the current SDK is '
600 '${sdk.version}.'); 612 '${sdk.version}.');
601 } 613 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/pub/lib/src/solver/version_solver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698