You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MemberImpl.java 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import java.lang.reflect.Modifier;
  14. import java.util.ArrayList;
  15. import java.util.Collection;
  16. import java.util.HashSet;
  17. import java.util.Iterator;
  18. import java.util.List;
  19. public class MemberImpl implements Comparable, AnnotatedElement,Member {
  20. protected Kind kind;
  21. protected UnresolvedType declaringType;
  22. protected int modifiers;
  23. protected UnresolvedType returnType;
  24. protected String name;
  25. protected UnresolvedType[] parameterTypes;
  26. private final String signature;
  27. private String paramSignature;
  28. private boolean reportedCantFindDeclaringType = false;
  29. private boolean reportedUnresolvableMember = false;
  30. /**
  31. * All the signatures that a join point with this member as its signature has.
  32. * The fact that this has to go on MemberImpl and not ResolvedMemberImpl says a lot about
  33. * how broken the Member/ResolvedMember distinction currently is.
  34. */
  35. private JoinPointSignatureIterator joinPointSignatures = null;
  36. public MemberImpl(
  37. Kind kind,
  38. UnresolvedType declaringType,
  39. int modifiers,
  40. String name,
  41. String signature)
  42. {
  43. this.kind = kind;
  44. this.declaringType = declaringType;
  45. this.modifiers = modifiers;
  46. this.name = name;
  47. this.signature = signature;
  48. if (kind == FIELD) {
  49. this.returnType = UnresolvedType.forSignature(signature);
  50. this.parameterTypes = UnresolvedType.NONE;
  51. } else {
  52. Object[] returnAndParams = signatureToTypes(signature,false);
  53. this.returnType = (UnresolvedType) returnAndParams[0];
  54. this.parameterTypes = (UnresolvedType[]) returnAndParams[1];
  55. // always safe not to do this ?!?
  56. // String oldsig=new String(signature);
  57. // signature = typesToSignature(returnType,parameterTypes,true);
  58. }
  59. }
  60. public MemberImpl(
  61. Kind kind,
  62. UnresolvedType declaringType,
  63. int modifiers,
  64. UnresolvedType returnType,
  65. String name,
  66. UnresolvedType[] parameterTypes)
  67. {
  68. super();
  69. this.kind = kind;
  70. this.declaringType = declaringType;
  71. this.modifiers = modifiers;
  72. this.returnType = returnType;
  73. this.name = name;
  74. this.parameterTypes = parameterTypes;
  75. if (kind == FIELD) {
  76. this.signature = returnType.getErasureSignature();
  77. } else {
  78. this.signature = typesToSignature(returnType, parameterTypes,true);
  79. }
  80. }
  81. /* (non-Javadoc)
  82. * @see org.aspectj.weaver.Member#resolve(org.aspectj.weaver.World)
  83. */
  84. public ResolvedMember resolve(World world) {
  85. return world.resolve(this);
  86. }
  87. // ---- utility methods
  88. /** returns an Object[] pair of UnresolvedType, UnresolvedType[] representing return type,
  89. * argument types parsed from the JVM bytecode signature of a method. Yes,
  90. * this should actually return a nice statically-typed pair object, but we
  91. * don't have one of those.
  92. *
  93. * <blockquote><pre>
  94. * UnresolvedType.signatureToTypes("()[Z")[0].equals(Type.forSignature("[Z"))
  95. * UnresolvedType.signatureToTypes("(JJ)I")[1]
  96. * .equals(UnresolvedType.forSignatures(new String[] {"J", "J"}))
  97. * </pre></blockquote>
  98. *
  99. * @param signature the JVM bytecode method signature string we want to break apart
  100. * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types.
  101. */
  102. public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean useRawTypes) {
  103. StringBuffer buf = new StringBuffer();
  104. buf.append("(");
  105. for (int i = 0, len = paramTypes.length; i < len; i++) {
  106. if (paramTypes[i].isParameterizedType() && useRawTypes) buf.append(paramTypes[i].getErasureSignature());
  107. else if (paramTypes[i].isTypeVariableReference() && useRawTypes) buf.append(paramTypes[i].getErasureSignature());
  108. else buf.append(paramTypes[i].getSignature());
  109. }
  110. buf.append(")");
  111. if (returnType.isParameterizedType() && useRawTypes) buf.append(returnType.getErasureSignature());
  112. else if (returnType.isTypeVariableReference() && useRawTypes) buf.append(returnType.getErasureSignature());
  113. else buf.append(returnType.getSignature());
  114. return buf.toString();
  115. }
  116. /**
  117. * Returns "(<signaturesOfParamTypes>,...)" - unlike the other typesToSignature
  118. * that also includes the return type, this one just deals with the parameter types.
  119. */
  120. public static String typesToSignature(UnresolvedType[] paramTypes) {
  121. StringBuffer buf = new StringBuffer();
  122. buf.append("(");
  123. for(int i=0;i<paramTypes.length;i++) {
  124. buf.append(paramTypes[i].getSignature());
  125. }
  126. buf.append(")");
  127. return buf.toString();
  128. }
  129. /**
  130. * returns an Object[] pair of UnresolvedType, UnresolvedType[] representing return type,
  131. * argument types parsed from the JVM bytecode signature of a method. Yes,
  132. * this should actually return a nice statically-typed pair object, but we
  133. * don't have one of those.
  134. *
  135. * <blockquote><pre>
  136. * UnresolvedType.signatureToTypes("()[Z")[0].equals(Type.forSignature("[Z"))
  137. * UnresolvedType.signatureToTypes("(JJ)I")[1]
  138. * .equals(UnresolvedType.forSignatures(new String[] {"J", "J"}))
  139. * </pre></blockquote>
  140. *
  141. * @param signature the JVM bytecode method signature string we want to break apart
  142. * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types.
  143. */
  144. private static Object[] signatureToTypes(String sig,boolean keepParameterizationInfo) {
  145. List l = new ArrayList();
  146. int i = 1;
  147. boolean hasAnyAnglies = sig.indexOf('<')!=-1;
  148. while (true) {
  149. char c = sig.charAt(i);
  150. if (c == ')') break; // break out when the hit the ')'
  151. int start = i;
  152. while (c == '[') c = sig.charAt(++i);
  153. if (c == 'L' || c == 'P') {
  154. int nextSemicolon = sig.indexOf(';',start);
  155. int firstAngly = (hasAnyAnglies?sig.indexOf('<',start):-1);
  156. if (!hasAnyAnglies || firstAngly == -1 || firstAngly>nextSemicolon) {
  157. i = nextSemicolon + 1;
  158. l.add(UnresolvedType.forSignature(sig.substring(start, i)));
  159. } else {
  160. // generics generics generics
  161. // Have to skip to the *correct* ';'
  162. boolean endOfSigReached = false;
  163. int posn = firstAngly;
  164. int genericDepth=0;
  165. while (!endOfSigReached) {
  166. switch (sig.charAt(posn)) {
  167. case '<': genericDepth++;break;
  168. case '>': genericDepth--;break;
  169. case ';': if (genericDepth==0) endOfSigReached=true;break;
  170. default:
  171. }
  172. posn++;
  173. }
  174. // posn now points to the correct nextSemicolon :)
  175. i=posn;
  176. l.add(UnresolvedType.forSignature(sig.substring(start,i)));
  177. }
  178. } else if (c=='T') { // assumed 'reference' to a type variable, so just "Tname;"
  179. int nextSemicolon = sig.indexOf(';',start);
  180. String nextbit = sig.substring(start,nextSemicolon);
  181. l.add(UnresolvedType.forSignature(nextbit));
  182. i=nextSemicolon+1;
  183. } else {
  184. i++;
  185. l.add(UnresolvedType.forSignature(sig.substring(start, i)));
  186. }
  187. }
  188. UnresolvedType[] paramTypes = (UnresolvedType[]) l.toArray(new UnresolvedType[l.size()]);
  189. UnresolvedType returnType = UnresolvedType.forSignature(sig.substring(i+1, sig.length()));
  190. return new Object[] { returnType, paramTypes };
  191. }
  192. // ---- factory methods
  193. public static MemberImpl field(String declaring, int mods, String name, String signature) {
  194. return field(declaring, mods, UnresolvedType.forSignature(signature), name);
  195. }
  196. public static Member field(UnresolvedType declaring, int mods, String name, UnresolvedType type) {
  197. return new MemberImpl(FIELD, declaring, mods, type, name, UnresolvedType.NONE);
  198. }
  199. public static MemberImpl method(UnresolvedType declaring, int mods, String name, String signature) {
  200. Object[] pair = signatureToTypes(signature,false);
  201. return method(declaring, mods, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]);
  202. }
  203. public static MemberImpl monitorEnter() {
  204. return new MemberImpl(MONITORENTER,UnresolvedType.OBJECT,Modifier.STATIC,ResolvedType.VOID,"<lock>",UnresolvedType.ARRAY_WITH_JUST_OBJECT);
  205. }
  206. public static MemberImpl monitorExit() {
  207. return new MemberImpl(MONITOREXIT,UnresolvedType.OBJECT,Modifier.STATIC,ResolvedType.VOID,"<unlock>",UnresolvedType.ARRAY_WITH_JUST_OBJECT);
  208. }
  209. public static Member pointcut(UnresolvedType declaring, String name, String signature) {
  210. Object[] pair = signatureToTypes(signature,false);
  211. return pointcut(declaring, 0, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]);
  212. }
  213. private static MemberImpl field(String declaring, int mods, UnresolvedType ty, String name) {
  214. return new MemberImpl(
  215. FIELD,
  216. UnresolvedType.forName(declaring),
  217. mods,
  218. ty,
  219. name,
  220. UnresolvedType.NONE);
  221. }
  222. public static MemberImpl method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
  223. return new MemberImpl(
  224. //??? this calls <clinit> a method
  225. name.equals("<init>") ? CONSTRUCTOR : METHOD,
  226. declTy,
  227. mods,
  228. rTy,
  229. name,
  230. paramTys);
  231. }
  232. private static Member pointcut(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
  233. return new MemberImpl(
  234. POINTCUT,
  235. declTy,
  236. mods,
  237. rTy,
  238. name,
  239. paramTys);
  240. }
  241. public static ResolvedMemberImpl makeExceptionHandlerSignature(UnresolvedType inType, UnresolvedType catchType) {
  242. return new ResolvedMemberImpl(
  243. HANDLER,
  244. inType,
  245. Modifier.STATIC,
  246. "<catch>",
  247. "(" + catchType.getSignature() + ")V");
  248. }
  249. // ---- parsing methods
  250. /** Takes a string in this form:
  251. *
  252. * <blockquote><pre>
  253. * static? TypeName TypeName.Id
  254. * </pre></blockquote>
  255. * Pretty much just for testing, and as such should perhaps be moved.
  256. */
  257. public static MemberImpl fieldFromString(String str) {
  258. str = str.trim();
  259. final int len = str.length();
  260. int i = 0;
  261. int mods = 0;
  262. if (str.startsWith("static", i)) {
  263. mods = Modifier.STATIC;
  264. i += 6;
  265. while (Character.isWhitespace(str.charAt(i))) i++;
  266. }
  267. int start = i;
  268. while (! Character.isWhitespace(str.charAt(i))) i++;
  269. UnresolvedType retTy = UnresolvedType.forName(str.substring(start, i));
  270. start = i;
  271. i = str.lastIndexOf('.');
  272. UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
  273. start = ++i;
  274. String name = str.substring(start, len).trim();
  275. return new MemberImpl(
  276. FIELD,
  277. declaringTy,
  278. mods,
  279. retTy,
  280. name,
  281. UnresolvedType.NONE);
  282. }
  283. /** Takes a string in this form:
  284. *
  285. * <blockquote><pre>
  286. * (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
  287. * </pre></blockquote>
  288. * Pretty much just for testing, and as such should perhaps be moved.
  289. */
  290. public static Member methodFromString(String str) {
  291. str = str.trim();
  292. // final int len = str.length();
  293. int i = 0;
  294. int mods = 0;
  295. if (str.startsWith("static", i)) {
  296. mods = Modifier.STATIC;
  297. i += 6;
  298. } else if (str.startsWith("interface", i)) {
  299. mods = Modifier.INTERFACE;
  300. i += 9;
  301. } else if (str.startsWith("private", i)) {
  302. mods = Modifier.PRIVATE;
  303. i += 7;
  304. }
  305. while (Character.isWhitespace(str.charAt(i))) i++;
  306. int start = i;
  307. while (! Character.isWhitespace(str.charAt(i))) i++;
  308. UnresolvedType returnTy = UnresolvedType.forName(str.substring(start, i));
  309. start = i;
  310. i = str.indexOf('(', i);
  311. i = str.lastIndexOf('.', i);
  312. UnresolvedType declaringTy = UnresolvedType.forName(str.substring(start, i).trim());
  313. start = ++i;
  314. i = str.indexOf('(', i);
  315. String name = str.substring(start, i).trim();
  316. start = ++i;
  317. i = str.indexOf(')', i);
  318. String[] paramTypeNames = parseIds(str.substring(start, i).trim());
  319. return method(declaringTy, mods, returnTy, name, UnresolvedType.forNames(paramTypeNames));
  320. }
  321. private static String[] parseIds(String str) {
  322. if (str.length() == 0) return ZERO_STRINGS;
  323. List l = new ArrayList();
  324. int start = 0;
  325. while (true) {
  326. int i = str.indexOf(',', start);
  327. if (i == -1) {
  328. l.add(str.substring(start).trim());
  329. break;
  330. }
  331. l.add(str.substring(start, i).trim());
  332. start = i+1;
  333. }
  334. return (String[]) l.toArray(new String[l.size()]);
  335. }
  336. private static final String[] ZERO_STRINGS = new String[0];
  337. // ---- things we know without resolution
  338. public boolean equals(Object other) {
  339. if (! (other instanceof Member)) return false;
  340. Member o = (Member) other;
  341. return (getKind() == o.getKind()
  342. && getName().equals(o.getName())
  343. && getSignature().equals(o.getSignature())
  344. && getDeclaringType().equals(o.getDeclaringType()));
  345. }
  346. /**
  347. * Equality is checked based on the underlying signature, so the hash code
  348. * of a member is based on its kind, name, signature, and declaring type. The
  349. * algorithm for this was taken from page 38 of effective java.
  350. */
  351. private volatile int hashCode = 0;
  352. public int hashCode() {
  353. if (hashCode == 0) {
  354. int result = 17;
  355. result = 37*result + getKind().hashCode();
  356. result = 37*result + getName().hashCode();
  357. result = 37*result + getSignature().hashCode();
  358. result = 37*result + getDeclaringType().hashCode();
  359. hashCode = result;
  360. }
  361. return hashCode;
  362. }
  363. /* (non-Javadoc)
  364. * @see org.aspectj.weaver.Member#compareTo(java.lang.Object)
  365. */
  366. public int compareTo(Object other) {
  367. Member o = (Member) other;
  368. int i = getName().compareTo(o.getName());
  369. if (i != 0) return i;
  370. return getSignature().compareTo(o.getSignature());
  371. }
  372. public String toString() {
  373. StringBuffer buf = new StringBuffer();
  374. buf.append(returnType.getName());
  375. buf.append(' ');
  376. buf.append(declaringType.getName());
  377. buf.append('.');
  378. buf.append(name);
  379. if (kind != FIELD) {
  380. buf.append("(");
  381. if (parameterTypes.length != 0) {
  382. buf.append(parameterTypes[0]);
  383. for (int i=1, len = parameterTypes.length; i < len; i++) {
  384. buf.append(", ");
  385. buf.append(parameterTypes[i].getName());
  386. }
  387. }
  388. buf.append(")");
  389. }
  390. return buf.toString();
  391. }
  392. /* (non-Javadoc)
  393. * @see org.aspectj.weaver.Member#toLongString()
  394. */
  395. public String toLongString() {
  396. StringBuffer buf = new StringBuffer();
  397. buf.append(kind);
  398. buf.append(' ');
  399. if (modifiers != 0) {
  400. buf.append(Modifier.toString(modifiers));
  401. buf.append(' ');
  402. }
  403. buf.append(toString());
  404. buf.append(" <");
  405. buf.append(signature);
  406. buf.append(" >");
  407. return buf.toString();
  408. }
  409. /* (non-Javadoc)
  410. * @see org.aspectj.weaver.Member#getKind()
  411. */
  412. public Kind getKind() { return kind; }
  413. /* (non-Javadoc)
  414. * @see org.aspectj.weaver.Member#getDeclaringType()
  415. */
  416. public UnresolvedType getDeclaringType() { return declaringType; }
  417. /* (non-Javadoc)
  418. * @see org.aspectj.weaver.Member#getReturnType()
  419. */
  420. public UnresolvedType getReturnType() { return returnType; }
  421. public UnresolvedType getGenericReturnType() { return getReturnType(); }
  422. public UnresolvedType[] getGenericParameterTypes() { return getParameterTypes(); }
  423. /* (non-Javadoc)
  424. * @see org.aspectj.weaver.Member#getType()
  425. */
  426. public UnresolvedType getType() { return returnType; }
  427. /* (non-Javadoc)
  428. * @see org.aspectj.weaver.Member#getName()
  429. */
  430. public String getName() { return name; }
  431. /* (non-Javadoc)
  432. * @see org.aspectj.weaver.Member#getParameterTypes()
  433. */
  434. public UnresolvedType[] getParameterTypes() { return parameterTypes; }
  435. /* (non-Javadoc)
  436. * @see org.aspectj.weaver.Member#getSignature()
  437. */
  438. public String getSignature() { return signature; }
  439. public int getArity() { return parameterTypes.length; }
  440. /* (non-Javadoc)
  441. * @see org.aspectj.weaver.Member#getParameterSignature()
  442. */
  443. public String getParameterSignature() {
  444. if (paramSignature != null) return paramSignature;
  445. StringBuffer sb = new StringBuffer();
  446. sb.append("(");
  447. for (int i = 0; i < parameterTypes.length; i++) {
  448. UnresolvedType tx = parameterTypes[i];
  449. sb.append(tx.getSignature());
  450. }
  451. sb.append(")");
  452. paramSignature = sb.toString();
  453. return paramSignature;
  454. }
  455. /* (non-Javadoc)
  456. * @see org.aspectj.weaver.Member#isCompatibleWith(org.aspectj.weaver.Member)
  457. */
  458. public boolean isCompatibleWith(Member am) {
  459. if (kind != METHOD || am.getKind() != METHOD) return true;
  460. if (! name.equals(am.getName())) return true;
  461. if (! equalTypes(getParameterTypes(), am.getParameterTypes())) return true;
  462. return getReturnType().equals(am.getReturnType());
  463. }
  464. private static boolean equalTypes(UnresolvedType[] a, UnresolvedType[] b) {
  465. int len = a.length;
  466. if (len != b.length) return false;
  467. for (int i = 0; i < len; i++) {
  468. if (!a[i].equals(b[i])) return false;
  469. }
  470. return true;
  471. }
  472. // ---- things we know only with resolution
  473. /* (non-Javadoc)
  474. * @see org.aspectj.weaver.Member#getModifiers(org.aspectj.weaver.World)
  475. */
  476. public int getModifiers(World world) {
  477. ResolvedMember resolved = resolve(world);
  478. if (resolved == null) {
  479. reportDidntFindMember(world);
  480. return 0;
  481. }
  482. return resolved.getModifiers();
  483. }
  484. /* (non-Javadoc)
  485. * @see org.aspectj.weaver.Member#getExceptions(org.aspectj.weaver.World)
  486. */
  487. public UnresolvedType[] getExceptions(World world) {
  488. ResolvedMember resolved = resolve(world);
  489. if (resolved == null) {
  490. reportDidntFindMember(world);
  491. return UnresolvedType.NONE;
  492. }
  493. return resolved.getExceptions();
  494. }
  495. /* (non-Javadoc)
  496. * @see org.aspectj.weaver.Member#isProtected(org.aspectj.weaver.World)
  497. */
  498. public final boolean isProtected(World world) {
  499. return Modifier.isProtected(resolve(world).getModifiers());
  500. }
  501. /* (non-Javadoc)
  502. * @see org.aspectj.weaver.Member#isStatic(org.aspectj.weaver.World)
  503. */
  504. public final boolean isStatic(World world) {
  505. return Modifier.isStatic(resolve(world).getModifiers());
  506. }
  507. /* (non-Javadoc)
  508. * @see org.aspectj.weaver.Member#isStrict(org.aspectj.weaver.World)
  509. */
  510. public final boolean isStrict(World world) {
  511. return Modifier.isStrict(resolve(world).getModifiers());
  512. }
  513. /* (non-Javadoc)
  514. * @see org.aspectj.weaver.Member#isStatic()
  515. */
  516. public final boolean isStatic() {
  517. return Modifier.isStatic(modifiers);
  518. }
  519. /* (non-Javadoc)
  520. * @see org.aspectj.weaver.Member#isInterface()
  521. */
  522. public final boolean isInterface() {
  523. return Modifier.isInterface(modifiers); // this is kinda weird
  524. }
  525. /* (non-Javadoc)
  526. * @see org.aspectj.weaver.Member#isPrivate()
  527. */
  528. public final boolean isPrivate() {
  529. return Modifier.isPrivate(modifiers);
  530. }
  531. /* (non-Javadoc)
  532. * @see org.aspectj.weaver.Member#canBeParameterized()
  533. */
  534. public boolean canBeParameterized() {
  535. return false;
  536. }
  537. /* (non-Javadoc)
  538. * @see org.aspectj.weaver.Member#getCallsiteModifiers()
  539. */
  540. public final int getCallsiteModifiers() {
  541. return modifiers & ~ Modifier.INTERFACE;
  542. }
  543. public int getModifiers() {
  544. return modifiers;
  545. }
  546. /* (non-Javadoc)
  547. * @see org.aspectj.weaver.Member#getExtractableName()
  548. */
  549. public final String getExtractableName() {
  550. if (name.equals("<init>")) return "init$";
  551. else if (name.equals("<clinit>")) return "clinit$";
  552. else return name;
  553. }
  554. /* (non-Javadoc)
  555. * @see org.aspectj.weaver.Member#hasAnnotation(org.aspectj.weaver.UnresolvedType)
  556. */
  557. public boolean hasAnnotation(UnresolvedType ofType) {
  558. throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
  559. }
  560. /* (non-Javadoc)
  561. * @see org.aspectj.weaver.AnnotatedElement#getAnnotationTypes()
  562. */
  563. /* (non-Javadoc)
  564. * @see org.aspectj.weaver.Member#getAnnotationTypes()
  565. */
  566. public ResolvedType[] getAnnotationTypes() {
  567. throw new UnsupportedOperationException("You should resolve this member and call hasAnnotation() on the result...");
  568. }
  569. /* (non-Javadoc)
  570. * @see org.aspectj.weaver.Member#getAnnotations()
  571. */
  572. public AnnotationX[] getAnnotations() {
  573. throw new UnsupportedOperationException("You should resolve this member '"+this+"' and call getAnnotations() on the result...");
  574. }
  575. // ---- fields 'n' stuff
  576. /* (non-Javadoc)
  577. * @see org.aspectj.weaver.Member#getDeclaringTypes(org.aspectj.weaver.World)
  578. */
  579. public Collection/*ResolvedType*/ getDeclaringTypes(World world) {
  580. ResolvedType myType = getDeclaringType().resolve(world);
  581. Collection ret = new HashSet();
  582. if (kind == CONSTRUCTOR) {
  583. // this is wrong if the member doesn't exist, but that doesn't matter
  584. ret.add(myType);
  585. } else if (isStatic() || kind == FIELD) {
  586. walkUpStatic(ret, myType);
  587. } else {
  588. walkUp(ret, myType);
  589. }
  590. return ret;
  591. }
  592. private boolean walkUp(Collection acc, ResolvedType curr) {
  593. if (acc.contains(curr)) return true;
  594. boolean b = false;
  595. for (Iterator i = curr.getDirectSupertypes(); i.hasNext(); ) {
  596. b |= walkUp(acc, (ResolvedType)i.next());
  597. }
  598. if (!b && curr.isParameterizedType()) {
  599. b = walkUp(acc,curr.getGenericType());
  600. }
  601. if (!b) {
  602. b = curr.lookupMemberNoSupers(this) != null;
  603. }
  604. if (b) acc.add(curr);
  605. return b;
  606. }
  607. private boolean walkUpStatic(Collection acc, ResolvedType curr) {
  608. if (curr.lookupMemberNoSupers(this) != null) {
  609. acc.add(curr);
  610. return true;
  611. } else {
  612. boolean b = false;
  613. for (Iterator i = curr.getDirectSupertypes(); i.hasNext(); ) {
  614. b |= walkUpStatic(acc, (ResolvedType)i.next());
  615. }
  616. if (!b && curr.isParameterizedType()) {
  617. b = walkUpStatic(acc,curr.getGenericType());
  618. }
  619. if (b) acc.add(curr);
  620. return b;
  621. }
  622. }
  623. // ---- reflective thisJoinPoint stuff
  624. /* (non-Javadoc)
  625. * @see org.aspectj.weaver.Member#getSignatureMakerName()
  626. */
  627. public String getSignatureMakerName() {
  628. if (getName().equals("<clinit>")) return "makeInitializerSig";
  629. Kind kind = getKind();
  630. if (kind == METHOD) {
  631. return "makeMethodSig";
  632. } else if (kind == CONSTRUCTOR) {
  633. return "makeConstructorSig";
  634. } else if (kind == FIELD) {
  635. return "makeFieldSig";
  636. } else if (kind == HANDLER) {
  637. return "makeCatchClauseSig";
  638. } else if (kind == STATIC_INITIALIZATION) {
  639. return "makeInitializerSig";
  640. } else if (kind == ADVICE) {
  641. return "makeAdviceSig";
  642. } else if (kind == MONITORENTER) {
  643. return "makeLockSig";
  644. } else if (kind == MONITOREXIT) {
  645. return "makeUnlockSig";
  646. } else {
  647. throw new RuntimeException("unimplemented");
  648. }
  649. }
  650. /* (non-Javadoc)
  651. * @see org.aspectj.weaver.Member#getSignatureType()
  652. */
  653. public String getSignatureType() {
  654. Kind kind = getKind();
  655. if (getName().equals("<clinit>")) return "org.aspectj.lang.reflect.InitializerSignature";
  656. if (kind == METHOD) {
  657. return "org.aspectj.lang.reflect.MethodSignature";
  658. } else if (kind == CONSTRUCTOR) {
  659. return "org.aspectj.lang.reflect.ConstructorSignature";
  660. } else if (kind == FIELD) {
  661. return "org.aspectj.lang.reflect.FieldSignature";
  662. } else if (kind == HANDLER) {
  663. return "org.aspectj.lang.reflect.CatchClauseSignature";
  664. } else if (kind == STATIC_INITIALIZATION) {
  665. return "org.aspectj.lang.reflect.InitializerSignature";
  666. } else if (kind == ADVICE) {
  667. return "org.aspectj.lang.reflect.AdviceSignature";
  668. } else if (kind == MONITORENTER) {
  669. return "org.aspectj.lang.reflect.LockSignature";
  670. } else if (kind == MONITOREXIT) {
  671. return "org.aspectj.lang.reflect.UnlockSignature";
  672. } else {
  673. throw new RuntimeException("unimplemented");
  674. }
  675. }
  676. /* (non-Javadoc)
  677. * @see org.aspectj.weaver.Member#getSignatureString(org.aspectj.weaver.World)
  678. */
  679. public String getSignatureString(World world) {
  680. if (getName().equals("<clinit>")) return getStaticInitializationSignatureString(world);
  681. Kind kind = getKind();
  682. if (kind == METHOD) {
  683. return getMethodSignatureString(world);
  684. } else if (kind == CONSTRUCTOR) {
  685. return getConstructorSignatureString(world);
  686. } else if (kind == FIELD) {
  687. return getFieldSignatureString(world);
  688. } else if (kind == HANDLER) {
  689. return getHandlerSignatureString(world);
  690. } else if (kind == STATIC_INITIALIZATION) {
  691. return getStaticInitializationSignatureString(world);
  692. } else if (kind == ADVICE) {
  693. return getAdviceSignatureString(world);
  694. } else if (kind == MONITORENTER || kind == MONITOREXIT) {
  695. return getMonitorSignatureString(world);
  696. } else {
  697. throw new RuntimeException("unimplemented");
  698. }
  699. }
  700. private String getHandlerSignatureString(World world) {
  701. StringBuffer buf = new StringBuffer();
  702. buf.append(makeString(0));
  703. buf.append('-');
  704. //buf.append(getName());
  705. buf.append('-');
  706. buf.append(makeString(getDeclaringType()));
  707. buf.append('-');
  708. buf.append(makeString(getParameterTypes()[0]));
  709. buf.append('-');
  710. String pName = "<missing>";
  711. String[] names = getParameterNames(world);
  712. if (names != null) pName = names[0];
  713. buf.append(pName);
  714. buf.append('-');
  715. return buf.toString();
  716. }
  717. private String getStaticInitializationSignatureString(World world) {
  718. StringBuffer buf = new StringBuffer();
  719. buf.append(makeString(getModifiers(world)));
  720. buf.append('-');
  721. //buf.append(getName());
  722. buf.append('-');
  723. buf.append(makeString(getDeclaringType()));
  724. buf.append('-');
  725. return buf.toString();
  726. }
  727. protected String getAdviceSignatureString(World world) {
  728. StringBuffer buf = new StringBuffer();
  729. buf.append(makeString(getModifiers(world)));
  730. buf.append('-');
  731. buf.append(getName());
  732. buf.append('-');
  733. buf.append(makeString(getDeclaringType()));
  734. buf.append('-');
  735. buf.append(makeString(getParameterTypes()));
  736. buf.append('-');
  737. buf.append(makeString(getParameterNames(world)));
  738. buf.append('-');
  739. buf.append(makeString(getExceptions(world)));
  740. buf.append('-');
  741. buf.append(makeString(getReturnType()));
  742. buf.append('-');
  743. return buf.toString();
  744. }
  745. protected String getMethodSignatureString(World world) {
  746. StringBuffer buf = new StringBuffer();
  747. buf.append(makeString(getModifiers(world)));
  748. buf.append('-');
  749. buf.append(getName());
  750. buf.append('-');
  751. buf.append(makeString(getDeclaringType()));
  752. buf.append('-');
  753. buf.append(makeString(getParameterTypes()));
  754. buf.append('-');
  755. buf.append(makeString(getParameterNames(world)));
  756. buf.append('-');
  757. buf.append(makeString(getExceptions(world)));
  758. buf.append('-');
  759. buf.append(makeString(getReturnType()));
  760. buf.append('-');
  761. return buf.toString();
  762. }
  763. protected String getMonitorSignatureString(World world) {
  764. StringBuffer buf = new StringBuffer();
  765. buf.append(makeString(Modifier.STATIC)); // modifiers
  766. buf.append('-');
  767. buf.append(getName()); // name
  768. buf.append('-');
  769. buf.append(makeString(getDeclaringType())); // Declaring Type
  770. buf.append('-');
  771. buf.append(makeString(getParameterTypes()[0])); // Parameter Types
  772. buf.append('-');
  773. buf.append(""); // Parameter names
  774. buf.append('-');
  775. return buf.toString();
  776. }
  777. protected String getConstructorSignatureString(World world) {
  778. StringBuffer buf = new StringBuffer();
  779. buf.append(makeString(getModifiers(world)));
  780. buf.append('-');
  781. buf.append('-');
  782. buf.append(makeString(getDeclaringType()));
  783. buf.append('-');
  784. buf.append(makeString(getParameterTypes()));
  785. buf.append('-');
  786. buf.append(makeString(getParameterNames(world)));
  787. buf.append('-');
  788. buf.append(makeString(getExceptions(world)));
  789. buf.append('-');
  790. return buf.toString();
  791. }
  792. protected String getFieldSignatureString(World world) {
  793. StringBuffer buf = new StringBuffer();
  794. buf.append(makeString(getModifiers(world)));
  795. buf.append('-');
  796. buf.append(getName());
  797. buf.append('-');
  798. buf.append(makeString(getDeclaringType()));
  799. buf.append('-');
  800. buf.append(makeString(getReturnType()));
  801. buf.append('-');
  802. return buf.toString();
  803. }
  804. protected String makeString(int i) {
  805. return Integer.toString(i, 16); //??? expensive
  806. }
  807. protected String makeString(UnresolvedType t) {
  808. // this is the inverse of the odd behavior for Class.forName w/ arrays
  809. if (t.isArray()) {
  810. // this behavior matches the string used by the eclipse compiler for Foo.class literals
  811. return t.getSignature().replace('/', '.');
  812. } else {
  813. return t.getName();
  814. }
  815. }
  816. protected String makeString(UnresolvedType[] types) {
  817. if (types == null) return "";
  818. StringBuffer buf = new StringBuffer();
  819. for (int i = 0, len=types.length; i < len; i++) {
  820. buf.append(makeString(types[i]));
  821. buf.append(':');
  822. }
  823. return buf.toString();
  824. }
  825. protected String makeString(String[] names) {
  826. if (names == null) return "";
  827. StringBuffer buf = new StringBuffer();
  828. for (int i = 0, len=names.length; i < len; i++) {
  829. buf.append(names[i]);
  830. buf.append(':');
  831. }
  832. return buf.toString();
  833. }
  834. /* (non-Javadoc)
  835. * @see org.aspectj.weaver.Member#getParameterNames(org.aspectj.weaver.World)
  836. */
  837. public String[] getParameterNames(World world) {
  838. ResolvedMember resolved = resolve(world);
  839. if (resolved == null) {
  840. reportDidntFindMember(world);
  841. return null;
  842. }
  843. return resolved.getParameterNames();
  844. }
  845. /**
  846. * All the signatures that a join point with this member as its signature has.
  847. */
  848. public Iterator getJoinPointSignatures(World inAWorld) {
  849. if (joinPointSignatures == null) {
  850. joinPointSignatures = new JoinPointSignatureIterator(this,inAWorld);
  851. }
  852. joinPointSignatures.reset();
  853. return joinPointSignatures;
  854. }
  855. /**
  856. * Raises an [Xlint:cantFindType] message if the declaring type
  857. * cannot be found or an [Xlint:unresolvableMember] message if the
  858. * type can be found (bug 149908)
  859. */
  860. private void reportDidntFindMember(World world) {
  861. if (reportedCantFindDeclaringType || reportedUnresolvableMember) return;
  862. ResolvedType rType = getDeclaringType().resolve(world);
  863. if (rType.isMissing()) {
  864. world.getLint().cantFindType.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,rType.getName()),null);
  865. reportedCantFindDeclaringType = true;
  866. } else {
  867. world.getLint().unresolvableMember.signal(getName(),null);
  868. reportedUnresolvableMember = true;
  869. }
  870. }
  871. }