public int getParamsCount() { return getParameterTypes().length; }
public NewMetaMethod(CachedMethod method) { super(method); bytecodeParameterTypes = method.getParameterTypes(); int size = bytecodeParameterTypes.length; CachedClass[] logicalParameterTypes; if (size <= 1) { logicalParameterTypes = EMPTY_TYPE_ARRAY; } else { logicalParameterTypes = new CachedClass[--size]; System.arraycopy(bytecodeParameterTypes, 1, logicalParameterTypes, 0, size); } setParametersTypes(logicalParameterTypes); }
public ReflectionMetaMethod(CachedMethod method) { this.method = method; setParametersTypes(method.getParameterTypes()); }
private int findMatchingMethod(CachedMethod[] data, int from, int to, MetaMethod method) { for (int j = from; j <= to; ++j) { CachedMethod aMethod = data[j]; CachedClass[] params1 = aMethod.getParameterTypes(); CachedClass[] params2 = method.getParameterTypes(); if (params1.length == params2.length) { boolean matches = true; for (int i = 0; i < params1.length; i++) { if (params1[i] != params2[i]) { matches = false; break; } } if (matches) { return j; } } } return -1; }
private int compareToMethod(Method other) { if (other == null) return -1; final int strComp = getName().compareTo(other.getName()); if (strComp != 0) return strComp; final int retComp = getReturnType().getName().compareTo(other.getReturnType().getName()); if (retComp != 0) return retComp; CachedClass[] params = getParameterTypes(); Class[] mparams = other.getParameterTypes(); final int pd = params.length - mparams.length; if (pd != 0) return pd; for (int i = 0; i != params.length; ++i) { final int nameComp = params[i].getName().compareTo(mparams[i].getName()); if (nameComp != 0) return nameComp; } return 0; }
public CachedMethod searchMethods(String name, CachedClass[] parameterTypes) { CachedMethod[] methods = getMethods(); CachedMethod res = null; for (CachedMethod m : methods) { if (m.getName().equals(name) && ReflectionCache.arrayContentsEq(parameterTypes, m.getParameterTypes()) && (res == null || res.getReturnType().isAssignableFrom(m.getReturnType()))) res = m; } return res; }
private int compareToCachedMethod(CachedMethod other) { if (other == null) return -1; final int strComp = getName().compareTo(other.getName()); if (strComp != 0) return strComp; final int retComp = getReturnType().getName().compareTo(other.getReturnType().getName()); if (retComp != 0) return retComp; CachedClass[] params = getParameterTypes(); CachedClass[] otherParams = other.getParameterTypes(); final int pd = params.length - otherParams.length; if (pd != 0) return pd; for (int i = 0; i != params.length; ++i) { final int nameComp = params[i].getName().compareTo(otherParams[i].getName()); if (nameComp != 0) return nameComp; } final int classComp = cachedClass.toString().compareTo(other.getDeclaringClass().toString()); if (classComp != 0) return classComp; throw new RuntimeException("Should never happen"); }
final int mod = method.getModifiers(); if (Modifier.isStatic(mod) && Modifier.isPublic(mod) && method.getCachedMethod().getAnnotation(Deprecated.class) == null) { CachedClass[] paramTypes = method.getParameterTypes(); if (paramTypes.length > 0) { List<MetaMethod> arr = map.get(paramTypes[0]);
private static void staticMethod(final MetaClass self, List<MetaMethod> arr, final CachedMethod method) { CachedClass[] paramTypes = method.getParameterTypes(); if (paramTypes.length == 0) return; NewInstanceMetaMethod metaMethod; if (paramTypes[0].isAssignableFrom(self.getTheClass())) { if (paramTypes[0].getTheClass() == self.getTheClass()) metaMethod = new NewInstanceMetaMethod(method); else metaMethod = new NewInstanceMetaMethod(method) { public CachedClass getDeclaringClass() { return ReflectionCache.getCachedClass(self.getTheClass()); } }; arr.add(metaMethod); } else { if (self.getTheClass().isAssignableFrom(paramTypes[0].getTheClass())) { metaMethod = new NewInstanceMetaMethod(method); arr.add(metaMethod); } } }
protected static void loadParameters(CachedMethod method, int argumentIndex, MethodVisitor mv) { CachedClass[] parameters = method.getParameterTypes(); int size = parameters.length - 1; for (int i = 0; i < size; i++) { // unpack argument from Object[] mv.visitVarInsn(ALOAD, argumentIndex); BytecodeHelper.pushConstant(mv, i); mv.visitInsn(AALOAD); // cast argument to parameter class, inclusive unboxing // for methods with primitive types Class type = parameters[i + 1].getTheClass(); BytecodeHelper.doCast(mv, type); } } }
continue; if (method.getParameterTypes().length == 0) continue;
/** * @return the matching method which should be found */ private MetaMethod findMethod(CachedMethod aMethod) { Object methods = getMethods(theClass, aMethod.getName(), false); if (methods instanceof FastArray) { FastArray m = (FastArray) methods; final int len = m.size; final Object data[] = m.getArray(); for (int i = 0; i != len; ++i) { MetaMethod method = (MetaMethod) data[i]; if (method.isMethod(aMethod)) { return method; } } } else { MetaMethod method = (MetaMethod) methods; if (method.getName().equals(aMethod.getName()) // TODO: should be better check for case when only diff in modifiers can be SYNTHETIC flag // && method.getModifiers() == aMethod.getModifiers() && method.getReturnType().equals(aMethod.getReturnType()) && MetaMethod.equal(method.getParameterTypes(), aMethod.getParameterTypes())) { return method; } } return aMethod; }
private void applyUse(CachedClass cachedClass) { CachedMethod[] methods = cachedClass.getMethods(); for (CachedMethod cachedMethod : methods) { if (cachedMethod.isStatic() && cachedMethod.isPublic()) { CachedClass[] paramTypes = cachedMethod.getParameterTypes(); if (paramTypes.length > 0) { CachedClass metaClass = paramTypes[0]; CategoryMethod mmethod = new CategoryMethod(cachedMethod, metaClass.getTheClass()); final String name = cachedMethod.getName(); CategoryMethodList list = get(name); if (list == null || list.level != level) { list = new CategoryMethodList(name, level, list); put(name, list); } list.add(mmethod); Collections.sort(list); cachePropertyAccessor(mmethod); } } } }
mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "doMethodInvoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); if (method.getParamsCount() == 2 && method.getParameterTypes()[0].isNumber && method.getParameterTypes()[1].isNumber) { mv.visitVarInsn(ALOAD, 1); BytecodeHelper.doCast(mv, method.getParameterTypes()[0].getTheClass()); Class type = method.getParameterTypes()[1].getTheClass(); BytecodeHelper.doCast(mv, type); } else { mv.visitVarInsn(ASTORE, 2); mv.visitVarInsn(ALOAD, 1); BytecodeHelper.doCast(mv, method.getParameterTypes()[0].getTheClass()); loadParameters(method, 2, mv);
private static void createInvokeMethod(CachedMethod method, ClassWriter cw, Class returnType, String methodDescriptor) { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "invoke", "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 1); BytecodeHelper.doCast(mv, method.getParameterTypes()[0].getTheClass()); loadParameters(method, 2, mv); mv.visitMethodInsn(INVOKESTATIC, BytecodeHelper.getClassInternalName(method.getDeclaringClass().getTheClass()), method.getName(), methodDescriptor, false); BytecodeHelper.box(mv, returnType); if (method.getReturnType() == void.class) { mv.visitInsn(ACONST_NULL); } mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
private static void createIsValidMethodMethod(CachedMethod method, ClassWriter cw, String className) { MethodVisitor mv; if (method.getParamsCount() == 2 && method.getParameterTypes()[0].isNumber && method.getParameterTypes()[1].isNumber) {
public boolean canBeCalledByReflector () { if (!Modifier.isPublic(cachedClass.getModifiers())) return false; if (!Modifier.isPublic(getModifiers())) return false; getParameterTypes(); for (int i = 0; i != parameterTypes.length; ++i) { if (!parameterTypes[i].isPrimitive && !Modifier.isPublic(parameterTypes[i].getModifiers())) return false; } return true; }
public CachedMethod searchMethods(String name, CachedClass[] parameterTypes) { CachedMethod[] methods = getMethods(); CachedMethod res = null; for (CachedMethod m : methods) { if (m.getName().equals(name) && ReflectionCache.arrayContentsEq(parameterTypes, m.getParameterTypes()) && (res == null || res.getReturnType().isAssignableFrom(m.getReturnType()))) res = m; } return res; }
public CachedMethod searchMethods(String name, CachedClass[] parameterTypes) { CachedMethod[] methods = getMethods(); CachedMethod res = null; for (int i = 0; i < methods.length; i++) { CachedMethod m = methods[i]; if (m.getName().equals(name) && ReflectionCache.arrayContentsEq(parameterTypes, m.getParameterTypes()) && (res == null || res.getReturnType().isAssignableFrom(m.getReturnType()))) res = m; } return res; }
public CachedMethod searchMethods(String name, CachedClass[] parameterTypes) { CachedMethod[] methods = getMethods(); CachedMethod res = null; for (int i = 0; i < methods.length; i++) { CachedMethod m = methods[i]; if (m.getName().equals(name) && ReflectionCache.arrayContentsEq(parameterTypes, m.getParameterTypes()) && (res == null || res.getReturnType().isAssignableFrom(m.getReturnType()))) res = m; } return res; }