| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 library dart_style.benchmark.benchmark; | |
| 6 | |
| 7 import 'dart:io'; | |
| 8 | |
| 9 import 'package:dart_style/dart_style.dart'; | |
| 10 | |
| 11 const NUM_TRIALS = 100; | |
| 12 const FORMATS_PER_TRIAL = 30; | |
| 13 | |
| 14 void main(List<String> args) { | |
| 15 var best = 99999999.0; | |
| 16 | |
| 17 // Run the benchmark several times. This ensures the VM is warmed up and lets | |
| 18 // us see how much variance there is. | |
| 19 for (var i = 0; i <= NUM_TRIALS; i++) { | |
| 20 var start = new DateTime.now(); | |
| 21 | |
| 22 // For a single benchmark, format the source multiple times. | |
| 23 for (var j = 0; j < FORMATS_PER_TRIAL; j++) { | |
| 24 formatSource(); | |
| 25 } | |
| 26 | |
| 27 var elapsed = new DateTime.now() | |
| 28 .difference(start).inMilliseconds / FORMATS_PER_TRIAL; | |
| 29 | |
| 30 // Keep track of the best run so far. | |
| 31 if (elapsed >= best) continue; | |
| 32 best = elapsed; | |
| 33 | |
| 34 // Don't print the first run. It's always terrible since the VM hasn't | |
| 35 // warmed up yet. | |
| 36 if (i == 0) continue; | |
| 37 printResult("Run ${padLeft('#$i', 3)}", elapsed); | |
| 38 } | |
| 39 | |
| 40 printResult("Best ", best); | |
| 41 } | |
| 42 | |
| 43 void printResult(String label, double time) { | |
| 44 print("$label: ${padLeft(time.toStringAsFixed(2), 4)}ms " | |
| 45 "${'=' * ((time * 5).toInt())}"); | |
| 46 } | |
| 47 | |
| 48 String padLeft(input, int length) { | |
| 49 var result = input.toString(); | |
| 50 if (result.length < length) { | |
| 51 result = " " * (length - result.length) + result; | |
| 52 } | |
| 53 | |
| 54 return result; | |
| 55 } | |
| 56 | |
| 57 void formatSource() { | |
| 58 var formatter = new DartFormatter(); | |
| 59 var result = formatter.format(source); | |
| 60 | |
| 61 // Sanity check to make sure the output is what we expect and to make sure | |
| 62 // the VM doesn't optimize "dead" code away. | |
| 63 if (result.length != 29791) { | |
| 64 print("Incorrect output (length ${result.length}):\n$result"); | |
| 65 exit(1); | |
| 66 } | |
| 67 } | |
| 68 | |
| 69 const source = r""" | |
| 70 // 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 |
| 71 // 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 |
| 72 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 73 | 4 |
| 74 library pub.solver.backtracking_solver; | 5 library pub.solver.backtracking_solver; |
| 75 | 6 |
| 76 import 'dart:async'; | 7 import 'dart:async'; |
| 77 import 'dart:collection' show Queue; | 8 import 'dart:collection' show Queue; |
| 78 | 9 |
| 79 import '../barback.dart' as barback; | 10 import '../barback.dart' as barback; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 152 cache = new PubspecCache(type, sources) { | 83 cache = new PubspecCache(type, sources) { |
| 153 for (var package in useLatest) { | 84 for (var package in useLatest) { |
| 154 _forceLatest.add(package); | 85 _forceLatest.add(package); |
| 155 } | 86 } |
| 156 | 87 |
| 157 for (var override in root.dependencyOverrides) { | 88 for (var override in root.dependencyOverrides) { |
| 158 _overrides[override.name] = override; | 89 _overrides[override.name] = override; |
| 159 } | 90 } |
| 160 | 91 |
| 161 // A deeply nested statement that's hard on the formatter. | 92 // A deeply nested statement that's hard on the formatter. |
| 162 isTwoWay = !isEvent && bindings.isWhole && (isCustomTag || | 93 isTwoWay = !isEvent && |
| 163 tag == 'input' && (name == 'value' || name =='checked') || | 94 bindings.isWhole && |
| 164 tag == 'select' && (name == 'selectedindex' || name == 'value') || | 95 (isCustomTag || |
| 165 tag == 'textarea' && name == 'value'); | 96 tag == 'input' && (name == 'value' || name == 'checked') || |
| 97 tag == 'select' && (name == 'selectedindex' || name == 'value') || |
| 98 tag == 'textarea' && name == 'value'); |
| 166 } | 99 } |
| 167 | 100 |
| 168 /// Run the solver. | 101 /// Run the solver. |
| 169 /// | 102 /// |
| 170 /// Completes with a list of specific package versions if successful or an | 103 /// Completes with a list of specific package versions if successful or an |
| 171 /// error if it failed to find a solution. | 104 /// error if it failed to find a solution. |
| 172 Future<SolveResult> solve() { | 105 Future<SolveResult> solve() { |
| 173 var stopwatch = new Stopwatch(); | 106 var stopwatch = new Stopwatch(); |
| 174 | 107 |
| 175 _logParameters(); | 108 _logParameters(); |
| 176 | 109 |
| 177 // Sort the overrides by package name to make sure they're deterministic. | 110 // Sort the overrides by package name to make sure they're deterministic. |
| 178 var overrides = _overrides.values.toList(); | 111 var overrides = _overrides.values.toList(); |
| 179 overrides.sort((a, b) => a.name.compareTo(b.name)); | 112 overrides.sort((a, b) => a.name.compareTo(b.name)); |
| 180 | 113 |
| 181 return newFuture(() { | 114 return newFuture(() { |
| 182 stopwatch.start(); | 115 stopwatch.start(); |
| 183 | 116 |
| 184 // Pre-cache the root package's known pubspec. | 117 // Pre-cache the root package's known pubspec. |
| 185 cache.cache(new PackageId.root(root), root.pubspec); | 118 cache.cache(new PackageId.root(root), root.pubspec); |
| 186 | 119 |
| 187 _validateSdkConstraint(root.pubspec); | 120 _validateSdkConstraint(root.pubspec); |
| 188 return _traverseSolution(); | 121 return _traverseSolution(); |
| 189 }).then((packages) { | 122 }).then((packages) { |
| 190 var pubspecs = new Map.fromIterable( | 123 var pubspecs = new Map.fromIterable(packages, |
| 191 packages, | 124 key: (id) => id.name, value: (id) => cache.getCachedPubspec(id)); |
| 192 key: (id) => id.name, | |
| 193 value: (id) => cache.getCachedPubspec(id)); | |
| 194 | 125 |
| 195 return new SolveResult.success( | 126 return new SolveResult.success(sources, root, lockFile, packages, |
| 196 sources, | 127 overrides, pubspecs, _getAvailableVersions(packages), |
| 197 root, | |
| 198 lockFile, | |
| 199 packages, | |
| 200 overrides, | |
| 201 pubspecs, | |
| 202 _getAvailableVersions(packages), | |
| 203 attemptedSolutions); | 128 attemptedSolutions); |
| 204 }).catchError((error) { | 129 }).catchError((error) { |
| 205 if (error is! SolveFailure) throw error; | 130 if (error is! SolveFailure) throw error; |
| 206 | 131 |
| 207 // Wrap a failure in a result so we can attach some other data. | 132 // Wrap a failure in a result so we can attach some other data. |
| 208 return new SolveResult.failure( | 133 return new SolveResult.failure( |
| 209 sources, | 134 sources, root, lockFile, overrides, error, attemptedSolutions); |
| 210 root, | |
| 211 lockFile, | |
| 212 overrides, | |
| 213 error, | |
| 214 attemptedSolutions); | |
| 215 }).whenComplete(() { | 135 }).whenComplete(() { |
| 216 // Gather some solving metrics. | 136 // Gather some solving metrics. |
| 217 var buffer = new StringBuffer(); | 137 var buffer = new StringBuffer(); |
| 218 buffer.writeln('${runtimeType} took ${stopwatch.elapsed} seconds.'); | 138 buffer.writeln('${runtimeType} took ${stopwatch.elapsed} seconds.'); |
| 219 buffer.writeln(cache.describeResults()); | 139 buffer.writeln(cache.describeResults()); |
| 220 log.solver(buffer); | 140 log.solver(buffer); |
| 221 }); | 141 }); |
| 222 } | 142 } |
| 223 | 143 |
| 224 /// Generates a map containing all of the known available versions for each | 144 /// Generates a map containing all of the known available versions for each |
| (...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 571 if (override != null) return override; | 491 if (override != null) return override; |
| 572 | 492 |
| 573 // Not overridden. | 493 // Not overridden. |
| 574 return dep; | 494 return dep; |
| 575 }).toSet(); | 495 }).toSet(); |
| 576 | 496 |
| 577 // Make sure the package doesn't have any bad dependencies. | 497 // Make sure the package doesn't have any bad dependencies. |
| 578 for (var dep in deps) { | 498 for (var dep in deps) { |
| 579 if (!dep.isRoot && _solver.sources[dep.source] is UnknownSource) { | 499 if (!dep.isRoot && _solver.sources[dep.source] is UnknownSource) { |
| 580 throw new UnknownSourceException( | 500 throw new UnknownSourceException( |
| 581 id.name, | 501 id.name, [new Dependency(id.name, id.version, dep)]); |
| 582 [new Dependency(id.name, id.version, dep)]); | |
| 583 } | 502 } |
| 584 } | 503 } |
| 585 | 504 |
| 586 return _traverseDeps(id, new DependencyQueue(_solver, deps)); | 505 return _traverseDeps(id, new DependencyQueue(_solver, deps)); |
| 587 }).catchError((error) { | 506 }).catchError((error) { |
| 588 if (error is! PackageNotFoundException) throw error; | 507 if (error is! PackageNotFoundException) throw error; |
| 589 | 508 |
| 590 // We can only get here if the lockfile refers to a specific package | 509 // We can only get here if the lockfile refers to a specific package |
| 591 // version that doesn't exist (probably because it was yanked). | 510 // version that doesn't exist (probably because it was yanked). |
| 592 throw new NoVersionException(id.name, null, id.version, []); | 511 throw new NoVersionException(id.name, null, id.version, []); |
| 593 }); | 512 }); |
| 594 } | 513 } |
| 595 | 514 |
| 596 /// Traverses the references that [depender] depends on, stored in [deps]. | 515 /// Traverses the references that [depender] depends on, stored in [deps]. |
| 597 /// | 516 /// |
| 598 /// Desctructively modifies [deps]. Completes to a list of packages if the | 517 /// Desctructively modifies [deps]. Completes to a list of packages if the |
| 599 /// traversal is complete. Completes it to an error if a failure occurred. | 518 /// traversal is complete. Completes it to an error if a failure occurred. |
| 600 /// Otherwise, recurses. | 519 /// Otherwise, recurses. |
| 601 Future<List<PackageId>> _traverseDeps(PackageId depender, | 520 Future<List<PackageId>> _traverseDeps( |
| 602 DependencyQueue deps) { | 521 PackageId depender, DependencyQueue deps) { |
| 603 // Move onto the next package if we've traversed all of these references. | 522 // Move onto the next package if we've traversed all of these references. |
| 604 if (deps.isEmpty) return _traversePackage(); | 523 if (deps.isEmpty) return _traversePackage(); |
| 605 | 524 |
| 606 return resetStack(() { | 525 return resetStack(() { |
| 607 return deps.advance().then((dep) { | 526 return deps.advance().then((dep) { |
| 608 var dependency = new Dependency(depender.name, depender.version, dep); | 527 var dependency = new Dependency(depender.name, depender.version, dep); |
| 609 return _registerDependency(dependency).then((_) { | 528 return _registerDependency(dependency).then((_) { |
| 610 if (dep.name == "barback") return _addImplicitDependencies(); | 529 if (dep.name == "barback") return _addImplicitDependencies(); |
| 611 }); | 530 }); |
| 612 }).then((_) => _traverseDeps(depender, deps)); | 531 }).then((_) => _traverseDeps(depender, deps)); |
| 613 }); | 532 }); |
| 614 } | 533 } |
| 615 | 534 |
| 616 /// Register [dependency]'s constraints on the package it depends on and | 535 /// Register [dependency]'s constraints on the package it depends on and |
| 617 /// enqueues the package for processing if necessary. | 536 /// enqueues the package for processing if necessary. |
| 618 Future _registerDependency(Dependency dependency) { | 537 Future _registerDependency(Dependency dependency) { |
| 619 return new Future.sync(() { | 538 return new Future.sync(() { |
| 620 _validateDependency(dependency); | 539 _validateDependency(dependency); |
| 621 | 540 |
| 622 var dep = dependency.dep; | 541 var dep = dependency.dep; |
| 623 var dependencies = _getDependencies(dep.name); | 542 var dependencies = _getDependencies(dep.name); |
| 624 dependencies.add(dependency); | 543 dependencies.add(dependency); |
| 625 | 544 |
| 626 var constraint = _getConstraint(dep.name); | 545 var constraint = _getConstraint(dep.name); |
| 627 | 546 |
| 628 // See if it's possible for a package to match that constraint. | 547 // See if it's possible for a package to match that constraint. |
| 629 if (constraint.isEmpty) { | 548 if (constraint.isEmpty) { |
| 630 var constraints = dependencies.map( | 549 var constraints = dependencies |
| 631 (dep) => " ${dep.dep.constraint} from ${dep.depender}").join('\n'); | 550 .map((dep) => " ${dep.dep.constraint} from ${dep.depender}") |
| 551 .join('\n'); |
| 632 _solver.logSolve('disjoint constraints on ${dep.name}:\n$constraints'); | 552 _solver.logSolve('disjoint constraints on ${dep.name}:\n$constraints'); |
| 633 throw new DisjointConstraintException(dep.name, dependencies); | 553 throw new DisjointConstraintException(dep.name, dependencies); |
| 634 } | 554 } |
| 635 | 555 |
| 636 var selected = _validateSelected(dep, constraint); | 556 var selected = _validateSelected(dep, constraint); |
| 637 if (selected != null) { | 557 if (selected != null) { |
| 638 // The selected package version is good, so enqueue it to traverse | 558 // The selected package version is good, so enqueue it to traverse |
| 639 // into it. | 559 // into it. |
| 640 _packages.add(selected); | 560 _packages.add(selected); |
| 641 return null; | 561 return null; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 654 /// Gets all versions of [dep] that match the current constraints placed on | 574 /// Gets all versions of [dep] that match the current constraints placed on |
| 655 /// it. | 575 /// it. |
| 656 Future<Iterable<PackageId>> _getAllowedVersions(PackageDep dep) { | 576 Future<Iterable<PackageId>> _getAllowedVersions(PackageDep dep) { |
| 657 var constraint = _getConstraint(dep.name); | 577 var constraint = _getConstraint(dep.name); |
| 658 return _solver.cache.getVersions(dep.toRef()).then((versions) { | 578 return _solver.cache.getVersions(dep.toRef()).then((versions) { |
| 659 var allowed = versions.where((id) => constraint.allows(id.version)); | 579 var allowed = versions.where((id) => constraint.allows(id.version)); |
| 660 | 580 |
| 661 if (allowed.isEmpty) { | 581 if (allowed.isEmpty) { |
| 662 _solver.logSolve('no versions for ${dep.name} match $constraint'); | 582 _solver.logSolve('no versions for ${dep.name} match $constraint'); |
| 663 throw new NoVersionException( | 583 throw new NoVersionException( |
| 664 dep.name, | 584 dep.name, null, constraint, _getDependencies(dep.name)); |
| 665 null, | |
| 666 constraint, | |
| 667 _getDependencies(dep.name)); | |
| 668 } | 585 } |
| 669 | 586 |
| 670 // If we're doing an upgrade on this package, only allow the latest | 587 // If we're doing an upgrade on this package, only allow the latest |
| 671 // version. | 588 // version. |
| 672 if (_solver._forceLatest.contains(dep.name)) allowed = [allowed.first]; | 589 if (_solver._forceLatest.contains(dep.name)) allowed = [allowed.first]; |
| 673 | 590 |
| 674 // Remove the locked version, if any, since that was already handled. | 591 // Remove the locked version, if any, since that was already handled. |
| 675 var locked = _getValidLocked(dep.name); | 592 var locked = _getValidLocked(dep.name); |
| 676 if (locked != null) { | 593 if (locked != null) { |
| 677 allowed = allowed.where((dep) => dep.version != locked.version); | 594 allowed = allowed.where((dep) => dep.version != locked.version); |
| 678 } | 595 } |
| 679 | 596 |
| 680 return allowed; | 597 return allowed; |
| 681 }).catchError((error, stackTrace) { | 598 }).catchError((error, stackTrace) { |
| 682 if (error is PackageNotFoundException) { | 599 if (error is PackageNotFoundException) { |
| 683 // Show the user why the package was being requested. | 600 // Show the user why the package was being requested. |
| 684 throw new DependencyNotFoundException( | 601 throw new DependencyNotFoundException( |
| 685 dep.name, | 602 dep.name, error, _getDependencies(dep.name)); |
| 686 error, | |
| 687 _getDependencies(dep.name)); | |
| 688 } | 603 } |
| 689 | 604 |
| 690 throw error; | 605 throw error; |
| 691 }); | 606 }); |
| 692 } | 607 } |
| 693 | 608 |
| 694 /// Ensures that dependency [dep] from [depender] is consistent with the | 609 /// Ensures that dependency [dep] from [depender] is consistent with the |
| 695 /// other dependencies on the same package. | 610 /// other dependencies on the same package. |
| 696 /// | 611 /// |
| 697 /// Throws a [SolveFailure] exception if not. Only validates sources and | 612 /// Throws a [SolveFailure] exception if not. Only validates sources and |
| 698 /// descriptions, not the version. | 613 /// descriptions, not the version. |
| 699 void _validateDependency(Dependency dependency) { | 614 void _validateDependency(Dependency dependency) { |
| 700 var dep = dependency.dep; | 615 var dep = dependency.dep; |
| 701 | 616 |
| 702 // Make sure the dependencies agree on source and description. | 617 // Make sure the dependencies agree on source and description. |
| 703 var required = _getRequired(dep.name); | 618 var required = _getRequired(dep.name); |
| 704 if (required == null) return; | 619 if (required == null) return; |
| 705 | 620 |
| 706 // Make sure all of the existing sources match the new reference. | 621 // Make sure all of the existing sources match the new reference. |
| 707 if (required.dep.source != dep.source) { | 622 if (required.dep.source != dep.source) { |
| 708 _solver.logSolve( | 623 _solver.logSolve( |
| 709 'source mismatch on ${dep.name}: ${required.dep.source} ' '!= ${dep.so
urce}'); | 624 'source mismatch on ${dep.name}: ${required.dep.source} ' '!= ${dep.so
urce}'); |
| 710 throw new SourceMismatchException(dep.name, [required, dependency]); | 625 throw new SourceMismatchException(dep.name, [required, dependency]); |
| 711 } | 626 } |
| 712 | 627 |
| 713 // Make sure all of the existing descriptions match the new reference. | 628 // Make sure all of the existing descriptions match the new reference. |
| 714 var source = _solver.sources[dep.source]; | 629 var source = _solver.sources[dep.source]; |
| 715 if (!source.descriptionsEqual(dep.description, required.dep.description)) { | 630 if (!source.descriptionsEqual(dep.description, required.dep.description)) { |
| 716 _solver.logSolve( | 631 _solver.logSolve('description mismatch on ${dep.name}: ' |
| 717 'description mismatch on ${dep.name}: ' | 632 '${required.dep.description} != ${dep.description}'); |
| 718 '${required.dep.description} != ${dep.description}'); | |
| 719 throw new DescriptionMismatchException(dep.name, [required, dependency]); | 633 throw new DescriptionMismatchException(dep.name, [required, dependency]); |
| 720 } | 634 } |
| 721 } | 635 } |
| 722 | 636 |
| 723 /// Validates the currently selected package against the new dependency that | 637 /// Validates the currently selected package against the new dependency that |
| 724 /// [dep] and [constraint] place on it. | 638 /// [dep] and [constraint] place on it. |
| 725 /// | 639 /// |
| 726 /// Returns `null` if there is no currently selected package, throws a | 640 /// Returns `null` if there is no currently selected package, throws a |
| 727 /// [SolveFailure] if the new reference it not does not allow the previously | 641 /// [SolveFailure] if the new reference it not does not allow the previously |
| 728 /// selected version, or returns the selected package if successful. | 642 /// selected version, or returns the selected package if successful. |
| 729 PackageId _validateSelected(PackageDep dep, VersionConstraint constraint) { | 643 PackageId _validateSelected(PackageDep dep, VersionConstraint constraint) { |
| 730 var selected = _solver.getSelected(dep.name); | 644 var selected = _solver.getSelected(dep.name); |
| 731 if (selected == null) return null; | 645 if (selected == null) return null; |
| 732 | 646 |
| 733 // Make sure it meets the constraint. | 647 // Make sure it meets the constraint. |
| 734 if (!dep.constraint.allows(selected.version)) { | 648 if (!dep.constraint.allows(selected.version)) { |
| 735 _solver.logSolve('selection $selected does not match $constraint'); | 649 _solver.logSolve('selection $selected does not match $constraint'); |
| 736 throw new NoVersionException( | 650 throw new NoVersionException( |
| 737 dep.name, | 651 dep.name, selected.version, constraint, _getDependencies(dep.name)); |
| 738 selected.version, | |
| 739 constraint, | |
| 740 _getDependencies(dep.name)); | |
| 741 } | 652 } |
| 742 | 653 |
| 743 return selected; | 654 return selected; |
| 744 } | 655 } |
| 745 | 656 |
| 746 /// Register pub's implicit dependencies. | 657 /// Register pub's implicit dependencies. |
| 747 /// | 658 /// |
| 748 /// Pub has an implicit version constraint on barback and various other | 659 /// Pub has an implicit version constraint on barback and various other |
| 749 /// packages used in barback's plugin isolate. | 660 /// packages used in barback's plugin isolate. |
| 750 Future _addImplicitDependencies() { | 661 Future _addImplicitDependencies() { |
| 751 /// Ensure we only add the barback dependency once. | 662 /// Ensure we only add the barback dependency once. |
| 752 if (_getDependencies("barback").length != 1) return new Future.value(); | 663 if (_getDependencies("barback").length != 1) return new Future.value(); |
| 753 | 664 |
| 754 return Future.wait(barback.pubConstraints.keys.map((depName) { | 665 return Future.wait(barback.pubConstraints.keys.map((depName) { |
| 755 var constraint = barback.pubConstraints[depName]; | 666 var constraint = barback.pubConstraints[depName]; |
| 756 _solver.logSolve( | 667 _solver |
| 757 'add implicit $constraint pub dependency on ' '$depName'); | 668 .logSolve('add implicit $constraint pub dependency on ' '$depName'); |
| 758 | 669 |
| 759 var override = _solver._overrides[depName]; | 670 var override = _solver._overrides[depName]; |
| 760 | 671 |
| 761 // Use the same source and description as the dependency override if one | 672 // Use the same source and description as the dependency override if one |
| 762 // exists. This is mainly used by the pkgbuild tests, which use dependency | 673 // exists. This is mainly used by the pkgbuild tests, which use dependency |
| 763 // overrides for all repo packages. | 674 // overrides for all repo packages. |
| 764 var pubDep = override == null ? | 675 var pubDep = override == null |
| 765 new PackageDep(depName, "hosted", constraint, depName) : | 676 ? new PackageDep(depName, "hosted", constraint, depName) |
| 766 override.withConstraint(constraint); | 677 : override.withConstraint(constraint); |
| 767 return _registerDependency( | 678 return _registerDependency( |
| 768 new Dependency("pub itself", Version.none, pubDep)); | 679 new Dependency("pub itself", Version.none, pubDep)); |
| 769 })); | 680 })); |
| 770 } | 681 } |
| 771 | 682 |
| 772 /// Gets the list of dependencies for package [name]. | 683 /// Gets the list of dependencies for package [name]. |
| 773 /// | 684 /// |
| 774 /// Creates an empty list if needed. | 685 /// Creates an empty list if needed. |
| 775 List<Dependency> _getDependencies(String name) { | 686 List<Dependency> _getDependencies(String name) { |
| 776 return _dependencies.putIfAbsent(name, () => <Dependency>[]); | 687 return _dependencies.putIfAbsent(name, () => <Dependency>[]); |
| 777 } | 688 } |
| 778 | 689 |
| 779 /// Gets a "required" reference to the package [name]. | 690 /// Gets a "required" reference to the package [name]. |
| 780 /// | 691 /// |
| 781 /// This is the first non-root dependency on that package. All dependencies | 692 /// This is the first non-root dependency on that package. All dependencies |
| 782 /// on a package must agree on source and description, except for references | 693 /// on a package must agree on source and description, except for references |
| 783 /// to the root package. This will return a reference to that "canonical" | 694 /// to the root package. This will return a reference to that "canonical" |
| 784 /// source and description, or `null` if there is no required reference yet. | 695 /// source and description, or `null` if there is no required reference yet. |
| 785 /// | 696 /// |
| 786 /// This is required because you may have a circular dependency back onto the | 697 /// This is required because you may have a circular dependency back onto the |
| 787 /// root package. That second dependency won't be a root dependency and it's | 698 /// root package. That second dependency won't be a root dependency and it's |
| 788 /// *that* one that other dependencies need to agree on. In other words, you | 699 /// *that* one that other dependencies need to agree on. In other words, you |
| 789 /// can have a bunch of dependencies back onto the root package as long as | 700 /// can have a bunch of dependencies back onto the root package as long as |
| 790 /// they all agree with each other. | 701 /// they all agree with each other. |
| 791 Dependency _getRequired(String name) { | 702 Dependency _getRequired(String name) { |
| 792 return _getDependencies( | 703 return _getDependencies(name).firstWhere((dep) => !dep.dep.isRoot, |
| 793 name).firstWhere((dep) => !dep.dep.isRoot, orElse: () => null); | 704 orElse: () => null); |
| 794 } | 705 } |
| 795 | 706 |
| 796 /// Gets the combined [VersionConstraint] currently being placed on package | 707 /// Gets the combined [VersionConstraint] currently being placed on package |
| 797 /// [name]. | 708 /// [name]. |
| 798 VersionConstraint _getConstraint(String name) { | 709 VersionConstraint _getConstraint(String name) { |
| 799 var constraint = _getDependencies( | 710 var constraint = _getDependencies(name) |
| 800 name).map( | 711 .map((dep) => dep.dep.constraint) |
| 801 (dep) => | 712 .fold(VersionConstraint.any, (a, b) => a.intersect(b)); |
| 802 dep.dep.constraint).fold(VersionConstraint.any, (a, b) => a.inte
rsect(b)); | |
| 803 | 713 |
| 804 return constraint; | 714 return constraint; |
| 805 } | 715 } |
| 806 | 716 |
| 807 /// Gets the package [name] that's currently contained in the lockfile if it | 717 /// Gets the package [name] that's currently contained in the lockfile if it |
| 808 /// meets [constraint] and has the same source and description as other | 718 /// meets [constraint] and has the same source and description as other |
| 809 /// references to that package. | 719 /// references to that package. |
| 810 /// | 720 /// |
| 811 /// Returns `null` otherwise. | 721 /// Returns `null` otherwise. |
| 812 PackageId _getValidLocked(String name) { | 722 PackageId _getValidLocked(String name) { |
| 813 var package = _solver.getLocked(name); | 723 var package = _solver.getLocked(name); |
| 814 if (package == null) return null; | 724 if (package == null) return null; |
| 815 | 725 |
| 816 var constraint = _getConstraint(name); | 726 var constraint = _getConstraint(name); |
| 817 if (!constraint.allows(package.version)) { | 727 if (!constraint.allows(package.version)) { |
| 818 _solver.logSolve('$package is locked but does not match $constraint'); | 728 _solver.logSolve('$package is locked but does not match $constraint'); |
| 819 return null; | 729 return null; |
| 820 } else { | 730 } else { |
| 821 _solver.logSolve('$package is locked'); | 731 _solver.logSolve('$package is locked'); |
| 822 } | 732 } |
| 823 | 733 |
| 824 var required = _getRequired(name); | 734 var required = _getRequired(name); |
| 825 if (required != null) { | 735 if (required != null) { |
| 826 if (package.source != required.dep.source) return null; | 736 if (package.source != required.dep.source) return null; |
| 827 | 737 |
| 828 var source = _solver.sources[package.source]; | 738 var source = _solver.sources[package.source]; |
| 829 if (!source.descriptionsEqual( | 739 if (!source.descriptionsEqual( |
| 830 package.description, | 740 package.description, required.dep.description)) return null; |
| 831 required.dep.description)) return null; | |
| 832 } | 741 } |
| 833 | 742 |
| 834 return package; | 743 return package; |
| 835 } | 744 } |
| 836 | 745 |
| 837 /// Run the dart2js compiler. | 746 /// Run the dart2js compiler. |
| 838 Future _doCompilation(Transform transform) { | 747 Future _doCompilation(Transform transform) { |
| 839 var provider = new _BarbackCompilerProvider(_environment, transform, | 748 var provider = new _BarbackCompilerProvider(_environment, transform, |
| 840 generateSourceMaps: _generateSourceMaps); | 749 generateSourceMaps: _generateSourceMaps); |
| 841 | 750 |
| 842 // Create a "path" to the entrypoint script. The entrypoint may not actually | 751 // Create a "path" to the entrypoint script. The entrypoint may not actually |
| 843 // be on disk, but this gives dart2js a root to resolve relative paths | 752 // be on disk, but this gives dart2js a root to resolve relative paths |
| 844 // against. | 753 // against. |
| 845 var id = transform.primaryInput.id; | 754 var id = transform.primaryInput.id; |
| 846 | 755 |
| 847 var entrypoint = _environment.graph.packages[id.package].path(id.path); | 756 var entrypoint = _environment.graph.packages[id.package].path(id.path); |
| 848 | 757 |
| 849 // Should have more sophisticated error-handling here. Need | 758 // Should have more sophisticated error-handling here. Need |
| 850 // to report compile errors to the user in an easily visible way. Need to | 759 // to report compile errors to the user in an easily visible way. Need to |
| 851 // make sure paths in errors are mapped to the original source path so they | 760 // make sure paths in errors are mapped to the original source path so they |
| 852 // can understand them. | 761 // can understand them. |
| 853 return dart.compile( | 762 return dart.compile(entrypoint, provider, |
| 854 entrypoint, provider, | |
| 855 commandLineOptions: _configCommandLineOptions, | 763 commandLineOptions: _configCommandLineOptions, |
| 856 csp: _configBool('csp'), | 764 csp: _configBool('csp'), |
| 857 checked: _configBool('checked'), | 765 checked: _configBool('checked'), |
| 858 minify: _configBool( | 766 minify: _configBool('minify', |
| 859 'minify', defaultsTo: _settings.mode == BarbackMode.RELEASE), | 767 defaultsTo: _settings.mode == BarbackMode.RELEASE), |
| 860 verbose: _configBool('verbose'), | 768 verbose: _configBool('verbose'), |
| 861 environment: _configEnvironment, | 769 environment: _configEnvironment, |
| 862 packageRoot: _environment.rootPackage.path("packages"), | 770 packageRoot: _environment.rootPackage.path("packages"), |
| 863 analyzeAll: _configBool('analyzeAll'), | 771 analyzeAll: _configBool('analyzeAll'), |
| 864 suppressWarnings: _configBool('suppressWarnings'), | 772 suppressWarnings: _configBool('suppressWarnings'), |
| 865 suppressHints: _configBool('suppressHints'), | 773 suppressHints: _configBool('suppressHints'), |
| 866 suppressPackageWarnings: _configBool( | 774 suppressPackageWarnings: _configBool('suppressPackageWarnings', |
| 867 'suppressPackageWarnings', defaultsTo: true), | 775 defaultsTo: true), |
| 868 terse: _configBool('terse'), | 776 terse: _configBool('terse'), |
| 869 includeSourceMapUrls: _settings.mode != BarbackMode.RELEASE); | 777 includeSourceMapUrls: _settings.mode != BarbackMode.RELEASE); |
| 870 } | 778 } |
| 871 } | 779 } |
| 872 | 780 |
| 873 /// Ensures that if [pubspec] has an SDK constraint, then it is compatible | 781 /// Ensures that if [pubspec] has an SDK constraint, then it is compatible |
| 874 /// with the current SDK. | 782 /// with the current SDK. |
| 875 /// | 783 /// |
| 876 /// Throws a [SolveFailure] if not. | 784 /// Throws a [SolveFailure] if not. |
| 877 void _validateSdkConstraint(Pubspec pubspec) { | 785 void _validateSdkConstraint(Pubspec pubspec) { |
| 878 if (pubspec.environment.sdkVersion.allows(sdk.version)) return; | 786 if (pubspec.environment.sdkVersion.allows(sdk.version)) return; |
| 879 | 787 |
| 880 throw new BadSdkVersionException( | 788 throw new BadSdkVersionException(pubspec.name, |
| 881 pubspec.name, | |
| 882 'Package ${pubspec.name} requires SDK version ' | 789 'Package ${pubspec.name} requires SDK version ' |
| 883 '${pubspec.environment.sdkVersion} but the current SDK is ' '${sdk.ver
sion}.'); | 790 '${pubspec.environment.sdkVersion} but the current SDK is ' '${sdk.version
}.'); |
| 884 } | 791 } |
| 885 """; | |
| OLD | NEW |