Don't annotate synthetics with contexts in L8.

Change-Id: I136085726ae64b6b8af5d0939879d66c52a19001
diff --git a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
index f2959bb..d1e6951 100644
--- a/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
+++ b/src/main/java/com/android/tools/r8/graph/DexAnnotation.java
@@ -366,11 +366,15 @@
             new DexValueString(dexItemFactory.createString(kind.descriptor)));
     DexAnnotationElement typeElement =
         new DexAnnotationElement(dexItemFactory.valueString, new DexValueType(synthesizingContext));
+    DexAnnotationElement[] elements;
+    if (synthesizingContext == null) {
+      elements = new DexAnnotationElement[] {kindElement};
+    } else {
+      elements = new DexAnnotationElement[] {kindElement, typeElement};
+    }
     return new DexAnnotation(
         VISIBILITY_BUILD,
-        new DexEncodedAnnotation(
-            dexItemFactory.annotationSynthesizedClass,
-            new DexAnnotationElement[] {kindElement, typeElement}));
+        new DexEncodedAnnotation(dexItemFactory.annotationSynthesizedClass, elements));
   }
 
   public static boolean hasSynthesizedClassAnnotation(
@@ -387,7 +391,8 @@
     if (annotation.annotation.type != factory.annotationSynthesizedClass) {
       return null;
     }
-    if (annotation.annotation.elements.length != 2) {
+    int length = annotation.annotation.elements.length;
+    if (length != 1 && length != 2) {
       return null;
     }
     assert factory.kindString.isLessThan(factory.valueString);
@@ -404,6 +409,9 @@
     if (kind == null) {
       return null;
     }
+    if (length != 2) {
+      return new Pair<>(kind, null);
+    }
     DexAnnotationElement valueElement = annotation.annotation.elements[1];
     if (valueElement.name != factory.valueString) {
       return null;
diff --git a/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java b/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java
index 6a611dc..3bf8883 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SynthesizingContext.java
@@ -67,7 +67,6 @@
 
   static SynthesizingContext fromSyntheticInputClass(
       DexProgramClass clazz, DexType synthesizingContextType, AppView<?> appView) {
-    assert synthesizingContextType != null;
     // A context that is itself synthetic must denote a synthesizing context from which to ensure
     // hygiene. This synthesizing context type is encoded on the synthetic for intermediate builds.
     FeatureSplit featureSplit =
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
index ac15138..cbdf447 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticFinalization.java
@@ -478,7 +478,11 @@
       AppView<?> appView) {
     if (shouldAnnotateSynthetics(appView.options())) {
       SyntheticMarker.addMarkerToClass(
-          externalSyntheticClass, kind, context, appView.dexItemFactory());
+          externalSyntheticClass,
+          kind,
+          context,
+          appView.dexItemFactory(),
+          appView.options().forceAnnotateSynthetics);
     }
   }
 
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
index d68558d..1d9b5b9 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMarker.java
@@ -12,6 +12,7 @@
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
+import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.Pair;
 
 public class SyntheticMarker {
@@ -20,21 +21,23 @@
       DexProgramClass clazz,
       SyntheticKind kind,
       SynthesizingContext context,
-      DexItemFactory factory) {
+      DexItemFactory factory,
+      boolean dontRecordSynthesizingContext) {
     clazz.setAnnotations(
         clazz
             .annotations()
             .getWithAddedOrReplaced(
                 DexAnnotation.createAnnotationSynthesizedClass(
-                    kind, context.getSynthesizingContextType(), factory)));
+                    kind,
+                    dontRecordSynthesizingContext ? null : context.getSynthesizingContextType(),
+                    factory)));
   }
 
   public static SyntheticMarker stripMarkerFromClass(DexProgramClass clazz, AppView<?> appView) {
     SyntheticMarker marker = internalStripMarkerFromClass(clazz, appView);
     assert marker != NO_MARKER
-        || DexAnnotation.getSynthesizedClassAnnotationContextType(
-                clazz.annotations(), appView.dexItemFactory())
-            == null;
+        || !DexAnnotation.hasSynthesizedClassAnnotation(
+            clazz.annotations(), appView.dexItemFactory());
     return marker;
   }
 
@@ -67,6 +70,18 @@
       }
     }
     clazz.setAnnotations(DexAnnotationSet.empty());
+    if (context == null) {
+      // If the class is marked as synthetic but has no synthesizing context, then we read the
+      // context type as the prefix. This happens for desugared library builds where the context of
+      // the generated
+      // synthetics becomes themselves. Using the original context could otherwise have referenced
+      // a type in the non-rewritten library and cause an non-rewritten output type.
+      String prefix = SyntheticNaming.getPrefixForExternalSyntheticType(kind, clazz.type);
+      context =
+          appView
+              .dexItemFactory()
+              .createType(DescriptorUtils.getDescriptorFromClassBinaryName(prefix));
+    }
     return new SyntheticMarker(
         kind, SynthesizingContext.fromSyntheticInputClass(clazz, context, appView));
   }