Version 2.1.79

Revert "Cherry-pick signature visitor"

This reverts commit e10f769fe0101a610803fed3287cb797c663f044.

Change-Id: I86d42f3a5cc1dae913eec0220935e5499479c054
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index ae3d5a4..d9cf88d 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -11,7 +11,7 @@
 
   // This field is accessed from release scripts using simple pattern matching.
   // Therefore, changing this field could break our release scripts.
-  public static final String LABEL = "2.1.78";
+  public static final String LABEL = "2.1.79";
 
   private Version() {
   }
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 24a99a0..2b75c58 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -341,7 +341,7 @@
             appView.options().reporter);
       }
     }
-    return ClassSignature.noSignature();
+    return ClassSignature.NO_CLASS_SIGNATURE;
   }
 
   private boolean verifyCorrectnessOfFieldHolder(DexEncodedField field) {
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 a92dc75..9c34474 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignature.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
@@ -174,7 +174,7 @@
 
   public static class ClassSignature implements DexDefinitionSignature<DexClass> {
 
-    private static final ClassSignature NO_CLASS_SIGNATURE =
+    public static final ClassSignature NO_CLASS_SIGNATURE =
         new ClassSignature(EMPTY_TYPE_PARAMS, NO_FIELD_TYPE_SIGNATURE, EMPTY_SUPER_INTERFACES);
 
     final List<FormalTypeParameter> formalTypeParameters;
diff --git a/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java b/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
deleted file mode 100644
index c95ce02..0000000
--- a/src/main/java/com/android/tools/r8/graph/GenericSignatureTypeRewriter.java
+++ /dev/null
@@ -1,326 +0,0 @@
-// 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;
-
-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.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;
-import com.android.tools.r8.graph.GenericSignature.ClassSignature;
-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;
-import java.util.List;
-
-public class GenericSignatureTypeRewriter {
-
-  private final AppView<?> appView;
-  private final DexProgramClass context;
-
-  private final FieldTypeSignature objectTypeSignature;
-
-  public GenericSignatureTypeRewriter(AppView<?> appView, DexProgramClass context) {
-    this.appView = appView;
-    this.context = context;
-    objectTypeSignature =
-        new ClassTypeSignature(appView.dexItemFactory().objectType, EMPTY_TYPE_ARGUMENTS);
-  }
-
-  public ClassSignature rewrite(ClassSignature classSignature) {
-    if (classSignature.hasNoSignature()) {
-      return classSignature;
-    }
-    return new ClassSignatureRewriter().run(classSignature);
-  }
-
-  public FieldTypeSignature rewrite(FieldTypeSignature fieldTypeSignature) {
-    if (fieldTypeSignature.hasNoSignature()) {
-      return fieldTypeSignature;
-    }
-    return new TypeSignatureRewriter().run(fieldTypeSignature);
-  }
-
-  public MethodTypeSignature rewrite(MethodTypeSignature methodTypeSignature) {
-    if (methodTypeSignature.hasNoSignature()) {
-      return methodTypeSignature;
-    }
-    return new MethodTypeSignatureRewriter().run(methodTypeSignature);
-  }
-
-  private class ClassSignatureRewriter implements GenericSignatureVisitor {
-
-    private final List<FormalTypeParameter> rewrittenTypeParameters = new ArrayList<>();
-    private ClassTypeSignature rewrittenSuperClass;
-    private final List<ClassTypeSignature> rewrittenSuperInterfaces = new ArrayList<>();
-
-    @Override
-    public void visitClassSignature(ClassSignature classSignature) {
-      classSignature.visit(this);
-    }
-
-    @Override
-    public void visitFormalTypeParameters(List<FormalTypeParameter> formalTypeParameters) {
-      for (FormalTypeParameter formalTypeParameter : formalTypeParameters) {
-        rewrittenTypeParameters.add(new FormalTypeParameterRewriter().run(formalTypeParameter));
-      }
-    }
-
-    @Override
-    public void visitSuperClass(ClassTypeSignature classTypeSignature) {
-      rewrittenSuperClass = new ClassTypeSignatureRewriter(true).run(classTypeSignature);
-      if (rewrittenSuperClass == null) {
-        rewrittenSuperClass =
-            new ClassTypeSignature(appView.dexItemFactory().objectType, EMPTY_TYPE_ARGUMENTS);
-      }
-    }
-
-    @Override
-    public void visitSuperInterface(ClassTypeSignature classTypeSignature) {
-      ClassTypeSignature superInterface =
-          new ClassTypeSignatureRewriter(true).run(classTypeSignature);
-      if (superInterface != null) {
-        rewrittenSuperInterfaces.add(superInterface);
-      }
-    }
-
-    private ClassSignature run(ClassSignature classSignature) {
-      classSignature.visit(this);
-      if (rewrittenTypeParameters.isEmpty()
-          && rewrittenSuperInterfaces.isEmpty()
-          && rewrittenSuperClass.isNoSignature()
-          && rewrittenSuperClass.type == appView.dexItemFactory().objectType) {
-        return ClassSignature.noSignature();
-      }
-      return new ClassSignature(
-          rewrittenTypeParameters.isEmpty() ? EMPTY_TYPE_PARAMS : rewrittenTypeParameters,
-          rewrittenSuperClass,
-          rewrittenSuperInterfaces.isEmpty() ? EMPTY_SUPER_INTERFACES : rewrittenSuperInterfaces);
-    }
-  }
-
-  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 = noSignature();
-    private final List<FieldTypeSignature> rewrittenInterfaceBounds = new ArrayList<>();
-
-    @Override
-    public void visitClassBound(FieldTypeSignature fieldSignature) {
-      rewrittenClassBound = new TypeSignatureRewriter().run(fieldSignature);
-    }
-
-    @Override
-    public void visitInterfaceBound(FieldTypeSignature fieldSignature) {
-      FieldTypeSignature interfaceBound = new TypeSignatureRewriter().run(fieldSignature);
-      if (interfaceBound != null) {
-        rewrittenInterfaceBounds.add(interfaceBound);
-      }
-    }
-
-    private FormalTypeParameter run(FormalTypeParameter formalTypeParameter) {
-      formalTypeParameter.visit(this);
-      // Guard against the case where we have <T::...> that is, no class or interfaces bounds.
-      if (rewrittenInterfaceBounds.isEmpty()
-          && (rewrittenClassBound == null || !rewrittenClassBound.hasSignature())) {
-        rewrittenClassBound = objectTypeSignature;
-      }
-      return new FormalTypeParameter(
-          formalTypeParameter.name,
-          rewrittenClassBound == null ? noSignature() : rewrittenClassBound,
-          rewrittenInterfaceBounds.isEmpty() ? EMPTY_TYPE_ARGUMENTS : rewrittenInterfaceBounds);
-    }
-  }
-
-  private class TypeSignatureRewriter implements GenericSignatureVisitor {
-
-    private TypeSignature run(TypeSignature typeSignature) {
-      if (typeSignature.isBaseTypeSignature()) {
-        return typeSignature;
-      }
-      assert typeSignature.isFieldTypeSignature();
-      return run(typeSignature.asFieldTypeSignature());
-    }
-
-    private FieldTypeSignature run(FieldTypeSignature fieldTypeSignature) {
-      if (fieldTypeSignature.isStar()) {
-        return fieldTypeSignature;
-      }
-      if (fieldTypeSignature.isTypeVariableSignature()) {
-        return fieldTypeSignature;
-      }
-      if (fieldTypeSignature.isArrayTypeSignature()) {
-        ArrayTypeSignature arrayTypeSignature = fieldTypeSignature.asArrayTypeSignature();
-        TypeSignature rewrittenElement = run(arrayTypeSignature.elementSignature);
-        if (rewrittenElement == null) {
-          return new ArrayTypeSignature(objectTypeSignature);
-        }
-        return rewrittenElement.toArrayTypeSignature();
-      }
-      assert fieldTypeSignature.isClassTypeSignature();
-      ClassTypeSignature classTypeSignature = fieldTypeSignature.asClassTypeSignature();
-      if (classTypeSignature.isNoSignature()) {
-        return classTypeSignature;
-      }
-      return new ClassTypeSignatureRewriter(false).run(classTypeSignature);
-    }
-  }
-
-  private class ClassTypeSignatureRewriter implements GenericSignatureVisitor {
-
-    private final AppInfoWithLiveness appInfoWithLiveness;
-    private final boolean isSuperClassOrInterface;
-
-    // These fields are updated when iterating the modeled structure.
-    private DexType currentType;
-
-    // The following references are used to have a head and tail pointer to the classTypeSignature
-    // link we are building. The topClassSignature will have a reference to the top-most package
-    // and class-name. The parentClassSignature is a pointer pointing to the tail always and will
-    // be linked and updated when calling ClassTypeSignature.link.
-    private ClassTypeSignature topClassSignature;
-    private ClassTypeSignature parentClassSignature;
-
-    private ClassTypeSignatureRewriter(boolean isSuperClassOrInterface) {
-      appInfoWithLiveness =
-          appView.appInfo().hasLiveness() ? appView.appInfo().withLiveness() : null;
-      this.isSuperClassOrInterface = isSuperClassOrInterface;
-    }
-
-    @Override
-    public void visitSimpleClass(ClassTypeSignature classTypeSignature) {
-      currentType = getTarget(classTypeSignature.type);
-      if (currentType == null) {
-        return;
-      }
-      classTypeSignature.visit(this);
-    }
-
-    @Override
-    public void visitTypeArguments(List<FieldTypeSignature> typeArguments) {
-      ClassTypeSignature newClassTypeSignature;
-      if (typeArguments.isEmpty()) {
-        newClassTypeSignature = new ClassTypeSignature(currentType, EMPTY_TYPE_ARGUMENTS);
-      } else {
-        List<FieldTypeSignature> rewrittenTypeArguments = new ArrayList<>(typeArguments.size());
-        for (FieldTypeSignature typeArgument : typeArguments) {
-          if (typeArgument.isStar()) {
-            rewrittenTypeArguments.add(typeArgument);
-            continue;
-          }
-          FieldTypeSignature rewritten = new TypeSignatureRewriter().run(typeArgument);
-          if (rewritten != null) {
-            rewrittenTypeArguments.add(rewritten.asArgument(typeArgument.getWildcardIndicator()));
-          } else {
-            rewrittenTypeArguments.add(STAR_FIELD_TYPE_SIGNATURE);
-          }
-        }
-        newClassTypeSignature = new ClassTypeSignature(currentType, rewrittenTypeArguments);
-      }
-      if (topClassSignature == null) {
-        topClassSignature = newClassTypeSignature;
-        parentClassSignature = newClassTypeSignature;
-      } else {
-        ClassTypeSignature.link(parentClassSignature, newClassTypeSignature);
-        parentClassSignature = newClassTypeSignature;
-      }
-    }
-
-    private ClassTypeSignature run(ClassTypeSignature classTypeSignature) {
-      currentType = getTarget(classTypeSignature.type);
-      if (currentType == null) {
-        return null;
-      }
-      classTypeSignature.visit(this);
-      return topClassSignature;
-    }
-
-    private DexType getTarget(DexType type) {
-      DexType rewrittenType = appView.graphLense().lookupType(type);
-      if (appInfoWithLiveness != null && appInfoWithLiveness.wasPruned(rewrittenType)) {
-        return null;
-      }
-      if (isSuperClassOrInterface && context.type == rewrittenType) {
-        return null;
-      }
-      return rewrittenType;
-    }
-  }
-}
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 fd5dc11..1f66108 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,25 +4,28 @@
 
 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;
-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.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.PredicateUtils;
 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.Function;
+import java.util.function.BiConsumer;
+import java.util.function.Consumer;
 import java.util.function.Predicate;
+import java.util.function.Supplier;
 
 // TODO(b/129925954): Reimplement this by using the internal encoding and transformation logic.
 public class GenericSignatureRewriter {
@@ -31,14 +34,12 @@
   private final NamingLens namingLens;
   private final InternalOptions options;
   private final Reporter reporter;
-  private final Predicate<DexType> isTypeMissing;
 
   public GenericSignatureRewriter(AppView<?> appView, NamingLens namingLens) {
     this.appView = appView;
     this.namingLens = namingLens;
     this.options = appView.options();
     this.reporter = options.reporter;
-    isTypeMissing = PredicateUtils.isNull(appView.appInfo()::definitionForWithoutExistenceAssert);
   }
 
   public void run(Iterable<? extends DexProgramClass> classes, ExecutorService executorService)
@@ -55,77 +56,51 @@
     ThreadUtils.processItems(
         classes,
         clazz -> {
-          GenericSignatureTypeRewriter typeRewriter =
-              new GenericSignatureTypeRewriter(appView, clazz);
+          GenericSignatureCollector genericSignatureCollector =
+              new GenericSignatureCollector(clazz);
+          GenericSignatureParser<DexType> genericSignatureParser =
+              new GenericSignatureParser<>(genericSignatureCollector);
           clazz.setAnnotations(
               rewriteGenericSignatures(
                   clazz.annotations(),
-                  signature -> {
-                    ClassSignature classSignature =
-                        GenericSignature.parseClassSignature(
-                            clazz.toSourceString(),
-                            signature,
-                            clazz.origin,
-                            appView.dexItemFactory(),
-                            options.reporter);
-                    if (classSignature.hasNoSignature()) {
-                      return null;
-                    }
-                    return typeRewriter
-                        .rewrite(classSignature)
-                        .toRenamedString(namingLens, isTypeMissing);
-                  }));
+                  genericSignatureParser::parseClassSignature,
+                  genericSignatureCollector::getRenamedSignature,
+                  (signature, e) ->
+                      options.warningInvalidSignature(clazz, clazz.getOrigin(), signature, e)));
           clazz.forEachField(
               field ->
                   field.setAnnotations(
                       rewriteGenericSignatures(
                           field.annotations(),
-                          signature -> {
-                            FieldTypeSignature fieldSignature =
-                                GenericSignature.parseFieldTypeSignature(
-                                    field.toSourceString(),
-                                    signature,
-                                    clazz.origin,
-                                    appView.dexItemFactory(),
-                                    options.reporter);
-                            if (fieldSignature.hasNoSignature()) {
-                              return null;
-                            }
-                            return typeRewriter
-                                .rewrite(fieldSignature)
-                                .toRenamedString(namingLens, isTypeMissing);
-                          })));
+                          genericSignatureParser::parseFieldSignature,
+                          genericSignatureCollector::getRenamedSignature,
+                          (signature, e) ->
+                              options.warningInvalidSignature(
+                                  field, clazz.getOrigin(), signature, e))));
           clazz.forEachMethod(
               method ->
                   method.setAnnotations(
                       rewriteGenericSignatures(
                           method.annotations(),
-                          signature -> {
-                            MethodTypeSignature methodSignature =
-                                GenericSignature.parseMethodSignature(
-                                    method.toSourceString(),
-                                    signature,
-                                    clazz.origin,
-                                    appView.dexItemFactory(),
-                                    options.reporter);
-                            if (methodSignature.hasNoSignature()) {
-                              return null;
-                            }
-                            return typeRewriter
-                                .rewrite(methodSignature)
-                                .toRenamedString(namingLens, isTypeMissing);
-                          })));
+                          genericSignatureParser::parseMethodSignature,
+                          genericSignatureCollector::getRenamedSignature,
+                          (signature, e) ->
+                              options.warningInvalidSignature(
+                                  method, clazz.getOrigin(), signature, e))));
         },
         executorService);
   }
 
   private DexAnnotationSet rewriteGenericSignatures(
-      DexAnnotationSet annotations, Function<String, String> rewrite) {
+      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 invalidOrPrunedIndex = VALID;
+    int invalid = VALID;
     DexAnnotation[] rewrittenAnnotations = null;
-    for (int i = 0; i < annotations.annotations.length && invalidOrPrunedIndex == VALID; i++) {
+    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) {
@@ -133,12 +108,16 @@
           System.arraycopy(annotations.annotations, 0, rewrittenAnnotations, 0, i);
         }
         String signature = DexAnnotation.getSignature(annotation);
-        String rewrittenSignature = rewrite.apply(signature);
-        if (rewrittenSignature != null) {
-          rewrittenAnnotations[i] =
-              DexAnnotation.createSignatureAnnotation(rewrittenSignature, appView.dexItemFactory());
-        } else {
-          invalidOrPrunedIndex = i;
+        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;
@@ -146,7 +125,7 @@
     }
 
     // Return the rewritten signatures if it was valid and could be rewritten.
-    if (invalidOrPrunedIndex == VALID) {
+    if (invalid == VALID) {
       return rewrittenAnnotations != null
           ? new DexAnnotationSet(rewrittenAnnotations)
           : annotations;
@@ -156,11 +135,156 @@
         new DexAnnotation[annotations.annotations.length - 1];
     int dest = 0;
     for (int i = 0; i < annotations.annotations.length; i++) {
-      if (i != invalidOrPrunedIndex) {
+      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.graphLense().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.graphLense().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/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 14788ba..af62b23 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -28,6 +28,7 @@
 import com.android.tools.r8.features.FeatureSplitConfiguration;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexDefinition;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexItem;
 import com.android.tools.r8.graph.DexItemFactory;
@@ -56,6 +57,7 @@
 import com.google.common.collect.Sets;
 import java.io.IOException;
 import java.io.PrintStream;
+import java.lang.reflect.GenericSignatureFormatError;
 import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
@@ -909,6 +911,31 @@
     }
   }
 
+  public void warningInvalidSignature(
+      DexDefinition item, Origin origin, String signature, GenericSignatureFormatError e) {
+    StringBuilder message = new StringBuilder("Invalid signature '");
+    message.append(signature);
+    message.append("' for ");
+    if (item.isDexClass()) {
+      message.append("class ");
+      message.append((item.asDexClass()).getType().toSourceString());
+    } else if (item.isDexEncodedField()) {
+      message.append("field ");
+      message.append(item.toSourceString());
+    } else {
+      assert item.isDexEncodedMethod();
+      message.append("method ");
+      message.append(item.toSourceString());
+    }
+    message.append(".");
+    message.append(System.lineSeparator());
+    message.append("Signature is ignored and will not be present in the output.");
+    message.append(System.lineSeparator());
+    message.append("Parser error: ");
+    message.append(e.getMessage());
+    reporter.warning(new StringDiagnostic(message.toString(), origin));
+  }
+
   public boolean printWarnings() {
     boolean printed = false;
     boolean printOutdatedToolchain = false;
diff --git a/src/main/java/com/android/tools/r8/utils/PredicateUtils.java b/src/main/java/com/android/tools/r8/utils/PredicateUtils.java
index f219259..880da5e 100644
--- a/src/main/java/com/android/tools/r8/utils/PredicateUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/PredicateUtils.java
@@ -4,7 +4,6 @@
 
 package com.android.tools.r8.utils;
 
-import java.util.function.Function;
 import java.util.function.Predicate;
 
 public class PredicateUtils {
@@ -21,8 +20,4 @@
   public static <T> Predicate<T> not(Predicate<T> predicate) {
     return t -> !predicate.test(t);
   }
-
-  public static <T, R> Predicate<T> isNull(Function<T, R> func) {
-    return t -> func.apply(t) == null;
-  }
 }
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 eb76047..cd057d2 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,6 +5,7 @@
 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 org.hamcrest.CoreMatchers.containsString;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertThrows;
@@ -170,7 +171,7 @@
             Origin.unknown(),
             new DexItemFactory(),
             new Reporter(testDiagnosticMessages));
-    assertEquals(ClassSignature.noSignature(), parsed);
+    assertEquals(NO_CLASS_SIGNATURE, parsed);
     return testDiagnosticMessages;
   }
 }
diff --git a/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java b/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java
index 20e13bf..d44fcd1 100644
--- a/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java
+++ b/src/test/java/com/android/tools/r8/naming/b126592786/B126592786.java
@@ -57,7 +57,7 @@
         .compile()
         .inspect(
             inspector -> {
-              String genericTypeDescriptor = "*";
+              String genericTypeDescriptor = "Ljava/lang/Object;";
               if (genericTypeLive) {
                 ClassSubject genericType = inspector.clazz(GenericType.class);
                 assertThat(genericType, isRenamed(minify));
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 e945182..adf7ba7 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,6 +4,7 @@
 
 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;
@@ -70,13 +71,18 @@
   }
 
   @Test
-  public void testR8WithAssertEnabled() throws Exception {
-    test(
-        testForR8(parameters.getBackend())
-            .addKeepRules("-dontobfuscate")
-            .addOptionsModification(
-                internalOptions ->
-                    internalOptions.testing.assertConsistentRenamingOfSignature = true));
+  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));
+        });
   }
 
   private void test(R8TestBuilder<?> builder) throws Exception {