use of org.codehaus.groovy.reflection.CachedMethod in project groovy-core by groovy.
the class ClosureMetaMethod method createMethodList.
public static List<MetaMethod> createMethodList(final String name, final Class declaringClass, final Closure closure) {
List<MetaMethod> res = new ArrayList<MetaMethod>();
if (closure instanceof MethodClosure) {
MethodClosure methodClosure = (MethodClosure) closure;
Object owner = closure.getOwner();
Class ownerClass = (Class) (owner instanceof Class ? owner : owner.getClass());
for (CachedMethod method : ReflectionCache.getCachedClass(ownerClass).getMethods()) {
if (method.getName().equals(methodClosure.getMethod())) {
MetaMethod metaMethod = new MethodClosureMetaMethod(name, declaringClass, closure, method);
res.add(adjustParamTypesForStdMethods(metaMethod, name));
}
}
} else {
if (closure instanceof GeneratedClosure) {
for (CachedMethod method : ReflectionCache.getCachedClass(closure.getClass()).getMethods()) {
if (method.getName().equals("doCall")) {
MetaMethod metaMethod = new ClosureMetaMethod(name, declaringClass, closure, method);
res.add(adjustParamTypesForStdMethods(metaMethod, name));
}
}
} else {
MetaMethod metaMethod = new AnonymousMetaMethod(closure, name, declaringClass);
res.add(adjustParamTypesForStdMethods(metaMethod, name));
}
}
return res;
}
use of org.codehaus.groovy.reflection.CachedMethod in project groovy-core by groovy.
the class DgmConverter method main.
public static void main(String[] args) throws IOException, ClassNotFoundException {
String targetDirectory = "target/classes/";
boolean info = (args.length == 1 && args[0].equals("--info")) || (args.length == 2 && args[0].equals("--info"));
if (info && args.length == 2) {
targetDirectory = args[1];
if (!targetDirectory.endsWith("/"))
targetDirectory += "/";
}
List<CachedMethod> cachedMethodsList = new ArrayList<CachedMethod>();
for (Class aClass : DefaultGroovyMethods.DGM_LIKE_CLASSES) {
Collections.addAll(cachedMethodsList, ReflectionCache.getCachedClass(aClass).getMethods());
}
final CachedMethod[] cachedMethods = cachedMethodsList.toArray(new CachedMethod[cachedMethodsList.size()]);
List<GeneratedMetaMethod.DgmMethodRecord> records = new ArrayList<GeneratedMetaMethod.DgmMethodRecord>();
int cur = 0;
for (CachedMethod method : cachedMethods) {
if (!method.isStatic() || !method.isPublic())
continue;
if (method.getCachedMethod().getAnnotation(Deprecated.class) != null)
continue;
if (method.getParameterTypes().length == 0)
continue;
final Class returnType = method.getReturnType();
final String className = "org/codehaus/groovy/runtime/dgm$" + cur++;
GeneratedMetaMethod.DgmMethodRecord record = new GeneratedMetaMethod.DgmMethodRecord();
records.add(record);
record.methodName = method.getName();
record.returnType = method.getReturnType();
record.parameters = method.getNativeParameterTypes();
record.className = className;
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
cw.visit(V1_3, ACC_PUBLIC, className, null, "org/codehaus/groovy/reflection/GeneratedMetaMethod", null);
createConstructor(cw);
final String methodDescriptor = BytecodeHelper.getMethodDescriptor(returnType, method.getNativeParameterTypes());
createInvokeMethod(method, cw, returnType, methodDescriptor);
createDoMethodInvokeMethod(method, cw, className, returnType, methodDescriptor);
createIsValidMethodMethod(method, cw, className);
cw.visitEnd();
final byte[] bytes = cw.toByteArray();
final FileOutputStream fileOutputStream = new FileOutputStream(targetDirectory + className + ".class");
fileOutputStream.write(bytes);
fileOutputStream.flush();
fileOutputStream.close();
}
GeneratedMetaMethod.DgmMethodRecord.saveDgmInfo(records, targetDirectory + "/META-INF/dgminfo");
if (info)
System.out.println("Saved " + cur + " dgm records to: " + targetDirectory + "/META-INF/dgminfo");
}
use of org.codehaus.groovy.reflection.CachedMethod in project groovy-core by groovy.
the class SimpleExtensionModule method createMetaMethods.
private void createMetaMethods(final Class extensionClass, final List<MetaMethod> metaMethods, final boolean isStatic) {
CachedClass cachedClass = ReflectionCache.getCachedClass(extensionClass);
CachedMethod[] methods = cachedClass.getMethods();
for (CachedMethod method : methods) {
if (method.isStatic() && method.isPublic() && method.getParamsCount() > 0) {
// an extension method is found
metaMethods.add(isStatic ? new NewStaticMetaMethod(method) : new NewInstanceMetaMethod(method));
}
}
}
use of org.codehaus.groovy.reflection.CachedMethod in project groovy by apache.
the class CallSiteGenerator method writeMethod.
private static MethodVisitor writeMethod(ClassWriter cw, String name, int argumentCount, final String superClass, CachedMethod cachedMethod, String receiverType, String parameterDescription, boolean useArray) {
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "call" + name, "(L" + receiverType + ";" + parameterDescription + ")Ljava/lang/Object;", null, null);
mv.visitCode();
final Label tryStart = new Label();
mv.visitLabel(tryStart);
// call for checking if method is still valid
for (int i = 0; i < argumentCount; ++i) mv.visitVarInsn(Opcodes.ALOAD, i);
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, superClass, "checkCall", "(Ljava/lang/Object;" + parameterDescription + ")Z", false);
Label l0 = new Label();
mv.visitJumpInsn(Opcodes.IFEQ, l0);
// valid method branch
Class callClass = cachedMethod.getDeclaringClass().getTheClass();
boolean useInterface = callClass.isInterface();
String type = BytecodeHelper.getClassInternalName(callClass.getName());
String descriptor = BytecodeHelper.getMethodDescriptor(cachedMethod.getReturnType(), cachedMethod.getNativeParameterTypes());
// prepare call
int invokeMethodCode = Opcodes.INVOKEVIRTUAL;
if (cachedMethod.isStatic()) {
invokeMethodCode = Opcodes.INVOKESTATIC;
} else {
mv.visitVarInsn(Opcodes.ALOAD, 1);
BytecodeHelper.doCast(mv, callClass);
if (useInterface)
invokeMethodCode = Opcodes.INVOKEINTERFACE;
}
Method method = cachedMethod.setAccessible();
Class<?>[] parameters = method.getParameterTypes();
int size = parameters.length;
for (int i = 0; i < size; i++) {
if (useArray) {
// unpack argument from Object[]
mv.visitVarInsn(Opcodes.ALOAD, 2);
BytecodeHelper.pushConstant(mv, i);
mv.visitInsn(Opcodes.AALOAD);
} else {
mv.visitVarInsn(Opcodes.ALOAD, i + 2);
}
// cast argument to parameter class, inclusive unboxing
// for methods with primitive types
BytecodeHelper.doCast(mv, parameters[i]);
}
// make call
mv.visitMethodInsn(invokeMethodCode, type, cachedMethod.getName(), descriptor, invokeMethodCode == Opcodes.INVOKEINTERFACE);
// produce result
BytecodeHelper.box(mv, cachedMethod.getReturnType());
if (cachedMethod.getReturnType() == void.class) {
mv.visitInsn(Opcodes.ACONST_NULL);
}
// return
mv.visitInsn(Opcodes.ARETURN);
// fall back after method change
mv.visitLabel(l0);
for (int i = 0; i < argumentCount; ++i) mv.visitVarInsn(Opcodes.ALOAD, i);
if (!useArray) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/ArrayUtil", "createArray", "(" + parameterDescription + ")[Ljava/lang/Object;", false);
}
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/callsite/CallSiteArray", "defaultCall" + name, "(Lorg/codehaus/groovy/runtime/callsite/CallSite;L" + receiverType + ";[Ljava/lang/Object;)Ljava/lang/Object;", false);
mv.visitInsn(Opcodes.ARETURN);
// exception unwrapping for stackless exceptions
final Label tryEnd = new Label();
mv.visitLabel(tryEnd);
final Label catchStart = new Label();
mv.visitLabel(catchStart);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/codehaus/groovy/runtime/ScriptBytecodeAdapter", "unwrap", "(Lgroovy/lang/GroovyRuntimeException;)Ljava/lang/Throwable;", false);
mv.visitInsn(Opcodes.ATHROW);
mv.visitTryCatchBlock(tryStart, tryEnd, catchStart, GRE);
mv.visitMaxs(0, 0);
mv.visitEnd();
return mv;
}
use of org.codehaus.groovy.reflection.CachedMethod in project groovy by apache.
the class MetaClassImpl method populateMethods.
private void populateMethods(LinkedList<CachedClass> superClasses, CachedClass firstGroovySuper) {
MetaMethodIndex.Header header = metaMethodIndex.getHeader(firstGroovySuper.getTheClass());
CachedClass c;
Iterator<CachedClass> iter = superClasses.iterator();
for (; iter.hasNext(); ) {
c = iter.next();
CachedMethod[] cachedMethods = c.getMethods();
for (CachedMethod metaMethod : cachedMethods) {
addToAllMethodsIfPublic(metaMethod);
if (!metaMethod.isPrivate() || c == firstGroovySuper)
addMetaMethodToIndex(metaMethod, header);
}
MetaMethod[] cachedMethods1 = getNewMetaMethods(c);
for (final MetaMethod method : cachedMethods1) {
if (!newGroovyMethodsSet.contains(method)) {
newGroovyMethodsSet.add(method);
addMetaMethodToIndex(method, header);
}
}
if (c == firstGroovySuper)
break;
}
MetaMethodIndex.Header last = header;
for (; iter.hasNext(); ) {
c = iter.next();
header = metaMethodIndex.getHeader(c.getTheClass());
if (last != null) {
metaMethodIndex.copyNonPrivateMethods(last, header);
}
last = header;
for (CachedMethod metaMethod : c.getMethods()) {
addToAllMethodsIfPublic(metaMethod);
addMetaMethodToIndex(metaMethod, header);
}
for (final MetaMethod method : getNewMetaMethods(c)) {
if (method.getName().equals("<init>") && !method.getDeclaringClass().equals(theCachedClass))
continue;
if (!newGroovyMethodsSet.contains(method)) {
newGroovyMethodsSet.add(method);
addMetaMethodToIndex(method, header);
}
}
}
}
Aggregations