1 package spoon.support.reflect.reference; 2 3 import java.lang.annotation.Annotation ; 4 import java.lang.reflect.Constructor ; 5 import java.lang.reflect.Method ; 6 import java.lang.reflect.Modifier ; 7 import java.util.ArrayList ; 8 import java.util.List ; 9 import java.util.Set ; 10 import java.util.TreeSet ; 11 12 import spoon.reflect.declaration.CtClass; 13 import spoon.reflect.declaration.CtExecutable; 14 import spoon.reflect.declaration.CtMethod; 15 import spoon.reflect.declaration.CtType; 16 import spoon.reflect.declaration.ModifierKind; 17 import spoon.reflect.reference.CtExecutableReference; 18 import spoon.reflect.reference.CtTypeReference; 19 import spoon.reflect.visitor.CtVisitor; 20 import spoon.support.util.RtHelper; 21 22 public class CtExecutableReferenceImpl<T> extends CtReferenceImpl implements 23 CtExecutableReference<T> { 24 private static final long serialVersionUID = 1L; 25 26 boolean stat = false; 27 28 List <CtTypeReference<?>> actualTypeArguments = new ArrayList <CtTypeReference<?>>(); 29 30 CtTypeReference<?> declaringType; 31 32 List <CtTypeReference<?>> parametersTypes = new ArrayList <CtTypeReference<?>>(); 33 34 CtTypeReference<T> type; 35 36 public CtExecutableReferenceImpl() { 37 super(); 38 } 39 40 public void accept(CtVisitor visitor) { 41 visitor.visitCtExecutableReference(this); 42 } 43 44 public List <CtTypeReference<?>> getActualTypeArguments() { 45 return actualTypeArguments; 46 } 47 48 @Override 49 public <A extends Annotation > A getAnnotation(Class <A> annotationType) { 50 A annotation = super.getAnnotation(annotationType); 51 if (annotation != null) 52 return annotation; 53 Class <?> c = getDeclaringType().getActualClass(); 55 for (Method m : RtHelper.getAllMethods(c)) { 56 if (!this.getSimpleName().equals(m.getName())) 57 continue; 58 if (getParameterTypes().size() != m.getParameterTypes().length) 59 continue; 60 int i = 0; 61 for (Class <?> t : m.getParameterTypes()) { 62 if (t != getParameterTypes().get(i).getActualClass()) { 63 break; 64 } 65 i++; 66 } 67 if (i == getParameterTypes().size()) { 68 m.setAccessible(true); 69 return m.getAnnotation(annotationType); 70 } 71 } 72 return null; 73 } 74 75 @Override 76 public Annotation [] getAnnotations() { 77 Annotation [] annotations = super.getAnnotations(); 78 if (annotations != null) 79 return annotations; 80 Class <?> c = getDeclaringType().getActualClass(); 82 for (Method m : RtHelper.getAllMethods(c)) { 83 if (!this.getSimpleName().equals(m.getName())) 84 continue; 85 if (getParameterTypes().size() != m.getParameterTypes().length) 86 continue; 87 int i = 0; 88 for (Class <?> t : m.getParameterTypes()) { 89 if (t != getParameterTypes().get(i).getActualClass()) { 90 break; 91 } 92 i++; 93 } 94 if (i == getParameterTypes().size()) { 95 m.setAccessible(true); 96 return m.getAnnotations(); 97 } 98 } 99 return null; 100 } 101 102 @SuppressWarnings ("unchecked") 103 public CtExecutable<T> getDeclaration() { 104 CtType<?> typeDecl = (CtType<?>) getDeclaringType().getDeclaration(); 105 if (typeDecl == null) 106 return null; 107 108 CtExecutable<?> ret = typeDecl.getMethod(getSimpleName(), 109 parametersTypes.toArray(new CtTypeReference<?>[0])); 110 if (ret == null && (typeDecl instanceof CtClass) 111 && (getSimpleName().equals("<init>"))) { 112 try { 113 return (CtExecutable<T>) ((CtClass<?>) typeDecl) 114 .getConstructor(parametersTypes 115 .toArray(new CtTypeReference<?>[0])); 116 } catch (ClassCastException e) { 117 e.printStackTrace(); 118 } 119 } 120 return (CtExecutable<T>) ret; 121 } 122 123 public CtTypeReference<?> getDeclaringType() { 124 return declaringType; 125 } 126 127 public List <CtTypeReference<?>> getParameterTypes() { 128 return parametersTypes; 129 } 130 131 public CtTypeReference<T> getType() { 132 return type; 133 } 134 135 @SuppressWarnings ("unchecked") 136 public <S extends T> CtExecutableReference<S> getOverloadingExecutable( 137 CtTypeReference<?> subType) { 138 if (subType == null || subType.equals(getDeclaringType())) 139 return null; 140 CtClass<?> c = (CtClass<?>) subType.getDeclaration(); 141 if (c == null) 142 return null; 143 for (CtMethod<?> m : c.getMethods()) { 144 if (m.getReference().isOverloading(this)) { 145 return (CtExecutableReference<S>) m.getReference(); 146 } 147 } 148 return getOverloadingExecutable(c.getSuperclass()); 149 } 150 151 public boolean isOverloading(CtExecutableReference<?> executable) { 152 if (!this.getDeclaringType().isSubtypeOf(executable.getDeclaringType())) 153 return false; 154 if (!this.getSimpleName().equals(executable.getSimpleName())) 155 return false; 156 List <CtTypeReference<?>> l1 = this.getParameterTypes(); 157 List <CtTypeReference<?>> l2 = executable.getParameterTypes(); 158 if (l1.size() != l2.size()) 159 return false; 160 for (int i = 0; i < l1.size(); i++) { 161 if (!l1.get(i).isAssignableFrom(l2.get(i))) { 162 return false; 163 } 164 } 165 return true; 166 } 167 168 public void setActualTypeArguments( 169 List <CtTypeReference<?>> actualTypeArguments) { 170 this.actualTypeArguments = actualTypeArguments; 171 } 172 173 public void setDeclaringType(CtTypeReference<?> declaringType) { 174 this.declaringType = declaringType; 175 } 176 177 public void setParameterTypes(List <CtTypeReference<?>> parameterTypes) { 178 this.parametersTypes = parameterTypes; 179 } 180 181 public void setType(CtTypeReference<T> type) { 182 this.type = type; 183 } 184 185 public Method getActualMethod() { 186 for (Method m : getDeclaringType().getActualClass() 187 .getDeclaredMethods()) { 188 if (!m.getName().equals(getSimpleName())) 189 continue; 190 if (m.getParameterTypes().length != getParameterTypes().size()) 191 continue; 192 boolean matches = true; 193 for (int i = 0; i < m.getParameterTypes().length; i++) { 194 if (m.getParameterTypes()[i] != getParameterTypes().get(i) 195 .getActualClass()) { 196 matches = false; 197 break; 198 } 199 } 200 if (matches) 201 return m; 202 } 203 return null; 204 } 205 206 public Constructor getActualConstructor() { 207 for (Constructor c : getDeclaringType().getActualClass() 208 .getDeclaredConstructors()) { 209 if (c.getParameterTypes().length != getParameterTypes().size()) 210 continue; 211 boolean matches = true; 212 for (int i = 0; i < c.getParameterTypes().length; i++) { 213 if (c.getParameterTypes()[i] != getParameterTypes().get(i) 214 .getActualClass()) { 215 matches = false; 216 break; 217 } 218 } 219 if (matches) 220 return c; 221 } 222 return null; 223 } 224 225 public boolean isStatic() { 226 return stat; 227 } 270 271 public void setStatic(boolean b) { 272 this.stat = b; 273 } 274 275 public boolean isFinal() { 276 CtExecutable e = getDeclaration(); 277 if (e != null) { 278 return e.hasModifier(ModifierKind.FINAL); 279 } else { 280 Method m = getActualMethod(); 281 if (m != null) { 282 return Modifier.isFinal(m.getModifiers()); 283 } 284 } 285 return false; 286 } 287 288 public Set <ModifierKind> getModifiers() { 289 CtExecutable e = getDeclaration(); 290 if (e != null) { 291 return e.getModifiers(); 292 } else { 293 Method m = getActualMethod(); 294 if (m != null) { 295 return RtHelper.getModifiers(m.getModifiers()); 296 } 297 Constructor c = getActualConstructor(); 298 if (c != null) { 299 return RtHelper.getModifiers(c.getModifiers()); 300 } 301 } 302 return new TreeSet <ModifierKind>(); 303 } 304 305 public CtExecutableReference<?> getOverloadedExecutable() { 306 CtTypeReference<?> st = getDeclaringType().getSuperclass(); 307 CtTypeReference<Object > objectType = getFactory().Type() 308 .createReference(Object .class); 309 if (st == null) 310 return getOverloadedExecutable(objectType, objectType); 311 else 312 return getOverloadedExecutable(st, objectType); 313 } 314 315 private CtExecutableReference<?> getOverloadedExecutable( 316 CtTypeReference<?> t, CtTypeReference<Object > objectType) { 317 if (t == null) 318 return null; 319 for (CtExecutableReference<?> e : t.getDeclaredExecutables()) { 320 if (this.isOverloading(e)) { 321 return e; 322 } 323 } 324 if (t.equals(objectType)) { 325 return null; 326 } 327 CtTypeReference<?> st = t.getSuperclass(); 328 if (st == null) 329 return getOverloadedExecutable(objectType, objectType); 330 return getOverloadedExecutable(t.getSuperclass(), objectType); 331 } 332 } 333 | Popular Tags |