Added getReturnTypes() method

Completing the reexistant getMethodNames() and getParameterTypes()
This commit is contained in:
Tumi 2013-12-24 15:47:23 +01:00
parent 2c80473aaf
commit d68e51991e

View File

@ -1,3 +1,4 @@
package com.esotericsoftware.reflectasm; package com.esotericsoftware.reflectasm;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -16,6 +17,7 @@ import static org.objectweb.asm.Opcodes.*;
public abstract class MethodAccess { public abstract class MethodAccess {
private String[] methodNames; private String[] methodNames;
private Class[][] parameterTypes; private Class[][] parameterTypes;
private Class[] returnTypes;
abstract public Object invoke (Object object, int methodIndex, Object... args); abstract public Object invoke (Object object, int methodIndex, Object... args);
@ -57,6 +59,10 @@ public abstract class MethodAccess {
public Class[][] getParameterTypes () { public Class[][] getParameterTypes () {
return parameterTypes; return parameterTypes;
} }
public Class[] getReturnTypes () {
return returnTypes;
}
static public MethodAccess get (Class type) { static public MethodAccess get (Class type) {
ArrayList<Method> methods = new ArrayList<Method>(); ArrayList<Method> methods = new ArrayList<Method>();
@ -72,12 +78,15 @@ public abstract class MethodAccess {
recursiveAddInterfaceMethodsToList(type, methods); recursiveAddInterfaceMethodsToList(type, methods);
} }
Class[][] parameterTypes = new Class[methods.size()][]; int n = methods.size();
String[] methodNames = new String[methods.size()]; String[] methodNames = new String[n];
for (int i = 0, n = methodNames.length; i < n; i++) { Class[][] parameterTypes = new Class[n][];
Class[] returnTypes = new Class[n];
for (int i = 0; i < n; i++) {
Method method = methods.get(i); Method method = methods.get(i);
methodNames[i] = method.getName(); methodNames[i] = method.getName();
parameterTypes[i] = method.getParameterTypes(); parameterTypes[i] = method.getParameterTypes();
returnTypes[i] = method.getReturnType();
} }
String className = type.getName(); String className = type.getName();
@ -117,14 +126,14 @@ public abstract class MethodAccess {
mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ASTORE, 4);
mv.visitVarInsn(ILOAD, 2); mv.visitVarInsn(ILOAD, 2);
Label[] labels = new Label[methods.size()]; Label[] labels = new Label[n];
for (int i = 0, n = labels.length; i < n; i++) for (int i = 0; i < n; i++)
labels[i] = new Label(); labels[i] = new Label();
Label defaultLabel = new Label(); Label defaultLabel = new Label();
mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels); mv.visitTableSwitchInsn(0, labels.length - 1, defaultLabel, labels);
StringBuilder buffer = new StringBuilder(128); StringBuilder buffer = new StringBuilder(128);
for (int i = 0, n = labels.length; i < n; i++) { for (int i = 0; i < n; i++) {
mv.visitLabel(labels[i]); mv.visitLabel(labels[i]);
if (i == 0) if (i == 0)
mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {classNameInternal}, 0, null); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[] {classNameInternal}, 0, null);
@ -135,8 +144,9 @@ public abstract class MethodAccess {
buffer.setLength(0); buffer.setLength(0);
buffer.append('('); buffer.append('(');
Method method = methods.get(i); String methodName = methodNames[i];
Class[] paramTypes = method.getParameterTypes(); Class[] paramTypes = parameterTypes[i];
Class returnType = returnTypes[i];
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) { for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
mv.visitVarInsn(ALOAD, 3); mv.visitVarInsn(ALOAD, 3);
mv.visitIntInsn(BIPUSH, paramIndex); mv.visitIntInsn(BIPUSH, paramIndex);
@ -186,10 +196,10 @@ public abstract class MethodAccess {
} }
buffer.append(')'); buffer.append(')');
buffer.append(Type.getDescriptor(method.getReturnType())); buffer.append(Type.getDescriptor(returnType));
mv.visitMethodInsn(isInterface ? INVOKEINTERFACE : INVOKEVIRTUAL, classNameInternal, method.getName(), buffer.toString()); mv.visitMethodInsn(isInterface ? INVOKEINTERFACE : INVOKEVIRTUAL, classNameInternal, methodName, buffer.toString());
switch (Type.getType(method.getReturnType()).getSort()) { switch (Type.getType(returnType).getSort()) {
case Type.VOID: case Type.VOID:
mv.visitInsn(ACONST_NULL); mv.visitInsn(ACONST_NULL);
break; break;
@ -248,6 +258,7 @@ public abstract class MethodAccess {
MethodAccess access = (MethodAccess)accessClass.newInstance(); MethodAccess access = (MethodAccess)accessClass.newInstance();
access.methodNames = methodNames; access.methodNames = methodNames;
access.parameterTypes = parameterTypes; access.parameterTypes = parameterTypes;
access.returnTypes = returnTypes;
return access; return access;
} catch (Exception ex) { } catch (Exception ex) {
throw new RuntimeException("Error constructing method access class: " + accessClassName, ex); throw new RuntimeException("Error constructing method access class: " + accessClassName, ex);