/** Are two annotations equal? */ private boolean annotationEquals(Annotation a, Annotation b) { if (a == b) { return true; } else if (a.getClass() != b.getClass()) { return false; } else { RVMClass annotationInterface = type.resolve().asClass(); RVMMethod[] annotationMethods = annotationInterface.getDeclaredMethods(); AnnotationFactory afB = (AnnotationFactory) Proxy.getInvocationHandler(b); try { for (RVMMethod method : annotationMethods) { String name = method.getName().toUnicodeString(); Object objA = getElementValue(name, method.getReturnType().resolve().getClassForType()); Object objB = afB.getValue(name, method.getReturnType().resolve().getClassForType()); if (!objA.getClass().isArray()) { if (!objA.equals(objB)) { return false; } } else { if (!Arrays.equals((Object[]) objA, (Object[]) objB)) { return false; } } } } catch (java.io.UTFDataFormatException e) { throw new Error(e); } return true; } }
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { checkMemberAccess(Member.DECLARED); if (!type.isClassType()) throwNoSuchMethodException(name, parameterTypes); if (name == null) { throwNoSuchMethodException(name, parameterTypes); } Atom aName = Atom.findOrCreateUnicodeAtom(name); if (aName == RVMClassLoader.StandardClassInitializerMethodName || aName == RVMClassLoader.StandardObjectInitializerMethodName) { // <init> and <clinit> are not methods. throwNoSuchMethodException(name, parameterTypes); } RVMMethod[] methods = type.asClass().getDeclaredMethods(); RVMMethod answer = null; for (RVMMethod meth : methods) { if (meth.getName() == aName && parametersMatch(meth.getParameterTypes(), parameterTypes)) { if (answer == null) { answer = meth; } else { RVMMethod m2 = meth; if (answer.getReturnType().resolve().isAssignableFrom(m2.getReturnType().resolve())) { answer = m2; } } } } if (answer == null) { throwNoSuchMethodException(name, parameterTypes); } return JikesRVMSupport.createMethod(answer); }
/** * Create a copy of the method that occurs in the annotation interface. The method body will * contain a read of the field at the constant pool index specified. * * @param annotationClass the class this method belongs to * @param constantPool for the class * @param memRef the member reference corresponding to this method * @param interfaceMethod the interface method that will copied to produce the annotation method * @param constantPoolIndex the index of the field that will be returned by this method * @return the created method */ static RVMMethod createAnnotationMethod( TypeReference annotationClass, int[] constantPool, MemberReference memRef, RVMMethod interfaceMethod, int constantPoolIndex) { byte[] bytecodes = new byte[] { (byte) JBC_aload_0, (byte) JBC_getfield, (byte) (constantPoolIndex >>> 8), (byte) constantPoolIndex, // Xreturn (byte) typeRefToReturnBytecode(interfaceMethod.getReturnType()) }; return new NormalMethod( annotationClass, memRef, (short) (ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC), null, (short) 1, (short) 2, bytecodes, null, null, null, constantPool, null, null, null, null); }
@Pure private RVMMethod getMethodInternal2(Atom aName, Class<?>... parameterTypes) { RVMMethod answer = null; RVMMethod[] methods = type.asClass().getVirtualMethods(); for (RVMMethod meth : methods) { if (meth.getName() == aName && meth.isPublic() && parametersMatch(meth.getParameterTypes(), parameterTypes)) { if (answer == null) { answer = meth; } else { RVMMethod m2 = meth; if (answer.getReturnType().resolve().isAssignableFrom(m2.getReturnType().resolve())) { answer = m2; } } } } return answer; }
@Pure private RVMMethod getMethodInternal1(Atom aName, Class<?>... parameterTypes) { RVMMethod answer = null; for (RVMClass current = type.asClass(); current != null && answer == null; current = current.getSuperClass()) { RVMMethod[] methods = current.getDeclaredMethods(); for (RVMMethod meth : methods) { if (meth.getName() == aName && meth.isPublic() && parametersMatch(meth.getParameterTypes(), parameterTypes)) { if (answer == null) { answer = meth; } else { RVMMethod m2 = meth; if (answer.getReturnType().resolve().isAssignableFrom(m2.getReturnType().resolve())) { answer = m2; } } } } } return answer; }
/** Hash code for annotation value */ private int annotationHashCode() { RVMClass annotationInterface = type.resolve().asClass(); RVMMethod[] annotationMethods = annotationInterface.getDeclaredMethods(); String typeString = type.toString(); int result = typeString.substring(1, typeString.length() - 1).hashCode(); try { for (RVMMethod method : annotationMethods) { String name = method.getName().toUnicodeString(); Object value = getElementValue(name, method.getReturnType().resolve().getClassForType()); int part_result = name.hashCode() * 127; if (value.getClass().isArray()) { if (value instanceof Object[]) { part_result ^= Arrays.hashCode((Object[]) value); } else if (value instanceof boolean[]) { part_result ^= Arrays.hashCode((boolean[]) value); } else if (value instanceof byte[]) { part_result ^= Arrays.hashCode((byte[]) value); } else if (value instanceof char[]) { part_result ^= Arrays.hashCode((char[]) value); } else if (value instanceof short[]) { part_result ^= Arrays.hashCode((short[]) value); } else if (value instanceof int[]) { part_result ^= Arrays.hashCode((int[]) value); } else if (value instanceof long[]) { part_result ^= Arrays.hashCode((long[]) value); } else if (value instanceof float[]) { part_result ^= Arrays.hashCode((float[]) value); } else if (value instanceof double[]) { part_result ^= Arrays.hashCode((double[]) value); } } else { part_result ^= value.hashCode(); } result += part_result; } } catch (java.io.UTFDataFormatException e) { throw new Error(e); } return result; }
Class<?> getReturnType() { return method.getReturnType().resolve().getClassForType(); }