Desugared library: fix static rewrites
Bug: 159441805
Change-Id: I396eb863ff325c480cb2ba562f9519790653ea49
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
index cfb48f2..be1bbfd 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/DesugaredLibraryRetargeter.java
@@ -50,10 +50,10 @@
private final AppView<?> appView;
private final Map<DexMethod, DexMethod> retargetLibraryMember = new IdentityHashMap<>();
- // Map virtualRewrites hold a methodName->method mapping for virtual methods which are
- // rewritten while the holder is non final but no superclass implement the method. In this case
- // d8 needs to force resolution of given methods to see if the invoke needs to be rewritten.
- private final Map<DexString, List<DexMethod>> virtualRewrites = new IdentityHashMap<>();
+ // Map nonFinalRewrite hold a methodName -> method mapping for methods which are rewritten while
+ // the holder is non final. In this case d8 needs to force resolution of given methods to see if
+ // the invoke needs to be rewritten.
+ private final Map<DexString, List<DexMethod>> nonFinalHolderRewrites = new IdentityHashMap<>();
// Non final virtual library methods requiring generation of emulated dispatch.
private final Set<DexEncodedMethod> emulatedDispatchMethods = Sets.newIdentityHashSet();
@@ -107,7 +107,7 @@
InvokeMethod invoke = instruction.asInvokeMethod();
DexMethod retarget = getRetargetLibraryMember(invoke.getInvokedMethod());
if (retarget == null) {
- if (!matchesVirtualRewrite(invoke.getInvokedMethod())) {
+ if (!matchesNonFinalHolderRewrite(invoke.getInvokedMethod())) {
continue;
}
// We need to force resolution, even on d8, to know if the invoke has to be rewritten.
@@ -128,7 +128,7 @@
// Due to emulated dispatch, we have to rewrite invoke-super differently or we end up in
// infinite loops. We do direct resolution. This is a very uncommon case.
- if (invoke.isInvokeSuper() && matchesVirtualRewrite(invoke.getInvokedMethod())) {
+ if (invoke.isInvokeSuper() && matchesNonFinalHolderRewrite(invoke.getInvokedMethod())) {
DexEncodedMethod dexEncodedMethod =
appView
.appInfoForDesugaring()
@@ -163,8 +163,8 @@
return retargetLibraryMember.get(method);
}
- private boolean matchesVirtualRewrite(DexMethod method) {
- List<DexMethod> dexMethods = virtualRewrites.get(method.name);
+ private boolean matchesNonFinalHolderRewrite(DexMethod method) {
+ List<DexMethod> dexMethods = nonFinalHolderRewrites.get(method.name);
if (dexMethods == null) {
return false;
}
@@ -188,17 +188,19 @@
DexType newHolder = retargetCoreLibMember.get(methodName).get(inType);
List<DexEncodedMethod> found = findDexEncodedMethodsWithName(methodName, typeClass);
for (DexEncodedMethod encodedMethod : found) {
- if (!encodedMethod.isStatic()) {
- virtualRewrites.putIfAbsent(encodedMethod.method.name, new ArrayList<>());
- virtualRewrites.get(encodedMethod.method.name).add(encodedMethod.method);
- if (InterfaceMethodRewriter.isEmulatedInterfaceDispatch(appView, encodedMethod)) {
- // In this case interface method rewriter takes care of it.
- continue;
- } else if (!encodedMethod.isFinal()) {
- // Virtual rewrites require emulated dispatch for inheritance.
- // The call is rewritten to the dispatch holder class instead.
- handleEmulateDispatch(appView, encodedMethod);
- newHolder = dispatchHolderTypeFor(encodedMethod);
+ if (!typeClass.isFinal()) {
+ nonFinalHolderRewrites.putIfAbsent(encodedMethod.method.name, new ArrayList<>());
+ nonFinalHolderRewrites.get(encodedMethod.method.name).add(encodedMethod.method);
+ if (!encodedMethod.isStatic()) {
+ if (InterfaceMethodRewriter.isEmulatedInterfaceDispatch(appView, encodedMethod)) {
+ // In this case interface method rewriter takes care of it.
+ continue;
+ } else if (!encodedMethod.isFinal()) {
+ // Virtual rewrites require emulated dispatch for inheritance.
+ // The call is rewritten to the dispatch holder class instead.
+ handleEmulateDispatch(appView, encodedMethod);
+ newHolder = dispatchHolderTypeFor(encodedMethod);
+ }
}
}
DexProto proto = encodedMethod.method.proto;
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetOverrideTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetOverrideTest.java
index 32bbe65..c2d88b0 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetOverrideTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/RetargetOverrideTest.java
@@ -123,19 +123,12 @@
System.out.println(myAtomicInteger.updateAndGet(x -> x + 100));
System.out.println("145");
- try {
- MyDateNoOverride.from(myCal.toInstant());
- System.out.println("b/159441805 fixed");
- } catch (NoSuchMethodError e) {
- // TODO(b/159441805): Should not throw.
- }
-
- try {
- MyDateOverride.from(myCal.toInstant());
- System.out.println("b/159441805 fixed");
- } catch (NoSuchMethodError e) {
- // TODO(b/159441805): Should not throw.
- }
+ Date date1 = MyDateNoOverride.from(myCal.toInstant());
+ System.out.println(date1.toInstant());
+ System.out.println("1990-03-22T00:00:00Z");
+ Date date2 = MyDateOverride.from(myCal.toInstant());
+ System.out.println(date2.toInstant());
+ System.out.println("1990-03-22T00:00:00Z");
System.out.println(MyDateDoubleOverride.from(myCal.toInstant()).toInstant());
System.out.println("1970-01-02T10:17:36.788Z");