Move DexAnnotationSet fields to DexDefinition

This is a cleanup that moves DexClass.annotations, DexEncodedField.annotations, and DexEncodedField.annotations to DexDefinition.annotations.

Change-Id: I98e5a3d64b081be3b2ee58d2c9276ceeddf3968e
diff --git a/src/main/java/com/android/tools/r8/PrintUses.java b/src/main/java/com/android/tools/r8/PrintUses.java
index d8d93ab..d492e67 100644
--- a/src/main/java/com/android/tools/r8/PrintUses.java
+++ b/src/main/java/com/android/tools/r8/PrintUses.java
@@ -250,7 +250,7 @@
       for (DexType type : method.method.proto.parameters.values) {
         registerTypeReference(type);
       }
-      for (DexAnnotation annotation : method.annotations.annotations) {
+      for (DexAnnotation annotation : method.annotations().annotations) {
         if (annotation.annotation.type == appInfo.dexItemFactory().annotationThrows) {
           DexValueArray dexValues = (DexValueArray) annotation.annotation.elements[0].value;
           for (DexValue dexValType : dexValues.getValues()) {
diff --git a/src/main/java/com/android/tools/r8/ResourceShrinker.java b/src/main/java/com/android/tools/r8/ResourceShrinker.java
index 21e4f10..efeccec 100644
--- a/src/main/java/com/android/tools/r8/ResourceShrinker.java
+++ b/src/main/java/com/android/tools/r8/ResourceShrinker.java
@@ -54,7 +54,6 @@
 import com.google.common.collect.Sets;
 import com.google.common.collect.Streams;
 import java.io.IOException;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
@@ -232,36 +231,24 @@
     }
 
     private void processAnnotations(DexProgramClass classDef) {
-      Stream<DexAnnotation> instanceFieldAnnotations =
-          classDef.instanceFields().stream()
+      Stream<DexAnnotation> classAnnotations = classDef.annotations().stream();
+      Stream<DexAnnotation> fieldAnnotations =
+          Streams.stream(classDef.fields())
               .filter(DexEncodedField::hasAnnotation)
-              .flatMap(f -> Arrays.stream(f.annotations.annotations));
-      Stream<DexAnnotation> staticFieldAnnotations =
-          classDef.staticFields().stream()
-              .filter(DexEncodedField::hasAnnotation)
-              .flatMap(f -> Arrays.stream(f.annotations.annotations));
-      Stream<DexAnnotation> virtualMethodAnnotations =
-          classDef.virtualMethods().stream()
+              .flatMap(f -> f.annotations().stream());
+      Stream<DexAnnotation> methodAnnotations =
+          Streams.stream(classDef.methods())
               .filter(DexEncodedMethod::hasAnnotation)
-              .flatMap(m -> Arrays.stream(m.annotations.annotations));
-      Stream<DexAnnotation> directMethodAnnotations =
-          classDef.directMethods().stream()
-              .filter(DexEncodedMethod::hasAnnotation)
-              .flatMap(m -> Arrays.stream(m.annotations.annotations));
-      Stream<DexAnnotation> classAnnotations = Arrays.stream(classDef.annotations.annotations);
+              .flatMap(m -> m.annotations().stream());
 
-      Streams.concat(
-          instanceFieldAnnotations,
-          staticFieldAnnotations,
-          virtualMethodAnnotations,
-          directMethodAnnotations,
-          classAnnotations)
-          .forEach(annotation -> {
-            for (DexAnnotationElement element : annotation.annotation.elements) {
-              DexValue value = element.value;
-              processAnnotationValue(value);
-            }
-          });
+      Streams.concat(classAnnotations, fieldAnnotations, methodAnnotations)
+          .forEach(
+              annotation -> {
+                for (DexAnnotationElement element : annotation.annotation.elements) {
+                  DexValue value = element.value;
+                  processAnnotationValue(value);
+                }
+              });
     }
 
     private void processIntArrayPayload(Instruction instruction) {
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index 6013392..2992824 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -527,10 +527,10 @@
         // Append the annotations to annotations array of the class.
         DexAnnotation[] copy =
             ObjectArrays.concat(
-                clazz.annotations.annotations,
+                clazz.annotations().annotations,
                 annotations.toArray(DexAnnotation.EMPTY_ARRAY),
                 DexAnnotation.class);
-        clazz.annotations = new DexAnnotationSet(copy);
+        clazz.setAnnotations(new DexAnnotationSet(copy));
       }
 
       // Clear the attribute structures now that they are represented in annotations.
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 c235e19..53f65b6 100644
--- a/src/main/java/com/android/tools/r8/dex/FileWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/FileWriter.java
@@ -594,10 +594,10 @@
     dest.putInt(fieldAnnotations.size());
     dest.putInt(methodAnnotations.size());
     dest.putInt(parameterAnnotations.size());
-    writeMemberAnnotations(fieldAnnotations,
-        item -> mixedSectionOffsets.getOffsetFor(item.annotations));
-    writeMemberAnnotations(methodAnnotations,
-        item -> mixedSectionOffsets.getOffsetFor(item.annotations));
+    writeMemberAnnotations(
+        fieldAnnotations, item -> mixedSectionOffsets.getOffsetFor(item.annotations()));
+    writeMemberAnnotations(
+        methodAnnotations, item -> mixedSectionOffsets.getOffsetFor(item.annotations()));
     writeMemberAnnotations(parameterAnnotations,
         item -> mixedSectionOffsets.getOffsetFor(item.parameterAnnotationsList));
   }
diff --git a/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java b/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java
index 2ee2c0c..2a6154d 100644
--- a/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java
+++ b/src/main/java/com/android/tools/r8/graph/AssemblyWriter.java
@@ -59,7 +59,7 @@
     ps.println("# Bytecode for");
     ps.println("# Class: '" + clazzName + "'");
     if (writeAllClassInfo) {
-      writeAnnotations(clazz.annotations, ps);
+      writeAnnotations(clazz.annotations(), ps);
       ps.println("# Flags: '" + clazz.accessFlags + "'");
       if (clazz.superType != application.dexItemFactory.objectType) {
         ps.println("# Extends: '" + clazz.superType.toSourceString() + "'");
@@ -87,7 +87,7 @@
       FieldSignature fieldSignature = naming != null
           ? naming.originalSignatureOf(field.field)
           : FieldSignature.fromDexField(field.field);
-      writeAnnotations(field.annotations, ps);
+      writeAnnotations(field.annotations(), ps);
       ps.print(field.accessFlags + " ");
       ps.println(fieldSignature);
     }
@@ -106,7 +106,7 @@
         : method.method.name.toString();
     ps.println("#");
     ps.println("# Method: '" + methodName + "':");
-    writeAnnotations(method.annotations, ps);
+    writeAnnotations(method.annotations(), ps);
     ps.println("# " + method.accessFlags);
     ps.println("#");
     ps.println();
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
index 0f60e07..50b4b2f 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
@@ -338,30 +338,25 @@
   }
 
   public static Collection<DexType> readAnnotationSynthesizedClassMap(
-      DexProgramClass programClass,
-      DexItemFactory dexItemFactory) {
-    DexAnnotation foundAnnotation = programClass.annotations.getFirstMatching(
-        dexItemFactory.annotationSynthesizedClassMap);
+      DexProgramClass clazz, DexItemFactory dexItemFactory) {
+    DexAnnotation foundAnnotation =
+        clazz.annotations().getFirstMatching(dexItemFactory.annotationSynthesizedClassMap);
     if (foundAnnotation != null) {
       if (foundAnnotation.annotation.elements.length != 1) {
-        throw new CompilationError(
-            getInvalidSynthesizedClassMapMessage(programClass, foundAnnotation));
+        throw new CompilationError(getInvalidSynthesizedClassMapMessage(clazz, foundAnnotation));
       }
       DexAnnotationElement value = foundAnnotation.annotation.elements[0];
       if (!value.name.toSourceString().equals("value")) {
-        throw new CompilationError(
-            getInvalidSynthesizedClassMapMessage(programClass, foundAnnotation));
+        throw new CompilationError(getInvalidSynthesizedClassMapMessage(clazz, foundAnnotation));
       }
       if (!(value.value instanceof DexValueArray)) {
-        throw new CompilationError(
-            getInvalidSynthesizedClassMapMessage(programClass, foundAnnotation));
+        throw new CompilationError(getInvalidSynthesizedClassMapMessage(clazz, foundAnnotation));
       }
       DexValueArray existingList = (DexValueArray) value.value;
       Collection<DexType> synthesized = new ArrayList<>(existingList.values.length);
       for (DexValue element : existingList.getValues()) {
         if (!(element instanceof DexValueType)) {
-          throw new CompilationError(
-              getInvalidSynthesizedClassMapMessage(programClass, foundAnnotation));
+          throw new CompilationError(getInvalidSynthesizedClassMapMessage(clazz, foundAnnotation));
         }
         synthesized.add(((DexValueType) element).value);
       }
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 ebd5c91..e616e9e 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotationDirectory.java
@@ -30,7 +30,7 @@
     parameterAnnotations = new ArrayList<>();
     while (methods.hasNext()) {
       DexEncodedMethod method = methods.next();
-      if (!method.annotations.isEmpty()) {
+      if (!method.annotations().isEmpty()) {
         methodAnnotations.add(method);
       }
       if (!method.parameterAnnotationsList.isEmpty()) {
@@ -44,14 +44,14 @@
     fieldAnnotations = new ArrayList<>();
     while (fields.hasNext()) {
       DexEncodedField field = fields.next();
-      if (!field.annotations.isEmpty()) {
+      if (!field.annotations().isEmpty()) {
         fieldAnnotations.add(field);
       }
     }
   }
 
   public DexAnnotationSet getClazzAnnotations() {
-    return clazz.annotations;
+    return clazz.annotations();
   }
 
   public List<DexEncodedMethod> getMethodAnnotations() {
@@ -83,7 +83,7 @@
       if (!other.clazz.hasOnlyInternalizableAnnotations()) {
         return false;
       }
-      return clazz.annotations.equals(other.clazz.annotations);
+      return clazz.annotations().equals(other.clazz.annotations());
     }
     return super.equals(obj);
   }
@@ -91,7 +91,7 @@
   @Override
   public final int hashCode() {
     if (classHasOnlyInternalizableAnnotations) {
-      return clazz.annotations.hashCode();
+      return clazz.annotations().hashCode();
     }
     return super.hashCode();
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java b/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java
index 04251a6..dd24ed6 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotationSet.java
@@ -6,12 +6,15 @@
 import com.android.tools.r8.dex.IndexedItemCollection;
 import com.android.tools.r8.dex.MixedSectionCollection;
 import com.android.tools.r8.utils.ArrayUtils;
+import com.google.common.collect.Sets;
 import java.util.Arrays;
-import java.util.HashSet;
+import java.util.Comparator;
 import java.util.List;
 import java.util.Set;
+import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 
 public class DexAnnotationSet extends CachedHashValueDexItem {
 
@@ -33,7 +36,7 @@
   }
 
   public static DexType findDuplicateEntryType(List<DexAnnotation> annotations) {
-    Set<DexType> seenTypes = new HashSet<>();
+    Set<DexType> seenTypes = Sets.newIdentityHashSet();
     for (DexAnnotation annotation : annotations) {
       if (!seenTypes.add(annotation.annotation.type)) {
         return annotation.annotation.type;
@@ -46,6 +49,16 @@
     return THE_EMPTY_ANNOTATIONS_SET;
   }
 
+  public void forEach(Consumer<DexAnnotation> consumer) {
+    for (DexAnnotation annotation : annotations) {
+      consumer.accept(annotation);
+    }
+  }
+
+  public Stream<DexAnnotation> stream() {
+    return Arrays.stream(annotations);
+  }
+
   public int size() {
     return annotations.length;
   }
@@ -85,7 +98,7 @@
       assert sorted == sortedHashCode();
       return;
     }
-    Arrays.sort(annotations, (a, b) -> a.annotation.type.compareTo(b.annotation.type));
+    Arrays.sort(annotations, Comparator.comparing(a -> a.annotation.type));
     for (DexAnnotation annotation : annotations) {
       annotation.annotation.sort();
     }
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 321b5c7..3e1a144 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -69,8 +69,6 @@
   private NestHostClassAttribute nestHost;
   private final List<NestMemberClassAttribute> nestMembers;
 
-  public DexAnnotationSet annotations;
-
   public DexClass(
       DexString sourceFile,
       DexTypeList interfaces,
@@ -88,6 +86,7 @@
       DexAnnotationSet annotations,
       Origin origin,
       boolean skipNameValidationForTesting) {
+    super(annotations);
     assert origin != null;
     this.origin = origin;
     this.sourceFile = sourceFile;
@@ -104,7 +103,6 @@
     assert nestMembers != null;
     this.enclosingMethod = enclosingMethod;
     this.innerClasses = innerClasses;
-    this.annotations = annotations;
     if (type == superType) {
       throw new CompilationError("Class " + type.toString() + " cannot extend itself");
     }
@@ -131,6 +129,10 @@
         Iterables.filter(Arrays.asList(staticFields), predicate::test));
   }
 
+  public Iterable<DexEncodedMember<?>> members() {
+    return Iterables.concat(fields(), methods());
+  }
+
   public Iterable<DexEncodedMethod> methods() {
     return methods(Predicates.alwaysTrue());
   }
@@ -369,30 +371,13 @@
    * specified consumer.
    */
   public void forEachAnnotation(Consumer<DexAnnotation> consumer) {
-    for (DexAnnotation annotation : annotations.annotations) {
-      consumer.accept(annotation);
-    }
-    for (DexEncodedMethod method : directMethods()) {
-      for (DexAnnotation annotation : method.annotations.annotations) {
-        consumer.accept(annotation);
-      }
+    annotations().forEach(consumer);
+    for (DexEncodedMethod method : methods()) {
+      method.annotations().forEach(consumer);
       method.parameterAnnotationsList.forEachAnnotation(consumer);
     }
-    for (DexEncodedMethod method : virtualMethods()) {
-      for (DexAnnotation annotation : method.annotations.annotations) {
-        consumer.accept(annotation);
-      }
-      method.parameterAnnotationsList.forEachAnnotation(consumer);
-    }
-    for (DexEncodedField field : instanceFields()) {
-      for (DexAnnotation annotation : field.annotations.annotations) {
-        consumer.accept(annotation);
-      }
-    }
-    for (DexEncodedField field : staticFields()) {
-      for (DexAnnotation annotation : field.annotations.annotations) {
-        consumer.accept(annotation);
-      }
+    for (DexEncodedField field : fields()) {
+      field.annotations().forEach(consumer);
     }
   }
 
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 df8a65f..dbf18c3 100644
--- a/src/main/java/com/android/tools/r8/graph/DexDefinition.java
+++ b/src/main/java/com/android/tools/r8/graph/DexDefinition.java
@@ -12,6 +12,25 @@
  */
 public abstract class DexDefinition extends DexItem {
 
+  private DexAnnotationSet annotations;
+
+  public DexDefinition(DexAnnotationSet annotations) {
+    assert annotations != null : "Should use DexAnnotationSet.THE_EMPTY_ANNOTATIONS_SET";
+    this.annotations = annotations;
+  }
+
+  public DexAnnotationSet annotations() {
+    return annotations;
+  }
+
+  public void clearAnnotations() {
+    setAnnotations(DexAnnotationSet.empty());
+  }
+
+  public void setAnnotations(DexAnnotationSet annotations) {
+    this.annotations = annotations;
+  }
+
   public boolean isDexClass() {
     return false;
   }
@@ -28,6 +47,14 @@
     return null;
   }
 
+  public boolean isDexEncodedMember() {
+    return false;
+  }
+
+  public DexEncodedMember<?> asDexEncodedMember() {
+    return null;
+  }
+
   public boolean isDexEncodedField() {
     return false;
   }
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 819dcde..4f332f9 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -24,7 +24,6 @@
 
   public final DexField field;
   public final FieldAccessFlags accessFlags;
-  public DexAnnotationSet annotations;
   private DexValue staticValue;
 
   private FieldOptimizationInfo optimizationInfo = DefaultFieldOptimizationInfo.getInstance();
@@ -35,9 +34,9 @@
       FieldAccessFlags accessFlags,
       DexAnnotationSet annotations,
       DexValue staticValue) {
+    super(annotations);
     this.field = field;
     this.accessFlags = accessFlags;
-    this.annotations = annotations;
     this.staticValue = staticValue;
   }
 
@@ -84,7 +83,7 @@
   public void collectIndexedItems(
       IndexedItemCollection indexedItems, DexMethod method, int instructionOffset) {
     field.collectIndexedItems(indexedItems, method, instructionOffset);
-    annotations.collectIndexedItems(indexedItems, method, instructionOffset);
+    annotations().collectIndexedItems(indexedItems, method, instructionOffset);
     if (accessFlags.isStatic()) {
       getStaticValue().collectIndexedItems(indexedItems, method, instructionOffset);
     }
@@ -92,7 +91,7 @@
 
   @Override
   void collectMixedSectionItems(MixedSectionCollection mixedItems) {
-    annotations.collectMixedSectionItems(mixedItems);
+    annotations().collectMixedSectionItems(mixedItems);
   }
 
   @Override
@@ -149,7 +148,7 @@
   }
 
   public boolean hasAnnotation() {
-    return !annotations.isEmpty();
+    return !annotations().isEmpty();
   }
 
   public boolean hasExplicitStaticValue() {
@@ -238,7 +237,7 @@
     if (this.field == field) {
       return this;
     }
-    DexEncodedField result = new DexEncodedField(field, accessFlags, annotations, staticValue);
+    DexEncodedField result = new DexEncodedField(field, accessFlags, annotations(), staticValue);
     result.optimizationInfo =
         optimizationInfo.isMutableFieldOptimizationInfo()
             ? optimizationInfo.asMutableFieldOptimizationInfo().mutableCopy()
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 591d807..6987227 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMember.java
@@ -5,9 +5,23 @@
 
 public abstract class DexEncodedMember<T extends PresortedComparable<T>> extends DexDefinition {
 
+  public DexEncodedMember(DexAnnotationSet annotations) {
+    super(annotations);
+  }
+
   public abstract T getKey();
 
   @Override
+  public boolean isDexEncodedMember() {
+    return true;
+  }
+
+  @Override
+  public DexEncodedMember<?> asDexEncodedMember() {
+    return this;
+  }
+
+  @Override
   public final boolean equals(Object other) {
     if (other == this) {
       return true;
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 a6ba743..184e15e 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -118,15 +118,16 @@
 
   public static final DexEncodedMethod[] EMPTY_ARRAY = {};
   public static final DexEncodedMethod SENTINEL =
-      new DexEncodedMethod(null, null, null, ParameterAnnotationsList.empty(), null);
+      new DexEncodedMethod(
+          null, null, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null);
   public static final DexEncodedMethod ANNOTATION_REFERENCE =
-      new DexEncodedMethod(null, null, null, ParameterAnnotationsList.empty(), null);
+      new DexEncodedMethod(
+          null, null, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null);
   public static final Int2ReferenceMap<DebugLocalInfo> NO_PARAMETER_INFO =
       new Int2ReferenceArrayMap<>(0);
 
   public final DexMethod method;
   public final MethodAccessFlags accessFlags;
-  public DexAnnotationSet annotations;
   public ParameterAnnotationsList parameterAnnotationsList;
   private Code code;
   // TODO(b/128967328): towards finer-grained inlining constraints,
@@ -241,9 +242,9 @@
       Code code,
       int classFileVersion,
       boolean d8R8Synthesized) {
+    super(annotations);
     this.method = method;
     this.accessFlags = accessFlags;
-    this.annotations = annotations;
     this.parameterAnnotationsList = parameterAnnotationsList;
     this.code = code;
     this.classFileVersion = classFileVersion;
@@ -605,7 +606,7 @@
     if (code != null) {
       code.collectIndexedItems(indexedItems, this.method);
     }
-    annotations.collectIndexedItems(indexedItems);
+    annotations().collectIndexedItems(indexedItems);
     parameterAnnotationsList.collectIndexedItems(indexedItems);
   }
 
@@ -620,7 +621,7 @@
     if (code != null) {
       code.collectMixedSectionItems(mixedItems);
     }
-    annotations.collectMixedSectionItems(mixedItems);
+    annotations().collectMixedSectionItems(mixedItems);
     parameterAnnotationsList.collectMixedSectionItems(mixedItems);
   }
 
@@ -1108,7 +1109,7 @@
     return new DexEncodedMethod(
         newMethod,
         newFlags,
-        target.annotations,
+        target.annotations(),
         target.parameterAnnotationsList,
         new SynthesizedCode(forwardSourceCodeBuilder::build),
         true);
@@ -1188,7 +1189,7 @@
 
   public boolean hasAnnotation() {
     checkIfObsolete();
-    return !annotations.isEmpty() || !parameterAnnotationsList.isEmpty();
+    return !annotations().isEmpty() || !parameterAnnotationsList.isEmpty();
   }
 
   public void registerCodeReferences(UseRegistry registry) {
@@ -1271,7 +1272,7 @@
       // Copy all the mutable state of a DexEncodedMethod here.
       method = from.method;
       accessFlags = from.accessFlags.copy();
-      annotations = from.annotations;
+      annotations = from.annotations();
       code = from.code;
       compilationState = from.compilationState;
       optimizationInfo = from.optimizationInfo.mutableCopy();
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 12253c0..1ac7c58 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -148,9 +148,7 @@
       if (sourceFile != null) {
         sourceFile.collectIndexedItems(indexedItems, method, instructionOffset);
       }
-      if (annotations != null) {
-        annotations.collectIndexedItems(indexedItems, method, instructionOffset);
-      }
+      annotations().collectIndexedItems(indexedItems, method, instructionOffset);
       if (interfaces != null) {
         interfaces.collectIndexedItems(indexedItems, method, instructionOffset);
       }
@@ -203,13 +201,10 @@
       synchronizedCollectAll(collector, staticFields);
       synchronizedCollectAll(collector, instanceFields);
     }
-    if (annotations != null) {
-      annotations.collectMixedSectionItems(collector);
-    }
+    annotations().collectMixedSectionItems(collector);
     if (interfaces != null) {
       interfaces.collectMixedSectionItems(collector);
     }
-    annotations.collectMixedSectionItems(collector);
   }
 
   private static <T extends DexItem> void synchronizedCollectAll(MixedSectionCollection collection,
@@ -291,7 +286,7 @@
   }
 
   public boolean hasAnnotations() {
-    return !annotations.isEmpty()
+    return !annotations().isEmpty()
         || hasAnnotations(virtualMethods)
         || hasAnnotations(directMethods)
         || hasAnnotations(staticFields)
@@ -446,29 +441,8 @@
    * entire scope.
    */
   public boolean hasReachabilitySensitiveAnnotation(DexItemFactory factory) {
-    for (DexEncodedMethod directMethod : directMethods) {
-      for (DexAnnotation annotation : directMethod.annotations.annotations) {
-        if (annotation.annotation.type == factory.annotationReachabilitySensitive) {
-          return true;
-        }
-      }
-    }
-    for (DexEncodedMethod virtualMethod : virtualMethods) {
-      for (DexAnnotation annotation : virtualMethod.annotations.annotations) {
-        if (annotation.annotation.type == factory.annotationReachabilitySensitive) {
-          return true;
-        }
-      }
-    }
-    for (DexEncodedField staticField : staticFields) {
-      for (DexAnnotation annotation : staticField.annotations.annotations) {
-        if (annotation.annotation.type == factory.annotationReachabilitySensitive) {
-          return true;
-        }
-      }
-    }
-    for (DexEncodedField instanceField : instanceFields) {
-      for (DexAnnotation annotation : instanceField.annotations.annotations) {
+    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/JarClassFileReader.java b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
index cf4a98e..eb17913 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -40,6 +40,7 @@
 import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.StringUtils;
 import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.collect.Iterables;
 import java.io.BufferedInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -475,13 +476,7 @@
     // or method is annotated, all methods get parsed with locals information.
     private void checkReachabilitySensitivity() {
       if (hasReachabilitySensitiveMethod || hasReachabilitySensitiveField()) {
-        for (DexEncodedMethod method : directMethods) {
-          Code code = method.getCode();
-          if (code != null && code.isCfCode()) {
-            code.asLazyCfCode().markReachabilitySensitive();
-          }
-        }
-        for (DexEncodedMethod method : virtualMethods) {
+        for (DexEncodedMethod method : Iterables.concat(directMethods, virtualMethods)) {
           Code code = method.getCode();
           if (code != null && code.isCfCode()) {
             code.asLazyCfCode().markReachabilitySensitive();
@@ -492,15 +487,8 @@
 
     private boolean hasReachabilitySensitiveField() {
       DexType reachabilitySensitive = application.getFactory().annotationReachabilitySensitive;
-      for (DexEncodedField field : instanceFields) {
-        for (DexAnnotation annotation : field.annotations.annotations) {
-          if (annotation.annotation.type == reachabilitySensitive) {
-            return true;
-          }
-        }
-      }
-      for (DexEncodedField field : staticFields) {
-        for (DexAnnotation annotation : field.annotations.annotations) {
+      for (DexEncodedField field : Iterables.concat(instanceFields, staticFields)) {
+        for (DexAnnotation annotation : field.annotations().annotations) {
           if (annotation.annotation.type == reachabilitySensitive) {
             return true;
           }
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index 6edeab0..4b82f19 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -506,9 +506,9 @@
   }
 
   private void clearSynthesizedClassMapping(Builder<?> builder) {
-    for (DexProgramClass programClass : builder.getProgramClasses()) {
-      programClass.annotations =
-          programClass.annotations.getWithout(builder.dexItemFactory.annotationSynthesizedClassMap);
+    for (DexProgramClass clazz : builder.getProgramClasses()) {
+      clazz.setAnnotations(
+          clazz.annotations().getWithout(builder.dexItemFactory.annotationSynthesizedClassMap));
     }
   }
 
@@ -538,7 +538,7 @@
       DexAnnotation updatedAnnotation =
           DexAnnotation.createAnnotationSynthesizedClassMap(synthesized, builder.dexItemFactory);
 
-      original.annotations = original.annotations.getWithAddedOrReplaced(updatedAnnotation);
+      original.setAnnotations(original.annotations().getWithAddedOrReplaced(updatedAnnotation));
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
index a0fb1c8..3cadabf 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/CovariantReturnTypeAnnotationTransformer.java
@@ -92,8 +92,8 @@
     }
     // Remove the CovariantReturnType annotations.
     for (DexEncodedMethod method : methodsWithCovariantReturnTypeAnnotation) {
-      method.annotations =
-          method.annotations.keepIf(x -> !isCovariantReturnTypeAnnotation(x.annotation));
+      method.setAnnotations(
+          method.annotations().keepIf(x -> !isCovariantReturnTypeAnnotation(x.annotation)));
     }
     // Add the newly constructed methods to the class.
     clazz.appendVirtualMethods(covariantReturnTypeMethods);
@@ -115,7 +115,7 @@
   }
 
   private boolean methodHasCovariantReturnTypeAnnotation(DexEncodedMethod method) {
-    for (DexAnnotation annotation : method.annotations.annotations) {
+    for (DexAnnotation annotation : method.annotations().annotations) {
       if (isCovariantReturnTypeAnnotation(annotation.annotation)) {
         return true;
       }
@@ -162,7 +162,7 @@
         new DexEncodedMethod(
             newMethod,
             newAccessFlags,
-            method.annotations.keepIf(x -> !isCovariantReturnTypeAnnotation(x.annotation)),
+            method.annotations().keepIf(x -> !isCovariantReturnTypeAnnotation(x.annotation)),
             method.parameterAnnotationsList.keepIf(Predicates.alwaysTrue()),
             new SynthesizedCode(forwardSourceCodeBuilder::build),
             true);
@@ -181,7 +181,7 @@
   // then this method returns the set { SubOfFoo, SubOfSubOfFoo }.
   private Set<DexType> getCovariantReturnTypes(DexClass clazz, DexEncodedMethod method) {
     Set<DexType> covariantReturnTypes = new HashSet<>();
-    for (DexAnnotation annotation : method.annotations.annotations) {
+    for (DexAnnotation annotation : method.annotations().annotations) {
       if (isCovariantReturnTypeAnnotation(annotation.annotation)) {
         getCovariantReturnTypesFromAnnotation(
             clazz, method, annotation.annotation, covariantReturnTypes);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
index 04ce705..4409c30 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceProcessor.java
@@ -94,8 +94,14 @@
         newFlags.promoteToStatic();
         DexEncodedMethod.setDebugInfoWithFakeThisParameter(
             code, companionMethod.getArity(), appView);
-        DexEncodedMethod implMethod = new DexEncodedMethod(
-            companionMethod, newFlags, virtual.annotations, virtual.parameterAnnotationsList, code, true);
+        DexEncodedMethod implMethod =
+            new DexEncodedMethod(
+                companionMethod,
+                newFlags,
+                virtual.annotations(),
+                virtual.parameterAnnotationsList,
+                code,
+                true);
         implMethod.copyMetadata(virtual);
         virtual.setDefaultInterfaceMethodImplementation(implMethod);
         companionMethods.add(implMethod);
@@ -129,12 +135,11 @@
             : "Static interface method " + direct.toSourceString() + " is expected to "
             + "either be public or private in " + iface.origin;
         DexMethod companionMethod = rewriter.staticAsMethodOfCompanionClass(oldMethod);
-        Code code = direct.getCode();
         DexEncodedMethod implMethod =
             new DexEncodedMethod(
                 companionMethod,
                 newFlags,
-                direct.annotations,
+                direct.annotations(),
                 direct.parameterAnnotationsList,
                 direct.getCode(),
                 true);
@@ -161,7 +166,7 @@
               new DexEncodedMethod(
                   companionMethod,
                   newFlags,
-                  direct.annotations,
+                  direct.annotations(),
                   direct.parameterAnnotationsList,
                   code,
                   true);
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
index 330d72a..fae9325 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/LambdaClass.java
@@ -631,7 +631,7 @@
               new DexEncodedMethod(
                   callTarget,
                   newAccessFlags,
-                  encodedMethod.annotations,
+                  encodedMethod.annotations(),
                   encodedMethod.parameterAnnotationsList,
                   encodedMethod.getCode(),
                   true);
@@ -686,7 +686,7 @@
               new DexEncodedMethod(
                   callTarget,
                   newAccessFlags,
-                  encodedMethod.annotations,
+                  encodedMethod.annotations(),
                   encodedMethod.parameterAnnotationsList,
                   encodedMethod.getCode(),
                   true);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
index a5e9d5c4..6512985 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/LambdaMerger.java
@@ -360,7 +360,7 @@
 
     // Rewrite lambda class references into lambda group class
     // references inside methods from the processing queue.
-    rewriteLambdaReferences(converter, executorService, feedback);
+    rewriteLambdaReferences(converter, executorService);
     this.mode = null;
 
     appView.setHorizontallyMergedLambdaClasses(
@@ -425,8 +425,7 @@
     }
   }
 
-  private void rewriteLambdaReferences(
-      IRConverter converter, ExecutorService executorService, OptimizationFeedback feedback)
+  private void rewriteLambdaReferences(IRConverter converter, ExecutorService executorService)
       throws ExecutionException {
     if (methodsToReprocess.isEmpty()) {
       return;
@@ -442,27 +441,22 @@
   private void analyzeClass(DexProgramClass clazz) {
     lambdaInvalidator.accept(clazz.superType);
     lambdaInvalidator.accept(clazz.interfaces);
-    lambdaInvalidator.accept(clazz.annotations);
+    lambdaInvalidator.accept(clazz.annotations());
 
     for (DexEncodedField field : clazz.staticFields()) {
-      lambdaInvalidator.accept(field.annotations);
+      lambdaInvalidator.accept(field.annotations());
       if (field.field.type != clazz.type) {
         // Ignore static fields of the same type.
         lambdaInvalidator.accept(field.field, clazz.type);
       }
     }
     for (DexEncodedField field : clazz.instanceFields()) {
-      lambdaInvalidator.accept(field.annotations);
+      lambdaInvalidator.accept(field.annotations());
       lambdaInvalidator.accept(field.field, clazz.type);
     }
 
-    for (DexEncodedMethod method : clazz.directMethods()) {
-      lambdaInvalidator.accept(method.annotations);
-      lambdaInvalidator.accept(method.parameterAnnotationsList);
-      lambdaInvalidator.accept(method.method, clazz.type);
-    }
-    for (DexEncodedMethod method : clazz.virtualMethods()) {
-      lambdaInvalidator.accept(method.annotations);
+    for (DexEncodedMethod method : clazz.methods()) {
+      lambdaInvalidator.accept(method.annotations());
       lambdaInvalidator.accept(method.parameterAnnotationsList);
       lambdaInvalidator.accept(method.method, clazz.type);
     }
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupId.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupId.java
index 996099b..b1fabf6 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupId.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupId.java
@@ -60,7 +60,7 @@
     this.signature = signature;
     this.mainMethodName = mainMethod.method.name;
     this.mainMethodProto = mainMethod.method.proto;
-    this.mainMethodAnnotations = mainMethod.annotations;
+    this.mainMethodAnnotations = mainMethod.annotations();
     this.mainMethodParamAnnotations = mainMethod.parameterAnnotationsList;
     this.innerClassAccess = inner != null ? inner.getAccess() : MISSING_INNER_CLASS_ATTRIBUTE;
     this.enclosing = enclosing;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java
index 568a8cb..9344464 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupIdFactory.java
@@ -87,40 +87,36 @@
   }
 
   public static boolean hasValidAnnotations(Kotlin kotlin, DexClass lambda) {
-    if (!lambda.annotations.isEmpty()) {
-      for (DexAnnotation annotation : lambda.annotations.annotations) {
-        if (DexAnnotation.isSignatureAnnotation(annotation, kotlin.factory)) {
-          continue;
-        }
-        if (annotation.annotation.type == kotlin.metadata.kotlinMetadataType) {
-          continue;
-        }
-        return false;
+    for (DexAnnotation annotation : lambda.annotations().annotations) {
+      if (DexAnnotation.isSignatureAnnotation(annotation, kotlin.factory)) {
+        continue;
       }
+      if (annotation.annotation.type == kotlin.metadata.kotlinMetadataType) {
+        continue;
+      }
+      return false;
     }
     return true;
   }
 
   String validateAnnotations(Kotlin kotlin, DexClass lambda) throws LambdaStructureError {
     String signature = null;
-    if (!lambda.annotations.isEmpty()) {
-      for (DexAnnotation annotation : lambda.annotations.annotations) {
-        if (DexAnnotation.isSignatureAnnotation(annotation, kotlin.factory)) {
-          signature = DexAnnotation.getSignature(annotation);
-          continue;
-        }
-
-        if (annotation.annotation.type == kotlin.metadata.kotlinMetadataType) {
-          // Ignore kotlin metadata on lambda classes. Metadata on synthetic
-          // classes exists but is not used in the current Kotlin version (1.2.21)
-          // and newly generated lambda _group_ class is not exactly a kotlin class.
-          continue;
-        }
-
-        assert !hasValidAnnotations(kotlin, lambda);
-        throw new LambdaStructureError(
-            "unexpected annotation: " + annotation.annotation.type.toSourceString());
+    for (DexAnnotation annotation : lambda.annotations().annotations) {
+      if (DexAnnotation.isSignatureAnnotation(annotation, kotlin.factory)) {
+        signature = DexAnnotation.getSignature(annotation);
+        continue;
       }
+
+      if (annotation.annotation.type == kotlin.metadata.kotlinMetadataType) {
+        // Ignore kotlin metadata on lambda classes. Metadata on synthetic
+        // classes exists but is not used in the current Kotlin version (1.2.21)
+        // and newly generated lambda _group_ class is not exactly a kotlin class.
+        continue;
+      }
+
+      assert !hasValidAnnotations(kotlin, lambda);
+      throw new LambdaStructureError(
+          "unexpected annotation: " + annotation.annotation.type.toSourceString());
     }
     assert hasValidAnnotations(kotlin, lambda);
     return signature;
@@ -206,21 +202,31 @@
     }
   }
 
-  void checkDirectMethodAnnotations(DexEncodedMethod method) throws LambdaStructureError {
-    if (!method.annotations.isEmpty()) {
-      throw new LambdaStructureError("unexpected method annotations [" +
-          method.annotations.toSmaliString() + "] on " + method.method.toSourceString());
+  private static void checkDirectMethodAnnotations(DexEncodedMethod method)
+      throws LambdaStructureError {
+    if (!method.annotations().isEmpty()) {
+      throw new LambdaStructureError(
+          "unexpected method annotations ["
+              + method.annotations().toSmaliString()
+              + "] on "
+              + method.method.toSourceString());
     }
     if (!method.parameterAnnotationsList.isEmpty()) {
-      throw new LambdaStructureError("unexpected method parameters annotations [" +
-          method.annotations.toSmaliString() + "] on " + method.method.toSourceString());
+      throw new LambdaStructureError(
+          "unexpected method parameters annotations ["
+              + method.parameterAnnotationsList.toSmaliString()
+              + "] on "
+              + method.method.toSourceString());
     }
   }
 
   private static void checkFieldAnnotations(DexEncodedField field) throws LambdaStructureError {
-    if (!field.annotations.isEmpty()) {
-      throw new LambdaStructureError("unexpected field annotations [" +
-          field.annotations.toSmaliString() + "] on " + field.field.toSourceString());
+    if (field.hasAnnotation()) {
+      throw new LambdaStructureError(
+          "unexpected field annotations ["
+              + field.annotations().toSmaliString()
+              + "] on "
+              + field.field.toSourceString());
     }
   }
 
@@ -231,8 +237,8 @@
   }
 
   @SafeVarargs
-  static <T extends AccessFlags> void checkAccessFlags(String message, int actual, T... expected)
-      throws LambdaStructureError {
+  private static <T extends AccessFlags> void checkAccessFlags(
+      String message, int actual, T... expected) throws LambdaStructureError {
     for (T flag : expected) {
       if (actual == flag.materialize()) {
         return;
diff --git a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
index 1600057..d458662 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -139,7 +139,7 @@
     int access = clazz.accessFlags.getAsCfAccessFlags();
     String desc = namingLens.lookupDescriptor(clazz.type).toString();
     String name = namingLens.lookupInternalName(clazz.type);
-    String signature = getSignature(clazz.annotations);
+    String signature = getSignature(clazz.annotations());
     String superName =
         clazz.type == options.itemFactory.objectType
             ? null
@@ -149,8 +149,8 @@
       interfaces[i] = namingLens.lookupInternalName(clazz.interfaces.values[i]);
     }
     writer.visit(version, access, name, signature, superName, interfaces);
-    writeAnnotations(writer::visitAnnotation, clazz.annotations.annotations);
-    ImmutableMap<DexString, DexValue> defaults = getAnnotationDefaults(clazz.annotations);
+    writeAnnotations(writer::visitAnnotation, clazz.annotations().annotations);
+    ImmutableMap<DexString, DexValue> defaults = getAnnotationDefaults(clazz.annotations());
 
     if (clazz.getEnclosingMethod() != null) {
       clazz.getEnclosingMethod().write(writer, namingLens);
@@ -291,10 +291,10 @@
     int access = field.accessFlags.getAsCfAccessFlags();
     String name = namingLens.lookupName(field.field).toString();
     String desc = namingLens.lookupDescriptor(field.field.type).toString();
-    String signature = getSignature(field.annotations);
+    String signature = getSignature(field.annotations());
     Object value = getStaticValue(field);
     FieldVisitor visitor = writer.visitField(access, name, desc, signature, value);
-    writeAnnotations(visitor::visitAnnotation, field.annotations.annotations);
+    writeAnnotations(visitor::visitAnnotation, field.annotations().annotations);
     visitor.visitEnd();
   }
 
@@ -306,8 +306,8 @@
     int access = method.accessFlags.getAsCfAccessFlags();
     String name = namingLens.lookupName(method.method).toString();
     String desc = method.descriptor(namingLens);
-    String signature = getSignature(method.annotations);
-    String[] exceptions = getExceptions(method.annotations);
+    String signature = getSignature(method.annotations());
+    String[] exceptions = getExceptions(method.annotations());
     MethodVisitor visitor = writer.visitMethod(access, name, desc, signature, exceptions);
     if (defaults.containsKey(method.method.name)) {
       AnnotationVisitor defaultVisitor = visitor.visitAnnotationDefault();
@@ -316,8 +316,8 @@
         defaultVisitor.visitEnd();
       }
     }
-    writeMethodParametersAnnotation(visitor, method.annotations.annotations);
-    writeAnnotations(visitor::visitAnnotation, method.annotations.annotations);
+    writeMethodParametersAnnotation(visitor, method.annotations().annotations);
+    writeAnnotations(visitor::visitAnnotation, method.annotations().annotations);
     writeParameterAnnotations(visitor, method.parameterAnnotationsList);
     if (!method.shouldNotHaveCode()) {
       writeCode(method, visitor, classFileVersion);
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
index a195f97..fec6a34 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinClassMetadataReader.java
@@ -25,10 +25,7 @@
       Kotlin kotlin,
       DexClass clazz,
       DiagnosticsHandler reporter) {
-    if (clazz.annotations.isEmpty()) {
-      return null;
-    }
-    DexAnnotation meta = clazz.annotations.getFirstMatching(kotlin.metadata.kotlinMetadataType);
+    DexAnnotation meta = clazz.annotations().getFirstMatching(kotlin.metadata.kotlinMetadataType);
     if (meta != null) {
       try {
         return createKotlinInfo(kotlin, clazz, meta.annotation);
diff --git a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
index b295da3..9507b32 100644
--- a/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
+++ b/src/main/java/com/android/tools/r8/kotlin/KotlinMetadataRewriter.java
@@ -47,7 +47,7 @@
 
   public static void removeKotlinMetadataFromRenamedClass(AppView<?> appView, DexClass clazz) {
     // Remove @Metadata in DexAnnotation form if a class is renamed.
-    clazz.annotations = clazz.annotations.keepIf(anno -> isNotKotlinMetadata(appView, anno));
+    clazz.setAnnotations(clazz.annotations().keepIf(anno -> isNotKotlinMetadata(appView, anno)));
     // Clear associated {@link KotlinInfo} to avoid accidentally deserialize it back to
     // DexAnnotation we've just removed above.
     if (clazz.isProgramClass()) {
@@ -72,11 +72,12 @@
             // TODO(b/70169921): if this option is settled down, this assertion is meaningless.
             assert lens.lookupType(clazz.type, appView.dexItemFactory()) == clazz.type
                     || appView.options().enableKotlinMetadataRewritingForRenamedClasses
-                : clazz.toSourceString() + " != "
+                : clazz.toSourceString()
+                    + " != "
                     + lens.lookupType(clazz.type, appView.dexItemFactory());
 
             DexAnnotation oldMeta =
-                clazz.annotations.getFirstMatching(kotlin.metadata.kotlinMetadataType);
+                clazz.annotations().getFirstMatching(kotlin.metadata.kotlinMetadataType);
             // If @Metadata is already gone, e.g., by {@link AnnotationRemover} if type Metadata is
             // determined as dead (e.g., due to no keep rule), nothing to do.
             if (oldMeta == null) {
@@ -86,11 +87,11 @@
             kotlinInfo.rewrite(appView, lens);
 
             DexAnnotation newMeta = createKotlinMetadataAnnotation(kotlinInfo.createHeader());
-            clazz.annotations = clazz.annotations.rewrite(anno -> anno == oldMeta ? newMeta : anno);
+            clazz.setAnnotations(
+                clazz.annotations().rewrite(anno -> anno == oldMeta ? newMeta : anno));
           }
         },
-        executorService
-    );
+        executorService);
   }
 
   private DexAnnotation createKotlinMetadataAnnotation(KotlinClassHeader header) {
diff --git a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
index 45c59a8..e891f95 100644
--- a/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
+++ b/src/main/java/com/android/tools/r8/naming/signature/GenericSignatureRewriter.java
@@ -54,28 +54,28 @@
     // ClassNameMinifier.
     for (DexProgramClass clazz : classes) {
       genericSignatureCollector.setCurrentClassContext(clazz);
-      clazz.annotations =
+      clazz.setAnnotations(
           rewriteGenericSignatures(
-              clazz.annotations,
+              clazz.annotations(),
               genericSignatureParser::parseClassSignature,
               genericSignatureCollector::getRenamedSignature,
-              (signature, e) -> parseError(clazz, clazz.getOrigin(), signature, e));
+              (signature, e) -> parseError(clazz, clazz.getOrigin(), signature, e)));
       clazz.forEachField(
           field ->
-              field.annotations =
+              field.setAnnotations(
                   rewriteGenericSignatures(
-                      field.annotations,
+                      field.annotations(),
                       genericSignatureParser::parseFieldSignature,
                       genericSignatureCollector::getRenamedSignature,
-                      (signature, e) -> parseError(field, clazz.getOrigin(), signature, e)));
+                      (signature, e) -> parseError(field, clazz.getOrigin(), signature, e))));
       clazz.forEachMethod(
           method ->
-              method.annotations =
+              method.setAnnotations(
                   rewriteGenericSignatures(
-                      method.annotations,
+                      method.annotations(),
                       genericSignatureParser::parseMethodSignature,
                       genericSignatureCollector::getRenamedSignature,
-                      (signature, e) -> parseError(method, clazz.getOrigin(), signature, e)));
+                      (signature, e) -> parseError(method, clazz.getOrigin(), signature, e))));
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/shaking/AnnotationFixer.java b/src/main/java/com/android/tools/r8/shaking/AnnotationFixer.java
index 356f609..0fe561c 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationFixer.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationFixer.java
@@ -27,21 +27,21 @@
 
   public void run(Iterable<DexProgramClass> classes) {
     for (DexProgramClass clazz : classes) {
-      clazz.annotations = clazz.annotations.rewrite(this::rewriteAnnotation);
+      clazz.setAnnotations(clazz.annotations().rewrite(this::rewriteAnnotation));
       clazz.forEachMethod(this::processMethod);
       clazz.forEachField(this::processField);
     }
   }
 
   private void processMethod(DexEncodedMethod method) {
-    method.annotations = method.annotations.rewrite(this::rewriteAnnotation);
+    method.setAnnotations(method.annotations().rewrite(this::rewriteAnnotation));
     method.parameterAnnotationsList =
         method.parameterAnnotationsList.rewrite(
             dexAnnotationSet -> dexAnnotationSet.rewrite(this::rewriteAnnotation));
   }
 
   private void processField(DexEncodedField field) {
-    field.annotations = field.annotations.rewrite(this::rewriteAnnotation);
+    field.setAnnotations(field.annotations().rewrite(this::rewriteAnnotation));
   }
 
   private DexAnnotation rewriteAnnotation(DexAnnotation original) {
diff --git a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
index fd3e7f5..6cfa6d8 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
@@ -8,7 +8,6 @@
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationElement;
-import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexDefinition;
 import com.android.tools.r8.graph.DexEncodedAnnotation;
@@ -157,7 +156,7 @@
   }
 
   private static boolean hasSignatureAnnotation(DexProgramClass clazz, DexItemFactory itemFactory) {
-    for (DexAnnotation annotation : clazz.annotations.annotations) {
+    for (DexAnnotation annotation : clazz.annotations().annotations) {
       if (DexAnnotation.isSignatureAnnotation(annotation, itemFactory)) {
         return true;
       }
@@ -230,23 +229,23 @@
   public void run() {
     for (DexProgramClass clazz : appView.appInfo().classes()) {
       stripAttributes(clazz);
-      clazz.annotations =
-          clazz.annotations.rewrite(annotation -> rewriteAnnotation(clazz, annotation));
+      clazz.setAnnotations(
+          clazz.annotations().rewrite(annotation -> rewriteAnnotation(clazz, annotation)));
       clazz.forEachMethod(this::processMethod);
       clazz.forEachField(this::processField);
     }
   }
 
   private void processMethod(DexEncodedMethod method) {
-    method.annotations =
-        method.annotations.rewrite(annotation -> rewriteAnnotation(method, annotation));
+    method.setAnnotations(
+        method.annotations().rewrite(annotation -> rewriteAnnotation(method, annotation)));
     method.parameterAnnotationsList =
         method.parameterAnnotationsList.keepIf(this::filterParameterAnnotations);
   }
 
   private void processField(DexEncodedField field) {
-    field.annotations =
-        field.annotations.rewrite(annotation -> rewriteAnnotation(field, annotation));
+    field.setAnnotations(
+        field.annotations().rewrite(annotation -> rewriteAnnotation(field, annotation)));
   }
 
   private DexAnnotation rewriteAnnotation(DexDefinition holder, DexAnnotation original) {
@@ -359,13 +358,8 @@
 
   public static void clearAnnotations(AppView<?> appView) {
     for (DexProgramClass clazz : appView.appInfo().classes()) {
-      clazz.annotations = DexAnnotationSet.empty();
-      for (DexEncodedMethod method : clazz.methods()) {
-        method.annotations = DexAnnotationSet.empty();
-      }
-      for (DexEncodedField field : clazz.fields()) {
-        field.annotations = DexAnnotationSet.empty();
-      }
+      clazz.clearAnnotations();
+      clazz.members().forEach(DexDefinition::clearAnnotations);
     }
   }
 }
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 b55b96e..e2dfeb8 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -28,6 +28,7 @@
 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;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexClasspathClass;
@@ -1286,15 +1287,14 @@
       enqueueFirstNonSerializableClassInitializer(holder, reason);
     }
 
-    if (!holder.annotations.isEmpty()) {
-      processAnnotations(holder, holder.annotations.annotations);
-    }
+    processAnnotations(holder, holder);
+
     // If this type has deferred annotations, we have to process those now, too.
     Set<DexAnnotation> annotations = deferredAnnotations.remove(holder.type);
     if (annotations != null && !annotations.isEmpty()) {
       assert holder.accessFlags.isAnnotation();
       assert annotations.stream().allMatch(a -> a.annotation.type == holder.type);
-      annotations.forEach(annotation -> handleAnnotation(holder, annotation));
+      annotations.forEach(annotation -> processAnnotation(holder, holder, annotation));
     }
 
     rootSet.forEachDependentStaticMember(holder, appView, this::enqueueDependentItem);
@@ -1351,31 +1351,43 @@
     internalEnqueueRootItem(consequent, reasons, precondition);
   }
 
-  private void processAnnotations(DexDefinition holder, DexAnnotation[] annotations) {
+  private void processAnnotations(DexProgramClass holder, DexDefinition annotatedItem) {
+    processAnnotations(holder, annotatedItem, annotatedItem.annotations());
+  }
+
+  private void processAnnotations(
+      DexProgramClass holder, DexDefinition annotatedItem, DexAnnotationSet annotations) {
+    processAnnotations(holder, annotatedItem, annotations.annotations);
+  }
+
+  private void processAnnotations(
+      DexProgramClass holder, DexDefinition annotatedItem, DexAnnotation[] annotations) {
     for (DexAnnotation annotation : annotations) {
-      processAnnotation(holder, annotation);
+      processAnnotation(holder, annotatedItem, annotation);
     }
   }
 
-  private void processAnnotation(DexDefinition holder, DexAnnotation annotation) {
-    handleAnnotation(holder, annotation);
-  }
-
-  private void handleAnnotation(DexDefinition holder, DexAnnotation annotation) {
+  private void processAnnotation(
+      DexProgramClass holder, DexDefinition annotatedItem, DexAnnotation annotation) {
+    assert annotatedItem == holder
+        || (annotatedItem.isDexEncodedField()
+            && annotatedItem.asDexEncodedField().field.holder == holder.type)
+        || (annotatedItem.isDexEncodedMethod()
+            && annotatedItem.asDexEncodedMethod().method.holder == holder.type);
     assert !holder.isDexClass() || holder.asDexClass().isProgramClass();
     DexType type = annotation.annotation.type;
     recordTypeReference(type);
     DexClass clazz = appView.definitionFor(type);
     boolean annotationTypeIsLibraryClass = clazz == null || clazz.isNotProgramClass();
     boolean isLive = annotationTypeIsLibraryClass || liveTypes.contains(clazz.asProgramClass());
-    if (!shouldKeepAnnotation(holder, annotation, isLive, appView)) {
+    if (!shouldKeepAnnotation(annotatedItem, annotation, isLive, appView)) {
       // Remember this annotation for later.
       if (!annotationTypeIsLibraryClass) {
         deferredAnnotations.computeIfAbsent(type, ignore -> new HashSet<>()).add(annotation);
       }
       return;
     }
-    KeepReason reason = KeepReason.annotatedOn(holder);
+    KeepReason reason = KeepReason.annotatedOn(annotatedItem);
     liveAnnotations.add(annotation, reason);
     AnnotationReferenceMarker referenceMarker =
         new AnnotationReferenceMarker(annotation.annotation.type, appView.dexItemFactory(), reason);
@@ -1561,9 +1573,9 @@
       return;
     }
     markReferencedTypesAsLive(method);
-    processAnnotations(method, method.annotations.annotations);
+    processAnnotations(clazz, method);
     method.parameterAnnotationsList.forEachAnnotation(
-        annotation -> processAnnotation(method, annotation));
+        annotation -> processAnnotation(clazz, method, annotation));
 
     if (Log.ENABLED) {
       Log.verbose(getClass(), "Method `%s` is targeted.", method.method);
@@ -1815,7 +1827,7 @@
       if (reachableFields != null) {
         for (DexEncodedField field : reachableFields.getItems()) {
           // TODO(b/120959039): Should the reason this field is reachable come from the set?
-          markInstanceFieldAsLive(field, KeepReason.reachableFromLiveType(clazz.type));
+          markInstanceFieldAsLive(clazz, field, KeepReason.reachableFromLiveType(clazz.type));
         }
       }
       clazz = getProgramClassOrNull(clazz.superType);
@@ -1881,7 +1893,7 @@
             encodedField.field);
       }
     }
-    processAnnotations(encodedField, encodedField.annotations.annotations);
+    processAnnotations(clazz, encodedField);
     liveFields.add(encodedField, reason);
 
     // Add all dependent members to the workqueue.
@@ -1891,7 +1903,8 @@
     analyses.forEach(analysis -> analysis.processNewlyLiveField(encodedField));
   }
 
-  private void markInstanceFieldAsLive(DexEncodedField field, KeepReason reason) {
+  private void markInstanceFieldAsLive(
+      DexProgramClass holder, DexEncodedField field, KeepReason reason) {
     assert field != null;
     assert field.isProgramField(appView);
     markTypeAsLive(field.field.holder, reason);
@@ -1899,7 +1912,7 @@
     if (Log.ENABLED) {
       Log.verbose(getClass(), "Adding instance field `%s` to live set.", field.field);
     }
-    processAnnotations(field, field.annotations.annotations);
+    processAnnotations(holder, field);
     liveFields.add(field, reason);
 
     // Add all dependent members to the workqueue.
@@ -2038,7 +2051,7 @@
       markStaticFieldAsLive(encodedField, reason);
     } else {
       if (isInstantiatedOrHasInstantiatedSubtype(clazz)) {
-        markInstanceFieldAsLive(encodedField, reason);
+        markInstanceFieldAsLive(clazz, encodedField, reason);
       } else {
         // Add the field to the reachable set if the type later becomes instantiated.
         reachableInstanceFields
@@ -2966,9 +2979,9 @@
       }
     }
     markParameterAndReturnTypesAsLive(method);
-    processAnnotations(method, method.annotations.annotations);
+    processAnnotations(clazz, method);
     method.parameterAnnotationsList.forEachAnnotation(
-        annotation -> processAnnotation(method, annotation));
+        annotation -> processAnnotation(clazz, method, annotation));
     method.registerCodeReferences(useRegistryFactory.create(appView, clazz, method, this));
 
     // Add all dependent members to the workqueue.
diff --git a/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java b/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java
index 47cc590..3a6fcae 100644
--- a/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java
+++ b/src/main/java/com/android/tools/r8/shaking/MainDexDirectReferenceTracer.java
@@ -43,7 +43,7 @@
       assert clazz != null;
       consumer.accept(type);
       // Super and interfaces are live, no need to add them.
-      traceAnnotationsDirectDependencies(clazz.annotations);
+      traceAnnotationsDirectDependencies(clazz.annotations());
       clazz.forEachField(field -> consumer.accept(field.field.type));
       clazz.forEachMethod(method -> {
         traceMethodDirectDependencies(method.method, consumer);
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 4186091..7495c6b 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetBuilder.java
@@ -871,11 +871,11 @@
   }
 
   static boolean containsAnnotation(ProguardTypeMatcher classAnnotation, DexClass clazz) {
-    return containsAnnotation(classAnnotation, clazz.annotations);
+    return containsAnnotation(classAnnotation, clazz.annotations());
   }
 
   static boolean containsAnnotation(ProguardTypeMatcher classAnnotation, DexEncodedMethod method) {
-    if (containsAnnotation(classAnnotation, method.annotations)) {
+    if (containsAnnotation(classAnnotation, method.annotations())) {
       return true;
     }
     for (int i = 0; i < method.parameterAnnotationsList.size(); i++) {
@@ -887,7 +887,7 @@
   }
 
   static boolean containsAnnotation(ProguardTypeMatcher classAnnotation, DexEncodedField field) {
-    return containsAnnotation(classAnnotation, field.annotations);
+    return containsAnnotation(classAnnotation, field.annotations());
   }
 
   private static boolean containsAnnotation(
diff --git a/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java b/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
index 53bb117..666cb87 100644
--- a/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
+++ b/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
@@ -17,6 +17,7 @@
 import com.android.tools.r8.code.IfNez;
 import com.android.tools.r8.code.Instruction;
 import com.android.tools.r8.code.ReturnVoid;
+import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexCode;
 import com.android.tools.r8.graph.DexCode.Try;
 import com.android.tools.r8.graph.DexEncodedMethod;
@@ -160,7 +161,8 @@
         null);
     MethodAccessFlags flags = MethodAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC, false);
     DexEncodedMethod method =
-        new DexEncodedMethod(null, flags, null, ParameterAnnotationsList.empty(), code);
+        new DexEncodedMethod(
+            null, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code);
     return new JumboStringRewriter(method, string, factory).rewrite();
   }
 }
diff --git a/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java b/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
index b567014..7b7036f 100644
--- a/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
+++ b/src/test/java/com/android/tools/r8/ir/conversion/CallGraphTestBase.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8.ir.conversion;
 
 import com.android.tools.r8.TestBase;
+import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
@@ -20,7 +21,8 @@
             dexItemFactory.createProto(dexItemFactory.voidType),
             methodName);
     return new Node(
-        new DexEncodedMethod(signature, null, null, ParameterAnnotationsList.empty(), null));
+        new DexEncodedMethod(
+            signature, null, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null));
   }
 
   Node createForceInlinedNode(String methodName) {
diff --git a/src/test/java/com/android/tools/r8/shaking/annotations/ProgramAnnotationRemovalTest.java b/src/test/java/com/android/tools/r8/shaking/annotations/ProgramAnnotationRemovalTest.java
index 0cf779d..3396686 100644
--- a/src/test/java/com/android/tools/r8/shaking/annotations/ProgramAnnotationRemovalTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/annotations/ProgramAnnotationRemovalTest.java
@@ -67,12 +67,12 @@
     MethodSubject methodWithLiveProgramAnnotationSubject =
         testClassSubject.uniqueMethodWithName("methodWithLiveProgramAnnotation");
     assertThat(methodWithLiveProgramAnnotationSubject, isPresent());
-    assertEquals(1, methodWithLiveProgramAnnotationSubject.getMethod().annotations.size());
+    assertEquals(1, methodWithLiveProgramAnnotationSubject.getMethod().annotations().size());
 
     MethodSubject methodWithDeadProgramAnnotationSubject =
         testClassSubject.uniqueMethodWithName("methodWithDeadProgramAnnotation");
     assertThat(methodWithDeadProgramAnnotationSubject, isPresent());
-    assertEquals(0, methodWithDeadProgramAnnotationSubject.getMethod().annotations.size());
+    assertEquals(0, methodWithDeadProgramAnnotationSubject.getMethod().annotations().size());
 
     result.assertSuccessWithOutputLines("@" + liveAnnotationClassSubject.getFinalName() + "()");
   }
diff --git a/src/test/java/com/android/tools/r8/shaking/attributes/KeepAttributesDotsTest.java b/src/test/java/com/android/tools/r8/shaking/attributes/KeepAttributesDotsTest.java
index 58671ab..5a978c6 100644
--- a/src/test/java/com/android/tools/r8/shaking/attributes/KeepAttributesDotsTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/attributes/KeepAttributesDotsTest.java
@@ -69,11 +69,11 @@
 
   private void inspect(CodeInspector inspector) {
     ClassSubject clazz = inspector.clazz(Main.class);
-    assertTrue(clazz.getDexClass().annotations.isEmpty());
+    assertTrue(clazz.getDexClass().annotations().isEmpty());
     MethodSubject main = clazz.uniqueMethodWithName("main");
-    assertTrue(main.getMethod().annotations.isEmpty());
+    assertTrue(main.getMethod().annotations().isEmpty());
     FieldSubject field = clazz.uniqueFieldWithName("field");
-    assertTrue(field.getField().annotations.isEmpty());
+    assertTrue(field.getField().annotations().isEmpty());
     assertTrue(clazz.getDexClass().sourceFile == null || clazz.getDexClass().sourceFile.size == 0);
     assertNull(main.getLineNumberTable());
     assertTrue(main.getLocalVariableTable().isEmpty());
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
index 3e83c5d..c0dba89 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundClassSubject.java
@@ -230,7 +230,7 @@
     assert !name.endsWith("EnclosingClass")
         && !name.endsWith("EnclosingMethod")
         && !name.endsWith("InnerClass");
-    DexAnnotation annotation = codeInspector.findAnnotation(name, dexClass.annotations);
+    DexAnnotation annotation = codeInspector.findAnnotation(name, dexClass.annotations());
     return annotation == null
         ? new AbsentAnnotationSubject()
         : new FoundAnnotationSubject(annotation);
@@ -296,12 +296,12 @@
   @Override
   public String getOriginalSignatureAttribute() {
     return codeInspector.getOriginalSignatureAttribute(
-        dexClass.annotations, GenericSignatureParser::parseClassSignature);
+        dexClass.annotations(), GenericSignatureParser::parseClassSignature);
   }
 
   @Override
   public String getFinalSignatureAttribute() {
-    return codeInspector.getFinalSignatureAttribute(dexClass.annotations);
+    return codeInspector.getFinalSignatureAttribute(dexClass.annotations());
   }
 
   @Override
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
index 6494955..411dad2 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundFieldSubject.java
@@ -134,17 +134,17 @@
   @Override
   public String getOriginalSignatureAttribute() {
     return codeInspector.getOriginalSignatureAttribute(
-        dexField.annotations, GenericSignatureParser::parseFieldSignature);
+        dexField.annotations(), GenericSignatureParser::parseFieldSignature);
   }
 
   @Override
   public String getFinalSignatureAttribute() {
-    return codeInspector.getFinalSignatureAttribute(dexField.annotations);
+    return codeInspector.getFinalSignatureAttribute(dexField.annotations());
   }
 
   @Override
   public AnnotationSubject annotation(String name) {
-    DexAnnotation annotation = codeInspector.findAnnotation(name, dexField.annotations);
+    DexAnnotation annotation = codeInspector.findAnnotation(name, dexField.annotations());
     return annotation == null
         ? new AbsentAnnotationSubject()
         : new FoundAnnotationSubject(annotation);
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
index c220f01..fe574e4 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
@@ -37,7 +37,6 @@
 import com.android.tools.r8.utils.codeinspector.LocalVariableTable.LocalVariableTableEntry;
 import com.google.common.base.Predicates;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Streams;
 import it.unimi.dsi.fastutil.objects.Object2IntMap;
 import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
 import java.util.Arrays;
@@ -180,7 +179,7 @@
   @Override
   public String getOriginalSignatureAttribute() {
     return codeInspector.getOriginalSignatureAttribute(
-        dexMethod.annotations, GenericSignatureParser::parseMethodSignature);
+        dexMethod.annotations(), GenericSignatureParser::parseMethodSignature);
   }
 
   public DexMethod getOriginalDexMethod(DexItemFactory dexItemFactory) {
@@ -194,7 +193,7 @@
 
   @Override
   public String getFinalSignatureAttribute() {
-    return codeInspector.getFinalSignatureAttribute(dexMethod.annotations);
+    return codeInspector.getFinalSignatureAttribute(dexMethod.annotations());
   }
 
   public Iterable<InstructionSubject> instructions() {
@@ -338,7 +337,7 @@
 
   @Override
   public AnnotationSubject annotation(String name) {
-    DexAnnotation annotation = codeInspector.findAnnotation(name, dexMethod.annotations);
+    DexAnnotation annotation = codeInspector.findAnnotation(name, dexMethod.annotations());
     return annotation == null
         ? new AbsentAnnotationSubject()
         : new FoundAnnotationSubject(annotation);