Create a "PackageRef" class that defines a versionless package reference.

R=nweiz@google.com

Review URL: https://codereview.chromium.org//13952013

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@22187 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/sdk/lib/_internal/pub/lib/src/package.dart b/sdk/lib/_internal/pub/lib/src/package.dart
index ce1ad35..62a2a98 100644
--- a/sdk/lib/_internal/pub/lib/src/package.dart
+++ b/sdk/lib/_internal/pub/lib/src/package.dart
@@ -36,7 +36,7 @@
 
   /// The ids of the packages that this package depends on. This is what is
   /// specified in the pubspec when this package depends on another.
-  List<PackageRef> get dependencies => pubspec.dependencies;
+  List<PackageDep> get dependencies => pubspec.dependencies;
 
   /// Returns the path to the README file at the root of the entrypoint, or null
   /// if no README file is found. If multiple READMEs are found, this uses the
@@ -77,54 +77,107 @@
   String toString() => '$name $version ($dir)';
 }
 
-/// An unambiguous resolved reference to a package. A package ID contains enough
-/// information to correctly install the package.
-///
-/// Note that it's possible for multiple distinct package IDs to point to
-/// different directories that happen to contain identical packages. For
-/// example, the same package may be available from multiple sources. As far as
-/// Pub is concerned, those packages are different.
-class PackageId implements Comparable<PackageId> {
+/// This is the private base class of [PackageRef], [PackageID], and
+/// [PackageDep]. It contains functionality and state that those classes share
+/// but is private so that from outside of this library, there is no type
+/// relationship between those three types.
+class _PackageName {
+  _PackageName(this.name, this.source, this.description);
+
   /// The name of the package being identified.
   final String name;
 
   /// The [Source] used to look up this package given its [description]. If
-  /// this is a root package ID, this will be `null`.
+  /// this is a root package, this will be `null`.
   final Source source;
 
-  /// The package's version.
-  final Version version;
-
   /// The metadata used by the package's [source] to identify and locate it. It
   /// contains whatever [Source]-specific data it needs to be able to install
   /// the package. For example, the description of a git sourced package might
   /// by the URL "git://github.com/dart/uilib.git".
   final description;
 
-  PackageId(this.name, this.source, this.version, this.description);
-
-  /// Creates an ID for the given root package.
-  PackageId.root(Package package)
-      : name = package.name,
-        source = null,
-        version = package.version,
-        description = package.name;
-
-  /// Whether this ID identifies the root package.
+  /// Whether this package is the root package.
   bool get isRoot => source == null;
 
-  int get hashCode => name.hashCode ^ source.hashCode ^ version.hashCode;
-
   /// Gets the directory where this package is or would be found in the
   /// [SystemCache].
   Future<String> get systemCacheDirectory => source.systemCacheDirectory(this);
 
+  String toString() {
+    if (isRoot) return "$name (root)";
+    if (source.isDefault) return name;
+    return "$name from $source";
+  }
+
+  /// Returns a [PackageRef] with this one's [name], [source], and
+  /// [description].
+  PackageRef toRef() => new PackageRef(name, source, description);
+
+  /// Returns a [PackageId] for this package with the given concrete version.
+  PackageId atVersion(Version version) =>
+    new PackageId(name, source, version, description);
+
+  /// Returns `true` if this package's description matches [other]'s.
+  bool descriptionEquals(PackageDep other) {
+    return source.descriptionsEqual(description, other.description);
+  }
+}
+
+/// A reference to a [Package], but not any particular version(s) of it.
+class PackageRef extends _PackageName {
+  PackageRef(String name, Source source, description)
+      : super(name, source, description);
+
+  int get hashCode => name.hashCode ^ source.hashCode;
+
   bool operator ==(other) {
-    if (other is! PackageId) return false;
-    // TODO(rnystrom): We're assuming here the name/version/source tuple is
-    // enough to uniquely identify the package and that we don't need to delve
-    // into the description.
-    return other.name == name &&
+    // TODO(rnystrom): We're assuming here that we don't need to delve into the
+    // description.
+    return other is PackageRef &&
+           other.name == name &&
+           other.source == source;
+  }
+
+  /// Gets the list of ids of all versions of the package that are described by
+  /// this reference.
+  Future<List<PackageId>> getVersions() {
+    if (isRoot) {
+      throw new StateError("Cannot get versions for the root package.");
+    }
+
+    return source.getVersions(name, description).then((versions) {
+      return versions.map((version) => atVersion(version)).toList();
+    });
+  }
+}
+
+/// A reference to a specific version of a package. A package ID contains
+/// enough information to correctly install the package.
+///
+/// Note that it's possible for multiple distinct package IDs to point to
+/// different packages that have identical contents. For example, the same
+/// package may be available from multiple sources. As far as Pub is concerned,
+/// those packages are different.
+class PackageId extends _PackageName {
+  /// The package's version.
+  final Version version;
+
+  PackageId(String name, Source source, this.version, description)
+      : super(name, source, description);
+
+  /// Creates an ID for the given root package.
+  PackageId.root(Package package)
+      : version = package.version,
+        super(package.name, null, package.name);
+
+  int get hashCode => name.hashCode ^ source.hashCode ^ version.hashCode;
+
+  bool operator ==(other) {
+    // TODO(rnystrom): We're assuming here that we don't need to delve into the
+    // description.
+    return other is PackageId &&
+           other.name == name &&
            other.source == source &&
            other.version == version;
   }
@@ -135,78 +188,35 @@
     return "$name $version from $source";
   }
 
-  int compareTo(PackageId other) {
-    var sourceComp = source.name.compareTo(other.source.name);
-    if (sourceComp != 0) return sourceComp;
-
-    var nameComp = name.compareTo(other.name);
-    if (nameComp != 0) return nameComp;
-
-    return version.compareTo(other.version);
-  }
-
   /// Returns the pubspec for this package.
   Future<Pubspec> describe() => source.systemCache.describe(this);
 
-  /// Returns a future that completes to the resovled [PackageId] for this id.
+  /// Returns a future that completes to the resolved [PackageId] for this id.
   Future<PackageId> get resolved => source.resolveId(this);
-
-  /// Returns a [PackageRef] that references this package and constrains its
-  /// version to exactly match [version].
-  PackageRef toRef() {
-    return new PackageRef(name, source, version, description);
-  }
-
-  /// Returns `true` if this id's description matches [other]'s.
-  bool descriptionEquals(PackageRef other) {
-    return source.descriptionsEqual(description, other.description);
-  }
 }
 
-/// A reference to a package. Unlike a [PackageId], a PackageRef may not
-/// unambiguously refer to a single package. It may describe a range of allowed
-/// packages.
-class PackageRef {
-  /// The name of the package being identified.
-  final String name;
-
-  /// The [Source] used to look up the package. If this refers to a root
-  /// package, this will be `null`.
-  final Source source;
-
+/// A reference to a constrained range of versions of one package.
+class PackageDep extends _PackageName {
   /// The allowed package versions.
   final VersionConstraint constraint;
 
-  /// The metadata used to identify the package being referenced. The
-  /// interpretation of this will vary based on the [source].
-  final description;
-
-  PackageRef(this.name, this.source, this.constraint, this.description);
-
-  // TODO(rnystrom): Remove this if the old version solver is removed.
-  /// Creates a reference to the given root package.
-  PackageRef.root(Package package)
-      : name = package.name,
-        source = null,
-        constraint = package.version,
-        description = package.name;
-
-  /// Whether this refers to the root package.
-  bool get isRoot => source == null;
+  PackageDep(String name, Source source, this.constraint, description)
+      : super(name, source, description);
 
   String toString() {
     if (isRoot) return "$name $constraint (root)";
     return "$name $constraint from $source ($description)";
   }
 
-  /// Returns a [PackageId] generated from this [PackageRef] with the given
-  /// concrete version.
-  PackageId atVersion(Version version) =>
-    new PackageId(name, source, version, description);
+  int get hashCode => name.hashCode ^ source.hashCode;
 
-  /// Returns `true` if this reference's description matches [other]'s.
-  bool descriptionEquals(PackageRef other) {
-    return source.descriptionsEqual(description, other.description);
+  bool operator ==(other) {
+    // TODO(rnystrom): We're assuming here that we don't need to delve into the
+    // description.
+    return other is PackageDep &&
+           other.name == name &&
+           other.source == source &&
+           other.constraint == constraint;
   }
 }
 
diff --git a/sdk/lib/_internal/pub/lib/src/path_source.dart b/sdk/lib/_internal/pub/lib/src/path_source.dart
index c103c1b..72d4065 100644
--- a/sdk/lib/_internal/pub/lib/src/path_source.dart
+++ b/sdk/lib/_internal/pub/lib/src/path_source.dart
@@ -18,7 +18,6 @@
 import 'source.dart';
 import 'utils.dart';
 
-// TODO(rnystrom): Support relative paths. (See comment in _validatePath().)
 /// A package [Source] that installs packages from a given local file path.
 class PathSource extends Source {
   final name = 'path';
diff --git a/sdk/lib/_internal/pub/lib/src/pubspec.dart b/sdk/lib/_internal/pub/lib/src/pubspec.dart
index a5c67ac..69dc880 100644
--- a/sdk/lib/_internal/pub/lib/src/pubspec.dart
+++ b/sdk/lib/_internal/pub/lib/src/pubspec.dart
@@ -23,10 +23,10 @@
   final Version version;
 
   /// The packages this package depends on.
-  final List<PackageRef> dependencies;
+  final List<PackageDep> dependencies;
 
   /// The packages this package depends on when it is the root package.
-  final List<PackageRef> devDependencies;
+  final List<PackageDep> devDependencies;
 
   /// The environment-related metadata.
   final PubspecEnvironment environment;
@@ -65,8 +65,8 @@
   Pubspec.empty()
     : name = null,
       version = Version.none,
-      dependencies = <PackageRef>[],
-      devDependencies = <PackageRef>[],
+      dependencies = <PackageDep>[],
+      devDependencies = <PackageDep>[],
       environment = new PubspecEnvironment(),
       fields = {};
 
@@ -233,9 +233,9 @@
   }
 }
 
-List<PackageRef> _parseDependencies(String pubspecPath, SourceRegistry sources,
+List<PackageDep> _parseDependencies(String pubspecPath, SourceRegistry sources,
     yaml) {
-  var dependencies = <PackageRef>[];
+  var dependencies = <PackageDep>[];
 
   // Allow an empty dependencies key.
   if (yaml == null) return dependencies;
@@ -283,7 +283,7 @@
     description = source.parseDescription(pubspecPath, description,
         fromLockFile: false);
 
-    dependencies.add(new PackageRef(
+    dependencies.add(new PackageDep(
         name, source, versionConstraint, description));
   });
 
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 a5e3e3c..c5580a9 100644
--- a/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
+++ b/sdk/lib/_internal/pub/lib/src/solver/backtracking_solver.dart
@@ -347,33 +347,32 @@
     return _solver.cache.getPubspec(id).then((pubspec) {
       _validateSdkConstraint(pubspec);
 
-      var refs = pubspec.dependencies.toList();
+      var deps = pubspec.dependencies.toList();
 
       // Include dev dependencies of the root package.
-      if (id.isRoot) refs.addAll(pubspec.devDependencies);
+      if (id.isRoot) deps.addAll(pubspec.devDependencies);
 
-      // Given a package ref, returns a future that completes to a pair of the
-      // ref and the number of versions available for it.
-      getNumVersions(PackageRef ref) {
+      // Given a package dep, returns a future that completes to a pair of the
+      // dep and the number of versions available for it.
+      getNumVersions(PackageDep dep) {
         // There is only ever one version of the root package.
-        if (ref.isRoot) {
-          return new Future.value(new Pair<PackageRef, int>(ref, 1));
+        if (dep.isRoot) {
+          return new Future.value(new Pair<PackageDep, int>(dep, 1));
         }
 
-        return _solver.cache.getVersions(ref.name, ref.source, ref.description)
-            .then((versions) {
-          return new Pair<PackageRef, int>(ref, versions.length);
+        return _solver.cache.getVersions(dep.toRef()).then((versions) {
+          return new Pair<PackageDep, int>(dep, versions.length);
         }).catchError((error) {
           // If it fails for any reason, just treat that as no versions. This
           // will sort this reference higher so that we can traverse into it
           // and report the error more properly.
-          log.solver("Could not get versions for $ref:\n$error\n\n"
+          log.solver("Could not get versions for $dep:\n$error\n\n"
               "${getAttachedStackTrace(error)}");
-          return new Pair<PackageRef, int>(ref, 0);
+          return new Pair<PackageDep, int>(dep, 0);
         });
       }
 
-      return Future.wait(refs.map(getNumVersions)).then((pairs) {
+      return Future.wait(deps.map(getNumVersions)).then((pairs) {
         // Future.wait() returns an immutable list, so make a copy.
         pairs = pairs.toList();
 
@@ -393,8 +392,8 @@
           return a.first.name.compareTo(b.first.name);
         });
 
-        var queue = new Queue<PackageRef>.from(pairs.map((pair) => pair.first));
-        return _traverseRefs(id.name, queue);
+        var queue = new Queue<PackageDep>.from(pairs.map((pair) => pair.first));
+        return _traverseDeps(id.name, queue);
       });
     });
   }
@@ -403,135 +402,134 @@
   /// Desctructively modifies [refs]. Completes to a list of packages if the
   /// traversal is complete. Completes it to an error if a failure occurred.
   /// Otherwise, recurses.
-  Future<List<PackageId>> _traverseRefs(String depender,
-      Queue<PackageRef> refs) {
+  Future<List<PackageId>> _traverseDeps(String depender,
+      Queue<PackageDep> deps) {
     // Move onto the next package if we've traversed all of these references.
-    if (refs.isEmpty) return _traversePackage();
+    if (deps.isEmpty) return _traversePackage();
 
     // Pump the event loop to flatten the stack trace and workaround #9583.
     // If that bug is fixed, this can be Future.sync() instead.
     return new Future(() {
-      var ref = refs.removeFirst();
+      var dep = deps.removeFirst();
 
-      _validateDependency(ref, depender);
-      var constraint = _addConstraint(ref, depender);
+      _validateDependency(dep, depender);
+      var constraint = _addConstraint(dep, depender);
 
-      var selected = _validateSelected(ref, constraint);
+      var selected = _validateSelected(dep, constraint);
       if (selected != null) {
         // The selected package version is good, so enqueue it to traverse into
         // it.
         _packages.add(selected);
-        return _traverseRefs(depender, refs);
+        return _traverseDeps(depender, deps);
       }
 
       // We haven't selected a version. Get all of the versions that match the
       // constraints we currently have for this package and add them to the
       // set of solutions to try.
-      return _selectPackage(ref, constraint).then(
-          (_) => _traverseRefs(depender, refs));
+      return _selectPackage(dep, constraint).then(
+          (_) => _traverseDeps(depender, deps));
     });
   }
 
-  /// Ensures that dependency [ref] from [depender] is consistent with the
+  /// Ensures that dependency [dep] from [depender] is consistent with the
   /// other dependencies on the same package. Throws a [SolverFailure]
   /// exception if not. Only validates sources and descriptions, not the
   /// version.
-  void _validateDependency(PackageRef ref, String depender) {
+  void _validateDependency(PackageDep dep, String depender) {
     // Make sure the dependencies agree on source and description.
-    var required = _getRequired(ref.name);
+    var required = _getRequired(dep.name);
     if (required == null) return;
 
     // Make sure all of the existing sources match the new reference.
-    if (required.ref.source.name != ref.source.name) {
-      _solver.logSolve('source mismatch on ${ref.name}: ${required.ref.source} '
-                       '!= ${ref.source}');
-      throw new SourceMismatchException(ref.name,
-          [required, new Dependency(depender, ref)]);
+    if (required.dep.source.name != dep.source.name) {
+      _solver.logSolve('source mismatch on ${dep.name}: ${required.dep.source} '
+                       '!= ${dep.source}');
+      throw new SourceMismatchException(dep.name,
+          [required, new Dependency(depender, dep)]);
     }
 
     // Make sure all of the existing descriptions match the new reference.
-    if (!ref.descriptionEquals(required.ref)) {
-      _solver.logSolve('description mismatch on ${ref.name}: '
-                       '${required.ref.description} != ${ref.description}');
-      throw new DescriptionMismatchException(ref.name,
-          [required, new Dependency(depender, ref)]);
+    if (!dep.descriptionEquals(required.dep)) {
+      _solver.logSolve('description mismatch on ${dep.name}: '
+                       '${required.dep.description} != ${dep.description}');
+      throw new DescriptionMismatchException(dep.name,
+          [required, new Dependency(depender, dep)]);
     }
   }
 
-  /// Adds the version constraint that [depender] places on [ref] to the
-  /// overall constraint that all shared dependencies place on [ref]. Throws a
+  /// Adds the version constraint that [depender] places on [dep] to the
+  /// overall constraint that all shared dependencies place on [dep]. Throws a
   /// [SolverFailure] if that results in an unsolvable constraints.
   ///
   /// Returns the combined [VersionConstraint] that all dependers place on the
   /// package.
-  VersionConstraint _addConstraint(PackageRef ref, String depender) {
+  VersionConstraint _addConstraint(PackageDep dep, String depender) {
     // Add the dependency.
-    var dependencies = _getDependencies(ref.name);
-    dependencies.add(new Dependency(depender, ref));
+    var dependencies = _getDependencies(dep.name);
+    dependencies.add(new Dependency(depender, dep));
 
     // Determine the overall version constraint.
     var constraint = dependencies
-        .map((dep) => dep.ref.constraint)
+        .map((dep) => dep.dep.constraint)
         .fold(VersionConstraint.any, (a, b) => a.intersect(b));
 
     // See if it's possible for a package to match that constraint.
     if (constraint.isEmpty) {
-      _solver.logSolve('disjoint constraints on ${ref.name}');
-      throw new DisjointConstraintException(ref.name, dependencies);
+      _solver.logSolve('disjoint constraints on ${dep.name}');
+      throw new DisjointConstraintException(dep.name, dependencies);
     }
 
     return constraint;
   }
 
   /// Validates the currently selected package against the new dependency that
-  /// [ref] and [constraint] place on it. Returns `null` if there is no
+  /// [dep] and [constraint] place on it. Returns `null` if there is no
   /// currently selected package, throws a [SolverFailure] if the new reference
   /// it not does not allow the previously selected version, or returns the
   /// selected package if successful.
-  PackageId _validateSelected(PackageRef ref, VersionConstraint constraint) {
-    var selected = _solver.getSelected(ref.name);
+  PackageId _validateSelected(PackageDep dep, VersionConstraint constraint) {
+    var selected = _solver.getSelected(dep.name);
     if (selected == null) return null;
 
     // Make sure it meets the constraint.
-    if (!ref.constraint.allows(selected.version)) {
+    if (!dep.constraint.allows(selected.version)) {
       _solver.logSolve('selection $selected does not match $constraint');
-      throw new NoVersionException(ref.name, constraint,
-                                   _getDependencies(ref.name));
+      throw new NoVersionException(dep.name, constraint,
+                                   _getDependencies(dep.name));
     }
 
     return selected;
   }
 
-  /// Tries to select a package that matches [ref] and [constraint]. Updates
+  /// Tries to select a package that matches [dep] and [constraint]. Updates
   /// the solver state so that we can backtrack from this decision if it turns
   /// out wrong, but continues traversing with the new selection.
   ///
   /// Returns a future that completes with a [SolverFailure] if a version
   /// could not be selected or that completes successfully if a package was
   /// selected and traversing should continue.
-  Future _selectPackage(PackageRef ref, VersionConstraint constraint) {
-    return _solver.cache.getVersions(ref.name, ref.source, ref.description)
-        .then((versions) {
+  Future _selectPackage(PackageDep dep, VersionConstraint constraint) {
+    return _solver.cache.getVersions(dep.toRef()).then((versions) {
       var allowed = versions.where((id) => constraint.allows(id.version));
 
       // See if it's in the lockfile. If so, try that version first. If the
       // locked version doesn't match our constraint, just ignore it.
-      var locked = _getValidLocked(ref.name, constraint);
+      var locked = _getValidLocked(dep.name, constraint);
       if (locked != null) {
-        allowed = allowed.where((ref) => ref.version != locked.version)
+        allowed = allowed.where((dep) => dep.version != locked.version)
             .toList();
         allowed.insert(0, locked);
       }
 
       if (allowed.isEmpty) {
-        _solver.logSolve('no versions for ${ref.name} match $constraint');
-        throw new NoVersionException(ref.name, constraint,
-                                     _getDependencies(ref.name));
+        _solver.logSolve('no versions for ${dep.name} match $constraint');
+        throw new NoVersionException(dep.name, constraint,
+                                     _getDependencies(dep.name));
       }
 
       // If we're doing an upgrade on this package, only allow the latest
       // version.
-      if (_solver._forceLatest.contains(ref.name)) allowed = [allowed.first];
+      if (_solver._forceLatest.contains(dep.name)) allowed = [allowed.first];
 
       // Try the first package in the allowed set and keep track of the list of
       // other possible versions in case that fails.
@@ -558,7 +556,7 @@
   /// they all agree with each other.
   Dependency _getRequired(String name) {
     return _getDependencies(name)
-        .firstWhere((dep) => !dep.ref.isRoot, orElse: () => null);
+        .firstWhere((dep) => !dep.dep.isRoot, orElse: () => null);
   }
 
   /// Gets the package [name] that's currently contained in the lockfile if it
@@ -577,8 +575,8 @@
 
     var required = _getRequired(name);
     if (required != null) {
-      if (package.source.name != required.ref.source.name) return null;
-      if (!package.descriptionEquals(required.ref)) return null;
+      if (package.source.name != required.dep.source.name) return null;
+      if (!package.descriptionEquals(required.dep)) return null;
     }
 
     return package;
diff --git a/sdk/lib/_internal/pub/lib/src/solver/version_solver.dart b/sdk/lib/_internal/pub/lib/src/solver/version_solver.dart
index a816262..efd9e85 100644
--- a/sdk/lib/_internal/pub/lib/src/solver/version_solver.dart
+++ b/sdk/lib/_internal/pub/lib/src/solver/version_solver.dart
@@ -70,7 +70,7 @@
 /// Used to avoid requesting the same pubspec from the server repeatedly.
 class PubspecCache {
   final SourceRegistry _sources;
-  final _versions = new Map<PackageId, List<PackageId>>();
+  final _versions = new Map<PackageRef, List<PackageId>>();
   final _pubspecs = new Map<PackageId, Pubspec>();
 
   /// The number of times a version list was requested and it wasn't cached and
@@ -119,32 +119,21 @@
   Pubspec getCachedPubspec(PackageId id) => _pubspecs[id];
 
   /// Gets the list of versions for [package] in descending order.
-  Future<List<PackageId>> getVersions(String package, Source source,
-      description) {
-    // Create a fake ID to use as a key.
-    // TODO(rnystrom): Create a separate type for (name, source, description)
-    // without a version.
-    var id = new PackageId(package, source, Version.none, description);
-
+  Future<List<PackageId>> getVersions(PackageRef package) {
     // See if we have it cached.
-    var versions = _versions[id];
+    var versions = _versions[package];
     if (versions != null) {
       versionCacheHits++;
       return new Future.value(versions);
     }
 
     versionCacheMisses++;
-    return source.getVersions(package, description).then((versions) {
-      var ids = versions
-          .map((version) => new PackageId(package, source, version,
-              description))
-          .toList();
-
+    return package.getVersions().then((ids) {
       // Sort by descending version so we try newer versions first.
       ids.sort((a, b) => b.version.compareTo(a.version));
 
       log.solver('requested $package version list');
-      _versions[id] = ids;
+      _versions[package] = ids;
       return ids;
     });
   }
@@ -155,12 +144,12 @@
   /// The name of the package that has this dependency.
   final String depender;
 
-  /// The referenced dependent package.
-  final PackageRef ref;
+  /// The package being depended on.
+  final PackageDep dep;
 
-  Dependency(this.depender, this.ref);
+  Dependency(this.depender, this.dep);
 
-  String toString() => '$depender -> $ref';
+  String toString() => '$depender -> $dep';
 }
 
 /// Base class for all failures that can occur while trying to resolve versions.
@@ -180,10 +169,10 @@
   /// passed, it will be called for each dependency and the result will be
   /// written next to the dependency.
   void writeDependencies(StringBuffer buffer,
-      [String describe(PackageRef ref)]) {
+      [String describe(PackageDep dep)]) {
     var map = {};
     for (var dep in dependencies) {
-      map[dep.depender] = dep.ref;
+      map[dep.depender] = dep.dep;
     }
 
     var names = map.keys.toList();
@@ -207,7 +196,7 @@
 
     var map = {};
     for (var dep in dependencies) {
-      map[dep.depender] = dep.ref;
+      map[dep.depender] = dep.dep;
     }
 
     var names = map.keys.toList();
@@ -224,9 +213,9 @@
   String get _message;
 
   /// Describes a dependencie's reference in the output message. Override this
-  /// to highlight which aspect of [ref] led to the failure.
-  String _describeDependency(PackageRef ref) =>
-      "depends on version ${ref.constraint}";
+  /// to highlight which aspect of [dep] led to the failure.
+  String _describeDependency(PackageDep dep) =>
+      "depends on version ${dep.constraint}";
 }
 
 /// Exception thrown when the [VersionSolver] fails to find a solution after a
@@ -288,8 +277,8 @@
 
   String get _message => "Incompatible dependencies on '$package'";
 
-  String _describeDependency(PackageRef ref) =>
-      "depends on it from source ${ref.source}";
+  String _describeDependency(PackageDep dep) =>
+      "depends on it from source ${dep.source}";
 }
 
 /// Exception thrown when two packages with the same name and source but
@@ -301,8 +290,8 @@
 
   String get _message => "Incompatible dependencies on '$package'";
 
-  String _describeDependency(PackageRef ref) {
+  String _describeDependency(PackageDep dep) {
     // TODO(nweiz): Dump descriptions to YAML when that's supported.
-    return "depends on it with description ${json.stringify(ref.description)}";
+    return "depends on it with description ${json.stringify(dep.description)}";
   }
 }
diff --git a/sdk/lib/_internal/pub/lib/src/source.dart b/sdk/lib/_internal/pub/lib/src/source.dart
index ba2afa4..2486e78 100644
--- a/sdk/lib/_internal/pub/lib/src/source.dart
+++ b/sdk/lib/_internal/pub/lib/src/source.dart
@@ -209,7 +209,7 @@
   ///
   /// By default, this just returns [id].
   Future<PackageId> resolveId(PackageId id) => new Future.value(id);
-  
+
   /// Returns the [Package]s that have been installed in the system cache.
   List<Package> getCachedPackages() {
     if (shouldCache) {
diff --git a/sdk/lib/_internal/pub/lib/src/validator/dependency.dart b/sdk/lib/_internal/pub/lib/src/validator/dependency.dart
index 711e82d..c147f7b 100644
--- a/sdk/lib/_internal/pub/lib/src/validator/dependency.dart
+++ b/sdk/lib/_internal/pub/lib/src/validator/dependency.dart
@@ -41,9 +41,9 @@
   }
 
   /// Warn that dependencies should use the hosted source.
-  Future _warnAboutSource(PackageRef ref) {
+  Future _warnAboutSource(PackageDep dep) {
     return entrypoint.cache.sources['hosted']
-        .getVersions(ref.name, ref.name)
+        .getVersions(dep.name, dep.name)
         .catchError((e) => <Version>[])
         .then((versions) {
       var constraint;
@@ -51,23 +51,23 @@
       if (primary != null) {
         constraint = _constraintForVersion(primary);
       } else {
-        constraint = ref.constraint.toString();
-        if (!ref.constraint.isAny && ref.constraint is! Version) {
+        constraint = dep.constraint.toString();
+        if (!dep.constraint.isAny && dep.constraint is! Version) {
           constraint = '"$constraint"';
         }
       }
 
       // Path sources are errors. Other sources are just warnings.
       var messages = warnings;
-      if (ref.source is PathSource) {
+      if (dep.source is PathSource) {
         messages = errors;
       }
 
-      messages.add('Don\'t depend on "${ref.name}" from the ${ref.source.name} '
+      messages.add('Don\'t depend on "${dep.name}" from the ${dep.source.name} '
               'source. Use the hosted source instead. For example:\n'
           '\n'
           'dependencies:\n'
-          '  ${ref.name}: $constraint\n'
+          '  ${dep.name}: $constraint\n'
           '\n'
           'Using the hosted source ensures that everyone can download your '
               'package\'s dependencies along with your package.');
@@ -75,20 +75,20 @@
   }
 
   /// Warn that dependencies should have version constraints.
-  void _warnAboutConstraint(PackageRef ref) {
+  void _warnAboutConstraint(PackageDep dep) {
     var lockFile = entrypoint.loadLockFile();
-    var message = 'Your dependency on "${ref.name}" should have a version '
+    var message = 'Your dependency on "${dep.name}" should have a version '
         'constraint.';
-    var locked = lockFile.packages[ref.name];
+    var locked = lockFile.packages[dep.name];
     if (locked != null) {
       message = '$message For example:\n'
         '\n'
         'dependencies:\n'
-        '  ${ref.name}: ${_constraintForVersion(locked.version)}\n';
+        '  ${dep.name}: ${_constraintForVersion(locked.version)}\n';
     }
     warnings.add("$message\n"
         "Without a constraint, you're promising to support all future "
-        "versions of ${ref.name}.");
+        "versions of ${dep.name}.");
   }
 
   /// Returns the suggested version constraint for a dependency that was tested
diff --git a/sdk/lib/_internal/pub/test/version_solver_test.dart b/sdk/lib/_internal/pub/test/version_solver_test.dart
index 380803a..6c2cb22 100644
--- a/sdk/lib/_internal/pub/test/version_solver_test.dart
+++ b/sdk/lib/_internal/pub/test/version_solver_test.dart
@@ -940,8 +940,8 @@
   var sdkConstraint = null;
 
   // Build the pubspec dependencies.
-  var dependencies = <PackageRef>[];
-  var devDependencies = <PackageRef>[];
+  var dependencies = <PackageDep>[];
+  var devDependencies = <PackageDep>[];
 
   dependencyStrings.forEach((name, constraint) {
     parseSource(name, (isDev, name, source) {
@@ -953,12 +953,12 @@
         return;
       }
 
-      var ref = new PackageRef(packageName, source, constraint, name);
+      var dep = new PackageDep(packageName, source, constraint, name);
 
       if (isDev) {
-        devDependencies.add(ref);
+        devDependencies.add(dep);
       } else {
-        dependencies.add(ref);
+        dependencies.add(dep);
       }
     });
   });