1 32 package net.sf.retrotranslator.runtime.impl; 33 34 import java.lang.reflect.*; 35 import java.util.*; 36 import net.sf.retrotranslator.runtime.asm.AnnotationVisitor; 37 import net.sf.retrotranslator.runtime.asm.signature.*; 38 import net.sf.retrotranslator.runtime.java.lang.annotation.Annotation_; 39 40 43 public class MethodDescriptor extends GenericDeclarationDescriptor { 44 45 private String name; 46 private String desc; 47 private ClassDescriptor classDescriptor; 48 private LazyValue<Class , Method> method; 49 private LazyValue<String , Class > returnType; 50 private LazyValue<Object , Object > defaultValue; 51 private LazyValue<Class , Constructor> constructor; 52 private LazyValue<TypeDescriptor, Type> genericReturnType; 53 private LazyList<TypeDescriptor,Type> genericParameterTypes; 54 private LazyList<TypeDescriptor,Type> genericExceptionTypes; 55 private LazyList<List<AnnotationValue>, Annotation_[]> parameterAnnotations; 56 57 public MethodDescriptor(ClassDescriptor classDescriptor, int access, final String name, final String desc, String signature) { 58 this.classDescriptor = classDescriptor; 59 this.access = access; 60 this.name = name; 61 this.desc = desc; 62 if (signature != null) new SignatureReader(signature).accept(this); 63 this.returnType = createReturnType(); 64 if (name.equals(RuntimeTools.CONSTRUCTOR_NAME)) { 65 this.constructor = createConstructor(); 66 } else if (!name.equals(RuntimeTools.STATIC_NAME)) { 67 this.method = createMethod(); 68 } 69 parameterAnnotations = createParameterAnnotations(); 70 } 71 72 private LazyValue<String , Class > createReturnType() { 73 return new LazyValue<String , Class >(desc) { 74 protected Class resolve(String input) { 75 return getClassByType(net.sf.retrotranslator.runtime.asm.Type.getReturnType(input)); 76 } 77 }; 78 } 79 80 private LazyValue<Class , Constructor> createConstructor() { 81 return new LazyValue<Class , Constructor>(classDescriptor.getTarget()) { 82 protected Constructor resolve(Class input) { 83 for (Constructor constructor : input.getDeclaredConstructors()) { 84 if (RuntimeTools.getConstructorDescriptor(constructor).equals(desc)) return constructor; 85 } 86 return null; 87 } 88 }; 89 } 90 91 private LazyValue<Class , Method> createMethod() { 92 return new LazyValue<Class , Method>(classDescriptor.getTarget()) { 93 protected Method resolve(Class input) { 94 for (Method method : input.getDeclaredMethods()) { 95 if (method.getName().equals(name) && 96 net.sf.retrotranslator.runtime.asm.Type.getMethodDescriptor(method).equals(desc)) return method; 97 } 98 return null; 99 } 100 }; 101 } 102 103 public String getName() { 104 return name; 105 } 106 107 public String getDesc() { 108 return desc; 109 } 110 111 public Class getReturnType() { 112 return returnType.get(); 113 } 114 115 public Object getDefaultValue() { 116 return defaultValue == null ? null : RuntimeTools.cloneNonEmptyArray(defaultValue.get()); 117 } 118 119 public static MethodDescriptor getInstance(Method method) { 120 ClassDescriptor classDescriptor = ClassDescriptor.getInstance(method.getDeclaringClass()); 121 String desc = net.sf.retrotranslator.runtime.asm.Type.getMethodDescriptor(method); 122 MethodDescriptor methodDescriptor = classDescriptor.getMethodDescriptor(method.getName() + desc); 123 if (methodDescriptor == null) { 124 methodDescriptor = new MethodDescriptor(classDescriptor, method.getModifiers(), method.getName(), desc, null); 125 } 126 methodDescriptor.method.provide(method); 127 return methodDescriptor; 128 } 129 130 public static MethodDescriptor getInstance(Constructor constructor) { 131 ClassDescriptor classDescriptor = ClassDescriptor.getInstance(constructor.getDeclaringClass()); 132 String desc = RuntimeTools.getConstructorDescriptor(constructor); 133 MethodDescriptor methodDescriptor = classDescriptor.getMethodDescriptor(RuntimeTools.CONSTRUCTOR_NAME + desc); 134 if (methodDescriptor == null) { 135 methodDescriptor = new MethodDescriptor(classDescriptor, constructor.getModifiers(), constructor.getName(), desc, null); 136 } 137 methodDescriptor.constructor.provide(constructor); 138 return methodDescriptor; 139 } 140 141 public GenericDeclaration getTarget() { 142 return method != null ? method.get() : constructor != null ? constructor.get() : null; 143 } 144 145 public Method getMethod() { 146 return method == null ? null : method.get(); 147 } 148 149 public Constructor getConstructor() { 150 return constructor == null ? null : constructor.get(); 151 } 152 153 public ClassDescriptor getClassDescriptor() { 154 return classDescriptor; 155 } 156 157 protected TypeVariable findTypeVariable(String name) { 158 TypeVariable variable = getTypeVariable(name); 159 return variable != null ? variable : classDescriptor.findTypeVariable(name); 160 } 161 162 public Annotation_[][] getParameterAnnotations() { 163 return parameterAnnotations.getClone(); 164 } 165 166 private LazyList<List<AnnotationValue>, Annotation_[]> createParameterAnnotations() { 167 return new LazyList<List<AnnotationValue>, Annotation_[]>() { 168 protected Annotation_[] resolve(List<AnnotationValue> input) { 169 return createAnnotations(input); 170 } 171 172 protected Annotation_[][] newArray(int size) { 173 return new Annotation_[net.sf.retrotranslator.runtime.asm.Type.getArgumentTypes(desc).length][]; 174 } 175 }; 176 } 177 178 public Type getGenericReturnType() { 179 return genericReturnType == null ? null : genericReturnType.get(); 180 } 181 182 public Type[] getGenericParameterTypes() { 183 return genericParameterTypes == null ? null : genericParameterTypes.getClone(); 184 } 185 186 public Type[] getGenericExceptionTypes() { 187 return genericExceptionTypes == null ? null : genericExceptionTypes.getClone(); 188 } 189 190 protected Annotation_[] createAnnotations(Annotation_[] declaredAnnotations) { 191 return declaredAnnotations; 192 } 193 194 public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { 195 if (!visible) return EMPTY_VISITOR; 196 List<AnnotationValue> values = parameterAnnotations.get(parameter); 197 if (values == null) { 198 values = new ArrayList<AnnotationValue>(); 199 parameterAnnotations.set(parameter, values); 200 } 201 AnnotationValue value = new AnnotationValue(desc); 202 values.add(value); 203 return value; 204 } 205 206 public void visit(String name, Object value) { 207 setDefaultValue(value); 208 } 209 210 public void visitEnum(String name, String desc, String value) { 211 setDefaultValue(new EnumValue(desc, value)); 212 } 213 214 public AnnotationVisitor visitAnnotation(String name, String desc) { 215 AnnotationValue value = new AnnotationValue(desc); 216 setDefaultValue(value); 217 return value; 218 } 219 220 public AnnotationVisitor visitArray(String name) { 221 AnnotationArray array = new AnnotationArray(); 222 setDefaultValue(array); 223 return array; 224 } 225 226 public SignatureVisitor visitParameterType() { 227 TypeDescriptor descriptor = new TypeDescriptor(); 228 if (genericParameterTypes == null) genericParameterTypes = getLazyList(); 229 genericParameterTypes.add(descriptor); 230 return descriptor; 231 } 232 233 public SignatureVisitor visitReturnType() { 234 TypeDescriptor descriptor = new TypeDescriptor(); 235 genericReturnType = getLazyType(descriptor); 236 return descriptor; 237 } 238 239 public SignatureVisitor visitExceptionType() { 240 TypeDescriptor descriptor = new TypeDescriptor(); 241 if (genericExceptionTypes == null) genericExceptionTypes = getLazyList(); 242 genericExceptionTypes.add(descriptor); 243 return descriptor; 244 } 245 246 private void setDefaultValue(Object o) { 247 defaultValue = new LazyValue<Object , Object >(o) { 248 protected Object resolve(Object input) { 249 return resolveValue(input, getReturnType(), MethodDescriptor.this); 250 } 251 }; 252 } 253 254 } 255 | Popular Tags |