Support for setting library-method-override info on synthesized methods

Change-Id: Id33210e3250f8804b7f196d11ebc995ada192c24
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 e8c908a..616c9ec 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClass.java
@@ -1194,6 +1194,8 @@
   /** Returns kotlin class info if the class is synthesized by kotlin compiler. */
   public abstract KotlinClassLevelInfo getKotlinInfo();
 
+  public abstract ClassKind<?> getKind();
+
   public final String getSimpleName() {
     return getType().getSimpleName();
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
index 2937cd2..9c11896 100644
--- a/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexClasspathClass.java
@@ -126,6 +126,11 @@
   }
 
   @Override
+  public ClassKind<DexClasspathClass> getKind() {
+    return ClassKind.CLASSPATH;
+  }
+
+  @Override
   public DexClasspathClass get() {
     return this;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
index a145cba..7dc2241 100644
--- a/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexLibraryClass.java
@@ -144,6 +144,11 @@
   }
 
   @Override
+  public ClassKind<DexLibraryClass> getKind() {
+    return ClassKind.LIBRARY;
+  }
+
+  @Override
   public DexLibraryClass get() {
     return this;
   }
diff --git a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
index 029fd1e..6f5c0fe 100644
--- a/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
+++ b/src/main/java/com/android/tools/r8/graph/DexProgramClass.java
@@ -574,6 +574,11 @@
     return kotlinInfo;
   }
 
+  @Override
+  public ClassKind<DexProgramClass> getKind() {
+    return ClassKind.PROGRAM;
+  }
+
   public void setKotlinInfo(KotlinClassLevelInfo kotlinInfo) {
     assert kotlinInfo != null;
     assert this.kotlinInfo == getNoKotlinInfo();
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
index da83f1e..068a1a7 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticClassBuilder.java
@@ -178,7 +178,7 @@
     EnclosingMethodAttribute enclosingMembers = null;
     List<InnerClassAttribute> innerClasses = Collections.emptyList();
     for (SyntheticMethodBuilder builder : methods) {
-      DexEncodedMethod method = builder.build();
+      DexEncodedMethod method = builder.build(getClassKind());
       if (method.isNonPrivateVirtualMethod()) {
         virtualMethods.add(method);
       } else {
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
index 781be07..41c19f5 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticItems.java
@@ -1002,7 +1002,7 @@
       builder.setName(methodReference.getName());
       builder.setProto(methodReference.getProto());
       buildMethodCallback.accept(builder);
-      methodDefinition = builder.build();
+      methodDefinition = builder.build(clazz.getKind());
       methodCollection.addMethod(methodDefinition);
       newMethodCallback.accept((T) DexClassAndMethod.create(clazz, methodDefinition));
       return methodDefinition;
diff --git a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
index 64746c9..b758859 100644
--- a/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
+++ b/src/main/java/com/android/tools/r8/synthesis/SyntheticMethodBuilder.java
@@ -5,6 +5,7 @@
 
 import com.android.tools.r8.androidapi.ComputedApiLevel;
 import com.android.tools.r8.cf.CfVersion;
+import com.android.tools.r8.graph.ClassKind;
 import com.android.tools.r8.graph.Code;
 import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexEncodedMethod;
@@ -19,6 +20,7 @@
 import com.android.tools.r8.ir.optimize.info.DefaultMethodOptimizationInfo;
 import com.android.tools.r8.ir.optimize.info.MethodOptimizationInfo;
 import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
+import com.android.tools.r8.utils.OptionalBool;
 
 public class SyntheticMethodBuilder {
 
@@ -40,6 +42,7 @@
   private ComputedApiLevel apiLevelForDefinition = ComputedApiLevel.notSet();
   private ComputedApiLevel apiLevelForCode = ComputedApiLevel.notSet();
   private MethodOptimizationInfo optimizationInfo = DefaultMethodOptimizationInfo.getInstance();
+  private OptionalBool isLibraryMethodOverride = OptionalBool.UNKNOWN;
 
   private boolean checkAndroidApiLevels = true;
 
@@ -55,8 +58,9 @@
     this.syntheticKind = syntheticKind;
   }
 
-  public boolean hasName() {
-    return name != null;
+  public SyntheticMethodBuilder setIsLibraryMethodOverride(OptionalBool isLibraryMethodOverride) {
+    this.isLibraryMethodOverride = isLibraryMethodOverride;
+    return this;
   }
 
   public SyntheticMethodBuilder setName(String name) {
@@ -127,7 +131,7 @@
     return this;
   }
 
-  DexEncodedMethod build() {
+  DexEncodedMethod build(ClassKind<?> classKind) {
     assert name != null;
     DexMethod methodSignature = getMethodSignature();
     MethodAccessFlags accessFlags = getAccessFlags();
@@ -145,6 +149,11 @@
             .setApiLevelForCode(apiLevelForCode)
             .setOptimizationInfo(optimizationInfo)
             .applyIf(!checkAndroidApiLevels, DexEncodedMethod.Builder::disableAndroidApiLevelCheck)
+            .applyIf(
+                classKind == ClassKind.PROGRAM
+                    && accessFlags.belongsToVirtualPool()
+                    && !isLibraryMethodOverride.isUnknown(),
+                builder -> builder.setIsLibraryMethodOverride(isLibraryMethodOverride))
             .build();
     assert !syntheticKind.isSingleSyntheticMethod()
         || isValidSingleSyntheticMethod(method, syntheticKind);