Model generic signatures for methods

Bug: 129925954
Change-Id: Ief5eebee91bf27f7d92a17e656ae8bd7e2714d08
diff --git a/src/main/java/com/android/tools/r8/GenerateLintFiles.java b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
index c295175..6a2a8c5 100644
--- a/src/main/java/com/android/tools/r8/GenerateLintFiles.java
+++ b/src/main/java/com/android/tools/r8/GenerateLintFiles.java
@@ -25,6 +25,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -142,6 +143,7 @@
           new DexEncodedMethod(
               method.method,
               method.accessFlags,
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               code,
@@ -174,7 +176,7 @@
             Collections.emptyList(),
             null,
             Collections.emptyList(),
-            ClassSignature.NO_CLASS_SIGNATURE,
+            ClassSignature.noSignature(),
             DexAnnotationSet.empty(),
             DexEncodedField.EMPTY_ARRAY,
             DexEncodedField.EMPTY_ARRAY,
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 f39795b..77a7d70 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -461,6 +461,7 @@
     for (DexProgramClass clazz : appView.appInfo().classes()) {
       insertAttributeAnnotationsForClass(clazz);
       clazz.fields().forEach(this::insertAttributeAnnotationsForField);
+      clazz.methods().forEach(this::insertAttributeAnnotationsForMethod);
     }
   }
 
@@ -546,18 +547,33 @@
   }
 
   private void insertAttributeAnnotationsForField(DexEncodedField field) {
-    if (field.getFieldSignature().hasNoSignature()) {
+    if (field.getGenericSignature().hasNoSignature()) {
       return;
     }
-    // Append the annotations to annotations array of the class.
+    // Append the annotations to annotations array of the field.
     field.setAnnotations(
         new DexAnnotationSet(
             ArrayUtils.appendSingleElement(
                 field.annotations().annotations,
                 DexAnnotation.createSignatureAnnotation(
-                    field.getFieldSignature().toRenamedString(namingLens, isTypeMissing),
+                    field.getGenericSignature().toRenamedString(namingLens, isTypeMissing),
                     options.itemFactory))));
-    field.clearFieldSignature();
+    field.clearGenericSignature();
+  }
+
+  private void insertAttributeAnnotationsForMethod(DexEncodedMethod method) {
+    if (method.getGenericSignature().hasNoSignature()) {
+      return;
+    }
+    // Append the annotations to annotations array of the method.
+    method.setAnnotations(
+        new DexAnnotationSet(
+            ArrayUtils.appendSingleElement(
+                method.annotations().annotations,
+                DexAnnotation.createSignatureAnnotation(
+                    method.getGenericSignature().toRenamedString(namingLens, isTypeMissing),
+                    options.itemFactory))));
+    method.clearGenericSignature();
   }
 
   private void setCallSiteContexts(ExecutorService executorService) throws ExecutionException {
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 6f00265..4941d0b 100644
--- a/src/main/java/com/android/tools/r8/dex/DexParser.java
+++ b/src/main/java/com/android/tools/r8/dex/DexParser.java
@@ -674,11 +674,22 @@
         code = codes.get(codeOff);
       }
       DexMethod method = indexedItems.getMethod(methodIndex);
+      DexAnnotationSet methodAnnotations = annotationIterator.getNextFor(method);
+      String methodSignature = DexAnnotation.getSignature(methodAnnotations, dexItemFactory);
+      if (methodSignature != null) {
+        methodAnnotations = methodAnnotations.getWithout(dexItemFactory.annotationSignature);
+      }
       methods[i] =
           new DexEncodedMethod(
               method,
               accessFlags,
-              annotationIterator.getNextFor(method),
+              GenericSignature.parseMethodSignature(
+                  method.name.toString(),
+                  methodSignature,
+                  origin,
+                  dexItemFactory,
+                  options.reporter),
+              methodAnnotations,
               parameterAnnotationsIterator.getNextFor(method),
               code);
     }
@@ -1343,7 +1354,7 @@
     private EnclosingMethodAttribute enclosingMethodAttribute = null;
     private List<InnerClassAttribute> innerClasses = null;
     private List<DexAnnotation> lazyAnnotations = null;
-    private ClassSignature classSignature = ClassSignature.NO_CLASS_SIGNATURE;
+    private ClassSignature classSignature = ClassSignature.noSignature();
 
     public DexAnnotationSet getAnnotations() {
       if (lazyAnnotations != null) {
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 d883e3e..f23ffde 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -769,7 +769,7 @@
   }
 
   public void clearClassSignature() {
-    classSignature = ClassSignature.NO_CLASS_SIGNATURE;
+    classSignature = ClassSignature.noSignature();
   }
 
   public void removeInnerClasses(Predicate<InnerClassAttribute> predicate) {
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 8e51e49..b484342 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedField.java
@@ -4,7 +4,6 @@
 package com.android.tools.r8.graph;
 
 import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
 import static com.android.tools.r8.ir.analysis.type.Nullability.maybeNull;
 import static com.android.tools.r8.kotlin.KotlinMetadataUtils.NO_KOTLIN_INFO;
 
@@ -31,7 +30,7 @@
   private DexValue staticValue;
   private final boolean deprecated;
   /** Generic signature information if the attribute is present in the input */
-  private FieldTypeSignature fieldSignature;
+  private FieldTypeSignature genericSignature;
 
   private FieldOptimizationInfo optimizationInfo = DefaultFieldOptimizationInfo.getInstance();
   private KotlinFieldLevelInfo kotlinMemberInfo = NO_KOTLIN_INFO;
@@ -39,7 +38,7 @@
   public DexEncodedField(
       DexField field,
       FieldAccessFlags accessFlags,
-      FieldTypeSignature fieldSignature,
+      FieldTypeSignature genericSignature,
       DexAnnotationSet annotations,
       DexValue staticValue,
       boolean deprecated) {
@@ -48,18 +47,18 @@
     this.accessFlags = accessFlags;
     this.staticValue = staticValue;
     this.deprecated = deprecated;
-    this.fieldSignature = fieldSignature;
-    assert fieldSignature != null;
-    assert GenericSignatureUtils.verifyNoDuplicateGenericDefinitions(fieldSignature, annotations);
+    this.genericSignature = genericSignature;
+    assert genericSignature != null;
+    assert GenericSignatureUtils.verifyNoDuplicateGenericDefinitions(genericSignature, annotations);
   }
 
   public DexEncodedField(
       DexField field,
       FieldAccessFlags accessFlags,
-      FieldTypeSignature fieldSignature,
+      FieldTypeSignature genericSignature,
       DexAnnotationSet annotations,
       DexValue staticValue) {
-    this(field, accessFlags, fieldSignature, annotations, staticValue, false);
+    this(field, accessFlags, genericSignature, annotations, staticValue, false);
   }
 
   public DexType type() {
@@ -299,7 +298,7 @@
     }
     // TODO(b/169923358): Consider removing the fieldSignature here.
     DexEncodedField result =
-        new DexEncodedField(field, accessFlags, fieldSignature, annotations(), staticValue);
+        new DexEncodedField(field, accessFlags, genericSignature, annotations(), staticValue);
     result.optimizationInfo =
         optimizationInfo.isMutableFieldOptimizationInfo()
             ? optimizationInfo.asMutableFieldOptimizationInfo().mutableCopy()
@@ -322,16 +321,16 @@
     return true;
   }
 
-  public FieldTypeSignature getFieldSignature() {
-    return fieldSignature;
+  public FieldTypeSignature getGenericSignature() {
+    return genericSignature;
   }
 
-  public void setFieldSignature(FieldTypeSignature fieldSignature) {
-    assert fieldSignature != null;
-    this.fieldSignature = fieldSignature;
+  public void setGenericSignature(FieldTypeSignature genericSignature) {
+    assert genericSignature != null;
+    this.genericSignature = genericSignature;
   }
 
-  public void clearFieldSignature() {
-    this.fieldSignature = NO_FIELD_TYPE_SIGNATURE;
+  public void clearGenericSignature() {
+    this.genericSignature = FieldTypeSignature.noSignature();
   }
 }
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 c30f69c..a972aed 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -42,6 +42,7 @@
 import com.android.tools.r8.dex.MixedSectionCollection;
 import com.android.tools.r8.errors.InternalCompilerError;
 import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.code.Invoke;
 import com.android.tools.r8.ir.code.NumericType;
@@ -131,6 +132,7 @@
       new DexEncodedMethod(
           null,
           MethodAccessFlags.fromDexAccessFlags(0),
+          MethodTypeSignature.noSignature(),
           DexAnnotationSet.empty(),
           ParameterAnnotationsList.empty(),
           null);
@@ -149,6 +151,8 @@
   private CallSiteOptimizationInfo callSiteOptimizationInfo = CallSiteOptimizationInfo.bottom();
   private int classFileVersion;
   private KotlinMethodLevelInfo kotlinMemberInfo = NO_KOTLIN_INFO;
+  /** Generic signature information if the attribute is present in the input */
+  private MethodTypeSignature genericSignature;
 
   private DexEncodedMethod defaultInterfaceMethodImplementation = null;
 
@@ -225,25 +229,44 @@
   public DexEncodedMethod(
       DexMethod method,
       MethodAccessFlags accessFlags,
+      MethodTypeSignature genericSignature,
       DexAnnotationSet annotations,
       ParameterAnnotationsList parameterAnnotationsList,
       Code code) {
-    this(method, accessFlags, annotations, parameterAnnotationsList, code, false, -1);
+    this(
+        method,
+        accessFlags,
+        genericSignature,
+        annotations,
+        parameterAnnotationsList,
+        code,
+        false,
+        -1);
   }
 
   public DexEncodedMethod(
       DexMethod method,
       MethodAccessFlags accessFlags,
+      MethodTypeSignature genericSignature,
       DexAnnotationSet annotations,
       ParameterAnnotationsList parameterAnnotationsList,
       Code code,
       boolean d8R8Synthesized) {
-    this(method, accessFlags, annotations, parameterAnnotationsList, code, d8R8Synthesized, -1);
+    this(
+        method,
+        accessFlags,
+        genericSignature,
+        annotations,
+        parameterAnnotationsList,
+        code,
+        d8R8Synthesized,
+        -1);
   }
 
   public DexEncodedMethod(
       DexMethod method,
       MethodAccessFlags accessFlags,
+      MethodTypeSignature genericSignature,
       DexAnnotationSet annotations,
       ParameterAnnotationsList parameterAnnotationsList,
       Code code,
@@ -252,6 +275,7 @@
     this(
         method,
         accessFlags,
+        genericSignature,
         annotations,
         parameterAnnotationsList,
         code,
@@ -263,6 +287,7 @@
   public DexEncodedMethod(
       DexMethod method,
       MethodAccessFlags accessFlags,
+      MethodTypeSignature genericSignature,
       DexAnnotationSet annotations,
       ParameterAnnotationsList parameterAnnotationsList,
       Code code,
@@ -273,6 +298,7 @@
     this.method = method;
     this.accessFlags = accessFlags;
     this.deprecated = deprecated;
+    this.genericSignature = genericSignature;
     this.parameterAnnotationsList = parameterAnnotationsList;
     this.code = code;
     this.classFileVersion = classFileVersion;
@@ -1146,6 +1172,7 @@
         new DexEncodedMethod(
             newMethod,
             accessFlags,
+            MethodTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             ParameterAnnotationsList.empty(),
             code,
@@ -1175,6 +1202,7 @@
     return new DexEncodedMethod(
         newMethod,
         accessFlags,
+        MethodTypeSignature.noSignature(),
         DexAnnotationSet.empty(),
         ParameterAnnotationsList.empty(),
         code,
@@ -1278,6 +1306,7 @@
     return new DexEncodedMethod(
         newMethod,
         newFlags,
+        MethodTypeSignature.noSignature(),
         DexAnnotationSet.empty(),
         ParameterAnnotationsList.empty(),
         new SynthesizedCode(forwardSourceCodeBuilder::build),
@@ -1399,6 +1428,19 @@
     }
   }
 
+  public MethodTypeSignature getGenericSignature() {
+    return genericSignature;
+  }
+
+  public void setGenericSignature(MethodTypeSignature genericSignature) {
+    assert genericSignature != null;
+    this.genericSignature = genericSignature;
+  }
+
+  public void clearGenericSignature() {
+    this.genericSignature = MethodTypeSignature.noSignature();
+  }
+
   private static Builder syntheticBuilder(DexEncodedMethod from) {
     return new Builder(from, true);
   }
@@ -1411,6 +1453,7 @@
 
     private DexMethod method;
     private final MethodAccessFlags accessFlags;
+    private final MethodTypeSignature genericSignature;
     private final DexAnnotationSet annotations;
     private OptionalBool isLibraryMethodOverride = OptionalBool.UNKNOWN;
     private ParameterAnnotationsList parameterAnnotations;
@@ -1429,6 +1472,7 @@
       // Copy all the mutable state of a DexEncodedMethod here.
       method = from.method;
       accessFlags = from.accessFlags.copy();
+      genericSignature = from.getGenericSignature();
       annotations = from.annotations();
       code = from.code;
       compilationState = CompilationState.NOT_PROCESSED;
@@ -1529,6 +1573,7 @@
           new DexEncodedMethod(
               method,
               accessFlags,
+              genericSignature,
               annotations,
               parameterAnnotations,
               code,
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignature.java b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
index bbff32c..ffb7eed 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignature.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
@@ -128,6 +128,12 @@
     default MethodTypeSignature asMethodTypeSignature() {
       return null;
     }
+
+    boolean hasSignature();
+
+    default boolean hasNoSignature() {
+      return !hasSignature();
+    }
   }
 
   public static class FormalTypeParameter {
@@ -168,7 +174,7 @@
 
   public static class ClassSignature implements DexDefinitionSignature<DexClass> {
 
-    public static final ClassSignature NO_CLASS_SIGNATURE =
+    private static final ClassSignature NO_CLASS_SIGNATURE =
         new ClassSignature(EMPTY_TYPE_PARAMS, NO_FIELD_TYPE_SIGNATURE, EMPTY_SUPER_INTERFACES);
 
     final List<FormalTypeParameter> formalTypeParameters;
@@ -195,14 +201,11 @@
       return superInterfaceSignatures;
     }
 
+    @Override
     public boolean hasSignature() {
       return this != NO_CLASS_SIGNATURE;
     }
 
-    public boolean hasNoSignature() {
-      return !hasSignature();
-    }
-
     @Override
     public boolean isClassSignature() {
       return true;
@@ -235,6 +238,10 @@
     public String toString() {
       return toRenamedString(NamingLens.getIdentityLens(), alwaysTrue());
     }
+
+    public static ClassSignature noSignature() {
+      return NO_CLASS_SIGNATURE;
+    }
   }
 
   public abstract static class TypeSignature {
@@ -318,14 +325,11 @@
       return null;
     }
 
+    @Override
     public boolean hasSignature() {
       return this != GenericSignature.NO_FIELD_TYPE_SIGNATURE;
     }
 
-    public boolean hasNoSignature() {
-      return !hasSignature();
-    }
-
     public abstract FieldTypeSignature asArgument(WildcardIndicator indicator);
 
     public boolean isStar() {
@@ -346,6 +350,10 @@
     public String toString() {
       return toRenamedString(NamingLens.getIdentityLens(), alwaysTrue());
     }
+
+    public static FieldTypeSignature noSignature() {
+      return NO_FIELD_TYPE_SIGNATURE;
+    }
   }
 
   static final class StarFieldTypeSignature extends FieldTypeSignature {
@@ -367,7 +375,7 @@
     }
   }
 
-  public static final ClassTypeSignature NO_FIELD_TYPE_SIGNATURE =
+  private static final ClassTypeSignature NO_FIELD_TYPE_SIGNATURE =
       new ClassTypeSignature(DexItemFactory.nullValueType, EMPTY_TYPE_ARGUMENTS);
 
   public static class ClassTypeSignature extends FieldTypeSignature {
@@ -579,7 +587,7 @@
 
   public static class MethodTypeSignature implements DexDefinitionSignature<DexEncodedMethod> {
 
-    public static final MethodTypeSignature NO_METHOD_TYPE_SIGNATURE =
+    private static final MethodTypeSignature NO_METHOD_TYPE_SIGNATURE =
         new MethodTypeSignature(
             EMPTY_TYPE_PARAMS, EMPTY_TYPE_SIGNATURES, ReturnType.VOID, EMPTY_TYPE_SIGNATURES);
 
@@ -588,6 +596,10 @@
     final ReturnType returnType;
     final List<TypeSignature> throwsSignatures;
 
+    public static MethodTypeSignature noSignature() {
+      return NO_METHOD_TYPE_SIGNATURE;
+    }
+
     MethodTypeSignature(
         final List<FormalTypeParameter> formalTypeParameters,
         List<TypeSignature> typeSignatures,
@@ -623,6 +635,7 @@
       return true;
     }
 
+    @Override
     public boolean hasSignature() {
       return this != NO_METHOD_TYPE_SIGNATURE;
     }
@@ -642,6 +655,21 @@
     public List<FormalTypeParameter> getFormalTypeParameters() {
       return formalTypeParameters;
     }
+
+    public String toRenamedString(NamingLens namingLens, Predicate<DexType> isTypeMissing) {
+      if (hasNoSignature()) {
+        return null;
+      }
+      GenericSignaturePrinter genericSignaturePrinter =
+          new GenericSignaturePrinter(namingLens, isTypeMissing);
+      genericSignaturePrinter.visitMethodSignature(this);
+      return genericSignaturePrinter.toString();
+    }
+
+    @Override
+    public String toString() {
+      return toRenamedString(NamingLens.getIdentityLens(), alwaysTrue());
+    }
   }
 
   public static ClassSignature parseClassSignature(
@@ -1013,7 +1041,6 @@
       if (symbol == '^') {
         do {
           scanSymbol();
-
           // ThrowsSignature ::= ("^" ClassTypeSignature) | ("^" TypeVariableSignature).
           if (symbol == 'T') {
             throwsSignatureBuilder.add(updateTypeVariableSignature());
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java b/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java
index e75ee78..f68675f 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignaturePrinter.java
@@ -8,6 +8,8 @@
 import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
 import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
 import com.android.tools.r8.graph.GenericSignature.FormalTypeParameter;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.ReturnType;
 import com.android.tools.r8.graph.GenericSignature.TypeSignature;
 import com.android.tools.r8.graph.GenericSignature.WildcardIndicator;
 import com.android.tools.r8.naming.NamingLens;
@@ -38,6 +40,35 @@
   }
 
   @Override
+  public void visitMethodSignature(MethodTypeSignature methodSignature) {
+    methodSignature.visit(this);
+  }
+
+  @Override
+  public void visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
+    sb.append("(");
+    typeSignatures.forEach(this::visitTypeSignature);
+    sb.append(")");
+  }
+
+  @Override
+  public void visitReturnType(ReturnType returnType) {
+    if (returnType.isVoidDescriptor()) {
+      sb.append("V");
+    } else {
+      visitTypeSignature(returnType.typeSignature);
+    }
+  }
+
+  @Override
+  public void visitThrowsSignatures(List<TypeSignature> typeSignatures) {
+    for (TypeSignature typeSignature : typeSignatures) {
+      sb.append("^");
+      visitTypeSignature(typeSignature);
+    }
+  }
+
+  @Override
   public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
     if (formalTypeParameters.isEmpty()) {
       return;
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
index 4cce25e..7804c5f 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
@@ -7,7 +7,8 @@
 import static com.android.tools.r8.graph.GenericSignature.EMPTY_SUPER_INTERFACES;
 import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_ARGUMENTS;
 import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_PARAMS;
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
+import static com.android.tools.r8.graph.GenericSignature.EMPTY_TYPE_SIGNATURES;
+import static com.android.tools.r8.graph.GenericSignature.FieldTypeSignature.noSignature;
 import static com.android.tools.r8.graph.GenericSignature.StarFieldTypeSignature.STAR_FIELD_TYPE_SIGNATURE;
 
 import com.android.tools.r8.graph.GenericSignature.ArrayTypeSignature;
@@ -15,6 +16,8 @@
 import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
 import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
 import com.android.tools.r8.graph.GenericSignature.FormalTypeParameter;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.ReturnType;
 import com.android.tools.r8.graph.GenericSignature.TypeSignature;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import java.util.ArrayList;
@@ -48,6 +51,13 @@
     return new TypeSignatureRewriter().run(fieldTypeSignature);
   }
 
+  public MethodTypeSignature rewrite(MethodTypeSignature methodTypeSignature) {
+    if (methodTypeSignature.hasNoSignature() || appView.graphLens().isIdentityLens()) {
+      return methodTypeSignature;
+    }
+    return new MethodTypeSignatureRewriter().run(methodTypeSignature);
+  }
+
   private class ClassSignatureRewriter implements GenericSignatureVisitor {
 
     private final List<FormalTypeParameter> rewrittenTypeParameters = new ArrayList<>();
@@ -90,7 +100,7 @@
           && rewrittenSuperInterfaces.isEmpty()
           && rewrittenSuperClass.isNoSignature()
           && rewrittenSuperClass.type == appView.dexItemFactory().objectType) {
-        return ClassSignature.NO_CLASS_SIGNATURE;
+        return ClassSignature.noSignature();
       }
       return new ClassSignature(
           rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
@@ -99,9 +109,77 @@
     }
   }
 
+  private class MethodTypeSignatureRewriter implements GenericSignatureVisitor {
+
+    private final List<FormalTypeParameter> rewrittenTypeParameters = new ArrayList<>();
+    private final List<TypeSignature> rewrittenTypeSignatures = new ArrayList<>();
+
+    ReturnType rewrittenReturnType = null;
+    private final List<TypeSignature> rewrittenThrowsSignatures = new ArrayList<>();
+
+    @Override
+    public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
+      for (FormalTypeParameter formalTypeParameter : formalTypeParameters) {
+        rewrittenTypeParameters.add(new FormalTypeParameterRewriter().run(formalTypeParameter));
+      }
+    }
+
+    @Override
+    public void visitMethodTypeSignatures(List<TypeSignature> typeSignatures) {
+      for (TypeSignature typeSignature : typeSignatures) {
+        TypeSignature rewrittenType = new TypeSignatureRewriter().run(typeSignature);
+        rewrittenTypeSignatures.add(rewrittenType == null ? objectTypeSignature : rewrittenType);
+      }
+    }
+
+    @Override
+    public void visitReturnType(ReturnType returnType) {
+      if (returnType.isVoidDescriptor()) {
+        rewrittenReturnType = ReturnType.VOID;
+      } else {
+        TypeSignature originalType = returnType.typeSignature();
+        TypeSignature rewrittenType = new TypeSignatureRewriter().run(originalType);
+        if (rewrittenType == null) {
+          rewrittenReturnType = ReturnType.VOID;
+        } else if (rewrittenType == originalType) {
+          rewrittenReturnType = returnType;
+        } else {
+          rewrittenReturnType = new ReturnType(rewrittenType);
+        }
+      }
+    }
+
+    @Override
+    public void visitThrowsSignatures(List<TypeSignature> typeSignatures) {
+      for (TypeSignature typeSignature : typeSignatures) {
+        TypeSignature rewrittenType = new TypeSignatureRewriter().run(typeSignature);
+        // If a throwing type is no longer found we remove it from the signature.
+        if (rewrittenType != null) {
+          rewrittenThrowsSignatures.add(rewrittenType);
+        }
+      }
+    }
+
+    private MethodTypeSignature run(MethodTypeSignature methodTypeSignature) {
+      methodTypeSignature.visit(this);
+      assert rewrittenReturnType != null;
+      if (rewrittenTypeParameters.isEmpty()
+          && rewrittenTypeSignatures.isEmpty()
+          && rewrittenReturnType.isVoidDescriptor()
+          && rewrittenThrowsSignatures.isEmpty()) {
+        return MethodTypeSignature.noSignature();
+      }
+      return new MethodTypeSignature(
+          rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
+          rewrittenTypeSignatures.isEmpty() ? EMPTY_TYPE_SIGNATURES : rewrittenTypeSignatures,
+          rewrittenReturnType,
+          rewrittenThrowsSignatures.isEmpty() ? EMPTY_TYPE_SIGNATURES : rewrittenThrowsSignatures);
+    }
+  }
+
   private class FormalTypeParameterRewriter implements GenericSignatureVisitor {
 
-    private FieldTypeSignature rewrittenClassBound = NO_FIELD_TYPE_SIGNATURE;
+    private FieldTypeSignature rewrittenClassBound = noSignature();
     private final List<FieldTypeSignature> rewrittenInterfaceBounds = new ArrayList<>();
 
     @Override
@@ -126,7 +204,7 @@
       }
       return new FormalTypeParameter(
           formalTypeParameter.name,
-          rewrittenClassBound == null ? NO_FIELD_TYPE_SIGNATURE : rewrittenClassBound,
+          rewrittenClassBound == null ? noSignature() : rewrittenClassBound,
           rewrittenInterfaceBounds.isEmpty() ? EMPTY_TYPE_ARGUMENTS : rewrittenInterfaceBounds);
     }
   }
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureUtils.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureUtils.java
index 7c0dcd2..a3d2eb4 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignatureUtils.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignatureUtils.java
@@ -4,10 +4,6 @@
 
 package com.android.tools.r8.graph;
 
-import static com.android.tools.r8.graph.GenericSignature.ClassSignature.NO_CLASS_SIGNATURE;
-import static com.android.tools.r8.graph.GenericSignature.MethodTypeSignature.NO_METHOD_TYPE_SIGNATURE;
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
-
 import com.android.tools.r8.graph.GenericSignature.DexDefinitionSignature;
 
 public class GenericSignatureUtils {
@@ -15,10 +11,7 @@
   public static boolean verifyNoDuplicateGenericDefinitions(
       DexDefinitionSignature<?> signature, DexAnnotationSet annotations) {
     assert signature != null;
-    if (signature == NO_METHOD_TYPE_SIGNATURE
-        || signature == NO_FIELD_TYPE_SIGNATURE
-        || signature == NO_CLASS_SIGNATURE
-        || annotations == null) {
+    if (signature.hasNoSignature() || annotations == null) {
       return true;
     }
     // The check is on the string descriptor to allow for not passing in a factory.
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureVisitor.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureVisitor.java
index 6d9385e..d3840dd 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignatureVisitor.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignatureVisitor.java
@@ -9,9 +9,9 @@
 import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
 import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
 import com.android.tools.r8.graph.GenericSignature.FormalTypeParameter;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.GenericSignature.ReturnType;
 import com.android.tools.r8.graph.GenericSignature.TypeSignature;
-import com.android.tools.r8.naming.MemberNaming.MethodSignature;
 import java.util.List;
 
 public interface GenericSignatureVisitor {
@@ -20,7 +20,7 @@
     throw new Unreachable("Implement if visited");
   }
 
-  default void visitMethodSignature(MethodSignature methodSignature) {
+  default void visitMethodSignature(MethodTypeSignature methodSignature) {
     throw new Unreachable("Implement if visited");
   }
 
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 ccaa837..b71bfa0 100644
--- a/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
+++ b/src/main/java/com/android/tools/r8/graph/JarClassFileReader.java
@@ -34,6 +34,7 @@
 import com.android.tools.r8.graph.DexValue.DexValueType;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
 import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.jar.CfApplicationWriter;
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.shaking.ProguardKeepAttributes;
@@ -208,7 +209,7 @@
     private final List<NestMemberClassAttribute> nestMembers = new ArrayList<>();
     private EnclosingMethodAttribute enclosingMember = null;
     private final List<InnerClassAttribute> innerClasses = new ArrayList<>();
-    private ClassSignature classSignature = ClassSignature.NO_CLASS_SIGNATURE;
+    private ClassSignature classSignature = ClassSignature.noSignature();
     private List<DexAnnotation> annotations = null;
     private List<DexAnnotationElement> defaultAnnotations = null;
     private final List<DexEncodedField> staticFields = new ArrayList<>();
@@ -680,6 +681,7 @@
     private List<List<DexAnnotation>> parameterAnnotationsLists = null;
     private List<DexValue> parameterNames = null;
     private List<DexValue> parameterFlags = null;
+    private final MethodTypeSignature genericSignature;
     final DexMethod method;
     final MethodAccessFlags flags;
     final boolean deprecated;
@@ -702,10 +704,13 @@
         addAnnotation(DexAnnotation.createThrowsAnnotation(
             values, parent.application.getFactory()));
       }
-      if (signature != null && !signature.isEmpty()) {
-        addAnnotation(DexAnnotation.createSignatureAnnotation(
-            signature, parent.application.getFactory()));
-      }
+      genericSignature =
+          GenericSignature.parseMethodSignature(
+              name,
+              signature,
+              parent.origin,
+              parent.application.getFactory(),
+              parent.application.options.reporter);
     }
 
     @Override
@@ -832,6 +837,7 @@
           new DexEncodedMethod(
               method,
               flags,
+              genericSignature,
               createAnnotationSet(annotations, options),
               parameterAnnotationsList,
               code,
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
index 4a4936b..f4158c5 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ClassMerger.java
@@ -4,8 +4,6 @@
 
 package com.android.tools.r8.horizontalclassmerging;
 
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
-
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexAnnotationSet;
@@ -18,6 +16,7 @@
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.shaking.FieldAccessInfoCollectionModifier;
@@ -153,7 +152,7 @@
             classIdField,
             FieldAccessFlags.fromSharedAccessFlags(
                 Constants.ACC_PUBLIC + Constants.ACC_FINAL + Constants.ACC_SYNTHETIC),
-            NO_FIELD_TYPE_SIGNATURE,
+            FieldTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             null);
     target.appendInstanceField(encodedField);
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorMerger.java
index 9baf6ad..8ffb694 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/ConstructorMerger.java
@@ -14,6 +14,7 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.ir.conversion.ExtraConstantIntParameter;
@@ -164,6 +165,7 @@
         new DexEncodedMethod(
             newConstructorReference,
             getAccessFlags(),
+            MethodTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             ParameterAnnotationsList.empty(),
             synthesizedCode,
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
index ec8d495..28ec4a9 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/SyntheticArgumentClass.java
@@ -76,7 +76,7 @@
               Collections.emptyList(),
               null,
               Collections.emptyList(),
-              ClassSignature.NO_CLASS_SIGNATURE,
+              ClassSignature.noSignature(),
               DexAnnotationSet.empty(),
               DexEncodedField.EMPTY_ARRAY,
               DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
index b26d2ea..d52c4d4 100644
--- a/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
+++ b/src/main/java/com/android/tools/r8/horizontalclassmerging/VirtualMethodMerger.java
@@ -11,6 +11,7 @@
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -171,6 +172,7 @@
         new DexEncodedMethod(
             newMethodReference,
             getAccessFlags(),
+            MethodTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             ParameterAnnotationsList.empty(),
             synthesizedCode,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
index 3f40cba..f2ae9a1 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/ClassProcessor.java
@@ -16,6 +16,7 @@
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -363,6 +364,7 @@
         new DexEncodedMethod(
             newMethod,
             MethodAccessFlags.fromCfAccessFlags(Opcodes.ACC_PUBLIC, false),
+            MethodTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             ParameterAnnotationsList.empty(),
             new SynthesizedCode(
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 01fb238..fd4abda 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
@@ -167,6 +167,7 @@
         new DexEncodedMethod(
             newMethod,
             newAccessFlags,
+            methodDefinition.getGenericSignature(),
             methodDefinition
                 .annotations()
                 .keepIf(x -> !isCovariantReturnTypeAnnotation(x.annotation)),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
index 2d4fb70..64dad3e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
@@ -23,6 +23,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ResolutionResult;
@@ -112,7 +113,7 @@
             Collections.emptyList(),
             null,
             Collections.emptyList(),
-            ClassSignature.NO_CLASS_SIGNATURE,
+            ClassSignature.noSignature(),
             DexAnnotationSet.empty(),
             DexEncodedField.EMPTY_ARRAY,
             DexEncodedField.EMPTY_ARRAY,
@@ -447,7 +448,13 @@
                   emulatedDispatchMethod.getProto(),
                   emulatedDispatchMethod.getName());
       return new DexEncodedMethod(
-          newMethod, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), null, true);
+          newMethod,
+          flags,
+          MethodTypeSignature.noSignature(),
+          DexAnnotationSet.empty(),
+          ParameterAnnotationsList.empty(),
+          null,
+          true);
     }
 
     private DexEncodedMethod generateHolderDispatchMethod(
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
index 88fc45a..e2f3271 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryWrapperSynthesizer.java
@@ -4,8 +4,6 @@
 
 package com.android.tools.r8.ir.desugar;
 
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
-
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.AppView;
@@ -28,6 +26,8 @@
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.FieldAccessFlags;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.ir.conversion.IRConverter;
@@ -233,7 +233,7 @@
         Collections.emptyList(),
         null,
         Collections.emptyList(),
-        ClassSignature.NO_CLASS_SIGNATURE,
+        ClassSignature.noSignature(),
         DexAnnotationSet.empty(),
         DexEncodedField.EMPTY_ARRAY, // No static fields.
         new DexEncodedField[] {wrapperField},
@@ -375,6 +375,7 @@
     return new DexEncodedMethod(
         methodToInstall,
         newFlags,
+        MethodTypeSignature.noSignature(),
         DexAnnotationSet.empty(),
         ParameterAnnotationsList.empty(),
         code,
@@ -430,7 +431,7 @@
     FieldAccessFlags fieldAccessFlags =
         FieldAccessFlags.fromCfAccessFlags(Constants.ACC_FINAL | Constants.ACC_SYNTHETIC);
     return new DexEncodedField(
-        field, fieldAccessFlags, NO_FIELD_TYPE_SIGNATURE, DexAnnotationSet.empty(), null);
+        field, fieldAccessFlags, FieldTypeSignature.noSignature(), DexAnnotationSet.empty(), null);
   }
 
   private DexEncodedMethod synthesizeConstructor(DexField field) {
@@ -452,6 +453,7 @@
     return new DexEncodedMethod(
         methodToInstall,
         accessFlags,
+        MethodTypeSignature.noSignature(),
         DexAnnotationSet.empty(),
         ParameterAnnotationsList.empty(),
         code,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
index 6d37c32..5cda030 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/InterfaceMethodRewriter.java
@@ -713,7 +713,7 @@
             Collections.emptyList(),
             null,
             Collections.emptyList(),
-            ClassSignature.NO_CLASS_SIGNATURE,
+            ClassSignature.noSignature(),
             DexAnnotationSet.empty(),
             DexEncodedField.EMPTY_ARRAY,
             DexEncodedField.EMPTY_ARRAY,
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 069f4b3..fd1bfe1 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
@@ -27,6 +27,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.GraphLens.NestedGraphLens;
 import com.android.tools.r8.graph.MethodAccessFlags;
@@ -99,6 +100,7 @@
             new DexEncodedMethod(
                 companionMethod,
                 newFlags,
+                virtual.getGenericSignature(),
                 virtual.annotations(),
                 virtual.parameterAnnotationsList,
                 code,
@@ -139,6 +141,7 @@
             new DexEncodedMethod(
                 companionMethod,
                 newFlags,
+                direct.getGenericSignature(),
                 direct.annotations(),
                 direct.parameterAnnotationsList,
                 direct.getCode(),
@@ -166,6 +169,7 @@
               new DexEncodedMethod(
                   companionMethod,
                   newFlags,
+                  direct.getGenericSignature(),
                   direct.annotations(),
                   direct.parameterAnnotationsList,
                   code,
@@ -213,7 +217,7 @@
             Collections.emptyList(),
             null,
             Collections.emptyList(),
-            ClassSignature.NO_CLASS_SIGNATURE,
+            ClassSignature.noSignature(),
             DexAnnotationSet.empty(),
             DexEncodedField.EMPTY_ARRAY,
             DexEncodedField.EMPTY_ARRAY,
@@ -271,6 +275,7 @@
               newMethod,
               MethodAccessFlags.fromSharedAccessFlags(
                   Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNTHETIC, false),
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               forwardMethodBuilder.build(),
@@ -298,7 +303,7 @@
             Collections.emptyList(),
             null,
             Collections.emptyList(),
-            ClassSignature.NO_CLASS_SIGNATURE,
+            ClassSignature.noSignature(),
             DexAnnotationSet.empty(),
             DexEncodedField.EMPTY_ARRAY,
             DexEncodedField.EMPTY_ARRAY,
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 6f4cad3..0f050c5 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
@@ -4,8 +4,6 @@
 
 package com.android.tools.r8.ir.desugar;
 
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
-
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.errors.Unimplemented;
 import com.android.tools.r8.errors.Unreachable;
@@ -26,6 +24,8 @@
 import com.android.tools.r8.graph.DexValue.DexValueNull;
 import com.android.tools.r8.graph.FieldAccessFlags;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -163,7 +163,7 @@
             Collections.emptyList(),
             null,
             Collections.emptyList(),
-            ClassSignature.NO_CLASS_SIGNATURE,
+            ClassSignature.noSignature(),
             DexAnnotationSet.empty(),
             synthesizeStaticFields(),
             synthesizeInstanceFields(),
@@ -234,6 +234,7 @@
             mainMethod,
             MethodAccessFlags.fromSharedAccessFlags(
                 Constants.ACC_PUBLIC | Constants.ACC_FINAL, false),
+            MethodTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             ParameterAnnotationsList.empty(),
             LambdaMainMethodSourceCode.build(this, mainMethod),
@@ -252,6 +253,7 @@
                       | Constants.ACC_SYNTHETIC
                       | Constants.ACC_BRIDGE,
                   false),
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               LambdaBridgeMethodSourceCode.build(this, bridgeMethod, mainMethod),
@@ -273,6 +275,7 @@
                 (stateless ? Constants.ACC_PRIVATE : Constants.ACC_PUBLIC)
                     | Constants.ACC_SYNTHETIC,
                 true),
+            MethodTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             ParameterAnnotationsList.empty(),
             LambdaConstructorSourceCode.build(this),
@@ -285,6 +288,7 @@
               classConstructor,
               MethodAccessFlags.fromSharedAccessFlags(
                   Constants.ACC_SYNTHETIC | Constants.ACC_STATIC, true),
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               LambdaClassConstructorSourceCode.build(this),
@@ -306,7 +310,7 @@
           new DexEncodedField(
               getCaptureField(i),
               accessFlags,
-              NO_FIELD_TYPE_SIGNATURE,
+              FieldTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               null);
     }
@@ -330,7 +334,7 @@
                     | Constants.ACC_FINAL
                     | Constants.ACC_SYNTHETIC
                     | Constants.ACC_STATIC),
-            NO_FIELD_TYPE_SIGNATURE,
+            FieldTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             DexValueNull.NULL);
     return fields;
@@ -622,6 +626,7 @@
                         new DexEncodedMethod(
                             callTarget,
                             newAccessFlags,
+                            encodedMethod.getGenericSignature(),
                             encodedMethod.annotations(),
                             encodedMethod.parameterAnnotationsList,
                             encodedMethod.getCode(),
@@ -694,6 +699,7 @@
                         new DexEncodedMethod(
                             callTarget,
                             newAccessFlags,
+                            encodedMethod.getGenericSignature(),
                             encodedMethod.annotations(),
                             encodedMethod.parameterAnnotationsList,
                             encodedMethod.getCode(),
@@ -723,6 +729,7 @@
           new DexEncodedMethod(
               callTarget,
               accessorFlags,
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               new SynthesizedCode(
@@ -761,6 +768,7 @@
           new DexEncodedMethod(
               callTarget,
               accessorFlags,
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               AccessorMethodSourceCode.build(LambdaClass.this, callTarget),
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
index 01b87d2..c0a1269 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/NestBasedAccessDesugaring.java
@@ -186,7 +186,7 @@
         Collections.emptyList(),
         null,
         Collections.emptyList(),
-        ClassSignature.NO_CLASS_SIGNATURE,
+        ClassSignature.noSignature(),
         DexAnnotationSet.empty(),
         DexEncodedField.EMPTY_ARRAY,
         DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
index 7b0d6b0..23cd37d 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/TwrCloseResourceRewriter.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.ir.code.IRCode;
@@ -135,8 +136,15 @@
             options, twrCloseResourceMethod);
     MethodAccessFlags flags = MethodAccessFlags.fromSharedAccessFlags(
         Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNTHETIC, false);
-    DexEncodedMethod method = new DexEncodedMethod(twrCloseResourceMethod,
-        flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code, true);
+    DexEncodedMethod method =
+        new DexEncodedMethod(
+            twrCloseResourceMethod,
+            flags,
+            MethodTypeSignature.noSignature(),
+            DexAnnotationSet.empty(),
+            ParameterAnnotationsList.empty(),
+            code,
+            true);
 
     // Create utility class.
     DexProgramClass utilityClass =
@@ -152,7 +160,7 @@
             Collections.emptyList(),
             null,
             Collections.emptyList(),
-            ClassSignature.NO_CLASS_SIGNATURE,
+            ClassSignature.noSignature(),
             DexAnnotationSet.empty(),
             DexEncodedField.EMPTY_ARRAY,
             DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
index 56d0a08..9e16ab0 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/Outliner.java
@@ -26,6 +26,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -1361,6 +1362,7 @@
           new DexEncodedMethod(
               method,
               methodAccess,
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               new OutlineCode(outline),
@@ -1392,7 +1394,7 @@
         Collections.emptyList(),
         null,
         Collections.emptyList(),
-        ClassSignature.NO_CLASS_SIGNATURE,
+        ClassSignature.noSignature(),
         DexAnnotationSet.empty(),
         DexEncodedField.EMPTY_ARRAY, // Static fields.
         DexEncodedField.EMPTY_ARRAY, // Instance fields.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
index 7a81edc..1694a7b 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
@@ -19,6 +19,7 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.MethodCollection;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -218,6 +219,7 @@
               methodReference,
               MethodAccessFlags.fromSharedAccessFlags(
                   Constants.ACC_PUBLIC | Constants.ACC_STATIC, false),
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               ServiceLoaderSourceCode.generate(serviceType, classes, appView.dexItemFactory()),
@@ -253,7 +255,7 @@
                       Collections.emptyList(),
                       null,
                       Collections.emptyList(),
-                      ClassSignature.NO_CLASS_SIGNATURE,
+                      ClassSignature.noSignature(),
                       DexAnnotationSet.empty(),
                       DexEncodedField.EMPTY_ARRAY, // Static fields.
                       DexEncodedField.EMPTY_ARRAY, // Instance fields.
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
index 4a2c485..d815826 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/EnumUnboxingRewriter.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.ir.optimize.enums;
 
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
 import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
 
 import com.android.tools.r8.dex.Constants;
@@ -24,6 +23,8 @@
 import com.android.tools.r8.graph.EnumValueInfoMapCollection.EnumValueInfo;
 import com.android.tools.r8.graph.EnumValueInfoMapCollection.EnumValueInfoMap;
 import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -422,7 +423,7 @@
         field,
         FieldAccessFlags.fromSharedAccessFlags(
             Constants.ACC_SYNTHETIC | Constants.ACC_STATIC | Constants.ACC_PUBLIC),
-        NO_FIELD_TYPE_SIGNATURE,
+        FieldTypeSignature.noSignature(),
         DexAnnotationSet.empty(),
         null);
   }
@@ -633,6 +634,7 @@
     return new DexEncodedMethod(
         method,
         synthesizedMethodAccessFlags(sync),
+        MethodTypeSignature.noSignature(),
         DexAnnotationSet.empty(),
         ParameterAnnotationsList.empty(),
         cfCode,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java b/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java
index b199c47..c203772 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/enums/UnboxedEnumMemberRelocator.java
@@ -122,7 +122,7 @@
               Collections.emptyList(),
               null,
               Collections.emptyList(),
-              ClassSignature.NO_CLASS_SIGNATURE,
+              ClassSignature.noSignature(),
               DexAnnotationSet.empty(),
               DexEncodedField.EMPTY_ARRAY,
               DexEncodedField.EMPTY_ARRAY,
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
index a29db28..977bdcf 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/lambda/kotlin/KotlinLambdaGroupClassBuilder.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.ir.optimize.lambda.kotlin;
 
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
 import static com.android.tools.r8.ir.analysis.type.Nullability.definitelyNotNull;
 
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
@@ -25,6 +24,8 @@
 import com.android.tools.r8.graph.EnclosingMethodAttribute;
 import com.android.tools.r8.graph.GenericSignature;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
@@ -158,6 +159,7 @@
                   new DexEncodedMethod(
                       method,
                       accessFlags,
+                      MethodTypeSignature.noSignature(),
                       isMainMethod ? id.mainMethodAnnotations : DexAnnotationSet.empty(),
                       isMainMethod
                           ? id.mainMethodParamAnnotations
@@ -252,6 +254,7 @@
         new DexEncodedMethod(
             initializerMethod,
             CONSTRUCTOR_FLAGS_RELAXED, // always create access-relaxed constructor.
+            MethodTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             ParameterAnnotationsList.empty(),
             new SynthesizedCode(
@@ -271,6 +274,7 @@
           new DexEncodedMethod(
               method,
               CLASS_INITIALIZER_FLAGS,
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               new SynthesizedCode(
@@ -293,7 +297,7 @@
         new DexEncodedField(
             group.getLambdaIdField(factory),
             CAPTURE_FIELD_FLAGS_RELAXED,
-            NO_FIELD_TYPE_SIGNATURE,
+            FieldTypeSignature.noSignature(),
             DexAnnotationSet.empty(),
             null);
 
@@ -302,7 +306,7 @@
           new DexEncodedField(
               group.getCaptureField(factory, id),
               CAPTURE_FIELD_FLAGS_RELAXED,
-              NO_FIELD_TYPE_SIGNATURE,
+              FieldTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               null);
     }
@@ -326,7 +330,7 @@
                 new DexEncodedField(
                     field,
                     SINGLETON_FIELD_FLAGS,
-                    NO_FIELD_TYPE_SIGNATURE,
+                    FieldTypeSignature.noSignature(),
                     DexAnnotationSet.empty(),
                     DexValueNull.NULL);
             result.add(encodedField);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryFieldSynthesis.java b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryFieldSynthesis.java
index a20b8bf..c411d08 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryFieldSynthesis.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/library/LibraryFieldSynthesis.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.ir.optimize.library;
 
 import static com.android.tools.r8.graph.DexLibraryClass.asLibraryClassOrNull;
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.AppView;
@@ -14,6 +13,7 @@
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexLibraryClass;
 import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
 
 /**
  * This class synthesizes library fields that we rely on for modeling.
@@ -39,7 +39,7 @@
                       field,
                       FieldAccessFlags.fromCfAccessFlags(
                           Constants.ACC_PRIVATE | Constants.ACC_FINAL),
-                      NO_FIELD_TYPE_SIGNATURE,
+                      FieldTypeSignature.noSignature(),
                       DexAnnotationSet.empty(),
                       null));
             }
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 ae7fcf5..b914a14 100644
--- a/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/jar/CfApplicationWriter.java
@@ -274,20 +274,6 @@
     return encodedAnnotation.elements[0].value;
   }
 
-  private String getSignature(DexAnnotationSet annotations) {
-    DexValue value =
-        getSystemAnnotationValue(annotations, application.dexItemFactory.annotationSignature);
-    if (value == null) {
-      return null;
-    }
-    // Signature has already been minified by ClassNameMinifier.renameTypesInGenericSignatures().
-    StringBuilder res = new StringBuilder();
-    for (DexValue part : value.asDexValueArray().getValues()) {
-      res.append(part.asDexValueString().getValue().toString());
-    }
-    return res.toString();
-  }
-
   private String getSourceDebugExtension(DexAnnotationSet annotations) {
     DexValue debugExtensions =
         getSystemAnnotationValue(
@@ -340,7 +326,7 @@
     }
     String name = namingLens.lookupName(field.field).toString();
     String desc = namingLens.lookupDescriptor(field.field.type).toString();
-    String signature = field.getFieldSignature().toRenamedString(namingLens, isTypeMissing);
+    String signature = field.getGenericSignature().toRenamedString(namingLens, isTypeMissing);
     Object value = getStaticValue(field);
     FieldVisitor visitor = writer.visitField(access, name, desc, signature, value);
     writeAnnotations(visitor::visitAnnotation, field.annotations().annotations);
@@ -360,7 +346,8 @@
     }
     String name = namingLens.lookupName(method.getReference()).toString();
     String desc = definition.descriptor(namingLens);
-    String signature = getSignature(definition.annotations());
+    String signature =
+        method.getDefinition().getGenericSignature().toRenamedString(namingLens, isTypeMissing);
     String[] exceptions = getExceptions(definition.annotations());
     MethodVisitor visitor = writer.visitMethod(access, name, desc, signature, exceptions);
     if (defaults.containsKey(definition.getName())) {
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 1a51edf..2c57aa4 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
@@ -4,30 +4,15 @@
 
 package com.android.tools.r8.naming.signature;
 
-import static com.android.tools.r8.utils.DescriptorUtils.getClassBinaryNameFromDescriptor;
-import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromClassBinaryName;
-
 import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexAnnotation;
-import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexProgramClass;
-import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.GenericSignature.ClassSignature;
 import com.android.tools.r8.graph.GenericSignatureTypeRewriter;
 import com.android.tools.r8.naming.NamingLens;
-import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Reporter;
-import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.ThreadUtils;
-import java.lang.reflect.GenericSignatureFormatError;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
-import java.util.function.BiConsumer;
-import java.util.function.Consumer;
-import java.util.function.Predicate;
-import java.util.function.Supplier;
 
 // TODO(b/169516860): We should generalize this to handle rewriting of attributes in general.
 public class GenericSignatureRewriter {
@@ -60,238 +45,16 @@
         clazz -> {
           GenericSignatureTypeRewriter genericSignatureTypeRewriter =
               new GenericSignatureTypeRewriter(appView, clazz);
-          GenericSignatureCollector genericSignatureCollector =
-              new GenericSignatureCollector(clazz);
-          GenericSignatureParser<DexType> genericSignatureParser =
-              new GenericSignatureParser<>(genericSignatureCollector);
-          ClassSignature classSignature = clazz.getClassSignature();
-          if (classSignature.hasSignature()) {
-            // TODO(b/129925954): We still have to rewrite to capture the lastWrittenType.
-            //  The design is utterly broken.
-            DexAnnotation classSignatureAnnotation =
-                DexAnnotation.createSignatureAnnotation(
-                    classSignature.toString(), options.itemFactory);
-            rewriteGenericSignatures(
-                new DexAnnotationSet(new DexAnnotation[] {classSignatureAnnotation}),
-                genericSignatureParser::parseClassSignature,
-                genericSignatureCollector::getRenamedSignature,
-                (signature, e) ->
-                    options.warningInvalidSignature(clazz, clazz.getOrigin(), signature, e));
-          }
-          clazz.setClassSignature(genericSignatureTypeRewriter.rewrite(classSignature));
+          clazz.setClassSignature(genericSignatureTypeRewriter.rewrite(clazz.getClassSignature()));
           clazz.forEachField(
               field ->
-                  field.setFieldSignature(
-                      genericSignatureTypeRewriter.rewrite(field.getFieldSignature())));
+                  field.setGenericSignature(
+                      genericSignatureTypeRewriter.rewrite(field.getGenericSignature())));
           clazz.forEachMethod(
               method ->
-                  method.setAnnotations(
-                      rewriteGenericSignatures(
-                          method.annotations(),
-                          genericSignatureParser::parseMethodSignature,
-                          genericSignatureCollector::getRenamedSignature,
-                          (signature, e) ->
-                              options.warningInvalidSignature(
-                                  method, clazz.getOrigin(), signature, e))));
+                  method.setGenericSignature(
+                      genericSignatureTypeRewriter.rewrite(method.getGenericSignature())));
         },
         executorService);
   }
-
-  // TODO(b/129925954): Remove this when using modeled signatures for methods and fields.
-  private DexAnnotationSet rewriteGenericSignatures(
-      DexAnnotationSet annotations,
-      Consumer<String> parser,
-      Supplier<String> collector,
-      BiConsumer<String, GenericSignatureFormatError> parseError) {
-    // There can be no more than one signature annotation in an annotation set.
-    final int VALID = -1;
-    int invalid = VALID;
-    DexAnnotation[] rewrittenAnnotations = null;
-    for (int i = 0; i < annotations.annotations.length && invalid == VALID; i++) {
-      DexAnnotation annotation = annotations.annotations[i];
-      if (DexAnnotation.isSignatureAnnotation(annotation, appView.dexItemFactory())) {
-        if (rewrittenAnnotations == null) {
-          rewrittenAnnotations = new DexAnnotation[annotations.annotations.length];
-          System.arraycopy(annotations.annotations, 0, rewrittenAnnotations, 0, i);
-        }
-        String signature = DexAnnotation.getSignature(annotation);
-        try {
-          parser.accept(signature);
-          String renamedSignature = collector.get();
-          assert verifyConsistentRenaming(parser, collector, renamedSignature);
-          DexAnnotation signatureAnnotation =
-              DexAnnotation.createSignatureAnnotation(renamedSignature, appView.dexItemFactory());
-          rewrittenAnnotations[i] = signatureAnnotation;
-        } catch (GenericSignatureFormatError e) {
-          parseError.accept(signature, e);
-          invalid = i;
-        }
-      } else if (rewrittenAnnotations != null) {
-        rewrittenAnnotations[i] = annotation;
-      }
-    }
-
-    // Return the rewritten signatures if it was valid and could be rewritten.
-    if (invalid == VALID) {
-      return rewrittenAnnotations != null
-          ? new DexAnnotationSet(rewrittenAnnotations)
-          : annotations;
-    }
-    // Remove invalid signature if found.
-    DexAnnotation[] prunedAnnotations =
-        new DexAnnotation[annotations.annotations.length - 1];
-    int dest = 0;
-    for (int i = 0; i < annotations.annotations.length; i++) {
-      if (i != invalid) {
-        prunedAnnotations[dest++] = annotations.annotations[i];
-      }
-    }
-    assert dest == prunedAnnotations.length;
-    return new DexAnnotationSet(prunedAnnotations);
-  }
-
-  /**
-   * Calling this method will clobber the parsed signature in the collector - ideally with the same
-   * string. Only use this after the original result has been collected.
-   */
-  private boolean verifyConsistentRenaming(
-      Consumer<String> parser, Supplier<String> collector, String renamedSignature) {
-    if (!options.testing.assertConsistentRenamingOfSignature) {
-      return true;
-    }
-    parser.accept(renamedSignature);
-    String reRenamedSignature = collector.get();
-    assert renamedSignature.equals(reRenamedSignature);
-    return true;
-  }
-
-  private class GenericSignatureCollector implements GenericSignatureAction<DexType> {
-    private StringBuilder renamedSignature;
-    private final DexProgramClass currentClassContext;
-    private DexType lastWrittenType = null;
-
-    GenericSignatureCollector(DexProgramClass clazz) {
-      this.currentClassContext = clazz;
-    }
-
-    String getRenamedSignature() {
-      return renamedSignature.toString();
-    }
-
-    @Override
-    public void parsedSymbol(char symbol) {
-      if (symbol == ';' && lastWrittenType == null) {
-        // The type was never written (maybe because it was merged with it's subtype).
-        return;
-      }
-      // If the super-class or interface has been merged, we will stop writing out type
-      // arguments, resulting in a signature on the form '<>' if we do not remove it.
-      if (symbol == '>' && removeWrittenCharacter(c -> c == '<')) {
-        return;
-      }
-      renamedSignature.append(symbol);
-    }
-
-    @Override
-    public void parsedIdentifier(String identifier) {
-      renamedSignature.append(identifier);
-    }
-
-    @Override
-    public DexType parsedTypeName(String name, ParserPosition parserPosition) {
-      if (parserPosition == ParserPosition.ENCLOSING_INNER_OR_TYPE_ANNOTATION
-          && lastWrittenType == null) {
-        // We are writing type-arguments for a merged class.
-        removeWrittenClassCharacter();
-        return null;
-      }
-      String originalDescriptor = getDescriptorFromClassBinaryName(name);
-      DexType type =
-          appView.graphLens().lookupType(appView.dexItemFactory().createType(originalDescriptor));
-      if (appView.appInfo().hasLiveness() && appView.withLiveness().appInfo().wasPruned(type)) {
-        type = appView.dexItemFactory().objectType;
-      }
-      DexString renamedDescriptor = namingLens.lookupDescriptor(type);
-      if (parserPosition == ParserPosition.CLASS_SUPER_OR_INTERFACE_ANNOTATION
-          && currentClassContext != null) {
-        // We may have merged the type down to the current class type.
-        DexString classDescriptor = currentClassContext.type.descriptor;
-        if (!originalDescriptor.equals(classDescriptor.toString())
-            && renamedDescriptor.equals(classDescriptor)) {
-          lastWrittenType = null;
-          removeWrittenClassCharacter();
-          return type;
-        }
-      }
-      renamedSignature.append(getClassBinaryNameFromDescriptor(renamedDescriptor.toString()));
-      lastWrittenType = type;
-      return type;
-    }
-
-    private boolean removeWrittenCharacter(Predicate<Character> removeIf) {
-      int index = renamedSignature.length() - 1;
-      if (index < 0 || !removeIf.test(renamedSignature.charAt(index))) {
-        return false;
-      }
-      renamedSignature.deleteCharAt(index);
-      return true;
-    }
-
-    private void removeWrittenClassCharacter() {
-      removeWrittenCharacter(c -> c == 'L');
-    }
-
-    @Override
-    public DexType parsedInnerTypeName(DexType enclosingType, String name) {
-      if (enclosingType == null) {
-        // We are writing inner type names
-        removeWrittenClassCharacter();
-        return null;
-      }
-      assert enclosingType.isClassType();
-      String enclosingDescriptor = enclosingType.toDescriptorString();
-      DexType type =
-          appView
-              .dexItemFactory()
-              .createType(
-                  getDescriptorFromClassBinaryName(
-                      getClassBinaryNameFromDescriptor(enclosingDescriptor)
-                          + DescriptorUtils.INNER_CLASS_SEPARATOR
-                          + name));
-      type = appView.graphLens().lookupType(type);
-      String renamedDescriptor = namingLens.lookupDescriptor(type).toString();
-      if (!renamedDescriptor.equals(type.toDescriptorString())) {
-        // TODO(b/147504070): If this is a merged class equal to the class context, do not add.
-        // Pick the renamed inner class from the fully renamed binary name.
-        String fullRenamedBinaryName = getClassBinaryNameFromDescriptor(renamedDescriptor);
-        String enclosingRenamedBinaryName =
-            getClassBinaryNameFromDescriptor(namingLens.lookupDescriptor(enclosingType).toString());
-        int innerClassPos = enclosingRenamedBinaryName.length() + 1;
-        if (innerClassPos < fullRenamedBinaryName.length()) {
-          renamedSignature.append(fullRenamedBinaryName.substring(innerClassPos));
-        } else if (appView.options().keepInnerClassStructure()) {
-          reporter.warning(
-              new StringDiagnostic(
-                  "Should have retained InnerClasses attribute of " + type + ".",
-                  appView.appInfo().originFor(type)));
-          renamedSignature.append(name);
-        }
-      } else {
-        // Did not find the class - keep the inner class name as is.
-        // TODO(b/110085899): Warn about missing classes in signatures?
-        renamedSignature.append(name);
-      }
-      return type;
-    }
-
-    @Override
-    public void start() {
-      renamedSignature = new StringBuilder();
-    }
-
-    @Override
-    public void stop() {
-      // nothing to do
-    }
-  }
 }
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 fe2861a..46e4629 100644
--- a/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
+++ b/src/main/java/com/android/tools/r8/shaking/AnnotationRemover.java
@@ -83,15 +83,10 @@
         assert !DexAnnotation.isMemberClassesAnnotation(annotation, dexItemFactory);
         assert !DexAnnotation.isEnclosingMethodAnnotation(annotation, dexItemFactory);
         assert !DexAnnotation.isEnclosingClassAnnotation(annotation, dexItemFactory);
-        // TODO(b/129925954): Signature is being represented as a class attribute.
-        assert !holder.isDexClass()
-            || !DexAnnotation.isSignatureAnnotation(annotation, dexItemFactory);
+        assert !DexAnnotation.isSignatureAnnotation(annotation, dexItemFactory);
         if (config.exceptions && DexAnnotation.isThrowingAnnotation(annotation, dexItemFactory)) {
           return true;
         }
-        if (config.signature && DexAnnotation.isSignatureAnnotation(annotation, dexItemFactory)) {
-          return true;
-        }
         if (DexAnnotation.isSourceDebugExtension(annotation, dexItemFactory)) {
           assert holder.isDexClass();
           appView.setSourceDebugExtensionForType(
@@ -202,13 +197,16 @@
         method.annotations().rewrite(annotation -> rewriteAnnotation(method, annotation)));
     method.parameterAnnotationsList =
         method.parameterAnnotationsList.keepIf(this::filterParameterAnnotations);
+    if (!keep.signature) {
+      method.clearGenericSignature();
+    }
   }
 
   private void processField(DexEncodedField field) {
     field.setAnnotations(
         field.annotations().rewrite(annotation -> rewriteAnnotation(field, annotation)));
     if (!keep.signature) {
-      field.clearFieldSignature();
+      field.clearGenericSignature();
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/shaking/ClassInitFieldSynthesizer.java b/src/main/java/com/android/tools/r8/shaking/ClassInitFieldSynthesizer.java
index 4786db4..3c83acd 100644
--- a/src/main/java/com/android/tools/r8/shaking/ClassInitFieldSynthesizer.java
+++ b/src/main/java/com/android/tools/r8/shaking/ClassInitFieldSynthesizer.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.shaking;
 
 import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
 
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.errors.Unreachable;
@@ -16,6 +15,7 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.FieldAccessFlags;
+import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.Visibility;
@@ -81,7 +81,7 @@
           new DexEncodedField(
               appView.dexItemFactory().createField(clazz.type, clinitField.type, clinitField.name),
               accessFlags,
-              NO_FIELD_TYPE_SIGNATURE,
+              FieldTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               null);
       clazz.appendStaticField(encodedClinitField);
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 3f8077f..9462690 100644
--- a/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
+++ b/src/main/java/com/android/tools/r8/shaking/VerticalClassMerger.java
@@ -27,6 +27,7 @@
 import com.android.tools.r8.graph.DexString;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.DexTypeList;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.GraphLens.MethodLookupResult;
 import com.android.tools.r8.graph.GraphLens.NonIdentityGraphLens;
@@ -1257,6 +1258,7 @@
           new DexEncodedMethod(
               newMethod,
               accessFlags,
+              MethodTypeSignature.noSignature(),
               DexAnnotationSet.empty(),
               ParameterAnnotationsList.empty(),
               code,
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
index 80c47f2..4f289c7 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
@@ -106,7 +106,7 @@
         nestMembers,
         enclosingMembers,
         innerClasses,
-        ClassSignature.NO_CLASS_SIGNATURE,
+        ClassSignature.noSignature(),
         DexAnnotationSet.empty(),
         staticFields,
         instanceFields,
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
index 7cc0c32..ee17db8 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
@@ -4,14 +4,13 @@
 package com.android.tools.r8.synthesis;
 
 import com.android.tools.r8.graph.Code;
-import com.android.tools.r8.graph.DexAnnotation;
 import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProto;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
-import java.util.List;
 
 public class SyntheticMethodBuilder {
 
@@ -24,7 +23,6 @@
   private DexProto proto = null;
   private SyntheticCodeGenerator codeGenerator = null;
   private MethodAccessFlags accessFlags = null;
-  private List<DexAnnotation> annotations = null;
 
   SyntheticMethodBuilder(SyntheticClassBuilder parent, String name) {
     this.parent = parent;
@@ -53,8 +51,9 @@
         new DexEncodedMethod(
             methodSignature,
             getAccessFlags(),
-            getAnnotations(),
-            getParameterAnnotations(),
+            MethodTypeSignature.noSignature(),
+            DexAnnotationSet.empty(),
+            ParameterAnnotationsList.empty(),
             getCodeObject(methodSignature),
             isCompilerSynthesized);
     assert isValidSyntheticMethod(method);
@@ -83,16 +82,6 @@
     return accessFlags;
   }
 
-  private DexAnnotationSet getAnnotations() {
-    return annotations == null
-        ? DexAnnotationSet.empty()
-        : new DexAnnotationSet(annotations.toArray(DexAnnotation.EMPTY_ARRAY));
-  }
-
-  private ParameterAnnotationsList getParameterAnnotations() {
-    return ParameterAnnotationsList.empty();
-  }
-
   private Code getCodeObject(DexMethod methodSignature) {
     return codeGenerator.generate(methodSignature);
   }
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index a429fb1..1633feb 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -1274,6 +1274,7 @@
         System.getProperty("com.android.tools.r8.trackDesugaredAPIConversions") != null;
     public boolean forceLibBackportsInL8CfToCf = false;
     public boolean enumUnboxingRewriteJavaCGeneratedMethod = false;
+    // TODO(b/154793333): Enable assertions always when resolved.
     public boolean assertConsistentRenamingOfSignature = false;
     public boolean allowStaticInterfaceMethodsForPreNApiLevel = false;
     public int verificationSizeLimitInBytesOverride = -1;
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 c72cf47..e5b4c08 100644
--- a/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
+++ b/src/test/java/com/android/tools/r8/dex/JumboStringProcessing.java
@@ -24,6 +24,7 @@
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -155,7 +156,12 @@
     MethodAccessFlags flags = MethodAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC, false);
     DexEncodedMethod method =
         new DexEncodedMethod(
-            null, flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code);
+            null,
+            flags,
+            MethodTypeSignature.noSignature(),
+            DexAnnotationSet.empty(),
+            ParameterAnnotationsList.empty(),
+            code);
     return new JumboStringRewriter(method, string, factory).rewrite();
   }
 }
diff --git a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
index b134ae5..81ae312 100644
--- a/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
+++ b/src/test/java/com/android/tools/r8/dex/SharedClassWritingTest.java
@@ -26,6 +26,7 @@
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.graph.LazyLoadedDexApplication;
@@ -87,6 +88,7 @@
         dexItemFactory.createMethod(
             holder, dexItemFactory.createProto(dexItemFactory.voidType), "theMethod"),
         MethodAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC, false),
+        MethodTypeSignature.noSignature(),
         DexAnnotationSet.empty(),
         ParameterAnnotationsList.empty(),
         code);
@@ -113,7 +115,7 @@
             Collections.emptyList(),
             null,
             Collections.emptyList(),
-            ClassSignature.NO_CLASS_SIGNATURE,
+            ClassSignature.noSignature(),
             DexAnnotationSet.empty(),
             DexEncodedField.EMPTY_ARRAY,
             DexEncodedField.EMPTY_ARRAY,
diff --git a/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java b/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
index 2519477..0011245 100644
--- a/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/graph/GenericSignatureTest.java
@@ -23,13 +23,13 @@
 import com.android.tools.r8.graph.GenericSignature.TypeSignature;
 import com.android.tools.r8.graph.GenericSignature.WildcardIndicator;
 import com.android.tools.r8.graph.GenericSignatureTestClassA.I;
-import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.shaking.AppInfoWithLiveness;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.FieldSubject;
+import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
 import java.util.List;
 import java.util.function.Consumer;
@@ -140,7 +140,7 @@
     DexEncodedField field = yyInZZ.getField();
     assertNotNull(field);
 
-    fieldTypeSignature = field.getFieldSignature();
+    fieldTypeSignature = field.getGenericSignature();
     assertTrue(fieldTypeSignature.hasSignature());
 
     // field type: A$Y$YY
@@ -157,13 +157,7 @@
     method = newYY.getMethod();
     assertNotNull(method);
 
-    methodTypeSignature =
-        GenericSignature.parseMethodSignature(
-            method.qualifiedName(),
-            getGenericSignature(method, appView),
-            Origin.unknown(),
-            appView.dexItemFactory(),
-            appView.options().reporter);
+    methodTypeSignature = method.getGenericSignature();
     assertNotNull(methodTypeSignature);
 
     assertEquals(1, methodTypeSignature.formalTypeParameters.size());
@@ -205,13 +199,7 @@
     method = convertToYY.getMethod();
     assertNotNull(method);
 
-    methodTypeSignature =
-        GenericSignature.parseMethodSignature(
-            method.qualifiedName(),
-            getGenericSignature(method, appView),
-            Origin.unknown(),
-            appView.dexItemFactory(),
-            appView.options().reporter);
+    methodTypeSignature = method.getGenericSignature();
     assertNotNull(methodTypeSignature);
 
     // return type: Function<A$Y$ZZ<TT>, A$Y$YY>
@@ -248,13 +236,7 @@
     assertNotNull(method);
 
     // return type: void
-    methodTypeSignature =
-        GenericSignature.parseMethodSignature(
-            method.qualifiedName(),
-            getGenericSignature(method, appView),
-            Origin.unknown(),
-            appView.dexItemFactory(),
-            appView.options().reporter);
+    methodTypeSignature = method.getGenericSignature();
     assertNotNull(methodTypeSignature);
     returnType = methodTypeSignature.returnType();
     assertTrue(returnType.isVoidDescriptor());
@@ -302,7 +284,7 @@
     checkMethodWildCard(y.uniqueMethodWithName("bar"), appView, WildcardIndicator.NEGATIVE);
     // Check for star
     checkFieldTypeSignature(
-        y.uniqueMethodWithName("baz"),
+        y.uniqueMethodWithName("baz").asFoundMethodSubject(),
         appView,
         typeSignature -> {
           assertTrue(typeSignature.isStar());
@@ -314,7 +296,7 @@
       AppView<AppInfoWithLiveness> appView,
       WildcardIndicator indicator) {
     checkFieldTypeSignature(
-        methodSubject,
+        methodSubject.asFoundMethodSubject(),
         appView,
         typeSignature -> {
           assertTrue(typeSignature.isTypeVariableSignature());
@@ -323,16 +305,10 @@
   }
 
   private void checkFieldTypeSignature(
-      MethodSubject methodSubject,
+      FoundMethodSubject methodSubject,
       AppView<AppInfoWithLiveness> appView,
       Consumer<FieldTypeSignature> fieldTypeConsumer) {
-    MethodTypeSignature methodTypeSignature =
-        GenericSignature.parseMethodSignature(
-            methodSubject.getOriginalName(),
-            getGenericSignature(methodSubject.getMethod(), appView),
-            Origin.unknown(),
-            appView.dexItemFactory(),
-            appView.options().reporter);
+    MethodTypeSignature methodTypeSignature = methodSubject.getMethod().getGenericSignature();
     TypeSignature typeSignature = methodTypeSignature.returnType.typeSignature;
     FieldTypeSignature fieldTypeSignature = typeSignature.asFieldTypeSignature();
     assertTrue(fieldTypeSignature.isClassTypeSignature());
diff --git a/src/test/java/com/android/tools/r8/graph/genericsignature/ClassSignatureTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/ClassSignatureTest.java
index fade8ed..e02f313 100644
--- a/src/test/java/com/android/tools/r8/graph/genericsignature/ClassSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/graph/genericsignature/ClassSignatureTest.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.graph.genericsignature;
 
 import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
-import static com.android.tools.r8.graph.GenericSignature.ClassSignature.NO_CLASS_SIGNATURE;
 import static com.google.common.base.Predicates.alwaysFalse;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.junit.Assert.assertEquals;
@@ -111,9 +110,9 @@
 
   @Test
   public void testSuperClassError() {
-    TestDiagnosticMessages testDiagnosticMessages = testParsingAndPrintingError("Lfoo/bar/baz");
-    testDiagnosticMessages.assertAllWarningsMatch(
-        diagnosticMessage(containsString("Invalid signature 'Lfoo/bar/baz'")));
+    testParsingAndPrintingError("Lfoo/bar/baz")
+        .assertAllWarningsMatch(
+            diagnosticMessage(containsString("Invalid signature 'Lfoo/bar/baz'")));
   }
 
   @Test
@@ -143,7 +142,12 @@
   }
 
   @Test
-  public void testFormalTypeParameters2() {}
+  public void testFormalTypeParameterEmptyInterfaceError() {
+    testParsingAndPrintingError("<T:Ljava/lang/Object;:>Lfoo/bar/baz<TT;>;")
+        .assertAllWarningsMatch(
+            diagnosticMessage(
+                containsString("Invalid signature '<T:Ljava/lang/Object;:>Lfoo/bar/baz<TT;>;'")));
+  }
 
   @Test
   public void testFormalTypeParametersEmptyError() {
@@ -171,7 +175,7 @@
             Origin.unknown(),
             new DexItemFactory(),
             new Reporter(testDiagnosticMessages));
-    assertEquals(NO_CLASS_SIGNATURE, parsed);
+    assertEquals(ClassSignature.noSignature(), parsed);
     return testDiagnosticMessages;
   }
 }
diff --git a/src/test/java/com/android/tools/r8/graph/genericsignature/FieldSignatureTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/FieldSignatureTest.java
index b0200fa..b6e34ad 100644
--- a/src/test/java/com/android/tools/r8/graph/genericsignature/FieldSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/graph/genericsignature/FieldSignatureTest.java
@@ -5,7 +5,6 @@
 package com.android.tools.r8.graph.genericsignature;
 
 import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
-import static com.android.tools.r8.graph.GenericSignature.NO_FIELD_TYPE_SIGNATURE;
 import static com.google.common.base.Predicates.alwaysFalse;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.junit.Assert.assertEquals;
@@ -104,7 +103,7 @@
             Origin.unknown(),
             new DexItemFactory(),
             new Reporter(testDiagnosticMessages));
-    assertEquals(NO_FIELD_TYPE_SIGNATURE, parsed);
+    assertEquals(FieldTypeSignature.noSignature(), parsed);
     return testDiagnosticMessages;
   }
 }
diff --git a/src/test/java/com/android/tools/r8/graph/genericsignature/MethodSignatureTest.java b/src/test/java/com/android/tools/r8/graph/genericsignature/MethodSignatureTest.java
new file mode 100644
index 0000000..c751918
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/graph/genericsignature/MethodSignatureTest.java
@@ -0,0 +1,136 @@
+// Copyright (c) 2020, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.graph.genericsignature;
+
+import static com.android.tools.r8.DiagnosticsMatcher.diagnosticMessage;
+import static com.google.common.base.Predicates.alwaysFalse;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThrows;
+
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.TestDiagnosticMessages;
+import com.android.tools.r8.TestDiagnosticMessagesImpl;
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.graph.DexItemFactory;
+import com.android.tools.r8.graph.GenericSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
+import com.android.tools.r8.graph.GenericSignaturePrinter;
+import com.android.tools.r8.naming.NamingLens;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.Reporter;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class MethodSignatureTest extends TestBase {
+
+  private final TestParameters parameters;
+
+  @Parameters(name = "{0}")
+  public static TestParametersCollection data() {
+    return getTestParameters().withNoneRuntime().build();
+  }
+
+  public MethodSignatureTest(TestParameters parameters) {
+    this.parameters = parameters;
+  }
+
+  @Test
+  public void testEmptyVoid() {
+    testParsingAndPrintingEqual("()V");
+  }
+
+  @Test
+  public void testThrowsOnly() {
+    testParsingAndPrintingError("^TT;")
+        .assertAllErrorsMatch(
+            diagnosticMessage(containsString("Invalid signature '^TT;' for method A.")));
+  }
+
+  @Test
+  public void testArguments() {
+    testParsingAndPrintingEqual("(TT;Lfoo/bar/Baz;[I)V");
+  }
+
+  @Test
+  public void testReturnType() {
+    testParsingAndPrintingEqual("()Lfoo/Baz;");
+  }
+
+  @Test
+  public void testTypeVariableReturn() {
+    testParsingAndPrintingEqual("()TR;");
+  }
+
+  @Test
+  public void testThrowsSingle() {
+    testParsingAndPrintingEqual("(Lfoo/Bar;)V^Ljava/lang/Exception;");
+  }
+
+  @Test
+  public void testThrowsMultiple() {
+    testParsingAndPrintingEqual("(Lfoo/Bar;)V^Ljava/lang/Exception;^TT;^Lfoo/bar/Baz;");
+  }
+
+  @Test
+  public void testThrowsMultipleError() {
+    // TODO(b/170287583): This should throw an error.
+    assertThrows(
+        AssertionError.class,
+        () -> testParsingAndPrintingEqual("(Lfoo/Bar;)V^Ljava/lang/Exception;^TT;Lfoo/bar/Baz;"));
+  }
+
+  @Test
+  public void testTypeArgument() {
+    testParsingAndPrintingEqual("<T:Ljava/lang/Object;>([I)V");
+  }
+
+  @Test
+  public void testTypeArgumentMultiple() {
+    testParsingAndPrintingEqual("<T:Ljava/lang/Object;R::LConsumer<TT;>;>([I)V");
+  }
+
+  @Test
+  public void testTypeArgumentMultipleThrows() {
+    testParsingAndPrintingEqual(
+        "<T:Ljava/lang/Object;R::LConsumer<TT;>;>([Lfoo<TR;>;)Lbaz<TR;>;^TR;^Lfoo<TT;>;");
+  }
+
+  @Test
+  public void testFormalTypeParameterEmptyInterfaceError() {
+    testParsingAndPrintingError("<T:Ljava/lang/Object;:>Lfoo/bar/baz<TT;>;")
+        .assertAllWarningsMatch(
+            diagnosticMessage(
+                containsString("Invalid signature '<T:Ljava/lang/Object;:>Lfoo/bar/baz<TT;>;'")));
+  }
+
+  private void testParsingAndPrintingEqual(String signature) {
+    MethodTypeSignature parsed =
+        GenericSignature.parseMethodSignature(
+            "A", signature, Origin.unknown(), new DexItemFactory(), new Reporter());
+    GenericSignaturePrinter genericSignaturePrinter =
+        new GenericSignaturePrinter(NamingLens.getIdentityLens(), alwaysFalse());
+    genericSignaturePrinter.visitMethodSignature(parsed);
+    String outSignature = genericSignaturePrinter.toString();
+    assertEquals(signature, outSignature);
+  }
+
+  private TestDiagnosticMessages testParsingAndPrintingError(String signature) {
+    TestDiagnosticMessagesImpl testDiagnosticMessages = new TestDiagnosticMessagesImpl();
+    MethodTypeSignature parsed =
+        GenericSignature.parseMethodSignature(
+            "A",
+            signature,
+            Origin.unknown(),
+            new DexItemFactory(),
+            new Reporter(testDiagnosticMessages));
+    assertEquals(MethodTypeSignature.noSignature(), parsed);
+    return testDiagnosticMessages;
+  }
+}
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 99b186f..4e41e64 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
@@ -13,6 +13,7 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.android.tools.r8.graph.ParameterAnnotationsList;
 import com.android.tools.r8.graph.ProgramMethod;
@@ -36,7 +37,7 @@
           Collections.emptyList(),
           null,
           Collections.emptyList(),
-          ClassSignature.NO_CLASS_SIGNATURE,
+          ClassSignature.noSignature(),
           DexAnnotationSet.empty(),
           DexEncodedField.EMPTY_ARRAY,
           DexEncodedField.EMPTY_ARRAY,
@@ -55,6 +56,7 @@
             new DexEncodedMethod(
                 signature,
                 MethodAccessFlags.fromDexAccessFlags(0),
+                MethodTypeSignature.noSignature(),
                 DexAnnotationSet.empty(),
                 ParameterAnnotationsList.empty(),
                 null));
diff --git a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
index fd09ef3..da157c2 100644
--- a/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
+++ b/src/test/java/com/android/tools/r8/maindexlist/MainDexListTests.java
@@ -47,6 +47,7 @@
 import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
 import com.android.tools.r8.graph.GenericSignature.ClassSignature;
+import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
 import com.android.tools.r8.graph.GraphLens;
 import com.android.tools.r8.graph.InitClassLens;
 import com.android.tools.r8.graph.MethodAccessFlags;
@@ -831,7 +832,7 @@
               Collections.emptyList(),
               null,
               Collections.emptyList(),
-              ClassSignature.NO_CLASS_SIGNATURE,
+              ClassSignature.noSignature(),
               DexAnnotationSet.empty(),
               DexEncodedField.EMPTY_ARRAY,
               DexEncodedField.EMPTY_ARRAY,
@@ -857,6 +858,7 @@
             new DexEncodedMethod(
                 voidReturnMethod,
                 access,
+                MethodTypeSignature.noSignature(),
                 DexAnnotationSet.empty(),
                 ParameterAnnotationsList.empty(),
                 code);
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java
index 88d208d..f88443d 100644
--- a/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/naming/MinifierMethodSignatureTest.java
@@ -95,10 +95,7 @@
           diagnostics.assertWarningsMatch(
               diagnosticMessage(
                   allOf(
-                      containsString("Invalid signature 'X' for method"),
-                      containsString(
-                          "java.lang.Throwable Methods.generic(java.lang.Throwable,"
-                              + " Methods$Inner)"),
+                      containsString("Invalid signature 'X' for method generic"),
                       containsString("Expected ( at position 1"))));
         },
         inspector -> noSignatureAttribute(lookupGeneric(inspector)));
@@ -181,6 +178,9 @@
                 ProguardKeepAttributes.SIGNATURE)
             .addKeepAllClassesRuleWithAllowObfuscation()
             .setMinApi(parameters.getApiLevel())
+            .addOptionsModification(
+                internalOptions ->
+                    internalOptions.testing.disableMappingToOriginalProgramVerification = true)
             .allowDiagnosticMessages()
             .compile();
 
diff --git a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
index 8757685..6ababf1 100644
--- a/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
+++ b/src/test/java/com/android/tools/r8/naming/b124357885/B124357885Test.java
@@ -10,19 +10,15 @@
 import static org.hamcrest.CoreMatchers.not;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
 
 import com.android.tools.r8.R8TestCompileResult;
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
-import com.android.tools.r8.graph.DexAnnotationElement;
-import com.android.tools.r8.graph.DexValue;
-import com.android.tools.r8.graph.DexValue.DexValueArray;
 import com.android.tools.r8.shaking.ProguardKeepAttributes;
 import com.android.tools.r8.utils.BooleanUtils;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.StringUtils;
-import com.android.tools.r8.utils.codeinspector.AnnotationSubject;
+import com.android.tools.r8.utils.codeinspector.ClassSubject;
 import com.android.tools.r8.utils.codeinspector.CodeInspector;
 import com.android.tools.r8.utils.codeinspector.MethodSubject;
 import java.lang.reflect.Method;
@@ -50,17 +46,7 @@
     this.minification = minification;
   }
 
-  private void checkSignatureAnnotation(CodeInspector inspector, AnnotationSubject signature) {
-    DexAnnotationElement[] elements = signature.getAnnotation().elements;
-    assertEquals(1, elements.length);
-    assertEquals("value", elements[0].name.toString());
-    assertTrue(elements[0].value.isDexValueArray());
-    DexValueArray array = elements[0].value.asDexValueArray();
-    StringBuilder builder = new StringBuilder();
-    for (DexValue value : array.getValues()) {
-      assertTrue(value.isDexValueString());
-      builder.append(value.asDexValueString().value);
-    }
+  private void checkSignature(CodeInspector inspector, String signature) {
     String fooImplFinalDescriptor =
         DescriptorUtils.javaTypeToDescriptor(inspector.clazz(FooImpl.class).getFinalName());
     StringBuilder expected =
@@ -71,7 +57,7 @@
             .append("<Ljava/lang/String;>")
             // Add the ; after the generic type.
             .append(";");
-    assertEquals(expected.toString(), builder.toString());
+    assertEquals(expected.toString(), signature);
   }
 
   @Test
@@ -90,14 +76,16 @@
             .inspect(
                 inspector -> {
                   assertThat(inspector.clazz(Main.class), isPresentAndNotRenamed());
-                  assertThat(inspector.clazz(Service.class), isPresentAndRenamed(minification));
                   assertThat(inspector.clazz(Foo.class), not(isPresent()));
                   assertThat(inspector.clazz(FooImpl.class), isPresentAndRenamed(minification));
+                  ClassSubject serviceClass = inspector.clazz(Service.class);
+                  assertThat(serviceClass, isPresentAndRenamed(minification));
                   // TODO(124477502): Using uniqueMethodWithName("fooList") does not work.
-                  assertEquals(1, inspector.clazz(Service.class).allMethods().size());
-                  MethodSubject fooList = inspector.clazz(Service.class).allMethods().get(0);
-                  AnnotationSubject signature = fooList.annotation("dalvik.annotation.Signature");
-                  checkSignatureAnnotation(inspector, signature);
+                  assertEquals(1, serviceClass.allMethods().size());
+                  MethodSubject fooList = serviceClass.allMethods().get(0);
+                  assertThat(fooList, isPresent());
+                  checkSignature(
+                      inspector, fooList.asFoundMethodSubject().getFinalSignatureAttribute());
                 });
 
     String fooImplFinalName = compileResult.inspector().clazz(FooImpl.class).getFinalName();
diff --git a/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java b/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java
index adf7ba7..e945182 100644
--- a/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/signature/GenericSignatureRenamingTest.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.naming.signature;
 
-import static org.junit.Assert.assertThrows;
 import static org.junit.Assume.assumeTrue;
 
 import com.android.tools.r8.CompilationMode;
@@ -71,18 +70,13 @@
   }
 
   @Test
-  public void testR8WithAssertEnabled() {
-    // TODO(b/154793333): Enable assertions always when resolved.
-    assertThrows(
-        AssertionError.class,
-        () -> {
-          test(
-              testForR8(parameters.getBackend())
-                  .addKeepRules("-dontobfuscate")
-                  .addOptionsModification(
-                      internalOptions ->
-                          internalOptions.testing.assertConsistentRenamingOfSignature = true));
-        });
+  public void testR8WithAssertEnabled() throws Exception {
+    test(
+        testForR8(parameters.getBackend())
+            .addKeepRules("-dontobfuscate")
+            .addOptionsModification(
+                internalOptions ->
+                    internalOptions.testing.assertConsistentRenamingOfSignature = true));
   }
 
   private void test(R8TestBuilder<?> builder) throws Exception {
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
index 5d4b3a4..de50f11 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/CodeInspector.java
@@ -3,8 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.utils.codeinspector;
 
-import static org.junit.Assert.assertTrue;
-
 import com.android.tools.r8.DexIndexedConsumer;
 import com.android.tools.r8.StringResource;
 import com.android.tools.r8.TestDiagnosticMessagesImpl;
@@ -17,7 +15,6 @@
 import com.android.tools.r8.graph.CfCode;
 import com.android.tools.r8.graph.Code;
 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.DexApplication;
 import com.android.tools.r8.graph.DexClass;
@@ -26,8 +23,6 @@
 import com.android.tools.r8.graph.DexCode.TryHandler;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.DexValue;
-import com.android.tools.r8.graph.DexValue.DexValueArray;
 import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
 import com.android.tools.r8.naming.ClassNameMapper;
 import com.android.tools.r8.naming.ClassNamingForNameMapper;
@@ -229,23 +224,6 @@
     return null;
   }
 
-  public String getFinalSignatureAttribute(DexAnnotationSet annotations) {
-    DexAnnotation annotation = findAnnotation("dalvik.annotation.Signature", annotations);
-    if (annotation == null) {
-      return null;
-    }
-    assert annotation.annotation.elements.length == 1;
-    DexAnnotationElement element = annotation.annotation.elements[0];
-    assert element.value.isDexValueArray();
-    StringBuilder builder = new StringBuilder();
-    DexValueArray valueArray = element.value.asDexValueArray();
-    for (DexValue value : valueArray.getValues()) {
-      assertTrue(value.isDexValueString());
-      builder.append(value.asDexValueString().getValue());
-    }
-    return builder.toString();
-  }
-
   public String getOriginalSignatureAttribute(
       String finalSignature, BiConsumer<GenericSignatureParser, String> parse) {
     if (finalSignature == null || mapping == null) {
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 fce43c7..4504213 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,12 +134,12 @@
   @Override
   public String getOriginalSignatureAttribute() {
     return codeInspector.getOriginalSignatureAttribute(
-        dexField.getFieldSignature().toString(), GenericSignatureParser::parseFieldSignature);
+        getFinalSignatureAttribute(), GenericSignatureParser::parseFieldSignature);
   }
 
   @Override
   public String getFinalSignatureAttribute() {
-    return dexField.getFieldSignature().toString();
+    return dexField.getGenericSignature().toString();
   }
 
   @Override
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 4e49582..4d5e0d3 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
@@ -186,8 +186,7 @@
   @Override
   public String getOriginalSignatureAttribute() {
     return codeInspector.getOriginalSignatureAttribute(
-        codeInspector.getFinalSignatureAttribute(dexMethod.annotations()),
-        GenericSignatureParser::parseMethodSignature);
+        getFinalSignatureAttribute(), GenericSignatureParser::parseMethodSignature);
   }
 
   public DexMethod getOriginalDexMethod(DexItemFactory dexItemFactory) {
@@ -201,7 +200,7 @@
 
   @Override
   public String getFinalSignatureAttribute() {
-    return codeInspector.getFinalSignatureAttribute(dexMethod.annotations());
+    return dexMethod.getGenericSignature().toString();
   }
 
   public Iterable<InstructionSubject> instructions() {