1 54 package org.logicalcobwebs.cglib.proxy; 55 56 import java.lang.reflect.Method ; 57 import java.util.*; 58 import org.logicalcobwebs.cglib.core.*; 59 import org.logicalcobwebs.asm.ClassVisitor; 60 import org.logicalcobwebs.asm.Type; 61 62 66 class MixinEmitter extends ClassEmitter { 67 private static final String FIELD_NAME = "CGLIB$DELEGATES"; 68 private static final Signature CSTRUCT_OBJECT_ARRAY = 69 TypeUtils.parseConstructor("Object[]"); 70 private static final Signature NEW_INSTANCE = 71 TypeUtils.parseSignature("org.logicalcobwebs.cglib.proxy.Mixin newInstance(Object[])"); 72 private static final Type MIXIN = 73 TypeUtils.parseType("org.logicalcobwebs.cglib.proxy.Mixin"); 74 75 public MixinEmitter(ClassVisitor v, String className, Class [] classes, int[] route) { 76 super(v); 77 78 begin_class(Constants.ACC_PUBLIC, 79 className, 80 MIXIN, 81 TypeUtils.getTypes(getInterfaces(classes)), 82 Constants.SOURCE_FILE); 83 EmitUtils.null_constructor(this); 84 EmitUtils.factory_method(this, NEW_INSTANCE); 85 86 declare_field(Constants.ACC_PRIVATE, FIELD_NAME, Constants.TYPE_OBJECT_ARRAY, null, null); 87 88 CodeEmitter e = begin_method(Constants.ACC_PUBLIC, CSTRUCT_OBJECT_ARRAY, null, null); 89 e.load_this(); 90 e.super_invoke_constructor(); 91 e.load_this(); 92 e.load_arg(0); 93 e.putfield(FIELD_NAME); 94 e.return_value(); 95 e.end_method(); 96 97 Set unique = new HashSet(); 98 for (int i = 0; i < classes.length; i++) { 99 Method [] methods = getMethods(classes[i]); 100 for (int j = 0; j < methods.length; j++) { 101 if (unique.add(MethodWrapper.create(methods[j]))) { 102 Method method = methods[j]; 103 e = begin_method(Constants.ACC_PUBLIC, 104 ReflectUtils.getSignature(method), 105 ReflectUtils.getExceptionTypes(method), 106 null); 107 e.load_this(); 108 e.getfield(FIELD_NAME); 109 e.aaload((route != null) ? route[i] : i); 110 e.checkcast(Type.getType(method.getDeclaringClass())); 111 e.load_args(); 112 e.invoke(method); 113 e.return_value(); 114 e.end_method(); 115 } 116 } 117 } 118 119 end_class(); 120 } 121 122 protected Class [] getInterfaces(Class [] classes) { 123 return classes; 124 } 125 126 protected Method [] getMethods(Class type) { 127 return type.getMethods(); 128 } 129 } 130 | Popular Tags |