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;
+ }
+ }
}