Revert "Add generic signature to emulated interfaces"
This reverts commit aaeee3ceabbe7edf939e96b6a49fae55810cd45d.
Reason for revert: b/182702580
Bug: 181750323,182702580
Change-Id: I52a8f0f6244d0252fafafc04591350108890e850
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 7a7fa38..0b4b188 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -10,9 +10,6 @@
import com.android.tools.r8.errors.CompilationError;
import com.android.tools.r8.errors.Unreachable;
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.kotlin.KotlinClassLevelInfo;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.references.ClassReference;
@@ -23,7 +20,6 @@
import com.android.tools.r8.utils.TraversalContinuation;
import com.google.common.base.MoreObjects;
import com.google.common.base.Predicates;
-import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import com.google.common.collect.Sets;
@@ -35,7 +31,6 @@
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
-import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -785,116 +780,13 @@
Predicate<DexType> ignore,
Set<DexType> seen);
- public void forEachImmediateInterface(Consumer<DexType> fn) {
- for (DexType iface : interfaces.values) {
- fn.accept(iface);
- }
- }
-
public void forEachImmediateSupertype(Consumer<DexType> fn) {
if (superType != null) {
fn.accept(superType);
}
- forEachImmediateInterface(fn);
- }
-
- public void forEachImmediateInterface(BiConsumer<DexType, ClassTypeSignature> consumer) {
- // If there is no generic signature information don't pass any type arguments.
- if (getClassSignature().superInterfaceSignatures().isEmpty()) {
- forEachImmediateInterface(
- superInterface ->
- consumer.accept(superInterface, new ClassTypeSignature(superInterface)));
- return;
+ for (DexType iface : interfaces.values) {
+ fn.accept(iface);
}
-
- Iterator<DexType> interfaceIterator = Arrays.asList(interfaces.values).iterator();
- Iterator<ClassTypeSignature> interfaceSignatureIterator =
- getClassSignature().superInterfaceSignatures().iterator();
-
- while (interfaceIterator.hasNext()) {
- assert interfaceSignatureIterator.hasNext();
- DexType superInterface = interfaceIterator.next();
- ClassTypeSignature superInterfaceSignatures = interfaceSignatureIterator.next();
- consumer.accept(superInterface, superInterfaceSignatures);
- }
- }
-
- public void forEachImmediateSupertype(BiConsumer<DexType, ClassTypeSignature> consumer) {
- if (superType != null) {
- consumer.accept(superType, classSignature.superClassSignature);
- }
- forEachImmediateInterface(consumer);
- }
-
- public void forEachImmediateInterfaceWithAppliedTypeArguments(
- List<FieldTypeSignature> typeArguments,
- BiConsumer<DexType, List<FieldTypeSignature>> consumer) {
- // If there is no generic signature information don't pass any type arguments.
- if (getClassSignature().superInterfaceSignatures().size() == 0) {
- forEachImmediateInterface(
- superInterface -> consumer.accept(superInterface, ImmutableList.of()));
- return;
- }
-
- Iterator<DexType> interfaceIterator = Arrays.asList(interfaces.values).iterator();
- Iterator<ClassTypeSignature> interfaceSignatureIterator =
- getClassSignature().superInterfaceSignatures().iterator();
-
- while (interfaceIterator.hasNext()) {
- assert interfaceSignatureIterator.hasNext();
- DexType superInterface = interfaceIterator.next();
- ClassTypeSignature superInterfaceSignatures = interfaceSignatureIterator.next();
-
- // With no type arguments erase the signatures.
- if (typeArguments.isEmpty() && superInterfaceSignatures.hasTypeVariableArguments()) {
- consumer.accept(superInterface, ImmutableList.of());
- continue;
- }
-
- consumer.accept(superInterface, applyTypeArguments(superInterfaceSignatures, typeArguments));
- }
- assert !interfaceSignatureIterator.hasNext();
- }
-
- public void forEachImmediateSupertypeWithAppliedTypeArguments(
- List<FieldTypeSignature> typeArguments,
- BiConsumer<DexType, List<FieldTypeSignature>> consumer) {
- if (superType != null) {
- consumer.accept(
- superType, applyTypeArguments(getClassSignature().superClassSignature, typeArguments));
- }
- forEachImmediateInterfaceWithAppliedTypeArguments(typeArguments, consumer);
- }
-
- private List<FieldTypeSignature> applyTypeArguments(
- ClassTypeSignature superInterfaceSignatures, List<FieldTypeSignature> appliedTypeArguments) {
- ImmutableList.Builder<FieldTypeSignature> superTypeArgumentsBuilder = ImmutableList.builder();
- if (superInterfaceSignatures.type.toSourceString().equals("java.util.Map")) {
- System.currentTimeMillis();
- }
- superInterfaceSignatures
- .typeArguments()
- .forEach(
- typeArgument -> {
- if (typeArgument.isTypeVariableSignature()) {
- for (int i = 0; i < getClassSignature().getFormalTypeParameters().size(); i++) {
- FormalTypeParameter formalTypeParameter =
- getClassSignature().getFormalTypeParameters().get(i);
- if (formalTypeParameter
- .getName()
- .equals(typeArgument.asTypeVariableSignature().typeVariable())) {
- if (i >= appliedTypeArguments.size()) {
- assert false;
- } else {
- superTypeArgumentsBuilder.add(appliedTypeArguments.get(i));
- }
- }
- }
- } else {
- superTypeArgumentsBuilder.add(typeArgument);
- }
- });
- return superTypeArgumentsBuilder.build();
}
@Override
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 2fa08c8..1dc1f4f 100644
--- a/src/main/java/com/android/tools/r8/graph/GenericSignature.java
+++ b/src/main/java/com/android/tools/r8/graph/GenericSignature.java
@@ -542,15 +542,6 @@
visitor.visitSimpleClass(innerTypeSignature);
}
}
-
- public boolean hasTypeVariableArguments() {
- for (FieldTypeSignature typeArgument : typeArguments) {
- if (typeArgument.isTypeVariableSignature()) {
- return true;
- }
- }
- return false;
- }
}
public static class ArrayTypeSignature extends FieldTypeSignature {
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 9de1141..3e665db 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
@@ -205,40 +205,6 @@
}
}
- // Emulated interfaces together with the generic signatures.
- static class EmulatedInterfaces {
- static EmulatedInterfaces EMPTY = new EmulatedInterfaces(ImmutableSet.of());
-
- final Set<DexType> emulatedInterfaces;
-
- EmulatedInterfaces(DexType emulatedInterface) {
- this.emulatedInterfaces = ImmutableSet.of(emulatedInterface);
- }
-
- private EmulatedInterfaces(Set<DexType> emulatedInterfaces) {
- this.emulatedInterfaces = emulatedInterfaces;
- }
-
- boolean isEmpty() {
- return emulatedInterfaces.isEmpty();
- }
-
- boolean contains(DexType type) {
- return emulatedInterfaces.contains(type);
- }
-
- Set<DexType> getEmulatedInterfaces() {
- return emulatedInterfaces;
- }
-
- EmulatedInterfaces merge(EmulatedInterfaces other) {
- ImmutableSet.Builder<DexType> newEmulatedInterfaces = ImmutableSet.builder();
- newEmulatedInterfaces.addAll(emulatedInterfaces);
- newEmulatedInterfaces.addAll(other.emulatedInterfaces);
- return new EmulatedInterfaces(newEmulatedInterfaces.build());
- }
- }
-
// List of emulated interfaces and corresponding signatures which may require forwarding methods.
// If one of the signatures has an override, then the class holding the override is required to
// add the forwarding methods for all signatures, and introduce the corresponding emulated
@@ -248,13 +214,13 @@
private static class EmulatedInterfaceInfo {
static final EmulatedInterfaceInfo EMPTY =
- new EmulatedInterfaceInfo(MethodSignatures.EMPTY, EmulatedInterfaces.EMPTY);
+ new EmulatedInterfaceInfo(MethodSignatures.EMPTY, ImmutableSet.of());
final MethodSignatures signatures;
- final EmulatedInterfaces emulatedInterfaces;
+ final ImmutableSet<DexType> emulatedInterfaces;
private EmulatedInterfaceInfo(
- MethodSignatures methodsToForward, EmulatedInterfaces emulatedInterfaces) {
+ MethodSignatures methodsToForward, ImmutableSet<DexType> emulatedInterfaces) {
this.signatures = methodsToForward;
this.emulatedInterfaces = emulatedInterfaces;
}
@@ -266,18 +232,17 @@
if (other.isEmpty()) {
return this;
}
+ ImmutableSet.Builder<DexType> newEmulatedInterfaces = ImmutableSet.builder();
+ newEmulatedInterfaces.addAll(emulatedInterfaces);
+ newEmulatedInterfaces.addAll(other.emulatedInterfaces);
return new EmulatedInterfaceInfo(
- signatures.merge(other.signatures), emulatedInterfaces.merge(other.emulatedInterfaces));
+ signatures.merge(other.signatures), newEmulatedInterfaces.build());
}
public boolean isEmpty() {
assert !emulatedInterfaces.isEmpty() || signatures.isEmpty();
return emulatedInterfaces.isEmpty();
}
-
- boolean contains(DexType type) {
- return emulatedInterfaces.contains(type);
- }
}
// Helper to keep track of the direct active subclass and nearest program subclass for reporting.
@@ -411,7 +376,7 @@
assert needsLibraryInfo();
MethodSignatures signatures = getDefaultMethods(iface);
EmulatedInterfaceInfo emulatedInterfaceInfo =
- new EmulatedInterfaceInfo(signatures, new EmulatedInterfaces(iface.type));
+ new EmulatedInterfaceInfo(signatures, ImmutableSet.of(iface.type));
return interfaceInfo.withEmulatedInterfaceInfo(emulatedInterfaceInfo);
}
@@ -458,13 +423,14 @@
// implement the interface and the emulated one for correct emulated dispatch.
// The class signature won't include the correct type parameters for the duplicated interfaces,
// i.e., there will be foo.A instead of foo.A<K,V>, but such parameters are unused.
- private void duplicateEmulatedInterfaces(DexClass clazz, EmulatedInterfaces emulatedInterfaces) {
+ private void duplicateEmulatedInterfaces(
+ DexClass clazz, ImmutableSet<DexType> emulatedInterfaces) {
if (clazz.isNotProgramClass()) {
return;
}
- Set<DexType> filtered = new HashSet<>(emulatedInterfaces.getEmulatedInterfaces());
+ Set<DexType> filtered = new HashSet<>(emulatedInterfaces);
WorkList<DexType> workList = WorkList.newIdentityWorkList();
- for (DexType emulatedInterface : emulatedInterfaces.getEmulatedInterfaces()) {
+ for (DexType emulatedInterface : emulatedInterfaces) {
DexClass iface = appView.definitionFor(emulatedInterface);
if (iface != null) {
assert iface.isLibraryClass()
@@ -482,7 +448,7 @@
workList.addIfNotSeen(iface.getInterfaces());
}
- for (DexType emulatedInterface : emulatedInterfaces.getEmulatedInterfaces()) {
+ for (DexType emulatedInterface : emulatedInterfaces) {
DexClass s = appView.definitionFor(emulatedInterface);
if (s != null) {
s = appView.definitionFor(s.superType);
@@ -493,17 +459,13 @@
}
}
- // Collect the signatures for the emulated interfaces to add.
- Map<DexType, GenericSignature.ClassTypeSignature> signatures = new IdentityHashMap<>();
- collectEmulatedInterfaces(clazz, filtered, signatures);
// We need to introduce them in deterministic order for deterministic compilation.
ArrayList<DexType> sortedEmulatedInterfaces = new ArrayList<>(filtered);
Collections.sort(sortedEmulatedInterfaces);
List<GenericSignature.ClassTypeSignature> extraInterfaceSignatures = new ArrayList<>();
for (DexType extraInterface : sortedEmulatedInterfaces) {
- GenericSignature.ClassTypeSignature signature = signatures.get(extraInterface);
- assert signature != null;
- extraInterfaceSignatures.add(signature);
+ extraInterfaceSignatures.add(
+ new GenericSignature.ClassTypeSignature(rewriter.getEmulatedInterface(extraInterface)));
}
// The emulated interface might already be implemented if the input class has gone through
// library desugaring already.
@@ -528,65 +490,6 @@
clazz.asProgramClass().addExtraInterfaces(extraInterfaceSignatures);
}
- private void collectEmulatedInterfaces(
- DexClass clazz,
- Set<DexType> emulatesInterfaces,
- Map<DexType, GenericSignature.ClassTypeSignature> extraInterfaceSignatures) {
- clazz.forEachImmediateSupertype(
- (type, signature) -> {
- if (emulatesInterfaces.contains(type)) {
- extraInterfaceSignatures.put(
- type,
- new GenericSignature.ClassTypeSignature(
- rewriter.getEmulatedInterface(type), signature.typeArguments()));
- }
- // TODO(b/182329331): Only handle type arguments for Cf to Cf desugar.
- collectEmulatedInterfacesWithPropagatedTypeArguments(
- type,
- appView.options().cfToCfDesugar ? signature.typeArguments() : null,
- emulatesInterfaces,
- extraInterfaceSignatures);
- });
- }
-
- private void collectEmulatedInterfacesWithPropagatedTypeArguments(
- DexType type,
- List<GenericSignature.FieldTypeSignature> typeArguments,
- Set<DexType> emulatesInterfaces,
- Map<DexType, GenericSignature.ClassTypeSignature> extraInterfaceSignatures) {
- DexClass clazz = appView.definitionFor(type);
- if (clazz == null) {
- return;
- }
- // TODO(b/182329331): Only handle type arguments for Cf to Cf desugar.
- if (appView.options().cfToCfDesugar) {
- assert typeArguments != null;
- clazz.forEachImmediateSupertypeWithAppliedTypeArguments(
- typeArguments,
- (iface, signature) -> {
- if (emulatesInterfaces.contains(iface)) {
- extraInterfaceSignatures.put(
- iface,
- new GenericSignature.ClassTypeSignature(
- rewriter.getEmulatedInterface(iface), signature));
- }
- collectEmulatedInterfacesWithPropagatedTypeArguments(
- iface, signature, emulatesInterfaces, extraInterfaceSignatures);
- });
- } else {
- assert typeArguments == null;
- clazz.forEachImmediateSupertype(
- iface -> {
- if (emulatesInterfaces.contains(iface)) {
- extraInterfaceSignatures.put(
- iface,
- new GenericSignature.ClassTypeSignature(rewriter.getEmulatedInterface(iface)));
- }
- collectEmulatedInterfacesWithPropagatedTypeArguments(
- iface, null, emulatesInterfaces, extraInterfaceSignatures);
- });
- }
- }
// If any of the signature would lead to a different behavior than the default method on the
// emulated interface, we need to resolve the forwarding methods.
private boolean shouldResolveForwardingMethodsForEmulatedInterfaces(
@@ -599,7 +502,7 @@
}
DexClass resolvedHolder = resolutionResult.asSingleResolution().getResolvedHolder();
if (!resolvedHolder.isLibraryClass()
- && !emulatedInterfaceInfo.contains(resolvedHolder.type)) {
+ && !emulatedInterfaceInfo.emulatedInterfaces.contains(resolvedHolder.type)) {
return true;
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java
index af6ca9e..a3b768d 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/DesugaredGenericSignatureTest.java
@@ -9,23 +9,15 @@
import static org.junit.Assert.assertEquals;
import com.android.tools.r8.NeverInline;
-import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.shaking.ProguardKeepAttributes;
-import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import java.io.Serializable;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
import java.nio.file.Path;
import java.time.LocalDate;
-import java.util.AbstractSequentialList;
-import java.util.LinkedHashMap;
import java.util.List;
-import java.util.function.UnaryOperator;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,6 +29,7 @@
private final TestParameters parameters;
private final boolean shrinkDesugaredLibrary;
+ private static final String EXPECTED = StringUtils.lines("1970", "1", "2");
@Parameters(name = "{1}, shrinkDesugaredLibrary: {0}")
public static List<Object[]> data() {
@@ -67,7 +60,7 @@
keepRuleConsumer.get(),
shrinkDesugaredLibrary)
.run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutput(expected(parameters, false));
+ .assertSuccessWithOutput(EXPECTED);
}
@Test
@@ -103,13 +96,13 @@
desugaredLibraryKeepRules,
shrinkDesugaredLibrary)
.run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutput(expected(parameters, true));
+ .assertSuccessWithOutput(EXPECTED);
} else {
testForJvm()
.addProgramFiles(jar)
.addRunClasspathFiles(getDesugaredLibraryInCF(parameters, options -> {}))
.run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutput(expected(parameters, true));
+ .assertSuccessWithOutput(EXPECTED);
}
}
@@ -136,7 +129,7 @@
keepRuleConsumer.get(),
shrinkDesugaredLibrary)
.run(parameters.getRuntime(), Main.class)
- .assertSuccessWithOutput(expected(parameters, false));
+ .assertSuccessWithOutput(EXPECTED);
}
private void checkRewrittenSignature(CodeInspector inspector) {
@@ -156,7 +149,6 @@
}
public interface Box<T> {
-
T addOne(T t);
}
@@ -169,61 +161,6 @@
}
}
- private static String expected(
- TestParameters parameters, boolean genericSignaturesOnEmulatedInterfaces) {
- final String EXPECTED = StringUtils.lines("Box", "1970", "1", "2");
- final String STRING_KEY_HASH_MAP_EXPECTED =
- StringUtils.lines(
- "StringKeyHashMap", "1", "j$.util.Map<java.lang.String, T>", "2", "true", "true");
- final String SAME_KEY_AND_VALUE_TYPE_HASH_MAP_EXPECTED =
- StringUtils.lines(
- "SameKeyAndValueTypeHashMap", "1", "j$.util.Map<T, T>", "2", "true", "true");
- final String TRANSFORMING_SEQUENTIAL_LIST_EXPECTED =
- StringUtils.lines("TransformingSequentialList", "2", "j$.util.List<T>");
-
- final String EXPECTED_WITH_EMULATED_INTERFACE =
- STRING_KEY_HASH_MAP_EXPECTED
- + SAME_KEY_AND_VALUE_TYPE_HASH_MAP_EXPECTED
- + TRANSFORMING_SEQUENTIAL_LIST_EXPECTED;
- final String EXPECTED_WITHOUT_EMULATED_INTERFACE_ART_BEFORE_O =
- StringUtils.lines(
- "StringKeyHashMap",
- "1",
- "interface j$.util.Map",
- "SameKeyAndValueTypeHashMap",
- "1",
- "interface j$.util.Map",
- "TransformingSequentialList",
- "2",
- "interface j$.util.List");
- final String EXPECTED_WITHOUT_EMULATED_INTERFACE_JVM_AND_ART_FROM_O =
- StringUtils.lines(
- "StringKeyHashMap",
- "0",
- "SameKeyAndValueTypeHashMap",
- "0",
- "TransformingSequentialList",
- "1");
-
- return EXPECTED
- + (genericSignaturesOnEmulatedInterfaces
- && !parameters
- .getApiLevel()
- .isGreaterThanOrEqualTo(TestBase.apiLevelWithDefaultInterfaceMethodsSupport())
- ? EXPECTED_WITH_EMULATED_INTERFACE
- : (parameters.isDexRuntime()
- && (parameters
- .getRuntime()
- .asDex()
- .getMinApiLevel()
- .isLessThan(AndroidApiLevel.N)
- || parameters
- .getApiLevel()
- .isLessThan(TestBase.apiLevelWithDefaultInterfaceMethodsSupport())))
- ? EXPECTED_WITHOUT_EMULATED_INTERFACE_ART_BEFORE_O
- : EXPECTED_WITHOUT_EMULATED_INTERFACE_JVM_AND_ART_FROM_O);
- }
-
public static class Main {
public static Box<java.time.LocalDate> bar() {
@@ -231,96 +168,10 @@
}
public static void main(String[] args) {
- testBox();
- testEmulatedInterfaceGenericSignatureStringKeyHashMap();
- testEmulatedInterfaceGenericSignatureSameKeyAndValueTypeHashMap();
- testEmulatedInterfaceGenericSignatureTransformingSequentialList();
- }
-
- public static void testBox() {
- System.out.println("Box");
LocalDate localDate = bar().addOne(LocalDate.of(1970, 1, 1));
System.out.println(localDate.getYear());
System.out.println(localDate.getMonthValue());
System.out.println(localDate.getDayOfMonth());
}
-
- public static void testEmulatedInterfaceGenericSignatureStringKeyHashMap() {
- System.out.println("StringKeyHashMap");
- Class<?> clazz = StringKeyHashMap.class;
- System.out.println(clazz.getGenericInterfaces().length);
- if (clazz.getGenericInterfaces().length == 0) {
- return;
- }
- Type genericInterface = clazz.getGenericInterfaces()[0];
- System.out.println(genericInterface);
- if (genericInterface instanceof ParameterizedType) {
- // The j$.util.Map emulated interface has the generic type arguments <String, T>.
- Type[] actualTypeArguments =
- ((ParameterizedType) genericInterface).getActualTypeArguments();
- System.out.println(actualTypeArguments.length);
- System.out.println(actualTypeArguments[0].equals(String.class));
- System.out.println(actualTypeArguments[1].equals(clazz.getTypeParameters()[0]));
- }
- }
-
- public static void testEmulatedInterfaceGenericSignatureSameKeyAndValueTypeHashMap() {
- System.out.println("SameKeyAndValueTypeHashMap");
- Class<?> clazz = SameKeyAndValueTypeHashMap.class;
- System.out.println(clazz.getGenericInterfaces().length);
- if (clazz.getGenericInterfaces().length == 0) {
- return;
- }
- Type genericInterface = clazz.getGenericInterfaces()[0];
- System.out.println(genericInterface);
- if (genericInterface instanceof ParameterizedType) {
- // The j$.util.Map emulated interface has the generic type arguments <T, T>.
- Type[] actualTypeArguments =
- ((ParameterizedType) genericInterface).getActualTypeArguments();
- System.out.println(actualTypeArguments.length);
- System.out.println(actualTypeArguments[0].equals(clazz.getTypeParameters()[0]));
- System.out.println(actualTypeArguments[1].equals(clazz.getTypeParameters()[0]));
- }
- }
-
- public static void testEmulatedInterfaceGenericSignatureTransformingSequentialList() {
- System.out.println("TransformingSequentialList");
- Class<?> clazz = TransformingSequentialList.class;
- System.out.println(clazz.getGenericInterfaces().length);
- if (clazz.getGenericInterfaces().length == 1) {
- return;
- }
- // j$.util.List emulated interface has the generic type argument <T>.
- System.out.println(clazz.getGenericInterfaces()[1]);
- }
- }
-
- // LinkedHashMap implements Map.
- abstract static class StringKeyHashMap<T> extends LinkedHashMap<String, T> {
-
- // Need at least one overridden default method for emulated dispatch.
- @Override
- public T getOrDefault(Object key, T defaultValue) {
- return super.getOrDefault(key, defaultValue);
- }
- }
-
- // LinkedHashMap implements Map.
- abstract static class SameKeyAndValueTypeHashMap<T> extends LinkedHashMap<T, T> {
-
- // Need at least one overridden default method for emulated dispatch.
- @Override
- public T getOrDefault(Object key, T defaultValue) {
- return super.getOrDefault(key, defaultValue);
- }
- }
-
- // AbstractSequentialList implements List further up the hierarchy.
- abstract static class TransformingSequentialList<F, T> extends AbstractSequentialList<T>
- implements Serializable {
-
- // Need at least one overridden default method for emulated dispatch.
- @Override
- public void replaceAll(UnaryOperator<T> operator) {}
}
}