Replace DexEncodedMember.getKey() by toReference()

This CL also renames Descriptor to DexMember for consistency with DexEncodedMember.

Change-Id: I9c754bd1b955043f35aa659edc23c249b3e758a1
diff --git a/src/main/java/com/android/tools/r8/dex/DexParser.java b/src/main/java/com/android/tools/r8/dex/DexParser.java
index c69d8e0..723d094 100644
--- a/src/main/java/com/android/tools/r8/dex/DexParser.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -14,7 +14,6 @@
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.graph.ClassAccessFlags;
 import com.android.tools.r8.graph.ClassKind;
-import com.android.tools.r8.graph.Descriptor;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationElement;
 import com.android.tools.r8.graph.DexAnnotationSet;
@@ -33,6 +32,7 @@
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexItem;
 import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.DexMember;
 import com.android.tools.r8.graph.DexMemberAnnotation;
 import com.android.tools.r8.graph.DexMemberAnnotation.DexFieldAnnotation;
 import com.android.tools.r8.graph.DexMemberAnnotation.DexMethodAnnotation;
@@ -570,7 +570,7 @@
     return new DexDebugInfo(start, parameters, events.toArray(DexDebugEvent.EMPTY_ARRAY));
   }
 
-  private static class MemberAnnotationIterator<S extends Descriptor<?, S>, T extends DexItem> {
+  private static class MemberAnnotationIterator<S extends DexMember<?, S>, T extends DexItem> {
 
     private int index = 0;
     private final DexMemberAnnotation<S, T>[] annotations;
@@ -1189,7 +1189,7 @@
     MethodHandleType type = MethodHandleType.getKind(dexReader.getUshort());
     dexReader.getUshort(); // unused
     int indexFieldOrMethod = dexReader.getUshort();
-    Descriptor<? extends DexItem, ? extends Descriptor<?, ?>> fieldOrMethod;
+    DexMember<? extends DexItem, ? extends DexMember<?, ?>> fieldOrMethod;
     switch (type) {
       case INSTANCE_GET:
       case INSTANCE_PUT:
diff --git a/src/main/java/com/android/tools/r8/dex/FileWriter.java b/src/main/java/com/android/tools/r8/dex/FileWriter.java
index 53f65b6..48c7c39 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -9,7 +9,6 @@
 import com.android.tools.r8.ByteBufferProvider;
 import com.android.tools.r8.code.Instruction;
 import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.graph.Descriptor;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationDirectory;
 import com.android.tools.r8.graph.DexAnnotationElement;
@@ -29,6 +28,7 @@
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
 import com.android.tools.r8.graph.DexItem;
+import com.android.tools.r8.graph.DexMember;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexMethodHandle;
 import com.android.tools.r8.graph.DexMethodHandle.MethodHandleType;
@@ -577,10 +577,10 @@
     }
   }
 
-  private <S extends Descriptor<T, S>, T extends DexEncodedMember<S>> void writeMemberAnnotations(
-      List<T> items, ToIntFunction<T> getter) {
-    for (T item : items) {
-      dest.putInt(item.getKey().getOffset(mapping));
+  private <S extends DexEncodedMember<S, T>, T extends DexMember<S, T>> void writeMemberAnnotations(
+      List<S> items, ToIntFunction<S> getter) {
+    for (S item : items) {
+      dest.putInt(item.toReference().getOffset(mapping));
       dest.putInt(getter.applyAsInt(item));
     }
   }
diff --git a/src/main/java/com/android/tools/r8/graph/AppInfo.java b/src/main/java/com/android/tools/r8/graph/AppInfo.java
index 29a5995..141f742 100644
--- a/src/main/java/com/android/tools/r8/graph/AppInfo.java
+++ b/src/main/java/com/android/tools/r8/graph/AppInfo.java
@@ -29,8 +29,8 @@
 
   private final DexApplication app;
   private final DexItemFactory dexItemFactory;
-  private final ConcurrentHashMap<DexType, Map<Descriptor<?, ?>, DexEncodedMember<?>>> definitions =
-      new ConcurrentHashMap<>();
+  private final ConcurrentHashMap<DexType, Map<DexMember<?, ?>, DexEncodedMember<?, ?>>>
+      definitions = new ConcurrentHashMap<>();
   // For some optimizations, e.g. optimizing synthetic classes, we may need to resolve the current
   // class being optimized.
   final ConcurrentHashMap<DexType, DexProgramClass> synthesizedClasses = new ConcurrentHashMap<>();
@@ -101,12 +101,12 @@
     return Collections.unmodifiableCollection(synthesizedClasses.values());
   }
 
-  private Map<Descriptor<?, ?>, DexEncodedMember<?>> computeDefinitions(DexType type) {
-    Builder<Descriptor<?, ?>, DexEncodedMember<?>> builder = ImmutableMap.builder();
+  private Map<DexMember<?, ?>, DexEncodedMember<?, ?>> computeDefinitions(DexType type) {
+    Builder<DexMember<?, ?>, DexEncodedMember<?, ?>> builder = ImmutableMap.builder();
     DexClass clazz = definitionFor(type);
     if (clazz != null) {
-      clazz.forEachMethod(method -> builder.put(method.getKey(), method));
-      clazz.forEachField(field -> builder.put(field.getKey(), field));
+      clazz.forEachMethod(method -> builder.put(method.toReference(), method));
+      clazz.forEachField(field -> builder.put(field.toReference(), field));
     }
     return builder.build();
   }
@@ -186,14 +186,14 @@
     return (DexEncodedField) getDefinitions(field.holder).get(field);
   }
 
-  private Map<Descriptor<?, ?>, DexEncodedMember<?>> getDefinitions(DexType type) {
-    Map<Descriptor<?, ?>, DexEncodedMember<?>> typeDefinitions = definitions.get(type);
+  private Map<DexMember<?, ?>, DexEncodedMember<?, ?>> getDefinitions(DexType type) {
+    Map<DexMember<?, ?>, DexEncodedMember<?, ?>> typeDefinitions = definitions.get(type);
     if (typeDefinitions != null) {
       return typeDefinitions;
     }
 
     typeDefinitions = computeDefinitions(type);
-    Map<Descriptor<?, ?>, DexEncodedMember<?>> existing =
+    Map<DexMember<?, ?>, DexEncodedMember<?, ?>> existing =
         definitions.putIfAbsent(type, typeDefinitions);
     return existing != null ? existing : typeDefinitions;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java b/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java
index e616e9e..75ec9be 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java
@@ -107,9 +107,9 @@
     throw new Unreachable();
   }
 
-  private static <T extends PresortedComparable<T>> boolean isSorted(
-      List<? extends DexEncodedMember<T>> items) {
-    return isSorted(items, DexEncodedMember::getKey);
+  private static <S extends DexEncodedMember<S, T>, T extends DexMember<S, T>> boolean isSorted(
+      List<S> items) {
+    return isSorted(items, DexEncodedMember::toReference);
   }
 
   private static <S, T extends Comparable<T>> boolean isSorted(
diff --git a/src/main/java/com/android/tools/r8/graph/DexClass.java b/src/main/java/com/android/tools/r8/graph/DexClass.java
index 3e1a144..9ce30c1 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -129,7 +129,7 @@
         Iterables.filter(Arrays.asList(staticFields), predicate::test));
   }
 
-  public Iterable<DexEncodedMember<?>> members() {
+  public Iterable<DexEncodedMember<?, ?>> members() {
     return Iterables.concat(fields(), methods());
   }
 
@@ -611,7 +611,8 @@
         && method.method.proto.parameters.values[0] != factory.objectArrayType;
   }
 
-  private <T extends DexItem, S extends Descriptor<T, S>> T lookupTarget(T[] items, S descriptor) {
+  private <T extends DexEncodedMember<T, S>, S extends DexMember<T, S>> T lookupTarget(
+      T[] items, S descriptor) {
     for (T entry : items) {
       if (descriptor.match(entry)) {
         return entry;
diff --git a/src/main/java/com/android/tools/r8/graph/DexDefinition.java b/src/main/java/com/android/tools/r8/graph/DexDefinition.java
index dbf18c3..7f6796d 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDefinition.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDefinition.java
@@ -51,7 +51,7 @@
     return false;
   }
 
-  public DexEncodedMember<?> asDexEncodedMember() {
+  public DexEncodedMember<?, ?> asDexEncodedMember() {
     return null;
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
index 4f332f9..d807874 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -19,7 +19,7 @@
 import com.android.tools.r8.kotlin.KotlinMemberInfo;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 
-public class DexEncodedField extends DexEncodedMember<DexField> {
+public class DexEncodedField extends DexEncodedMember<DexEncodedField, DexField> {
   public static final DexEncodedField[] EMPTY_ARRAY = {};
 
   public final DexField field;
@@ -110,12 +110,7 @@
   }
 
   @Override
-  public DexField getKey() {
-    return field;
-  }
-
-  @Override
-  public DexReference toReference() {
+  public DexField toReference() {
     return field;
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
index 6987227..c63aa9f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
@@ -3,13 +3,15 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.graph;
 
-public abstract class DexEncodedMember<T extends PresortedComparable<T>> extends DexDefinition {
+public abstract class DexEncodedMember<S extends DexEncodedMember<S, T>, T extends DexMember<S, T>>
+    extends DexDefinition {
 
   public DexEncodedMember(DexAnnotationSet annotations) {
     super(annotations);
   }
 
-  public abstract T getKey();
+  @Override
+  public abstract T toReference();
 
   @Override
   public boolean isDexEncodedMember() {
@@ -17,7 +19,7 @@
   }
 
   @Override
-  public DexEncodedMember<?> asDexEncodedMember() {
+  public DexEncodedMember<S, T> asDexEncodedMember() {
     return this;
   }
 
@@ -27,11 +29,11 @@
       return true;
     }
     return other.getClass() == getClass()
-        && ((DexEncodedMember<?>) other).getKey().equals(getKey());
+        && ((DexEncodedMember<?, ?>) other).toReference().equals(toReference());
   }
 
   @Override
   public final int hashCode() {
-    return getKey().hashCode();
+    return toReference().hashCode();
   }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 184e15e..b755c49 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -76,7 +76,7 @@
 import java.util.function.IntPredicate;
 import org.objectweb.asm.Opcodes;
 
-public class DexEncodedMethod extends DexEncodedMember<DexMethod> {
+public class DexEncodedMethod extends DexEncodedMember<DexEncodedMethod, DexMethod> {
 
   public static final String CONFIGURATION_DEBUGGING_PREFIX = "Shaking error: Missing method in ";
 
@@ -1163,14 +1163,7 @@
   }
 
   @Override
-  public DexMethod getKey() {
-    // Here, we can't check if the current instance of DexEncodedMethod is obsolete
-    // because itself can be used as a key while making mappings to avoid using obsolete instances.
-    return method;
-  }
-
-  @Override
-  public DexReference toReference() {
+  public DexMethod toReference() {
     checkIfObsolete();
     return method;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexField.java b/src/main/java/com/android/tools/r8/graph/DexField.java
index dfd3203..aafa665 100644
--- a/src/main/java/com/android/tools/r8/graph/DexField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexField.java
@@ -7,8 +7,7 @@
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.naming.NamingLens;
 
-public class DexField extends Descriptor<DexEncodedField, DexField> implements
-    PresortedComparable<DexField> {
+public class DexField extends DexMember<DexEncodedField, DexField> {
 
   public final DexType holder;
   public final DexType type;
diff --git a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
index df2402f..8cb71bb 100644
--- a/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexItemFactory.java
@@ -1539,7 +1539,7 @@
 
   public DexMethodHandle createMethodHandle(
       MethodHandleType type,
-      Descriptor<? extends DexItem, ? extends Descriptor<?, ?>> fieldOrMethod,
+      DexMember<? extends DexItem, ? extends DexMember<?, ?>> fieldOrMethod,
       boolean isInterface) {
     assert !sorted;
     DexMethodHandle methodHandle = new DexMethodHandle(type, fieldOrMethod, isInterface);
diff --git a/src/main/java/com/android/tools/r8/graph/Descriptor.java b/src/main/java/com/android/tools/r8/graph/DexMember.java
similarity index 73%
rename from src/main/java/com/android/tools/r8/graph/Descriptor.java
rename to src/main/java/com/android/tools/r8/graph/DexMember.java
index f0ba1b6..3adf342 100644
--- a/src/main/java/com/android/tools/r8/graph/Descriptor.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMember.java
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.graph;
 
-public abstract class Descriptor<T extends DexItem, S extends Descriptor<T,S>>
+public abstract class DexMember<T extends DexEncodedMember<T, S>, S extends DexMember<T, S>>
     extends DexReference implements PresortedComparable<S> {
 
   public abstract boolean match(S entry);
@@ -11,12 +11,12 @@
   public abstract boolean match(T entry);
 
   @Override
-  public boolean isDescriptor() {
+  public boolean isDexMember() {
     return true;
   }
 
   @Override
-  public Descriptor asDescriptor() {
+  public DexMember<T, S> asDexMember() {
     return this;
   }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/DexMemberAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexMemberAnnotation.java
index 6cc2fb4..b44992a 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMemberAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMemberAnnotation.java
@@ -6,7 +6,7 @@
 import com.android.tools.r8.dex.IndexedItemCollection;
 import com.android.tools.r8.dex.MixedSectionCollection;
 
-public class DexMemberAnnotation<T extends Descriptor<?,?>, S extends DexItem> extends DexItem {
+public class DexMemberAnnotation<T extends DexMember<?, ?>, S extends DexItem> extends DexItem {
 
   public final T item;
   public final S annotations;
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethod.java b/src/main/java/com/android/tools/r8/graph/DexMethod.java
index a1e98f7..9f26c54 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMethod.java
@@ -9,8 +9,7 @@
 import com.google.common.collect.Maps;
 import java.util.Map;
 
-public class DexMethod extends Descriptor<DexEncodedMethod, DexMethod>
-    implements PresortedComparable<DexMethod> {
+public class DexMethod extends DexMember<DexEncodedMethod, DexMethod> {
 
   public final DexType holder;
   public final DexProto proto;
diff --git a/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java b/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java
index 336842f..fbe8a9f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java
+++ b/src/main/java/com/android/tools/r8/graph/DexMethodHandle.java
@@ -187,7 +187,7 @@
   public final MethodHandleType type;
 
   // Field or method that the method handle is targeting.
-  public final Descriptor<? extends DexItem, ? extends Descriptor<?,?>> fieldOrMethod;
+  public final DexMember<? extends DexItem, ? extends DexMember<?, ?>> fieldOrMethod;
 
   public final boolean isInterface;
 
@@ -204,7 +204,7 @@
 
   public DexMethodHandle(
       MethodHandleType type,
-      Descriptor<? extends DexItem, ? extends Descriptor<?, ?>> fieldOrMethod,
+      DexMember<? extends DexItem, ? extends DexMember<?, ?>> fieldOrMethod,
       boolean isInterface) {
     this.type = type;
     this.fieldOrMethod = fieldOrMethod;
@@ -214,7 +214,7 @@
 
   public DexMethodHandle(
       MethodHandleType type,
-      Descriptor<? extends DexItem, ? extends Descriptor<?, ?>> fieldOrMethod,
+      DexMember<? extends DexItem, ? extends DexMember<?, ?>> fieldOrMethod,
       boolean isInterface,
       DexMethod rewrittenTarget) {
     this.type = type;
@@ -226,7 +226,7 @@
   public static DexMethodHandle fromAsmHandle(
       Handle handle, JarApplicationReader application, DexType clazz) {
     MethodHandleType methodHandleType = MethodHandleType.fromAsmHandle(handle, application, clazz);
-    Descriptor<? extends DexItem, ? extends Descriptor<?, ?>> descriptor =
+    DexMember<? extends DexItem, ? extends DexMember<?, ?>> descriptor =
         methodHandleType.isFieldType()
             ? application.getField(handle.getOwner(), handle.getName(), handle.getDesc())
             : application.getMethod(handle.getOwner(), handle.getName(), handle.getDesc());
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 1ac7c58..38aac2b 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -352,11 +352,11 @@
         && isSorted(instanceFields);
   }
 
-  private static <T extends DexEncodedMember<S>, S extends PresortedComparable<S>> boolean isSorted(
-      T[] items) {
+  private static <S extends DexEncodedMember<S, T>, T extends DexMember<S, T>> boolean isSorted(
+      S[] items) {
     synchronized (items) {
-      T[] sorted = items.clone();
-      Arrays.sort(sorted, Comparator.comparing(DexEncodedMember::getKey));
+      S[] sorted = items.clone();
+      Arrays.sort(sorted, Comparator.comparing(DexEncodedMember::toReference));
       return Arrays.equals(items, sorted);
     }
   }
@@ -441,7 +441,7 @@
    * entire scope.
    */
   public boolean hasReachabilitySensitiveAnnotation(DexItemFactory factory) {
-    for (DexEncodedMember<?> member : members()) {
+    for (DexEncodedMember<?, ?> member : members()) {
       for (DexAnnotation annotation : member.annotations().annotations) {
         if (annotation.annotation.type == factory.annotationReachabilitySensitive) {
           return true;
diff --git a/src/main/java/com/android/tools/r8/graph/DexReference.java b/src/main/java/com/android/tools/r8/graph/DexReference.java
index d51810e..42286db 100644
--- a/src/main/java/com/android/tools/r8/graph/DexReference.java
+++ b/src/main/java/com/android/tools/r8/graph/DexReference.java
@@ -21,11 +21,11 @@
     return null;
   }
 
-  public boolean isDescriptor() {
+  public boolean isDexMember() {
     return false;
   }
 
-  public Descriptor asDescriptor() {
+  public DexMember<?, ?> asDexMember() {
     return null;
   }
 
diff --git a/src/main/java/com/android/tools/r8/graph/JarApplicationReader.java b/src/main/java/com/android/tools/r8/graph/JarApplicationReader.java
index 27f4c9c..8b5977f 100644
--- a/src/main/java/com/android/tools/r8/graph/JarApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarApplicationReader.java
@@ -104,7 +104,7 @@
 
   public DexMethodHandle getMethodHandle(
       MethodHandleType type,
-      Descriptor<? extends DexItem, ? extends Descriptor<?, ?>> fieldOrMethod,
+      DexMember<? extends DexItem, ? extends DexMember<?, ?>> fieldOrMethod,
       boolean isInterface) {
     return options.itemFactory.createMethodHandle(type, fieldOrMethod, isInterface);
   }
diff --git a/src/main/java/com/android/tools/r8/graph/PresortedComparable.java b/src/main/java/com/android/tools/r8/graph/PresortedComparable.java
index 81e6d56..2dc3a3b 100644
--- a/src/main/java/com/android/tools/r8/graph/PresortedComparable.java
+++ b/src/main/java/com/android/tools/r8/graph/PresortedComparable.java
@@ -10,9 +10,9 @@
 
 public interface PresortedComparable<T> extends Presorted, Comparable<T> {
 
-  static <T extends PresortedComparable<T>> boolean isSorted(
-      List<? extends DexEncodedMember<T>> items) {
-    return isSorted(items, DexEncodedMember::getKey);
+  static <T extends DexEncodedMember<T, S>, S extends DexMember<T, S>> boolean isSorted(
+      List<? extends DexEncodedMember<T, S>> items) {
+    return isSorted(items, DexEncodedMember::toReference);
   }
 
   static <S, T extends Comparable<T>> boolean isSorted(S[] items, Function<S, T> getter) {
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/MemberPoolCollection.java b/src/main/java/com/android/tools/r8/ir/optimize/MemberPoolCollection.java
index aeedc02..97a8de6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/MemberPoolCollection.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/MemberPoolCollection.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.ir.optimize;
 
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.Descriptor;
 import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexMember;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.TopDownClassHierarchyTraversal;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
@@ -28,7 +28,7 @@
 import java.util.function.Predicate;
 
 // Per-class collection of member signatures.
-public abstract class MemberPoolCollection<T extends Descriptor> {
+public abstract class MemberPoolCollection<T extends DexMember> {
 
   final Equivalence<T> equivalence;
   final AppView<AppInfoWithLiveness> appView;
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 9ba9f6a..44b16b1 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -27,7 +27,6 @@
 import com.android.tools.r8.graph.AppInfoWithSubtyping;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.CfCode;
-import com.android.tools.r8.graph.Descriptor;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexCallSite;
@@ -41,6 +40,7 @@
 import com.android.tools.r8.graph.DexItem;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexLibraryClass;
+import com.android.tools.r8.graph.DexMember;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexMethodHandle;
 import com.android.tools.r8.graph.DexProgramClass;
@@ -2716,12 +2716,12 @@
     assert replaced == callSites.size();
   }
 
-  private static <T extends PresortedComparable<T>> SortedSet<T> toSortedDescriptorSet(
-      Set<? extends DexEncodedMember<T>> set) {
+  private static <S extends DexEncodedMember<S, T>, T extends DexMember<S, T>>
+      SortedSet<T> toSortedDescriptorSet(Set<S> set) {
     ImmutableSortedSet.Builder<T> builder =
         new ImmutableSortedSet.Builder<>(PresortedComparable::slowCompareTo);
-    for (DexEncodedMember<T> item : set) {
-      builder.add(item.getKey());
+    for (S item : set) {
+      builder.add(item.toReference());
     }
     return builder.build();
   }
@@ -3564,7 +3564,7 @@
     }
   }
 
-  private static final class TargetWithContext<T extends Descriptor<?, T>> {
+  private static final class TargetWithContext<T extends DexMember<?, T>> {
 
     private final T target;
     private final DexEncodedMethod context;
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
index 7495c6b..cdc5782 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -1539,7 +1539,7 @@
               // Create a Set of the fields to avoid quadratic behavior.
               fields =
                   Streams.stream(clazz.fields())
-                      .map(DexEncodedField::getKey)
+                      .map(DexEncodedField::toReference)
                       .collect(Collectors.toSet());
             }
             assert fields.contains(requiredField)
@@ -1552,7 +1552,7 @@
               // Create a Set of the methods to avoid quadratic behavior.
               methods =
                   Streams.stream(clazz.methods())
-                      .map(DexEncodedMethod::getKey)
+                      .map(DexEncodedMethod::toReference)
                       .collect(Collectors.toSet());
             }
             assert methods.contains(requiredMethod)
diff --git a/src/main/java/com/android/tools/r8/shaking/TreePruner.java b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
index 3ded35c..d0d51aa 100644
--- a/src/main/java/com/android/tools/r8/shaking/TreePruner.java
+++ b/src/main/java/com/android/tools/r8/shaking/TreePruner.java
@@ -8,6 +8,7 @@
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMember;
 import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexMember;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexReference;
@@ -17,7 +18,6 @@
 import com.android.tools.r8.graph.EnclosingMethodAttribute;
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.graph.NestMemberClassAttribute;
-import com.android.tools.r8.graph.PresortedComparable;
 import com.android.tools.r8.logging.Log;
 import com.android.tools.r8.utils.ExceptionUtils;
 import com.android.tools.r8.utils.InternalOptions;
@@ -243,8 +243,8 @@
     return context == null || !isTypeLive(context);
   }
 
-  private <S extends PresortedComparable<S>, T extends DexEncodedMember<S>>
-      int firstUnreachableIndex(List<T> items, Predicate<T> live) {
+  private <S extends DexEncodedMember<S, T>, T extends DexMember<S, T>> int firstUnreachableIndex(
+      List<S> items, Predicate<S> live) {
     for (int i = 0; i < items.size(); i++) {
       if (!live.test(items.get(i))) {
         return i;
@@ -268,7 +268,7 @@
     }
     for (int i = firstUnreachable; i < methods.size(); i++) {
       DexEncodedMethod method = methods.get(i);
-      if (appInfo.liveMethods.contains(method.getKey())) {
+      if (appInfo.liveMethods.contains(method.toReference())) {
         reachableMethods.add(method);
       } else if (options.configurationDebugging) {
         // Keep the method but rewrite its body, if it has one.
@@ -277,7 +277,7 @@
                 ? method
                 : method.toMethodThatLogsError(appView));
         methodsToKeepForConfigurationDebugging.add(method.method);
-      } else if (appInfo.targetedMethods.contains(method.getKey())) {
+      } else if (appInfo.targetedMethods.contains(method.toReference())) {
         // If the method is already abstract, and doesn't have code, let it be.
         if (method.shouldNotHaveCode() && !method.hasCode()) {
           reachableMethods.add(method);
diff --git a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
index 76db9fe..9d4b394 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -18,6 +18,7 @@
 import com.android.tools.r8.graph.DexEncodedMember;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexMember;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexProto;
@@ -30,7 +31,6 @@
 import com.android.tools.r8.graph.LookupResult;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
-import com.android.tools.r8.graph.PresortedComparable;
 import com.android.tools.r8.graph.ResolutionResult;
 import com.android.tools.r8.graph.RewrittenPrototypeDescription;
 import com.android.tools.r8.graph.TopDownClassHierarchyTraversal;
@@ -335,7 +335,7 @@
     }
 
     assert Streams.stream(Iterables.concat(clazz.fields(), clazz.methods()))
-        .map(DexEncodedMember::getKey)
+        .map(DexEncodedMember::toReference)
         .noneMatch(appInfo::isPinned);
 
     if (appView.options().featureSplitConfiguration != null &&
@@ -1269,15 +1269,15 @@
       return null;
     }
 
-    private <T extends DexEncodedMember<S>, S extends PresortedComparable<S>> void add(
-        Map<Wrapper<S>, T> map, T item, Equivalence<S> equivalence) {
-      map.put(equivalence.wrap(item.getKey()), item);
+    private <S extends DexEncodedMember<S, T>, T extends DexMember<S, T>> void add(
+        Map<Wrapper<T>, S> map, S item, Equivalence<T> equivalence) {
+      map.put(equivalence.wrap(item.toReference()), item);
     }
 
-    private <T extends DexEncodedMember<S>, S extends PresortedComparable<S>> void addAll(
-        Collection<Wrapper<S>> collection, Iterable<T> items, Equivalence<S> equivalence) {
-      for (T item : items) {
-        collection.add(equivalence.wrap(item.getKey()));
+    private <S extends DexEncodedMember<S, T>, T extends DexMember<S, T>> void addAll(
+        Collection<Wrapper<T>> collection, Iterable<S> items, Equivalence<T> equivalence) {
+      for (S item : items) {
+        collection.add(equivalence.wrap(item.toReference()));
       }
     }
 
diff --git a/src/main/java/com/android/tools/r8/utils/OrderedMergingIterator.java b/src/main/java/com/android/tools/r8/utils/OrderedMergingIterator.java
index 40fa54f..279f737 100644
--- a/src/main/java/com/android/tools/r8/utils/OrderedMergingIterator.java
+++ b/src/main/java/com/android/tools/r8/utils/OrderedMergingIterator.java
@@ -5,25 +5,25 @@
 
 import com.android.tools.r8.errors.InternalCompilerError;
 import com.android.tools.r8.graph.DexEncodedMember;
-import com.android.tools.r8.graph.PresortedComparable;
+import com.android.tools.r8.graph.DexMember;
 import java.util.Iterator;
 import java.util.List;
 import java.util.NoSuchElementException;
 
-public class OrderedMergingIterator<T extends DexEncodedMember<S>, S extends PresortedComparable<S>>
-    implements Iterator<T> {
+public class OrderedMergingIterator<S extends DexEncodedMember<S, T>, T extends DexMember<S, T>>
+    implements Iterator<S> {
 
-  private final List<T> one;
-  private final List<T> other;
+  private final List<S> one;
+  private final List<S> other;
   private int oneIndex = 0;
   private int otherIndex = 0;
 
-  public OrderedMergingIterator(List<T> one, List<T> other) {
+  public OrderedMergingIterator(List<S> one, List<S> other) {
     this.one = one;
     this.other = other;
   }
 
-  private static <T> T getNextChecked(List<T> list, int position) {
+  private S getNextChecked(List<S> list, int position) {
     if (position >= list.size()) {
       throw new NoSuchElementException();
     }
@@ -36,14 +36,14 @@
   }
 
   @Override
-  public T next() {
+  public S next() {
     if (oneIndex >= one.size()) {
       return getNextChecked(other, otherIndex++);
     }
     if (otherIndex >= other.size()) {
       return getNextChecked(one, oneIndex++);
     }
-    int comparison = one.get(oneIndex).getKey().compareTo(other.get(otherIndex).getKey());
+    int comparison = one.get(oneIndex).toReference().compareTo(other.get(otherIndex).toReference());
     if (comparison < 0) {
       return one.get(oneIndex++);
     }