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.

Member.java 24KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777
  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 Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import java.io.DataInputStream;
  14. import java.io.IOException;
  15. import java.lang.reflect.Modifier;
  16. import java.util.ArrayList;
  17. import java.util.Collection;
  18. import java.util.HashSet;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. import org.aspectj.util.TypeSafeEnum;
  22. public class Member implements Comparable {
  23. private final Kind kind;
  24. private final TypeX declaringType;
  25. protected final int modifiers; // protected because ResolvedMember uses it
  26. private final TypeX returnType;
  27. private final String name;
  28. private final TypeX[] parameterTypes;
  29. private final String signature;
  30. private String paramSignature;
  31. public Member(
  32. Kind kind,
  33. TypeX declaringType,
  34. int modifiers,
  35. String name,
  36. String signature)
  37. {
  38. this.kind = kind;
  39. this.declaringType = declaringType;
  40. this.modifiers = modifiers;
  41. this.name = name;
  42. this.signature = signature;
  43. if (kind == FIELD) {
  44. this.returnType = TypeX.forSignature(signature);
  45. this.parameterTypes = TypeX.NONE;
  46. } else {
  47. Object[] returnAndParams = signatureToTypes(signature);
  48. this.returnType = (TypeX) returnAndParams[0];
  49. this.parameterTypes = (TypeX[]) returnAndParams[1];
  50. }
  51. }
  52. public Member(
  53. Kind kind,
  54. TypeX declaringType,
  55. int modifiers,
  56. TypeX returnType,
  57. String name,
  58. TypeX[] parameterTypes)
  59. {
  60. super();
  61. this.kind = kind;
  62. this.declaringType = declaringType;
  63. this.modifiers = modifiers;
  64. this.returnType = returnType;
  65. this.name = name;
  66. this.parameterTypes = parameterTypes;
  67. if (kind == FIELD) {
  68. this.signature = returnType.getSignature();
  69. } else {
  70. this.signature = typesToSignature(returnType, parameterTypes);
  71. }
  72. }
  73. public ResolvedMember resolve(World world) {
  74. return world.resolve(this);
  75. }
  76. // ---- utility methods
  77. /** returns an Object[] pair of TypeX, TypeX[] representing return type,
  78. * argument types parsed from the JVM bytecode signature of a method. Yes,
  79. * this should actually return a nice statically-typed pair object, but we
  80. * don't have one of those.
  81. *
  82. * <blockquote><pre>
  83. * TypeX.signatureToTypes("()[Z")[0].equals(Type.forSignature("[Z"))
  84. * TypeX.signatureToTypes("(JJ)I")[1]
  85. * .equals(TypeX.forSignatures(new String[] {"J", "J"}))
  86. * </pre></blockquote>
  87. *
  88. * @param signature the JVM bytecode method signature string we want to break apart
  89. * @return a pair of TypeX, TypeX[] representing the return types and parameter types.
  90. */
  91. public static String typesToSignature(TypeX returnType, TypeX[] paramTypes) {
  92. StringBuffer buf = new StringBuffer();
  93. buf.append("(");
  94. for (int i = 0, len = paramTypes.length; i < len; i++) {
  95. buf.append(paramTypes[i].getSignature());
  96. }
  97. buf.append(")");
  98. buf.append(returnType.getSignature());
  99. return buf.toString();
  100. }
  101. /** returns an Object[] pair of TypeX, TypeX[] representing return type,
  102. * argument types parsed from the JVM bytecode signature of a method. Yes,
  103. * this should actually return a nice statically-typed pair object, but we
  104. * don't have one of those.
  105. *
  106. * <blockquote><pre>
  107. * TypeX.signatureToTypes("()[Z")[0].equals(Type.forSignature("[Z"))
  108. * TypeX.signatureToTypes("(JJ)I")[1]
  109. * .equals(TypeX.forSignatures(new String[] {"J", "J"}))
  110. * </pre></blockquote>
  111. *
  112. * @param signature the JVM bytecode method signature string we want to break apart
  113. * @return a pair of TypeX, TypeX[] representing the return types and parameter types.
  114. */
  115. private static Object[] signatureToTypes(String sig) {
  116. List l = new ArrayList();
  117. int i = 1;
  118. while (true) {
  119. char c = sig.charAt(i);
  120. if (c == ')') break;
  121. int start = i;
  122. while (c == '[') c = sig.charAt(++i);
  123. if (c == 'L') {
  124. i = sig.indexOf(';', start) + 1;
  125. l.add(TypeX.forSignature(sig.substring(start, i)));
  126. } else {
  127. l.add(TypeX.forSignature(sig.substring(start, ++i)));
  128. }
  129. }
  130. TypeX[] paramTypes = (TypeX[]) l.toArray(new TypeX[l.size()]);
  131. TypeX returnType = TypeX.forSignature(sig.substring(i+1, sig.length()));
  132. return new Object[] { returnType, paramTypes };
  133. }
  134. // ---- factory methods
  135. public static Member field(String declaring, int mods, String name, String signature) {
  136. return field(declaring, mods, TypeX.forSignature(signature), name);
  137. }
  138. public static Member field(TypeX declaring, int mods, String name, TypeX type) {
  139. return new Member(FIELD, declaring, mods, type, name, TypeX.NONE);
  140. }
  141. public static Member method(TypeX declaring, int mods, String name, String signature) {
  142. Object[] pair = signatureToTypes(signature);
  143. return method(declaring, mods, (TypeX) pair[0], name, (TypeX[]) pair[1]);
  144. }
  145. public static Member pointcut(TypeX declaring, String name, String signature) {
  146. Object[] pair = signatureToTypes(signature);
  147. return pointcut(declaring, 0, (TypeX) pair[0], name, (TypeX[]) pair[1]);
  148. }
  149. private static Member field(String declaring, int mods, TypeX ty, String name) {
  150. return new Member(
  151. FIELD,
  152. TypeX.forName(declaring),
  153. mods,
  154. ty,
  155. name,
  156. TypeX.NONE);
  157. }
  158. public static Member method(TypeX declTy, int mods, TypeX rTy, String name, TypeX[] paramTys) {
  159. return new Member(
  160. //??? this calls <clinit> a method
  161. name.equals("<init>") ? CONSTRUCTOR : METHOD,
  162. declTy,
  163. mods,
  164. rTy,
  165. name,
  166. paramTys);
  167. }
  168. private static Member pointcut(TypeX declTy, int mods, TypeX rTy, String name, TypeX[] paramTys) {
  169. return new Member(
  170. POINTCUT,
  171. declTy,
  172. mods,
  173. rTy,
  174. name,
  175. paramTys);
  176. }
  177. public static ResolvedMember makeExceptionHandlerSignature(TypeX inType, TypeX catchType) {
  178. return new ResolvedMember(
  179. HANDLER,
  180. inType,
  181. Modifier.STATIC,
  182. "<catch>",
  183. "(" + catchType.getSignature() + ")V");
  184. }
  185. // ---- parsing methods
  186. /** Takes a string in this form:
  187. *
  188. * <blockquote><pre>
  189. * static? TypeName TypeName.Id
  190. * </pre></blockquote>
  191. * Pretty much just for testing, and as such should perhaps be moved.
  192. */
  193. public static Member fieldFromString(String str) {
  194. str = str.trim();
  195. final int len = str.length();
  196. int i = 0;
  197. int mods = 0;
  198. if (str.startsWith("static", i)) {
  199. mods = Modifier.STATIC;
  200. i += 6;
  201. while (Character.isWhitespace(str.charAt(i))) i++;
  202. }
  203. int start = i;
  204. while (! Character.isWhitespace(str.charAt(i))) i++;
  205. TypeX retTy = TypeX.forName(str.substring(start, i));
  206. start = i;
  207. i = str.lastIndexOf('.');
  208. TypeX declaringTy = TypeX.forName(str.substring(start, i).trim());
  209. start = ++i;
  210. String name = str.substring(start, len).trim();
  211. return new Member(
  212. FIELD,
  213. declaringTy,
  214. mods,
  215. retTy,
  216. name,
  217. TypeX.NONE);
  218. }
  219. /** Takes a string in this form:
  220. *
  221. * <blockquote><pre>
  222. * (static|interface|private)? TypeName TypeName . Id ( TypeName , ...)
  223. * </pre></blockquote>
  224. * Pretty much just for testing, and as such should perhaps be moved.
  225. */
  226. public static Member methodFromString(String str) {
  227. str = str.trim();
  228. // final int len = str.length();
  229. int i = 0;
  230. int mods = 0;
  231. if (str.startsWith("static", i)) {
  232. mods = Modifier.STATIC;
  233. i += 6;
  234. } else if (str.startsWith("interface", i)) {
  235. mods = Modifier.INTERFACE;
  236. i += 9;
  237. } else if (str.startsWith("private", i)) {
  238. mods = Modifier.PRIVATE;
  239. i += 7;
  240. }
  241. while (Character.isWhitespace(str.charAt(i))) i++;
  242. int start = i;
  243. while (! Character.isWhitespace(str.charAt(i))) i++;
  244. TypeX returnTy = TypeX.forName(str.substring(start, i));
  245. start = i;
  246. i = str.indexOf('(', i);
  247. i = str.lastIndexOf('.', i);
  248. TypeX declaringTy = TypeX.forName(str.substring(start, i).trim());
  249. start = ++i;
  250. i = str.indexOf('(', i);
  251. String name = str.substring(start, i).trim();
  252. start = ++i;
  253. i = str.indexOf(')', i);
  254. String[] paramTypeNames = parseIds(str.substring(start, i).trim());
  255. return method(declaringTy, mods, returnTy, name, TypeX.forNames(paramTypeNames));
  256. }
  257. private static String[] parseIds(String str) {
  258. if (str.length() == 0) return ZERO_STRINGS;
  259. List l = new ArrayList();
  260. int start = 0;
  261. while (true) {
  262. int i = str.indexOf(',', start);
  263. if (i == -1) {
  264. l.add(str.substring(start).trim());
  265. break;
  266. }
  267. l.add(str.substring(start, i).trim());
  268. start = i+1;
  269. }
  270. return (String[]) l.toArray(new String[l.size()]);
  271. }
  272. private static final String[] ZERO_STRINGS = new String[0];
  273. // ---- things we know without resolution
  274. public boolean equals(Object other) {
  275. if (! (other instanceof Member)) return false;
  276. Member o = (Member) other;
  277. return (kind == o.kind
  278. && name.equals(o.name)
  279. && signature.equals(o.signature)
  280. && declaringType.equals(o.declaringType));
  281. }
  282. public int compareTo(Object other) {
  283. Member o = (Member) other;
  284. int i = getName().compareTo(o.getName());
  285. if (i != 0) return i;
  286. return getSignature().compareTo(o.getSignature());
  287. }
  288. /**
  289. * Equality is checked based on the underlying signature, so the hash code
  290. * of a member is based on its kind, name, signature, and declaring type. The
  291. * algorithm for this was taken from page 38 of effective java.
  292. */
  293. private volatile int hashCode = 0;
  294. public int hashCode() {
  295. if (hashCode == 0) {
  296. int result = 17;
  297. result = 37*result + kind.hashCode();
  298. result = 37*result + name.hashCode();
  299. result = 37*result + signature.hashCode();
  300. result = 37*result + declaringType.hashCode();
  301. hashCode = result;
  302. }
  303. return hashCode;
  304. }
  305. public String toString() {
  306. StringBuffer buf = new StringBuffer();
  307. buf.append(returnType);
  308. buf.append(' ');
  309. buf.append(declaringType);
  310. buf.append('.');
  311. buf.append(name);
  312. if (kind != FIELD) {
  313. buf.append("(");
  314. if (parameterTypes.length != 0) {
  315. buf.append(parameterTypes[0]);
  316. for (int i=1, len = parameterTypes.length; i < len; i++) {
  317. buf.append(", ");
  318. buf.append(parameterTypes[i]);
  319. }
  320. }
  321. buf.append(")");
  322. }
  323. return buf.toString();
  324. }
  325. public String toLongString() {
  326. StringBuffer buf = new StringBuffer();
  327. buf.append(kind);
  328. buf.append(' ');
  329. if (modifiers != 0) {
  330. buf.append(Modifier.toString(modifiers));
  331. buf.append(' ');
  332. }
  333. buf.append(toString());
  334. buf.append(" <");
  335. buf.append(signature);
  336. buf.append(" >");
  337. return buf.toString();
  338. }
  339. public Kind getKind() { return kind; }
  340. public TypeX getDeclaringType() { return declaringType; }
  341. public TypeX getReturnType() { return returnType; }
  342. public TypeX getType() { return returnType; }
  343. public String getName() { return name; }
  344. public TypeX[] getParameterTypes() { return parameterTypes; }
  345. /**
  346. * Return full signature, including return type, e.g. "()LFastCar;" for a signature without the return type,
  347. * use getParameterSignature() - it is importnant to choose the right one in the face of covariance.
  348. */
  349. public String getSignature() { return signature; }
  350. public int getArity() { return parameterTypes.length; }
  351. /**
  352. * Return signature without return type, e.g. "()" for a signature *with* the return type,
  353. * use getSignature() - it is important to choose the right one in the face of covariance.
  354. */
  355. public String getParameterSignature() {
  356. if (paramSignature != null) return paramSignature;
  357. StringBuffer sb = new StringBuffer();
  358. sb.append("(");
  359. for (int i = 0; i < parameterTypes.length; i++) {
  360. TypeX tx = parameterTypes[i];
  361. sb.append(tx.getSignature());
  362. }
  363. sb.append(")");
  364. paramSignature = sb.toString();
  365. return paramSignature;
  366. }
  367. public boolean isCompatibleWith(Member am) {
  368. if (kind != METHOD || am.getKind() != METHOD) return true;
  369. if (! name.equals(am.getName())) return true;
  370. if (! equalTypes(getParameterTypes(), am.getParameterTypes())) return true;
  371. return getReturnType().equals(am.getReturnType());
  372. }
  373. private static boolean equalTypes(TypeX[] a, TypeX[] b) {
  374. int len = a.length;
  375. if (len != b.length) return false;
  376. for (int i = 0; i < len; i++) {
  377. if (!a[i].equals(b[i])) return false;
  378. }
  379. return true;
  380. }
  381. // ---- things we know only with resolution
  382. public int getModifiers(World world) {
  383. return world.getModifiers(this);
  384. }
  385. public TypeX[] getExceptions(World world) {
  386. return world.getExceptions(this);
  387. }
  388. public final boolean isProtected(World world) {
  389. return Modifier.isProtected(world.getModifiers(this));
  390. }
  391. public final boolean isStatic(World world) {
  392. return Modifier.isStatic(world.getModifiers(this));
  393. }
  394. public final boolean isStrict(World world) {
  395. return Modifier.isStrict(world.getModifiers(this));
  396. }
  397. public final boolean isStatic() {
  398. return Modifier.isStatic(modifiers);
  399. }
  400. public final boolean isInterface() {
  401. return Modifier.isInterface(modifiers); // this is kinda weird
  402. }
  403. public final boolean isPrivate() {
  404. return Modifier.isPrivate(modifiers);
  405. }
  406. public final int getCallsiteModifiers() {
  407. return modifiers & ~ Modifier.INTERFACE;
  408. }
  409. public final String getExtractableName() {
  410. if (name.equals("<init>")) return "init$";
  411. else if (name.equals("<clinit>")) return "clinit$";
  412. else return name;
  413. }
  414. // ---- fields 'n' stuff
  415. public static final Member[] NONE = new Member[0];
  416. public static class Kind extends TypeSafeEnum {
  417. public Kind(String name, int key) { super(name, key); }
  418. public static Kind read(DataInputStream s) throws IOException {
  419. int key = s.readByte();
  420. switch(key) {
  421. case 1: return METHOD;
  422. case 2: return FIELD;
  423. case 3: return CONSTRUCTOR;
  424. case 4: return STATIC_INITIALIZATION;
  425. case 5: return POINTCUT;
  426. case 6: return ADVICE;
  427. case 7: return HANDLER;
  428. }
  429. throw new BCException("weird kind " + key);
  430. }
  431. }
  432. public static final Kind METHOD = new Kind("METHOD", 1);
  433. public static final Kind FIELD = new Kind("FIELD", 2);
  434. public static final Kind CONSTRUCTOR = new Kind("CONSTRUCTOR", 3);
  435. public static final Kind STATIC_INITIALIZATION = new Kind("STATIC_INITIALIZATION", 4);
  436. public static final Kind POINTCUT = new Kind("POINTCUT", 5);
  437. public static final Kind ADVICE = new Kind("ADVICE", 6);
  438. public static final Kind HANDLER = new Kind("HANDLER", 7);
  439. public Collection/*ResolvedTypeX*/ getDeclaringTypes(World world) {
  440. ResolvedTypeX myType = getDeclaringType().resolve(world);
  441. Collection ret = new HashSet();
  442. if (kind == CONSTRUCTOR) {
  443. // this is wrong if the member doesn't exist, but that doesn't matter
  444. ret.add(myType);
  445. } else if (isStatic() || kind == FIELD) {
  446. walkUpStatic(ret, myType);
  447. } else {
  448. walkUp(ret, myType);
  449. }
  450. return ret;
  451. }
  452. private boolean walkUp(Collection acc, ResolvedTypeX curr) {
  453. if (acc.contains(curr)) return true;
  454. boolean b = false;
  455. for (Iterator i = curr.getDirectSupertypes(); i.hasNext(); ) {
  456. b |= walkUp(acc, (ResolvedTypeX)i.next());
  457. }
  458. if (!b) {
  459. b = curr.lookupMemberNoSupers(this) != null;
  460. }
  461. if (b) acc.add(curr);
  462. return b;
  463. }
  464. private boolean walkUpStatic(Collection acc, ResolvedTypeX curr) {
  465. if (curr.lookupMemberNoSupers(this) != null) {
  466. acc.add(curr);
  467. return true;
  468. } else {
  469. boolean b = false;
  470. for (Iterator i = curr.getDirectSupertypes(); i.hasNext(); ) {
  471. b |= walkUpStatic(acc, (ResolvedTypeX)i.next());
  472. }
  473. if (b) acc.add(curr);
  474. return b;
  475. }
  476. }
  477. // ---- reflective thisJoinPoint stuff
  478. public String getSignatureMakerName() {
  479. if (getName().equals("<clinit>")) return "makeInitializerSig";
  480. Kind kind = getKind();
  481. if (kind == METHOD) {
  482. return "makeMethodSig";
  483. } else if (kind == CONSTRUCTOR) {
  484. return "makeConstructorSig";
  485. } else if (kind == FIELD) {
  486. return "makeFieldSig";
  487. } else if (kind == HANDLER) {
  488. return "makeCatchClauseSig";
  489. } else if (kind == STATIC_INITIALIZATION) {
  490. return "makeInitializerSig";
  491. } else if (kind == ADVICE) {
  492. return "makeAdviceSig";
  493. } else {
  494. throw new RuntimeException("unimplemented");
  495. }
  496. }
  497. public String getSignatureType() {
  498. Kind kind = getKind();
  499. if (getName().equals("<clinit>")) return "org.aspectj.lang.reflect.InitializerSignature";
  500. if (kind == METHOD) {
  501. return "org.aspectj.lang.reflect.MethodSignature";
  502. } else if (kind == CONSTRUCTOR) {
  503. return "org.aspectj.lang.reflect.ConstructorSignature";
  504. } else if (kind == FIELD) {
  505. return "org.aspectj.lang.reflect.FieldSignature";
  506. } else if (kind == HANDLER) {
  507. return "org.aspectj.lang.reflect.CatchClauseSignature";
  508. } else if (kind == STATIC_INITIALIZATION) {
  509. return "org.aspectj.lang.reflect.InitializerSignature";
  510. } else if (kind == ADVICE) {
  511. return "org.aspectj.lang.reflect.AdviceSignature";
  512. } else {
  513. throw new RuntimeException("unimplemented");
  514. }
  515. }
  516. public String getSignatureString(World world) {
  517. if (getName().equals("<clinit>")) return getStaticInitializationSignatureString(world);
  518. Kind kind = getKind();
  519. if (kind == METHOD) {
  520. return getMethodSignatureString(world);
  521. } else if (kind == CONSTRUCTOR) {
  522. return getConstructorSignatureString(world);
  523. } else if (kind == FIELD) {
  524. return getFieldSignatureString(world);
  525. } else if (kind == HANDLER) {
  526. return getHandlerSignatureString(world);
  527. } else if (kind == STATIC_INITIALIZATION) {
  528. return getStaticInitializationSignatureString(world);
  529. } else if (kind == ADVICE) {
  530. return getAdviceSignatureString(world);
  531. } else {
  532. throw new RuntimeException("unimplemented");
  533. }
  534. }
  535. private String getHandlerSignatureString(World world) {
  536. StringBuffer buf = new StringBuffer();
  537. buf.append(makeString(0));
  538. buf.append('-');
  539. //buf.append(getName());
  540. buf.append('-');
  541. buf.append(makeString(getDeclaringType()));
  542. buf.append('-');
  543. buf.append(makeString(getParameterTypes()[0]));
  544. buf.append('-');
  545. String pName = "<missing>";
  546. String[] names = getParameterNames(world);
  547. if (names != null) pName = names[0];
  548. buf.append(pName);
  549. buf.append('-');
  550. return buf.toString();
  551. }
  552. private String getStaticInitializationSignatureString(World world) {
  553. StringBuffer buf = new StringBuffer();
  554. buf.append(makeString(getModifiers(world)));
  555. buf.append('-');
  556. //buf.append(getName());
  557. buf.append('-');
  558. buf.append(makeString(getDeclaringType()));
  559. buf.append('-');
  560. return buf.toString();
  561. }
  562. protected String getAdviceSignatureString(World world) {
  563. StringBuffer buf = new StringBuffer();
  564. buf.append(makeString(getModifiers(world)));
  565. buf.append('-');
  566. buf.append(getName());
  567. buf.append('-');
  568. buf.append(makeString(getDeclaringType()));
  569. buf.append('-');
  570. buf.append(makeString(getParameterTypes()));
  571. buf.append('-');
  572. buf.append(makeString(getParameterNames(world)));
  573. buf.append('-');
  574. buf.append(makeString(getExceptions(world)));
  575. buf.append('-');
  576. buf.append(makeString(getReturnType()));
  577. buf.append('-');
  578. return buf.toString();
  579. }
  580. protected String getMethodSignatureString(World world) {
  581. StringBuffer buf = new StringBuffer();
  582. buf.append(makeString(getModifiers(world)));
  583. buf.append('-');
  584. buf.append(getName());
  585. buf.append('-');
  586. buf.append(makeString(getDeclaringType()));
  587. buf.append('-');
  588. buf.append(makeString(getParameterTypes()));
  589. buf.append('-');
  590. buf.append(makeString(getParameterNames(world)));
  591. buf.append('-');
  592. buf.append(makeString(getExceptions(world)));
  593. buf.append('-');
  594. buf.append(makeString(getReturnType()));
  595. buf.append('-');
  596. return buf.toString();
  597. }
  598. protected String getConstructorSignatureString(World world) {
  599. StringBuffer buf = new StringBuffer();
  600. buf.append(makeString(getModifiers(world)));
  601. buf.append('-');
  602. buf.append('-');
  603. buf.append(makeString(getDeclaringType()));
  604. buf.append('-');
  605. buf.append(makeString(getParameterTypes()));
  606. buf.append('-');
  607. buf.append(makeString(getParameterNames(world)));
  608. buf.append('-');
  609. buf.append(makeString(getExceptions(world)));
  610. buf.append('-');
  611. return buf.toString();
  612. }
  613. protected String getFieldSignatureString(World world) {
  614. StringBuffer buf = new StringBuffer();
  615. buf.append(makeString(getModifiers(world)));
  616. buf.append('-');
  617. buf.append(getName());
  618. buf.append('-');
  619. buf.append(makeString(getDeclaringType()));
  620. buf.append('-');
  621. buf.append(makeString(getReturnType()));
  622. buf.append('-');
  623. return buf.toString();
  624. }
  625. protected String makeString(int i) {
  626. return Integer.toString(i, 16); //??? expensive
  627. }
  628. protected String makeString(TypeX t) {
  629. // this is the inverse of the odd behavior for Class.forName w/ arrays
  630. if (t.isArray()) {
  631. // this behavior matches the string used by the eclipse compiler for Foo.class literals
  632. return t.getSignature().replace('/', '.');
  633. } else {
  634. return t.getName();
  635. }
  636. }
  637. protected String makeString(TypeX[] types) {
  638. if (types == null) return "";
  639. StringBuffer buf = new StringBuffer();
  640. for (int i = 0, len=types.length; i < len; i++) {
  641. buf.append(makeString(types[i]));
  642. buf.append(':');
  643. }
  644. return buf.toString();
  645. }
  646. protected String makeString(String[] names) {
  647. if (names == null) return "";
  648. StringBuffer buf = new StringBuffer();
  649. for (int i = 0, len=names.length; i < len; i++) {
  650. buf.append(names[i]);
  651. buf.append(':');
  652. }
  653. return buf.toString();
  654. }
  655. public String[] getParameterNames(World world) {
  656. return world.getParameterNames(this);
  657. }
  658. // ----
  659. }