Adopt class MethodDeclInfo to use @AutoValue
- Resolve TODO
- Encapsulate bridge/substitute the computation of access, naming, descriptor, signature computation to MethodDeclInfo.
- Apply Law of Demeter shortening.
PiperOrigin-RevId: 293922626
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/langmodel/MethodDeclInfo.java b/src/tools/android/java/com/google/devtools/build/android/desugar/langmodel/MethodDeclInfo.java
index 920b120..942276c 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/langmodel/MethodDeclInfo.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/langmodel/MethodDeclInfo.java
@@ -16,43 +16,151 @@
package com.google.devtools.build.android.desugar.langmodel;
+import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static org.objectweb.asm.Opcodes.ACC_STATIC;
+import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
+
+import com.google.auto.value.AutoValue;
+import com.google.common.collect.ImmutableList;
+import javax.annotation.Nullable;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.Type;
/** A unit data object represents a class or interface declaration. */
-// TODO(deltazulu): Consider @AutoValue-ize this class. (String[] as attribute is not supported).
-public final class MethodDeclInfo implements TypeMappable<MethodDeclInfo> {
- public final MethodKey methodKey;
- public final int ownerAccess;
- public final int memberAccess;
- public final String signature;
- public final String[] exceptions;
+@AutoValue
+public abstract class MethodDeclInfo implements TypeMappable<MethodDeclInfo> {
- public MethodDeclInfo(
+ public abstract MethodKey methodKey();
+
+ public abstract int ownerAccess();
+
+ public abstract int memberAccess();
+
+ @Nullable
+ public abstract String signature();
+
+ public abstract ImmutableList<String> exceptions();
+
+ public static MethodDeclInfo create(
+ MethodKey methodKey,
+ int ownerAccess,
+ int memberAccess,
+ @Nullable String signature,
+ @Nullable String[] exceptions) {
+ return create(
+ methodKey,
+ ownerAccess,
+ memberAccess,
+ signature,
+ exceptions == null ? ImmutableList.of() : ImmutableList.copyOf(exceptions));
+ }
+
+ private static MethodDeclInfo create(
MethodKey methodKey,
int ownerAccess,
int memberAccess,
String signature,
- String[] exceptions) {
- this.methodKey = methodKey;
- this.ownerAccess = ownerAccess;
- this.memberAccess = memberAccess;
- this.signature = signature;
- this.exceptions = exceptions;
+ ImmutableList<String> exceptions) {
+ return new AutoValue_MethodDeclInfo(
+ methodKey, ownerAccess, memberAccess, signature, exceptions);
+ }
+
+ public final ClassName owner() {
+ return methodKey().owner();
+ }
+
+ public final String ownerName() {
+ return methodKey().ownerName();
+ }
+
+ public final String name() {
+ return methodKey().name();
+ }
+
+ public final String descriptor() {
+ return methodKey().descriptor();
+ }
+
+ public final Type returnType() {
+ return methodKey().getReturnType();
+ }
+
+ public final ImmutableList<Type> argumentTypes() {
+ return ImmutableList.copyOf(methodKey().getArgumentTypes());
+ }
+
+ public final String[] exceptionArray() {
+ return exceptions().toArray(new String[0]);
+ }
+
+ /** The synthetic constructor for a private constructor. */
+ public final MethodDeclInfo bridgeOfConstructor(ClassName nestCompanion) {
+ return create(
+ methodKey().bridgeOfConstructor(nestCompanion),
+ ownerAccess(),
+ (memberAccess() & ~ACC_PRIVATE) | ACC_SYNTHETIC,
+ /* signature= */ null,
+ exceptions());
+ }
+
+ /** The synthetic bridge method for a private static method in a class. */
+ public final MethodDeclInfo bridgeOfClassStaticMethod() {
+ return create(
+ methodKey().bridgeOfClassStaticMethod(),
+ ownerAccess(),
+ ACC_STATIC | ACC_SYNTHETIC,
+ /* signature= */ null,
+ exceptions());
+ }
+
+ /** The synthetic bridge method for a private instance method in a class. */
+ public final MethodDeclInfo bridgeOfClassInstanceMethod() {
+ return create(
+ methodKey().bridgeOfClassInstanceMethod(),
+ ownerAccess(),
+ /* memberAccess= */ ACC_STATIC | ACC_SYNTHETIC,
+ /* signature= */ null,
+ exceptions());
+ }
+
+ /** The substitute method for a private static method in an interface. */
+ public final MethodDeclInfo substituteOfInterfaceStaticMethod() {
+ return create(
+ methodKey().substituteOfInterfaceStaticMethod(),
+ ownerAccess(),
+ (memberAccess() & ~0xf) | ACC_PUBLIC | ACC_STATIC,
+ /* signature= */ null,
+ exceptions());
+ }
+
+ /** The substitute method for a private instance method in an interface. */
+ public final MethodDeclInfo substituteOfInterfaceInstanceMethod() {
+ return create(
+ methodKey().substituteOfInterfaceInstanceMethod(),
+ ownerAccess(),
+ (memberAccess() & ~0xf) | ACC_PUBLIC | ACC_STATIC, // Unset static and access modifier bits.
+ /* signature= */ null,
+ exceptions());
}
public final MethodVisitor accept(ClassVisitor cv) {
return cv.visitMethod(
- memberAccess, methodKey.descriptor(), methodKey.descriptor(), signature, exceptions);
+ memberAccess(),
+ methodKey().name(),
+ methodKey().descriptor(),
+ signature(),
+ exceptionArray());
}
public final <R, P> R accept(MethodDeclVisitor<R, ? super MethodDeclInfo, P> visitor, P param) {
- if (methodKey.isConstructor()) {
+ if (methodKey().isConstructor()) {
return visitor.visitClassConstructor(this, param);
}
- boolean isInterface = (ownerAccess & Opcodes.ACC_INTERFACE) != 0;
- boolean isStatic = (memberAccess & Opcodes.ACC_STATIC) != 0;
+ boolean isInterface = (ownerAccess() & Opcodes.ACC_INTERFACE) != 0;
+ boolean isStatic = (memberAccess() & Opcodes.ACC_STATIC) != 0;
if (isInterface) {
return isStatic
? visitor.visitInterfaceStaticMethod(this, param)
@@ -66,7 +174,11 @@
@Override
public MethodDeclInfo acceptTypeMapper(TypeMapper typeMapper) {
- return new MethodDeclInfo(
- methodKey.acceptTypeMapper(typeMapper), ownerAccess, memberAccess, signature, exceptions);
+ return create(
+ methodKey().acceptTypeMapper(typeMapper),
+ ownerAccess(),
+ memberAccess(),
+ signature(),
+ exceptions());
}
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/MethodAccessorEmitter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/MethodAccessorEmitter.java
index c9e29b8..4ff019d 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/MethodAccessorEmitter.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/MethodAccessorEmitter.java
@@ -16,15 +16,10 @@
package com.google.devtools.build.android.desugar.nest;
-import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
-import static org.objectweb.asm.Opcodes.ACC_STATIC;
-import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
-
+import com.google.common.collect.ImmutableList;
import com.google.devtools.build.android.desugar.langmodel.ClassName;
import com.google.devtools.build.android.desugar.langmodel.MethodDeclInfo;
import com.google.devtools.build.android.desugar.langmodel.MethodDeclVisitor;
-import com.google.devtools.build.android.desugar.langmodel.MethodKey;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -60,29 +55,23 @@
*/
@Override
public MethodVisitor visitClassConstructor(MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
- ClassName nestCompanion = nestDigest.nestCompanion(methodDeclInfo.methodKey.owner());
- MethodKey constructorBridge = methodDeclInfo.methodKey.bridgeOfConstructor(nestCompanion);
- MethodVisitor mv =
- cv.visitMethod(
- (methodDeclInfo.memberAccess & ~ACC_PRIVATE) | ACC_SYNTHETIC,
- constructorBridge.name(),
- constructorBridge.descriptor(),
- /* signature= */ null,
- methodDeclInfo.exceptions);
+ ClassName nestCompanion = nestDigest.nestCompanion(methodDeclInfo.owner());
+ MethodDeclInfo constructorBridge = methodDeclInfo.bridgeOfConstructor(nestCompanion);
+ MethodVisitor mv = constructorBridge.accept(cv);
mv.visitCode();
mv.visitVarInsn(Opcodes.ALOAD, 0);
- Type[] constructorBridgeArgTypes = constructorBridge.getArgumentTypes();
+ ImmutableList<Type> constructorBridgeArgTypes = constructorBridge.argumentTypes();
// Exclude last placeholder element loading.
- for (int i = 0, slotOffset = 1; i < constructorBridgeArgTypes.length - 1; i++) {
- mv.visitVarInsn(constructorBridgeArgTypes[i].getOpcode(Opcodes.ILOAD), slotOffset);
- slotOffset += constructorBridgeArgTypes[i].getSize();
+ for (int i = 0, slotOffset = 1; i < constructorBridgeArgTypes.size() - 1; i++) {
+ mv.visitVarInsn(constructorBridgeArgTypes.get(i).getOpcode(Opcodes.ILOAD), slotOffset);
+ slotOffset += constructorBridgeArgTypes.get(i).getSize();
}
mv.visitMethodInsn(
Opcodes.INVOKESPECIAL,
- methodDeclInfo.methodKey.ownerName(),
- methodDeclInfo.methodKey.name(),
- methodDeclInfo.methodKey.descriptor(),
+ methodDeclInfo.ownerName(),
+ methodDeclInfo.name(),
+ methodDeclInfo.descriptor(),
/* isInterface= */ false);
mv.visitInsn(Opcodes.RETURN);
int slot = 0;
@@ -110,28 +99,22 @@
*/
@Override
public MethodVisitor visitClassStaticMethod(MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
- MethodKey bridgeMethod = methodDeclInfo.methodKey.bridgeOfClassStaticMethod();
- MethodVisitor mv =
- cv.visitMethod(
- ACC_STATIC | ACC_SYNTHETIC,
- bridgeMethod.name(),
- bridgeMethod.descriptor(),
- /* signature= */ null,
- methodDeclInfo.exceptions);
+ MethodDeclInfo bridgeMethod = methodDeclInfo.bridgeOfClassStaticMethod();
+ MethodVisitor mv = bridgeMethod.accept(cv);
mv.visitCode();
int slotOffset = 0;
- for (Type argType : bridgeMethod.getArgumentTypes()) {
+ for (Type argType : bridgeMethod.argumentTypes()) {
mv.visitVarInsn(argType.getOpcode(Opcodes.ILOAD), slotOffset);
slotOffset += argType.getSize();
}
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
- methodDeclInfo.methodKey.ownerName(),
- methodDeclInfo.methodKey.name(),
- methodDeclInfo.methodKey.descriptor(),
+ methodDeclInfo.ownerName(),
+ methodDeclInfo.name(),
+ methodDeclInfo.descriptor(),
/* isInterface= */ false);
- mv.visitInsn(bridgeMethod.getReturnType().getOpcode(Opcodes.IRETURN));
+ mv.visitInsn(bridgeMethod.returnType().getOpcode(Opcodes.IRETURN));
mv.visitMaxs(slotOffset, slotOffset);
mv.visitEnd();
return mv;
@@ -153,28 +136,22 @@
*/
@Override
public MethodVisitor visitClassInstanceMethod(MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
- MethodKey bridgeMethod = methodDeclInfo.methodKey.bridgeOfClassInstanceMethod();
- MethodVisitor mv =
- cv.visitMethod(
- ACC_STATIC | ACC_SYNTHETIC,
- bridgeMethod.name(),
- bridgeMethod.descriptor(),
- /* signature= */ null,
- methodDeclInfo.exceptions);
+ MethodDeclInfo bridgeMethod = methodDeclInfo.bridgeOfClassInstanceMethod();
+ MethodVisitor mv = bridgeMethod.accept(cv);
mv.visitCode();
int slotOffset = 0;
- for (Type argType : bridgeMethod.getArgumentTypes()) {
+ for (Type argType : bridgeMethod.argumentTypes()) {
mv.visitVarInsn(argType.getOpcode(Opcodes.ILOAD), slotOffset);
slotOffset += argType.getSize();
}
mv.visitMethodInsn(
Opcodes.INVOKESPECIAL,
- methodDeclInfo.methodKey.ownerName(),
- methodDeclInfo.methodKey.name(),
- methodDeclInfo.methodKey.descriptor(),
+ methodDeclInfo.ownerName(),
+ methodDeclInfo.name(),
+ methodDeclInfo.descriptor(),
/* isInterface= */ false);
- mv.visitInsn(bridgeMethod.getReturnType().getOpcode(Opcodes.IRETURN));
+ mv.visitInsn(bridgeMethod.returnType().getOpcode(Opcodes.IRETURN));
mv.visitMaxs(slotOffset, slotOffset);
mv.visitEnd();
return mv;
@@ -212,15 +189,7 @@
*/
@Override
public MethodVisitor visitInterfaceStaticMethod(MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
- MethodKey methodSubstitute = methodDeclInfo.methodKey.substituteOfInterfaceStaticMethod();
-
- // Unset static and access modifier bits.
- return cv.visitMethod(
- (methodDeclInfo.memberAccess & ~0xf) | ACC_PUBLIC | ACC_STATIC,
- methodSubstitute.name(),
- methodSubstitute.descriptor(),
- /* signature= */ null,
- methodDeclInfo.exceptions);
+ return methodDeclInfo.substituteOfInterfaceStaticMethod().accept(cv);
}
/**
@@ -254,14 +223,6 @@
@Override
public MethodVisitor visitInterfaceInstanceMethod(
MethodDeclInfo methodDeclInfo, ClassVisitor cv) {
- MethodKey methodSubstitute = methodDeclInfo.methodKey.substituteOfInterfaceInstanceMethod();
-
- // Unset static and access modifier bits.
- return cv.visitMethod(
- (methodDeclInfo.memberAccess & ~0xf) | ACC_PUBLIC | ACC_STATIC,
- methodSubstitute.name(),
- methodSubstitute.descriptor(),
- /* signature= */ null,
- methodDeclInfo.exceptions);
+ return methodDeclInfo.substituteOfInterfaceInstanceMethod().accept(cv);
}
}
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestBridgeRefConverter.java b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestBridgeRefConverter.java
index 9844ed6..499f994 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestBridgeRefConverter.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestBridgeRefConverter.java
@@ -133,8 +133,7 @@
@Override
public MethodKey visitInvokeStatic(MethodKey methodKey, MethodVisitor mv) {
- final MethodKey bridgeMethodKey;
- bridgeMethodKey = methodKey.bridgeOfClassStaticMethod();
+ MethodKey bridgeMethodKey = methodKey.bridgeOfClassStaticMethod();
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
bridgeMethodKey.ownerName(),
@@ -146,8 +145,7 @@
@Override
public MethodKey visitInterfaceInvokeStatic(MethodKey methodKey, MethodVisitor mv) {
- final MethodKey methodBridge;
- methodBridge = methodKey.substituteOfInterfaceStaticMethod();
+ final MethodKey methodBridge = methodKey.substituteOfInterfaceStaticMethod();
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
methodBridge.ownerName(),
@@ -159,8 +157,7 @@
@Override
public MethodKey visitInvokeInterface(MethodKey methodKey, MethodVisitor mv) {
- final MethodKey methodBridge;
- methodBridge = methodKey.substituteOfInterfaceInstanceMethod();
+ final MethodKey methodBridge = methodKey.substituteOfInterfaceInstanceMethod();
mv.visitMethodInsn(
Opcodes.INVOKESTATIC,
methodBridge.ownerName(),
diff --git a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestDesugaring.java b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestDesugaring.java
index 7d0c7de..4b8ef72 100644
--- a/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestDesugaring.java
+++ b/src/tools/android/java/com/google/devtools/build/android/desugar/nest/NestDesugaring.java
@@ -110,7 +110,7 @@
MethodKey methodKey = MethodKey.create(className, name, descriptor);
if (nestDigest.hasAnyTrackingReason(methodKey)) {
MethodDeclInfo methodDeclInfo =
- new MethodDeclInfo(methodKey, classAccess, access, signature, exceptions);
+ MethodDeclInfo.create(methodKey, classAccess, access, signature, exceptions);
// For interfaces, the following .accept converts the original method into a
// visibility-broadened renamed method in-place while preserving the method body
// implementation; for classes, the following .accept generates synthetic bridge methods and