Fix nest based desugaring of native methods

Fixes: 178440990
Bug: 179708461
Change-Id: I2b07eed5100913d547ce3a076a5b7a77bdd19f22
diff --git a/src/main/java/com/android/tools/r8/graph/AccessFlags.java b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
index 4bbcead..bc17474 100644
--- a/src/main/java/com/android/tools/r8/graph/AccessFlags.java
+++ b/src/main/java/com/android/tools/r8/graph/AccessFlags.java
@@ -291,4 +291,61 @@
     }
     return builder.toString();
   }
+
+  abstract static class BuilderBase<B extends BuilderBase<B, F>, F extends AccessFlags<F>> {
+
+    protected F flags;
+
+    BuilderBase(F flags) {
+      this.flags = flags;
+    }
+
+    public B setPackagePrivate() {
+      assert flags.isPackagePrivate();
+      return self();
+    }
+
+    public B setPrivate(boolean value) {
+      if (value) {
+        flags.setPrivate();
+      } else {
+        flags.unsetPrivate();
+      }
+      return self();
+    }
+
+    public B setProtected(boolean value) {
+      if (value) {
+        flags.setProtected();
+      } else {
+        flags.unsetProtected();
+      }
+      return self();
+    }
+
+    public B setPublic(boolean value) {
+      if (value) {
+        flags.setPublic();
+      } else {
+        flags.unsetPublic();
+      }
+      return self();
+    }
+
+    public B setStatic() {
+      flags.setStatic();
+      return self();
+    }
+
+    public B setSynthetic() {
+      flags.setSynthetic();
+      return self();
+    }
+
+    public F build() {
+      return flags;
+    }
+
+    public abstract B self();
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
index 84019a9..cb30ac2 100644
--- a/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
+++ b/src/main/java/com/android/tools/r8/graph/DexEncodedMethod.java
@@ -1198,22 +1198,24 @@
         .setTarget(method)
         .setInvokeType(accessFlags.isStatic() ? Invoke.Type.STATIC : Invoke.Type.DIRECT)
         .setIsInterface(holder.isInterface());
-    builder.setCode(
-        new SynthesizedCode(
-            forwardSourceCodeBuilder::build,
-            registry -> {
-              if (accessFlags.isStatic()) {
-                registry.registerInvokeStatic(method);
-              } else {
-                registry.registerInvokeDirect(method);
-              }
-            }));
-    builder.accessFlags.setSynthetic();
-    builder.accessFlags.setStatic();
-    builder.accessFlags.unsetPrivate();
-    if (holder.isInterface()) {
-      builder.accessFlags.setPublic();
-    }
+    builder
+        .setCode(
+            new SynthesizedCode(
+                forwardSourceCodeBuilder::build,
+                registry -> {
+                  if (accessFlags.isStatic()) {
+                    registry.registerInvokeStatic(method);
+                  } else {
+                    registry.registerInvokeDirect(method);
+                  }
+                }))
+        .setAccessFlags(
+            MethodAccessFlags.builder()
+                .setBridge()
+                .setPublic(holder.isInterface())
+                .setStatic()
+                .setSynthetic()
+                .build());
     return new ProgramMethod(holder, builder.build());
   }
 
@@ -1415,7 +1417,7 @@
   public static class Builder {
 
     private DexMethod method;
-    private final MethodAccessFlags accessFlags;
+    private MethodAccessFlags accessFlags;
     private final DexAnnotationSet annotations;
     private OptionalBool isLibraryMethodOverride = OptionalBool.UNKNOWN;
     private ParameterAnnotationsList parameterAnnotations;
@@ -1456,6 +1458,11 @@
       this.compilationState = compilationState;
     }
 
+    public Builder setAccessFlags(MethodAccessFlags accessFlags) {
+      this.accessFlags = accessFlags;
+      return this;
+    }
+
     public void setMethod(DexMethod method) {
       this.method = method;
     }
@@ -1523,8 +1530,9 @@
       return this;
     }
 
-    public void setCode(Code code) {
+    public Builder setCode(Code code) {
       this.code = code;
+      return this;
     }
 
     public DexEncodedMethod build() {
diff --git a/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java b/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
index 8c9c20e..4ebf72a 100644
--- a/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
+++ b/src/main/java/com/android/tools/r8/graph/MethodAccessFlags.java
@@ -150,6 +150,10 @@
     set(Constants.ACC_NATIVE);
   }
 
+  public void unsetNative() {
+    unset(Constants.ACC_NATIVE);
+  }
+
   public boolean isAbstract() {
     return isSet(Constants.ACC_ABSTRACT);
   }
@@ -170,6 +174,10 @@
     set(Constants.ACC_STRICT);
   }
 
+  public void unsetStrict() {
+    unset(Constants.ACC_STRICT);
+  }
+
   public boolean isConstructor() {
     return isSet(Constants.ACC_CONSTRUCTOR);
   }
@@ -195,4 +203,48 @@
   private void unsetDeclaredSynchronized() {
     unset(Constants.ACC_DECLARED_SYNCHRONIZED);
   }
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static class Builder extends BuilderBase<Builder, MethodAccessFlags> {
+
+    private Builder() {
+      super(MethodAccessFlags.fromSharedAccessFlags(0, false));
+    }
+
+    public Builder setBridge() {
+      flags.setBridge();
+      return this;
+    }
+
+    public Builder setConstructor() {
+      flags.setConstructor();
+      return this;
+    }
+
+    public Builder setStrict(boolean value) {
+      if (value) {
+        flags.setStrict();
+      } else {
+        flags.unsetStrict();
+      }
+      return this;
+    }
+
+    public Builder setSynchronized(boolean value) {
+      if (value) {
+        flags.setSynchronized();
+      } else {
+        flags.unsetSynchronized();
+      }
+      return this;
+    }
+
+    @Override
+    public Builder self() {
+      return this;
+    }
+  }
 }