use of org.codehaus.groovy.reflection.CachedClass in project groovy by apache.
the class MetaClassImpl method connectMultimethods.
private void connectMultimethods(List<CachedClass> superClasses, CachedClass firstGroovyClass) {
superClasses = DefaultGroovyMethods.reverse(superClasses);
MetaMethodIndex.Header last = null;
for (final CachedClass c : superClasses) {
MetaMethodIndex.Header methodIndex = metaMethodIndex.getHeader(c.getTheClass());
// It saves us a lot of space and some noticeable time
if (last != null)
metaMethodIndex.copyNonPrivateNonNewMetaMethods(last, methodIndex);
last = methodIndex;
if (c == firstGroovyClass)
break;
}
}
use of org.codehaus.groovy.reflection.CachedClass in project groovy by apache.
the class DgmConverter method loadParameters.
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);
}
}
use of org.codehaus.groovy.reflection.CachedClass in project groovy by apache.
the class DgmConverter method createDoMethodInvokeMethod.
private static void createDoMethodInvokeMethod(CachedMethod method, ClassWriter cw, String className, Class returnType, String methodDescriptor) {
MethodVisitor mv;
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());
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEVIRTUAL, className, "getParameterTypes", "()[Lorg/codehaus/groovy/reflection/CachedClass;", false);
mv.visitInsn(ICONST_0);
mv.visitInsn(AALOAD);
mv.visitVarInsn(ALOAD, 2);
mv.visitInsn(ICONST_0);
mv.visitInsn(AALOAD);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/codehaus/groovy/reflection/CachedClass", "coerceArgument", "(Ljava/lang/Object;)Ljava/lang/Object;", false);
// cast argument to parameter class, inclusive unboxing
// for methods with primitive types
Class type = method.getParameterTypes()[1].getTheClass();
BytecodeHelper.doCast(mv, type);
} else {
mv.visitVarInsn(ALOAD, 0);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, className, "coerceArgumentsToClasses", "([Ljava/lang/Object;)[Ljava/lang/Object;", false);
mv.visitVarInsn(ASTORE, 2);
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();
}
use of org.codehaus.groovy.reflection.CachedClass in project groovy-core by groovy.
the class MetaClassHelper method calculateParameterDistance.
private static long calculateParameterDistance(Class argument, CachedClass parameter) {
if (parameter.getTheClass() == argument)
return 0;
if (parameter.isInterface()) {
int dist = getMaximumInterfaceDistance(argument, parameter.getTheClass()) << INTERFACE_SHIFT;
if (dist > -1 || !(argument != null && Closure.class.isAssignableFrom(argument))) {
return dist;
}
// else go to object case
}
long objectDistance = 0;
if (argument != null) {
long pd = getPrimitiveDistance(parameter.getTheClass(), argument);
if (pd != -1)
return pd << PRIMITIVE_SHIFT;
// add one to dist to be sure interfaces are preferred
objectDistance += PRIMITIVES.length + 1;
// then the array version should be preferred
if (argument.isArray() && !parameter.isArray) {
objectDistance += 4;
}
Class clazz = ReflectionCache.autoboxType(argument);
while (clazz != null) {
if (clazz == parameter.getTheClass())
break;
if (clazz == GString.class && parameter.getTheClass() == String.class) {
objectDistance += 2;
break;
}
clazz = clazz.getSuperclass();
objectDistance += 3;
}
} else {
// choose the distance to Object if a parameter is null
// this will mean that Object is preferred over a more
// specific type
Class clazz = parameter.getTheClass();
if (clazz.isPrimitive()) {
objectDistance += 2;
} else {
while (clazz != Object.class && clazz != null) {
clazz = clazz.getSuperclass();
objectDistance += 2;
}
}
}
return objectDistance << OBJECT_SHIFT;
}
use of org.codehaus.groovy.reflection.CachedClass in project groovy-core by groovy.
the class MetaClassHelper method calculateParameterDistance.
public static long calculateParameterDistance(Class[] arguments, ParameterTypes pt) {
CachedClass[] parameters = pt.getParameterTypes();
if (parameters.length == 0)
return 0;
long ret = 0;
int noVargsLength = parameters.length - 1;
// we can safely iterate to this point
for (int i = 0; i < noVargsLength; i++) {
ret += calculateParameterDistance(arguments[i], parameters[i]);
}
if (arguments.length == parameters.length) {
// case C&D, we use baseType to calculate and set it
// to the value we need according to case C and D
// case C
CachedClass baseType = parameters[noVargsLength];
if (!parameters[noVargsLength].isAssignableFrom(arguments[noVargsLength])) {
// case D
baseType = ReflectionCache.getCachedClass(baseType.getTheClass().getComponentType());
// penalty for vargs
ret += 2l << VARGS_SHIFT;
}
ret += calculateParameterDistance(arguments[noVargsLength], baseType);
} else if (arguments.length > parameters.length) {
// case B
// we give our a vargs penalty for each exceeding argument and iterate
// by using parameters[noVargsLength].getComponentType()
// penalty for vargs
ret += (2l + arguments.length - parameters.length) << VARGS_SHIFT;
CachedClass vargsType = ReflectionCache.getCachedClass(parameters[noVargsLength].getTheClass().getComponentType());
for (int i = noVargsLength; i < arguments.length; i++) {
ret += calculateParameterDistance(arguments[i], vargsType);
}
} else {
// case A
// we give a penalty for vargs, since we have no direct
// match for the last argument
ret += 1l << VARGS_SHIFT;
}
return ret;
}
Aggregations