package net.sourceforge.retroweaver.translator; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; class MethodsMirror implements Mirror { public MethodsMirror(Class class_) { this.class_ = class_; translatedName = class_.getName().replace('.', '/'); } private final String translatedName; private final Class class_; public boolean exists() { return true; } public String getTranslatedName() { return translatedName; } public boolean isClassMirror() { return false; } /** * Returns true if the mirror contains a method that mirrors * <code>methodName</code>. The mirror method should be static, have the * same name, and have the exact same arguments excepting an argument of * type */ public boolean hasMethod(final String owner, final String methodName, final String methodDescriptor, final int opcode) { Type[] types = Type.getArgumentTypes(methodDescriptor); if (opcode == Opcodes.INVOKEVIRTUAL || opcode == Opcodes.INVOKEINTERFACE) { Type[] newTypes = new Type[types.length + 1]; newTypes[0] = Type.getType("L" + owner + ";"); System.arraycopy(types, 0, newTypes, 1, types.length); types = newTypes; } outer_loop: for (Method m : class_.getDeclaredMethods()) { final Type[] methodTypes = Type.getArgumentTypes(m); if (!m.getName().equals(methodName) || methodTypes.length != types.length) { continue; } for (int i = 0; i < types.length; ++i) { if (!types[i].equals(methodTypes[i])) { continue outer_loop; } } return true; } return false; } public boolean hasStaticField(String fieldName, String fieldDescriptor) { try { Field f = class_.getDeclaredField(fieldName); if ((f.getModifiers() & Modifier.STATIC) == 0) { // not a static field return false; } Type fieldType = Type.getType(f.getType()); Type argType = Type.getType(fieldDescriptor); return argType.equals(fieldType); } catch (NoSuchFieldException nsfe) { return false; } } }