Add flag to compile desugared library with j$.j$$.

Bug: b/274626810
Change-Id: Ie331f557c1867cb6095bfde52ff75e52055e4f35
diff --git a/buildSrc/src/main/java/desugaredlibrary/CustomConversionAsmRewriteDescription.java b/buildSrc/src/main/java/desugaredlibrary/CustomConversionAsmRewriteDescription.java
index 3ac81cd..d1b949b 100644
--- a/buildSrc/src/main/java/desugaredlibrary/CustomConversionAsmRewriteDescription.java
+++ b/buildSrc/src/main/java/desugaredlibrary/CustomConversionAsmRewriteDescription.java
@@ -35,12 +35,14 @@
   static Map<String, String> getWrapConvertOwnerMap() {
     HashMap<String, String> map = new HashMap<>();
     for (String theEnum : ENUM_WRAP_CONVERT_OWNER) {
-      map.put(theEnum, theEnum + "$EnumConversion");
-      map.put(withJavaPrefix(theEnum), theEnum + "$EnumConversion");
+      String theEnumJava = withJavaPrefix(theEnum);
+      map.put(theEnum, theEnumJava + "$EnumConversion");
+      map.put(theEnumJava, theEnumJava + "$EnumConversion");
     }
     for (String owner : WRAP_CONVERT_OWNER) {
-      map.put(withJavaPrefix(owner), owner + "$Wrapper");
-      map.put(owner, owner + "$VivifiedWrapper");
+      String ownerJava = withJavaPrefix(owner);
+      map.put(ownerJava, ownerJava + "$Wrapper");
+      map.put(owner, ownerJava + "$VivifiedWrapper");
     }
     return map;
   }
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index ff649f7..137cb8b 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -696,11 +696,8 @@
     internal.encodeChecksums = getIncludeClassesChecksum();
     internal.dexClassChecksumFilter = getDexClassChecksumFilter();
     internal.enableInheritanceClassInDexDistributor = isOptimizeMultidexForLinearAlloc();
-    internal.setDesugaredLibrarySpecification(desugaredLibrarySpecification);
-    internal.synthesizedClassPrefix =
-        synthesizedClassPrefix.isEmpty()
-            ? System.getProperty("com.android.tools.r8.synthesizedClassPrefix", "")
-            : synthesizedClassPrefix;
+
+    internal.configureDesugaredLibrary(desugaredLibrarySpecification, synthesizedClassPrefix);
     internal.desugaredLibraryKeepRuleConsumer = desugaredLibraryKeepRuleConsumer;
 
     if (!enableMissingLibraryApiModeling) {
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 1edde59..6eb01b6 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -211,10 +211,9 @@
     assert internal.enableInheritanceClassInDexDistributor;
     internal.enableInheritanceClassInDexDistributor = false;
 
-    assert desugaredLibrarySpecification != null;
-    internal.setDesugaredLibrarySpecification(desugaredLibrarySpecification);
-    internal.synthesizedClassPrefix =
-        desugaredLibrarySpecification.getSynthesizedLibraryClassesPackagePrefix();
+    internal.configureDesugaredLibrary(
+        desugaredLibrarySpecification,
+        desugaredLibrarySpecification.getSynthesizedLibraryClassesPackagePrefix());
 
     // Default is to remove all javac generated assertion code when generating dex.
     assert internal.assertionsConfiguration == null;
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 62a6e97..edec018 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -1144,11 +1144,7 @@
 
     internal.enableInheritanceClassInDexDistributor = isOptimizeMultidexForLinearAlloc();
 
-    internal.setDesugaredLibrarySpecification(desugaredLibrarySpecification);
-    internal.synthesizedClassPrefix =
-        synthesizedClassPrefix.isEmpty()
-            ? System.getProperty("com.android.tools.r8.synthesizedClassPrefix", "")
-            : synthesizedClassPrefix;
+    internal.configureDesugaredLibrary(desugaredLibrarySpecification, synthesizedClassPrefix);
     boolean l8Shrinking = !internal.synthesizedClassPrefix.isEmpty();
     // TODO(b/214382176): Enable all the time.
     internal.loadAllClassDefinitions = l8Shrinking;
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/TypeRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/TypeRewriter.java
index c8c5159..a529491 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/TypeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/TypeRewriter.java
@@ -15,7 +15,7 @@
 public abstract class TypeRewriter {
 
   public static TypeRewriter empty() {
-    return new EmptyPrefixRewritingMapper();
+    return new EmptyTypeRewriter();
   }
 
   public abstract void rewriteType(DexType type, DexType rewrittenType);
@@ -44,12 +44,12 @@
 
   public abstract void forAllRewrittenTypes(Consumer<DexType> consumer);
 
-  public static class MachineDesugarPrefixRewritingMapper extends TypeRewriter {
+  public static class MachineTypeRewriter extends TypeRewriter {
 
     private final Map<DexType, DexType> rewriteType;
     private final Map<DexType, DexType> rewriteDerivedTypeOnly;
 
-    public MachineDesugarPrefixRewritingMapper(MachineDesugaredLibrarySpecification specification) {
+    public MachineTypeRewriter(MachineDesugaredLibrarySpecification specification) {
       this.rewriteType = new ConcurrentHashMap<>(specification.getRewriteType());
       rewriteDerivedTypeOnly = specification.getRewriteDerivedTypeOnly();
     }
@@ -99,7 +99,7 @@
     }
   }
 
-  public static class EmptyPrefixRewritingMapper extends TypeRewriter {
+  public static class EmptyTypeRewriter extends TypeRewriter {
 
     @Override
     public DexType rewrittenType(DexType type, AppView<?> appView) {
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
index 31baed9..985eb29 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineDesugaredLibrarySpecification.java
@@ -6,6 +6,7 @@
 
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexReference;
 import com.android.tools.r8.graph.DexType;
@@ -14,6 +15,7 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion.LibraryValidator;
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.ListUtils;
 import com.android.tools.r8.utils.SemanticVersion;
 import com.android.tools.r8.utils.StringUtils;
@@ -261,4 +263,14 @@
   public boolean includesJDK11Methods() {
     return getLeadingVersionNumber() >= 2;
   }
+
+  public MachineDesugaredLibrarySpecification withPostPrefix(
+      DexItemFactory factory, String postPrefix) {
+    String oldPrefix = topLevelFlags.getSynthesizedLibraryClassesPackagePrefix();
+    String newPrefix = oldPrefix + DescriptorUtils.getPackageBinaryNameFromJavaType(postPrefix);
+    return new MachineDesugaredLibrarySpecification(
+        libraryCompilation,
+        topLevelFlags.withPostPrefix(postPrefix),
+        rewritingFlags.withPostPrefix(factory, oldPrefix, newPrefix));
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
index 6d3f489..a30322f 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineRewritingFlags.java
@@ -6,8 +6,11 @@
 
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.graph.DexMethod;
+import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.graph.DexTypeList;
 import com.android.tools.r8.graph.FieldAccessFlags;
 import com.android.tools.r8.graph.MethodAccessFlags;
 import com.google.common.collect.ImmutableMap;
@@ -232,6 +235,109 @@
         && legacyBackport.isEmpty();
   }
 
+  public MachineRewritingFlags withPostPrefix(
+      DexItemFactory factory, String oldPrefix, String newPrefix) {
+    return new MachineRewritingFlags(
+        typeMapWithPostPrefix(rewriteType, factory, oldPrefix, newPrefix),
+        maintainType,
+        typeMapWithPostPrefix(rewriteDerivedTypeOnly, factory, oldPrefix, newPrefix),
+        staticFieldRetarget,
+        covariantRetarget,
+        staticRetarget,
+        nonEmulatedVirtualRetarget,
+        emulatedVirtualRetarget,
+        emulatedVirtualRetargetThroughEmulatedInterface,
+        apiGenericTypesConversion,
+        emulatedInterfacesWithPostPrefix(factory, oldPrefix, newPrefix),
+        wrappers,
+        legacyBackport,
+        dontRetarget,
+        customConversionsWithPostPrefix(factory, oldPrefix, newPrefix),
+        neverOutlineApi,
+        amendLibraryMethod,
+        amendLibraryField);
+  }
+
+  private Map<DexType, CustomConversionDescriptor> customConversionsWithPostPrefix(
+      DexItemFactory factory, String oldPrefix, String newPrefix) {
+    ImmutableMap.Builder<DexType, CustomConversionDescriptor> builder = ImmutableMap.builder();
+    customConversions.forEach(
+        (k, v) ->
+            builder.put(
+                k,
+                new CustomConversionDescriptor(
+                    methodWithPostPrefix(v.getTo(), factory, oldPrefix, newPrefix),
+                    methodWithPostPrefix(v.getFrom(), factory, oldPrefix, newPrefix))));
+    return builder.build();
+  }
+
+  private Map<DexType, EmulatedInterfaceDescriptor> emulatedInterfacesWithPostPrefix(
+      DexItemFactory factory, String oldPrefix, String newPrefix) {
+    ImmutableMap.Builder<DexType, EmulatedInterfaceDescriptor> builder = ImmutableMap.builder();
+    emulatedInterfaces.forEach(
+        (k, v) -> builder.put(k, descriptorWithPostPrefix(v, factory, oldPrefix, newPrefix)));
+    return builder.build();
+  }
+
+  private EmulatedInterfaceDescriptor descriptorWithPostPrefix(
+      EmulatedInterfaceDescriptor descriptor,
+      DexItemFactory factory,
+      String oldPrefix,
+      String newPrefix) {
+    DexType rewritten =
+        typeWithPostPrefix(descriptor.getRewrittenType(), factory, oldPrefix, newPrefix);
+    Map<DexMethod, EmulatedDispatchMethodDescriptor> newDescriptors = new IdentityHashMap<>();
+    descriptor
+        .getEmulatedMethods()
+        .forEach(
+            (method, descr) -> {
+              assert descr.getInterfaceMethod().getMethod().getHolderType()
+                  == descriptor.getRewrittenType();
+              newDescriptors.put(
+                  method,
+                  new EmulatedDispatchMethodDescriptor(
+                      new DerivedMethod(
+                          descr.getInterfaceMethod().getMethod().withHolder(rewritten, factory),
+                          descr.getInterfaceMethod().getMachineHolderKind()),
+                      descr.getEmulatedDispatchMethod(),
+                      descr.getForwardingMethod(),
+                      descr.getDispatchCases()));
+            });
+    return new EmulatedInterfaceDescriptor(rewritten, newDescriptors);
+  }
+
+  private Map<DexType, DexType> typeMapWithPostPrefix(
+      Map<DexType, DexType> map, DexItemFactory factory, String oldPrefix, String newPrefix) {
+    ImmutableMap.Builder<DexType, DexType> builder = ImmutableMap.builder();
+    map.forEach((k, v) -> builder.put(k, typeWithPostPrefix(v, factory, oldPrefix, newPrefix)));
+    return builder.build();
+  }
+
+  private DexMethod methodWithPostPrefix(
+      DexMethod method, DexItemFactory factory, String oldPrefix, String newPrefix) {
+    return factory.createMethod(
+        method.getHolderType(),
+        protoWithPostPrefix(method.getProto(), factory, oldPrefix, newPrefix),
+        method.getName());
+  }
+
+  private DexProto protoWithPostPrefix(
+      DexProto proto, DexItemFactory factory, String oldPrefix, String newPrefix) {
+    DexType[] values = proto.getParameters().values;
+    DexType[] newValues = new DexType[values.length];
+    for (int i = 0; i < values.length; i++) {
+      newValues[i] = typeWithPostPrefix(values[i], factory, oldPrefix, newPrefix);
+    }
+    return factory.createProto(
+        typeWithPostPrefix(proto.getReturnType(), factory, oldPrefix, newPrefix),
+        DexTypeList.create(newValues));
+  }
+
+  private DexType typeWithPostPrefix(
+      DexType type, DexItemFactory factory, String oldPrefix, String newPrefix) {
+    return factory.createType(type.toDescriptorString().replace(oldPrefix, newPrefix));
+  }
+
   public static class Builder {
 
     Builder() {}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineTopLevelFlags.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineTopLevelFlags.java
index c5c1b4b..f944e8e 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineTopLevelFlags.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/machinespecification/MachineTopLevelFlags.java
@@ -5,7 +5,9 @@
 package com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification;
 
 import com.android.tools.r8.utils.AndroidApiLevel;
+import com.android.tools.r8.utils.DescriptorUtils;
 import com.google.common.collect.ImmutableList;
+import java.util.ArrayList;
 import java.util.List;
 
 public class MachineTopLevelFlags {
@@ -71,4 +73,25 @@
   public String getExtraKeepRulesConcatenated() {
     return String.join("\n", extraKeepRules);
   }
+
+  public MachineTopLevelFlags withPostPrefix(String postPrefix) {
+    assert postPrefix.endsWith(String.valueOf(DescriptorUtils.JAVA_PACKAGE_SEPARATOR));
+    String prefix =
+        DescriptorUtils.getJavaTypeFromBinaryName(synthesizedLibraryClassesPackagePrefix);
+    String cleanPostPrefix = DescriptorUtils.getJavaTypeFromBinaryName(postPrefix);
+    String newPrefix = prefix + cleanPostPrefix;
+    String newPrefixWithSlash = DescriptorUtils.getPackageBinaryNameFromJavaType(newPrefix);
+    List<String> newKeepRules = new ArrayList<>(extraKeepRules.size());
+    for (String kr : extraKeepRules) {
+      // TODO(b/278046666): Consider changing the ProguardRuleParser to avoid invalid replacements.
+      newKeepRules.add(kr.replace(prefix, newPrefix));
+    }
+    return new MachineTopLevelFlags(
+        requiredCompilationAPILevel,
+        newPrefixWithSlash,
+        identifier,
+        jsonSource,
+        supportAllCallbacksFromLibrary,
+        newKeepRules);
+  }
 }
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 f48a387..288ab00 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -64,7 +64,7 @@
 import com.android.tools.r8.ir.analysis.type.TypeElement;
 import com.android.tools.r8.ir.code.IRCode;
 import com.android.tools.r8.ir.desugar.TypeRewriter;
-import com.android.tools.r8.ir.desugar.TypeRewriter.MachineDesugarPrefixRewritingMapper;
+import com.android.tools.r8.ir.desugar.TypeRewriter.MachineTypeRewriter;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.nest.Nest;
@@ -1075,14 +1075,39 @@
     machineDesugaredLibrarySpecification = MachineDesugaredLibrarySpecification.empty();
   }
 
+  public void configureDesugaredLibrary(
+      DesugaredLibrarySpecification desugaredLibrarySpecification, String synthesizedClassPrefix) {
+    assert synthesizedClassPrefix != null;
+    assert desugaredLibrarySpecification != null;
+    String prefix =
+        synthesizedClassPrefix.isEmpty()
+            ? System.getProperty("com.android.tools.r8.synthesizedClassPrefix", "")
+            : synthesizedClassPrefix;
+    String postPrefix = System.getProperty("com.android.tools.r8.desugaredLibraryPostPrefix", null);
+    setDesugaredLibrarySpecification(desugaredLibrarySpecification, postPrefix);
+    String post =
+        postPrefix == null ? "" : DescriptorUtils.getPackageBinaryNameFromJavaType(postPrefix);
+    this.synthesizedClassPrefix = prefix.isEmpty() ? "" : prefix + post;
+  }
+
   public void setDesugaredLibrarySpecification(DesugaredLibrarySpecification specification) {
+    setDesugaredLibrarySpecification(specification, null);
+  }
+
+  private void setDesugaredLibrarySpecification(
+      DesugaredLibrarySpecification specification, String postPrefix) {
     if (specification.isEmpty()) {
       return;
     }
     loadMachineDesugaredLibrarySpecification =
-        (timing, app) ->
-            machineDesugaredLibrarySpecification =
-                specification.toMachineSpecification(app, timing);
+        (timing, app) -> {
+          MachineDesugaredLibrarySpecification machineSpec =
+              specification.toMachineSpecification(app, timing);
+          machineDesugaredLibrarySpecification =
+              postPrefix != null
+                  ? machineSpec.withPostPrefix(dexItemFactory(), postPrefix)
+                  : machineSpec;
+        };
   }
 
   private ThrowingBiConsumer<Timing, DexApplication, IOException>
@@ -1104,7 +1129,7 @@
 
   public TypeRewriter getTypeRewriter() {
     return machineDesugaredLibrarySpecification.requiresTypeRewriting()
-        ? new MachineDesugarPrefixRewritingMapper(machineDesugaredLibrarySpecification)
+        ? new MachineTypeRewriter(machineDesugaredLibrarySpecification)
         : TypeRewriter.empty();
   }
 
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/SimpleStreamPostPrefixTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/SimpleStreamPostPrefixTest.java
new file mode 100644
index 0000000..3515f94
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/SimpleStreamPostPrefixTest.java
@@ -0,0 +1,120 @@
+// Copyright (c) 2023, 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.desugar.desugaredlibrary;
+
+import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
+import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.getJdk8Jdk11;
+import static org.junit.Assert.assertTrue;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
+import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import java.util.ArrayList;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import org.junit.Assume;
+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 SimpleStreamPostPrefixTest extends DesugaredLibraryTestBase {
+
+  private static final String EXPECTED_RESULT = StringUtils.lines("3");
+
+  private final TestParameters parameters;
+  private final CompilationSpecification compilationSpecification;
+  private final LibraryDesugaringSpecification libraryDesugaringSpecification;
+
+  @Parameters(name = "{0}, spec: {1}, {2}")
+  public static List<Object[]> data() {
+    return buildParameters(
+        getTestParameters().withDexRuntimes().withAllApiLevels().build(),
+        getJdk8Jdk11(),
+        DEFAULT_SPECIFICATIONS);
+  }
+
+  public SimpleStreamPostPrefixTest(
+      TestParameters parameters,
+      LibraryDesugaringSpecification libraryDesugaringSpecification,
+      CompilationSpecification compilationSpecification) {
+    this.parameters = parameters;
+    this.compilationSpecification = compilationSpecification;
+    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
+  }
+
+  @Test
+  public void testSimpleStreamPostPrefix() throws Throwable {
+    Assume.assumeTrue(libraryDesugaringSpecification.hasEmulatedInterfaceDesugaring(parameters));
+    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
+        .addInnerClasses(getClass())
+        .addKeepMainRule(Executor.class)
+        .setL8PostPrefix("j$$.")
+        .compile()
+        .inspectL8(this::allRewritten)
+        .run(parameters.getRuntime(), Executor.class)
+        .assertSuccessWithOutput(EXPECTED_RESULT);
+  }
+
+  private void allRewritten(CodeInspector codeInspector) {
+    assertTrue(
+        codeInspector.allClasses().stream()
+            .allMatch(c -> c.toString().startsWith("j$.j$$.") || c.toString().startsWith("java.")));
+    Map<InstructionSubject, FoundMethodSubject> errors = new IdentityHashMap<>();
+    codeInspector.forAllClasses(
+        clazz ->
+            clazz.forAllMethods(
+                m -> {
+                  if (m.hasCode()) {
+                    for (InstructionSubject instruction : m.instructions()) {
+                      if (instruction.isInvoke()) {
+                        if (!isValidJ$$Type(instruction.getMethod().getHolderType())) {
+                          errors.put(instruction, m);
+                        }
+                        for (DexType referencedType :
+                            instruction.getMethod().getReferencedTypes()) {
+                          if (!isValidJ$$Type(referencedType)) {
+                            errors.put(instruction, m);
+                          }
+                        }
+                      } else if (instruction.isFieldAccess()) {
+                        if (!isValidJ$$Type(instruction.getField().getHolderType())) {
+                          errors.put(instruction, m);
+                        }
+                        if (!isValidJ$$Type(instruction.getField().getType())) {
+                          errors.put(instruction, m);
+                        }
+                      }
+                    }
+                  }
+                }));
+    assertTrue("Invalid invokes: " + errors, errors.isEmpty());
+  }
+
+  private boolean isValidJ$$Type(DexType type) {
+    return !type.toString().startsWith("j$.") || type.toString().startsWith("j$.j$$.");
+  }
+
+  @SuppressWarnings("unchecked")
+  static class Executor {
+
+    public static void main(String[] args) {
+      ArrayList<Integer> integers = new ArrayList<>();
+      integers.add(1);
+      integers.add(2);
+      integers.add(3);
+      List<Integer> collectedList = integers.stream().map(i -> i + 3).collect(Collectors.toList());
+      System.out.println(collectedList.size());
+    }
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
index ee7cde7..2cf1e98 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/test/DesugaredLibraryTestBuilder.java
@@ -57,10 +57,10 @@
   private Consumer<InternalOptions> l8OptionModifier = ConsumerUtils.emptyConsumer();
   private boolean l8FinalPrefixVerification = true;
   private boolean overrideDefaultLibraryFiles = false;
-
   private CustomLibrarySpecification customLibrarySpecification = null;
   private TestingKeepRuleConsumer keepRuleConsumer = null;
   private List<ExternalArtProfile> l8ResidualArtProfiles = new ArrayList<>();
+  private boolean managedPostPrefix = false;
 
   public DesugaredLibraryTestBuilder(
       T test,
@@ -171,6 +171,12 @@
     return this;
   }
 
+  public DesugaredLibraryTestBuilder<T> setL8PostPrefix(String postPrefix) {
+    System.setProperty("com.android.tools.r8.desugaredLibraryPostPrefix", postPrefix);
+    this.managedPostPrefix = true;
+    return this;
+  }
+
   public DesugaredLibraryTestBuilder<T> ignoreL8FinalPrefixVerification() {
     l8FinalPrefixVerification = false;
     return this;
@@ -371,6 +377,9 @@
       throws CompilationFailedException, IOException, ExecutionException {
     L8TestCompileResult l8Compile = compileDesugaredLibrary(compile, keepRuleConsumer);
     D8TestCompileResult customLibCompile = compileCustomLib();
+    if (managedPostPrefix) {
+      System.clearProperty("com.android.tools.r8.desugaredLibraryPostPrefix");
+    }
     return new DesugaredLibraryTestCompileResult<>(
         test,
         compile,