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 17KB

15 年之前
15 年之前
14 年之前
15 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
14 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
14 年之前
15 年之前
15 年之前
15 年之前
14 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
14 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  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 v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  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 Member {
  20. protected MemberKind kind;
  21. protected int modifiers;
  22. protected String name;
  23. protected UnresolvedType declaringType;
  24. protected UnresolvedType returnType;
  25. protected UnresolvedType[] parameterTypes;
  26. private final String erasedSignature; // eg. (Ljava/util/Set;V)Ljava/lang/String;
  27. private String paramSignature; // eg. (Ljava/util/Set<Ljava/lang/String;>;V) // no return type
  28. // OPTIMIZE move out of the member!
  29. private boolean reportedCantFindDeclaringType = false;
  30. private boolean reportedUnresolvableMember = false;
  31. /**
  32. * All the signatures that a join point with this member as its signature has.
  33. */
  34. private JoinPointSignatureIterator joinPointSignatures = null;
  35. /**
  36. * Construct a MemberImpl using an erased signature for the parameters and return type (member method/ctor) or type (member
  37. * field)
  38. */
  39. public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, String name, String erasedSignature) {
  40. this.kind = kind;
  41. this.declaringType = declaringType;
  42. this.modifiers = modifiers;
  43. this.name = name;
  44. this.erasedSignature = erasedSignature;
  45. if (kind == FIELD) {
  46. this.returnType = UnresolvedType.forSignature(erasedSignature);
  47. this.parameterTypes = UnresolvedType.NONE;
  48. } else {
  49. Object[] returnAndParams = signatureToTypes(erasedSignature);
  50. this.returnType = (UnresolvedType) returnAndParams[0];
  51. this.parameterTypes = (UnresolvedType[]) returnAndParams[1];
  52. }
  53. }
  54. /**
  55. * Construct a MemberImpl using real type information for the parameters and return type (member method/ctor) or type (member
  56. * field)
  57. */
  58. public MemberImpl(MemberKind kind, UnresolvedType declaringType, int modifiers, UnresolvedType returnType, String name,
  59. UnresolvedType[] parameterTypes) {
  60. this.kind = kind;
  61. this.declaringType = declaringType;
  62. this.modifiers = modifiers;
  63. this.returnType = returnType;
  64. this.name = name;
  65. this.parameterTypes = parameterTypes;
  66. if (kind == FIELD) {
  67. this.erasedSignature = returnType.getErasureSignature();
  68. } else {
  69. this.erasedSignature = typesToSignature(returnType, parameterTypes, true);
  70. // Check parameter recovery by collapsing types to the string then rebuilding them from that
  71. // this will check we are capable of having WeakRefs to the parameter types
  72. // String nonErasedSignature = getParameterSignature()+getReturnType().getSignature();
  73. // Object[] returnAndParams = signatureToTypes(nonErasedSignature);
  74. // UnresolvedType[] recoveredParams = (UnresolvedType[]) returnAndParams[1];
  75. // for (int jj=0;jj<parameterTypes.length;jj++) {
  76. // if (!parameterTypes[jj].getSignature().equals(recoveredParams[jj].getSignature())) {
  77. // throw new
  78. // RuntimeException(parameterTypes[jj].getSignature()+" != "+recoveredParams[jj].getSignature()+" "+paramSignature);
  79. // }
  80. // }
  81. }
  82. }
  83. public ResolvedMember resolve(World world) {
  84. return world.resolve(this);
  85. }
  86. // ---- utility methods
  87. /**
  88. * Build a signature based on the return type and parameter types. For example: "(Ljava/util/Set&lt;Ljava/lang/String;&gt;;)V" or
  89. * "(Ljava/util/Set;)V". The latter form shows what happens when the generics are erased
  90. */
  91. public static String typesToSignature(UnresolvedType returnType, UnresolvedType[] paramTypes, boolean eraseGenerics) {
  92. StringBuilder buf = new StringBuilder();
  93. buf.append("(");
  94. for (UnresolvedType paramType : paramTypes) {
  95. if (eraseGenerics) {
  96. buf.append(paramType.getErasureSignature());
  97. } else {
  98. buf.append(paramType.getSignature());
  99. }
  100. }
  101. buf.append(")");
  102. if (eraseGenerics) {
  103. buf.append(returnType.getErasureSignature());
  104. } else {
  105. buf.append(returnType.getSignature());
  106. }
  107. return buf.toString();
  108. }
  109. /**
  110. * Returns "(&lt;signaturesOfParamTypes&gt;,...)" - unlike the other typesToSignature that also includes the return type, this one
  111. * just deals with the parameter types.
  112. */
  113. public static String typesToSignature(UnresolvedType[] paramTypes) {
  114. StringBuilder buf = new StringBuilder();
  115. buf.append("(");
  116. for (UnresolvedType paramType : paramTypes) {
  117. buf.append(paramType.getSignature());
  118. }
  119. buf.append(")");
  120. return buf.toString();
  121. }
  122. /**
  123. * returns an Object[] pair of UnresolvedType, UnresolvedType[] representing return type, argument types parsed from the JVM
  124. * bytecode signature of a method. Yes, this should actually return a nice statically-typed pair object, but we don't have one
  125. * of those.
  126. *
  127. * <blockquote>
  128. *
  129. * <pre>
  130. * UnresolvedType.signatureToTypes(&quot;()[Z&quot;)[0].equals(Type.forSignature(&quot;[Z&quot;))
  131. * UnresolvedType.signatureToTypes(&quot;(JJ)I&quot;)[1]
  132. * .equals(UnresolvedType.forSignatures(new String[] {&quot;J&quot;, &quot;J&quot;}))
  133. * </pre>
  134. *
  135. * </blockquote>
  136. *
  137. * @param erasedSignature the JVM bytecode method signature string we want to break apart
  138. * @return a pair of UnresolvedType, UnresolvedType[] representing the return types and parameter types.
  139. */
  140. private static Object[] signatureToTypes(String sig) {
  141. boolean hasParameters = sig.charAt(1) != ')';
  142. if (hasParameters) {
  143. List<UnresolvedType> l = new ArrayList<>();
  144. int i = 1;
  145. boolean hasAnyAnglies = sig.indexOf('<') != -1;
  146. while (true) {
  147. char c = sig.charAt(i);
  148. if (c == ')') {
  149. break; // break out when the hit the ')'
  150. }
  151. int start = i;
  152. while (c == '[') {
  153. c = sig.charAt(++i);
  154. }
  155. if (c == 'L' || c == 'P') {
  156. int nextSemicolon = sig.indexOf(';', start);
  157. int firstAngly = (hasAnyAnglies ? sig.indexOf('<', start) : -1);
  158. if (!hasAnyAnglies || firstAngly == -1 || firstAngly > nextSemicolon) {
  159. i = nextSemicolon + 1;
  160. l.add(UnresolvedType.forSignature(sig.substring(start, i)));
  161. } else {
  162. // generics generics generics
  163. // Have to skip to the *correct* ';'
  164. boolean endOfSigReached = false;
  165. int posn = firstAngly;
  166. int genericDepth = 0;
  167. while (!endOfSigReached) {
  168. switch (sig.charAt(posn)) {
  169. case '<':
  170. genericDepth++;
  171. break;
  172. case '>':
  173. genericDepth--;
  174. break;
  175. case ';':
  176. if (genericDepth == 0) {
  177. endOfSigReached = true;
  178. }
  179. break;
  180. default:
  181. }
  182. posn++;
  183. }
  184. // posn now points to the correct nextSemicolon :)
  185. i = posn;
  186. l.add(UnresolvedType.forSignature(sig.substring(start, i)));
  187. }
  188. } else if (c == 'T') { // assumed 'reference' to a type
  189. // variable, so just "Tname;"
  190. int nextSemicolon = sig.indexOf(';', start);
  191. String nextbit = sig.substring(start, nextSemicolon + 1);
  192. l.add(UnresolvedType.forSignature(nextbit));
  193. i = nextSemicolon + 1;
  194. } else {
  195. i++;
  196. l.add(UnresolvedType.forSignature(sig.substring(start, i)));
  197. }
  198. }
  199. UnresolvedType[] paramTypes = l.toArray(UnresolvedType.NONE);
  200. UnresolvedType returnType = UnresolvedType.forSignature(sig.substring(i + 1, sig.length()));
  201. return new Object[] { returnType, paramTypes };
  202. } else {
  203. UnresolvedType returnType = UnresolvedType.forSignature(sig.substring(2));
  204. return new Object[] { returnType, UnresolvedType.NONE };
  205. }
  206. }
  207. // ---- factory methods
  208. public static MemberImpl field(String declaring, int mods, String name, String signature) {
  209. return field(declaring, mods, UnresolvedType.forSignature(signature), name);
  210. }
  211. // OPTIMIZE do we need to call this? unless necessary the signatureToTypes()
  212. // call smacks of laziness on the behalf of the caller of this method
  213. public static MemberImpl method(UnresolvedType declaring, int mods, String name, String signature) {
  214. Object[] pair = signatureToTypes(signature);
  215. return method(declaring, mods, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]);
  216. }
  217. public static MemberImpl monitorEnter() {
  218. return new MemberImpl(MONITORENTER, UnresolvedType.OBJECT, Modifier.STATIC, UnresolvedType.VOID, "<lock>",
  219. UnresolvedType.ARRAY_WITH_JUST_OBJECT);
  220. }
  221. public static MemberImpl monitorExit() {
  222. return new MemberImpl(MONITOREXIT, UnresolvedType.OBJECT, Modifier.STATIC, UnresolvedType.VOID, "<unlock>",
  223. UnresolvedType.ARRAY_WITH_JUST_OBJECT);
  224. }
  225. public static Member pointcut(UnresolvedType declaring, String name, String signature) {
  226. Object[] pair = signatureToTypes(signature);
  227. return pointcut(declaring, 0, (UnresolvedType) pair[0], name, (UnresolvedType[]) pair[1]);
  228. }
  229. private static MemberImpl field(String declaring, int mods, UnresolvedType ty, String name) {
  230. return new MemberImpl(FIELD, UnresolvedType.forName(declaring), mods, ty, name, UnresolvedType.NONE);
  231. }
  232. public static MemberImpl method(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
  233. return new MemberImpl(
  234. // ??? this calls <clinit> a method
  235. name.equals("<init>") ? CONSTRUCTOR : METHOD, declTy, mods, rTy, name, paramTys);
  236. }
  237. private static Member pointcut(UnresolvedType declTy, int mods, UnresolvedType rTy, String name, UnresolvedType[] paramTys) {
  238. return new MemberImpl(POINTCUT, declTy, mods, rTy, name, paramTys);
  239. }
  240. public static ResolvedMemberImpl makeExceptionHandlerSignature(UnresolvedType inType, UnresolvedType catchType) {
  241. return new ResolvedMemberImpl(HANDLER, inType, Modifier.STATIC, "<catch>", "(" + catchType.getSignature() + ")V");
  242. }
  243. @Override
  244. public final boolean equals(Object other) {
  245. if (!(other instanceof Member)) {
  246. return false;
  247. }
  248. Member o = (Member) other;
  249. return (getKind() == o.getKind() && getName().equals(o.getName()) && getSignature().equals(o.getSignature()) && getDeclaringType()
  250. .equals(o.getDeclaringType()));
  251. }
  252. /**
  253. * @return true if this member equals the one supplied in every respect other than the declaring type
  254. */
  255. public final boolean equalsApartFromDeclaringType(Object other) {
  256. if (!(other instanceof Member)) {
  257. return false;
  258. }
  259. Member o = (Member) other;
  260. return (getKind() == o.getKind() && getName().equals(o.getName()) && getSignature().equals(o.getSignature()));
  261. }
  262. /**
  263. * Equality is checked based on the underlying signature, so the hash code of a member is based on its kind, name, signature,
  264. * and declaring type. The algorithm for this was taken from page 38 of effective java.
  265. */
  266. private volatile int hashCode = 0;
  267. @Override
  268. public int hashCode() {
  269. if (hashCode == 0) {
  270. int result = 17;
  271. result = 37 * result + getKind().hashCode();
  272. result = 37 * result + getName().hashCode();
  273. result = 37 * result + getSignature().hashCode();
  274. result = 37 * result + getDeclaringType().hashCode();
  275. hashCode = result;
  276. }
  277. return hashCode;
  278. }
  279. public int compareTo(Member other) {
  280. Member o = other;
  281. int i = getName().compareTo(o.getName());
  282. if (i != 0) {
  283. return i;
  284. }
  285. return getSignature().compareTo(o.getSignature());
  286. }
  287. @Override
  288. public String toString() {
  289. StringBuilder buf = new StringBuilder();
  290. buf.append(returnType.getName());
  291. buf.append(' ');
  292. if (declaringType == null) {
  293. buf.append("<NULL>");
  294. } else {
  295. buf.append(declaringType.getName());
  296. }
  297. buf.append('.');
  298. buf.append(name);
  299. if (kind != FIELD) {
  300. buf.append("(");
  301. if (parameterTypes.length != 0) {
  302. buf.append(parameterTypes[0]);
  303. for (int i = 1, len = parameterTypes.length; i < len; i++) {
  304. buf.append(", ");
  305. buf.append(parameterTypes[i].getName());
  306. }
  307. }
  308. buf.append(")");
  309. }
  310. return buf.toString();
  311. }
  312. public MemberKind getKind() {
  313. return kind;
  314. }
  315. public UnresolvedType getDeclaringType() {
  316. return declaringType;
  317. }
  318. public UnresolvedType getReturnType() {
  319. return returnType;
  320. }
  321. public UnresolvedType getGenericReturnType() {
  322. return getReturnType();
  323. }
  324. public UnresolvedType[] getGenericParameterTypes() {
  325. return getParameterTypes();
  326. }
  327. public final UnresolvedType getType() {
  328. return returnType;
  329. }
  330. public String getName() {
  331. return name;
  332. }
  333. public UnresolvedType[] getParameterTypes() {
  334. return parameterTypes;
  335. }
  336. public String getSignature() {
  337. return erasedSignature;
  338. }
  339. public int getArity() {
  340. return parameterTypes.length;
  341. }
  342. public String getParameterSignature() {
  343. if (paramSignature == null) {
  344. StringBuilder sb = new StringBuilder("(");
  345. for (UnresolvedType parameterType : parameterTypes) {
  346. sb.append(parameterType.getSignature());
  347. }
  348. paramSignature = sb.append(")").toString();
  349. }
  350. return paramSignature;
  351. }
  352. // OPTIMIZE see next line. Why the hell are they in here if we only know it
  353. // once resolution has occurred...
  354. // ---- things we know only with resolution
  355. public int getModifiers(World world) {
  356. ResolvedMember resolved = resolve(world);
  357. if (resolved == null) {
  358. reportDidntFindMember(world);
  359. return 0;
  360. }
  361. return resolved.getModifiers();
  362. }
  363. public UnresolvedType[] getExceptions(World world) {
  364. ResolvedMember resolved = resolve(world);
  365. if (resolved == null) {
  366. reportDidntFindMember(world);
  367. return UnresolvedType.NONE;
  368. }
  369. return resolved.getExceptions();
  370. }
  371. public final boolean isStatic() {
  372. return Modifier.isStatic(modifiers);
  373. }
  374. public final boolean isInterface() {
  375. return Modifier.isInterface(modifiers);
  376. }
  377. public final boolean isPrivate() {
  378. return Modifier.isPrivate(modifiers);
  379. }
  380. public boolean canBeParameterized() {
  381. return false;
  382. }
  383. public int getModifiers() {
  384. return modifiers;
  385. }
  386. public AnnotationAJ[] getAnnotations() {
  387. throw new UnsupportedOperationException("You should resolve this member '" + this
  388. + "' and call getAnnotations() on the result...");
  389. }
  390. // ---- fields 'n' stuff
  391. public Collection<ResolvedType> getDeclaringTypes(World world) {
  392. ResolvedType myType = getDeclaringType().resolve(world);
  393. Collection<ResolvedType> ret = new HashSet<>();
  394. if (kind == CONSTRUCTOR) {
  395. // this is wrong if the member doesn't exist, but that doesn't
  396. // matter
  397. ret.add(myType);
  398. } else if (Modifier.isStatic(modifiers) || kind == FIELD) {
  399. walkUpStatic(ret, myType);
  400. } else {
  401. walkUp(ret, myType);
  402. }
  403. return ret;
  404. }
  405. private boolean walkUp(Collection<ResolvedType> acc, ResolvedType curr) {
  406. if (acc.contains(curr)) {
  407. return true;
  408. }
  409. boolean b = false;
  410. for (Iterator<ResolvedType> i = curr.getDirectSupertypes(); i.hasNext();) {
  411. b |= walkUp(acc, i.next());
  412. }
  413. if (!b && curr.isParameterizedType()) {
  414. b = walkUp(acc, curr.getGenericType());
  415. }
  416. if (!b) {
  417. b = curr.lookupMemberNoSupers(this) != null;
  418. }
  419. if (b) {
  420. acc.add(curr);
  421. }
  422. return b;
  423. }
  424. private boolean walkUpStatic(Collection<ResolvedType> acc, ResolvedType curr) {
  425. if (curr.lookupMemberNoSupers(this) != null) {
  426. acc.add(curr);
  427. return true;
  428. } else {
  429. boolean b = false;
  430. for (Iterator<ResolvedType> i = curr.getDirectSupertypes(); i.hasNext();) {
  431. b |= walkUpStatic(acc, i.next());
  432. }
  433. if (!b && curr.isParameterizedType()) {
  434. b = walkUpStatic(acc, curr.getGenericType());
  435. }
  436. if (b) {
  437. acc.add(curr);
  438. }
  439. return b;
  440. }
  441. }
  442. public String[] getParameterNames(World world) {
  443. ResolvedMember resolved = resolve(world);
  444. if (resolved == null) {
  445. reportDidntFindMember(world);
  446. return null;
  447. }
  448. return resolved.getParameterNames();
  449. }
  450. /**
  451. * All the signatures that a join point with this member as its signature has.
  452. */
  453. public JoinPointSignatureIterator getJoinPointSignatures(World inAWorld) {
  454. if (joinPointSignatures == null) {
  455. joinPointSignatures = new JoinPointSignatureIterator(this, inAWorld);
  456. }
  457. joinPointSignatures.reset();
  458. return joinPointSignatures;
  459. }
  460. /**
  461. * Raises an [Xlint:cantFindType] message if the declaring type cannot be found or an [Xlint:unresolvableMember] message if the
  462. * type can be found (bug 149908)
  463. */
  464. private void reportDidntFindMember(World world) {
  465. if (reportedCantFindDeclaringType || reportedUnresolvableMember) {
  466. return;
  467. }
  468. ResolvedType rType = getDeclaringType().resolve(world);
  469. if (rType.isMissing()) {
  470. world.getLint().cantFindType.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE, rType.getName()), null);
  471. reportedCantFindDeclaringType = true;
  472. } else {
  473. world.getLint().unresolvableMember.signal(getName(), null);
  474. reportedUnresolvableMember = true;
  475. }
  476. }
  477. public void wipeJoinpointSignatures() {
  478. joinPointSignatures = null;
  479. }
  480. }