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.

ResolvedMemberImpl.java 39KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088
  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.io.DataOutputStream;
  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.HashMap;
  19. import java.util.HashSet;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.Set;
  24. import org.aspectj.bridge.ISourceLocation;
  25. /**
  26. * This is the declared member, i.e. it will always correspond to an
  27. * actual method/... declaration
  28. */
  29. public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, AnnotatedElement, TypeVariableDeclaringElement, ResolvedMember {
  30. // TESTAPI - controlling whether parameter names come out in the debug string (for testing purposes)
  31. public static boolean showParameterNames = true;
  32. private String[] parameterNames = null;
  33. protected UnresolvedType[] checkedExceptions = UnresolvedType.NONE; // OPTIMIZE unpack on demand
  34. // private boolean isAjSynthetic = false;
  35. protected int start, end;
  36. protected ISourceContext sourceContext = null;
  37. private int bits;
  38. private static final int HAS_BACKING_GENERIC_MEMBER = 0x0001;
  39. private static final int IS_ANNOTATED_ELSEWHERE = 0x0002;
  40. private static final int IS_ANNOTATED_ELSEWHERE_INV = 0x0ffd;
  41. private static final int HAVE_CALCULATED_MY_ERASURE = 0x0004;
  42. private static final int HAS_ERASURE = 0x0008;
  43. private static final int IS_AJ_SYNTHETIC = 0x0010;
  44. private static final int IS_AJ_SYNTHETIC_INV = 0x0fef;
  45. protected RMMetaInfo metaInfo;
  46. protected static class RMMetaInfo {
  47. public ResolvedMember backingGenericMember;
  48. public ResolvedMember myErasure;
  49. }
  50. /**
  51. * if this member is a parameterized version of a member in a generic type,
  52. * then this field holds a reference to the member we parameterize.
  53. */
  54. // protected ResolvedMember backingGenericMember = null;
  55. protected Set annotationTypes = null;
  56. protected ResolvedType[][] parameterAnnotationTypes = null;
  57. // Some members are 'created' to represent other things (for example ITDs). These
  58. // members have their annotations stored elsewhere, and this flag indicates that is
  59. // the case. It is up to the caller to work out where that is!
  60. // Once determined the caller may choose to stash the annotations in this member...
  61. // private boolean isAnnotatedElsewhere = false; // this field is not serialized.
  62. // generic methods have type variables
  63. protected TypeVariable[] typeVariables;
  64. /** converts e.g. <T extends Number>.... List<T> to just Ljava/util/List<T;>;
  65. * whereas the full signature would be Ljava/util/List<T:Ljava/lang/Number;>;
  66. */
  67. private String myParameterSignatureWithBoundsRemoved = null;
  68. /**
  69. * converts e.g. <T extends Number>.... List<T> to just Ljava/util/List;
  70. */
  71. private String myParameterSignatureErasure = null;
  72. // private ResolvedMember myErasure = null;
  73. // private boolean calculatedMyErasure = false;
  74. //XXX deprecate this in favor of the constructor below
  75. public ResolvedMemberImpl(
  76. MemberKind kind,
  77. UnresolvedType declaringType,
  78. int modifiers,
  79. UnresolvedType returnType,
  80. String name,
  81. UnresolvedType[] parameterTypes)
  82. {
  83. super(kind, declaringType, modifiers, returnType, name, parameterTypes);
  84. }
  85. public ResolvedMemberImpl(
  86. MemberKind kind,
  87. UnresolvedType declaringType,
  88. int modifiers,
  89. UnresolvedType returnType,
  90. String name,
  91. UnresolvedType[] parameterTypes,
  92. UnresolvedType[] checkedExceptions)
  93. {
  94. super(kind, declaringType, modifiers, returnType, name, parameterTypes);
  95. this.checkedExceptions = checkedExceptions;
  96. }
  97. public ResolvedMemberImpl(
  98. MemberKind kind,
  99. UnresolvedType declaringType,
  100. int modifiers,
  101. UnresolvedType returnType,
  102. String name,
  103. UnresolvedType[] parameterTypes,
  104. UnresolvedType[] checkedExceptions,
  105. ResolvedMember backingGenericMember)
  106. {
  107. this(kind, declaringType, modifiers, returnType, name, parameterTypes,checkedExceptions);
  108. metaInfo= new RMMetaInfo();
  109. bits|=HAS_BACKING_GENERIC_MEMBER;
  110. metaInfo.backingGenericMember = backingGenericMember;
  111. if (backingGenericMember.isAjSynthetic()) bits|=IS_AJ_SYNTHETIC;
  112. // this.isAjSynthetic = backingGenericMember.isAjSynthetic();
  113. }
  114. public ResolvedMemberImpl(
  115. MemberKind kind,
  116. UnresolvedType declaringType,
  117. int modifiers,
  118. String name,
  119. String signature)
  120. {
  121. super(kind, declaringType, modifiers, name, signature);
  122. }
  123. /**
  124. * Compute the full set of signatures for a member. This walks up the hierarchy
  125. * giving the ResolvedMember in each defining type in the hierarchy. A shadowMember
  126. * can be created with a target type (declaring type) that does not actually define
  127. * the member. This is ok as long as the member is inherited in the declaring type.
  128. * Each declaring type in the line to the actual declaring type is added as an additional
  129. * signature. For example:
  130. *
  131. * class A { void foo(); }
  132. * class B extends A {}
  133. *
  134. * shadowMember : void B.foo()
  135. *
  136. * gives { void B.foo(), void A.foo() }
  137. * @param joinPointSignature
  138. * @param inAWorld
  139. */
  140. public static JoinPointSignature[] getJoinPointSignatures(Member joinPointSignature, World inAWorld) {
  141. // Walk up hierarchy creating one member for each type up to and including the
  142. // first defining type
  143. ResolvedType originalDeclaringType = joinPointSignature.getDeclaringType().resolve(inAWorld);
  144. ResolvedMemberImpl firstDefiningMember = (ResolvedMemberImpl) joinPointSignature.resolve(inAWorld);
  145. if (firstDefiningMember == null) {
  146. return new JoinPointSignature[0];
  147. }
  148. // declaringType can be unresolved if we matched a synthetic member generated by Aj...
  149. // should be fixed elsewhere but add this resolve call on the end for now so that we can
  150. // focus on one problem at a time...
  151. ResolvedType firstDefiningType = firstDefiningMember.getDeclaringType().resolve(inAWorld);
  152. if (firstDefiningType != originalDeclaringType) {
  153. if (joinPointSignature.getKind() == Member.CONSTRUCTOR) {
  154. return new JoinPointSignature[0];
  155. }
  156. // else if (shadowMember.isStatic()) {
  157. // return new ResolvedMember[] {firstDefiningMember};
  158. // }
  159. }
  160. List declaringTypes = new ArrayList();
  161. accumulateTypesInBetween(originalDeclaringType,
  162. firstDefiningType,
  163. declaringTypes);
  164. Set memberSignatures = new HashSet();
  165. for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
  166. ResolvedType declaringType = (ResolvedType) iter.next();
  167. ResolvedMember member = firstDefiningMember.withSubstituteDeclaringType(declaringType);
  168. memberSignatures.add(member);
  169. }
  170. if (shouldWalkUpHierarchyFor(firstDefiningMember)) {
  171. // now walk up the hierarchy from the firstDefiningMember and include the signature for
  172. // every type between the firstDefiningMember and the root defining member.
  173. Iterator superTypeIterator = firstDefiningType.getDirectSupertypes();
  174. List typesAlreadyVisited = new ArrayList();
  175. accumulateMembersMatching(firstDefiningMember,superTypeIterator,typesAlreadyVisited,memberSignatures);
  176. }
  177. JoinPointSignature[] ret = new JoinPointSignature[memberSignatures.size()];
  178. memberSignatures.toArray(ret);
  179. return ret;
  180. }
  181. private static boolean shouldWalkUpHierarchyFor(Member aMember) {
  182. if (aMember.getKind() == Member.CONSTRUCTOR) return false;
  183. if (aMember.getKind() == Member.FIELD) return false;
  184. if (aMember.isStatic()) return false;
  185. return true;
  186. }
  187. /**
  188. * Build a list containing every type between subtype and supertype, inclusively.
  189. */
  190. private static void accumulateTypesInBetween(ResolvedType subType, ResolvedType superType, List types) {
  191. types.add(subType);
  192. if (subType == superType) {
  193. return;
  194. } else {
  195. for (Iterator iter = subType.getDirectSupertypes(); iter.hasNext();) {
  196. ResolvedType parent = (ResolvedType) iter.next();
  197. if (superType.isAssignableFrom(parent)) {
  198. accumulateTypesInBetween(parent, superType,types);
  199. }
  200. }
  201. }
  202. }
  203. /**
  204. * We have a resolved member, possibly with type parameter references as parameters or return
  205. * type. We need to find all its ancestor members. When doing this, a type parameter matches
  206. * regardless of bounds (bounds can be narrowed down the hierarchy).
  207. */
  208. private static void accumulateMembersMatching(
  209. ResolvedMemberImpl memberToMatch,
  210. Iterator typesToLookIn,
  211. List typesAlreadyVisited,
  212. Set foundMembers) {
  213. while(typesToLookIn.hasNext()) {
  214. ResolvedType toLookIn = (ResolvedType) typesToLookIn.next();
  215. if (!typesAlreadyVisited.contains(toLookIn)) {
  216. typesAlreadyVisited.add(toLookIn);
  217. ResolvedMemberImpl foundMember = (ResolvedMemberImpl) toLookIn.lookupResolvedMember(memberToMatch,true);
  218. if (foundMember != null && isVisibleTo(memberToMatch,foundMember)) {
  219. List declaringTypes = new ArrayList();
  220. // declaring type can be unresolved if the member can from an ITD...
  221. ResolvedType resolvedDeclaringType = foundMember.getDeclaringType().resolve(toLookIn.getWorld());
  222. accumulateTypesInBetween(toLookIn, resolvedDeclaringType, declaringTypes);
  223. for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
  224. ResolvedType declaringType = (ResolvedType) iter.next();
  225. // typesAlreadyVisited.add(declaringType);
  226. ResolvedMember member = foundMember.withSubstituteDeclaringType(declaringType);
  227. foundMembers.add(member);
  228. }
  229. if (toLookIn.isParameterizedType() && foundMember.hasBackingGenericMember()) {
  230. foundMembers.add(new JoinPointSignature(foundMember.getBackingGenericMember(),foundMember.declaringType.resolve(toLookIn.getWorld())));
  231. }
  232. accumulateMembersMatching(foundMember,toLookIn.getDirectSupertypes(),typesAlreadyVisited,foundMembers);
  233. // if this was a parameterized type, look in the generic type that backs it too
  234. }
  235. }
  236. }
  237. }
  238. /**
  239. * Returns true if the parent member is visible to the child member
  240. * In the same declaring type this is always true, otherwise if parent is private
  241. * it is false.
  242. * @param childMember
  243. * @param parentMember
  244. * @return
  245. */
  246. private static boolean isVisibleTo(ResolvedMember childMember, ResolvedMember parentMember) {
  247. if (childMember.getDeclaringType().equals(parentMember.getDeclaringType())) return true;
  248. if (Modifier.isPrivate(parentMember.getModifiers())) {
  249. return false;
  250. } else {
  251. return true;
  252. }
  253. }
  254. // ----
  255. public final int getModifiers(World world) {
  256. return modifiers;
  257. }
  258. public final int getModifiers() {
  259. return modifiers;
  260. }
  261. // ----
  262. public final UnresolvedType[] getExceptions(World world) {
  263. return getExceptions();
  264. }
  265. public UnresolvedType[] getExceptions() {
  266. return checkedExceptions;
  267. }
  268. public ShadowMunger getAssociatedShadowMunger() {
  269. return null;
  270. }
  271. // ??? true or false?
  272. public boolean isAjSynthetic() {
  273. return (bits&IS_AJ_SYNTHETIC)!=0;
  274. // return isAjSynthetic;
  275. }
  276. protected void setAjSynthetic(boolean b) {
  277. if (b) bits|=IS_AJ_SYNTHETIC;
  278. else bits&=IS_AJ_SYNTHETIC_INV;
  279. // isAjSynthetic= b;
  280. }
  281. public boolean hasAnnotations() {
  282. return (annotationTypes!=null);
  283. }
  284. public boolean hasAnnotation(UnresolvedType ofType) {
  285. // The ctors don't allow annotations to be specified ... yet - but
  286. // that doesn't mean it is an error to call this method.
  287. // Normally the weaver will be working with subtypes of
  288. // this type - BcelField/BcelMethod
  289. if (annotationTypes==null) return false;
  290. return annotationTypes.contains(ofType);
  291. }
  292. public ResolvedType[] getAnnotationTypes() {
  293. // The ctors don't allow annotations to be specified ... yet - but
  294. // that doesn't mean it is an error to call this method.
  295. // Normally the weaver will be working with subtypes of
  296. // this type - BcelField/BcelMethod
  297. if (annotationTypes == null) return null;
  298. return (ResolvedType[])annotationTypes.toArray(new ResolvedType[]{});
  299. }
  300. public AnnotationX getAnnotationOfType(UnresolvedType ofType) {
  301. throw new UnsupportedOperationException("You should resolve this member and call getAnnotationOfType() on the result...");
  302. }
  303. public AnnotationX[] getAnnotations() {
  304. if ((bits&HAS_BACKING_GENERIC_MEMBER)!=0 && metaInfo.backingGenericMember!=null) return metaInfo.backingGenericMember.getAnnotations();
  305. // if (backingGenericMember != null) return backingGenericMember.getAnnotations();
  306. // return super.getAnnotations();
  307. throw new IllegalStateException("Unable to answer getAnnotations() for "+this.toString());
  308. }
  309. public void setAnnotationTypes(UnresolvedType[] annotationtypes) {
  310. if (annotationTypes == null) annotationTypes = new HashSet();
  311. for (int i = 0; i < annotationtypes.length; i++) {
  312. UnresolvedType typeX = annotationtypes[i];
  313. annotationTypes.add(typeX);
  314. }
  315. }
  316. public ResolvedType[][] getParameterAnnotationTypes() {
  317. if (parameterAnnotationTypes == null) return null;
  318. return parameterAnnotationTypes;
  319. }
  320. public AnnotationX[][] getParameterAnnotations() {
  321. if (hasBackingGenericMember()) return getBackingGenericMember().getParameterAnnotations();
  322. throw new IllegalStateException("Only a resolvedmember with backing generic member can answer this. Member="+toString());
  323. }
  324. public void addAnnotation(AnnotationX annotation) {
  325. // FIXME asc only allows for annotation types, not instances - should it?
  326. if (annotationTypes == null) annotationTypes = new HashSet();
  327. annotationTypes.add(annotation.getSignature());
  328. }
  329. public boolean isBridgeMethod() {
  330. return (modifiers & Constants.ACC_BRIDGE)!=0 && getKind().equals(METHOD);
  331. }
  332. public boolean isVarargsMethod() {
  333. return (modifiers & Constants.ACC_VARARGS)!=0;
  334. }
  335. public void setVarargsMethod() {
  336. modifiers = modifiers | Constants.ACC_VARARGS;
  337. }
  338. public boolean isSynthetic() {
  339. // See Bcelmethod.isSynthetic() which takes account of preJava5 Synthetic modifier
  340. return (modifiers & 4096)!=0; // do we know better?
  341. }
  342. public void write(DataOutputStream s) throws IOException {
  343. getKind().write(s);
  344. getDeclaringType().write(s);
  345. s.writeInt(modifiers);
  346. s.writeUTF(getName());
  347. s.writeUTF(getSignature());
  348. UnresolvedType.writeArray(getExceptions(), s);
  349. s.writeInt(getStart());
  350. s.writeInt(getEnd());
  351. s.writeBoolean(isVarargsMethod());
  352. // Write out any type variables...
  353. if (typeVariables==null) {
  354. s.writeInt(0);
  355. } else {
  356. s.writeInt(typeVariables.length);
  357. for (int i = 0; i < typeVariables.length; i++) {
  358. typeVariables[i].write(s);
  359. }
  360. }
  361. String gsig = getGenericSignature();
  362. if (getSignature().equals(gsig)) {
  363. s.writeBoolean(false);
  364. } else {
  365. s.writeBoolean(true);
  366. s.writeInt(parameterTypes.length);
  367. for (int i = 0; i < parameterTypes.length; i++) {
  368. UnresolvedType array_element = parameterTypes[i];
  369. array_element.write(s);
  370. }
  371. returnType.write(s);
  372. }
  373. }
  374. public String getGenericSignature() {
  375. StringBuffer sb = new StringBuffer();
  376. if (typeVariables!=null) {
  377. sb.append("<");
  378. for (int i = 0; i < typeVariables.length; i++) {
  379. sb.append(typeVariables[i].getSignature());
  380. }
  381. sb.append(">");
  382. }
  383. sb.append("(");
  384. for (int i = 0; i < parameterTypes.length; i++) {
  385. UnresolvedType array_element = parameterTypes[i];
  386. sb.append(array_element.getSignature());
  387. }
  388. sb.append(")");
  389. sb.append(returnType.getSignature());
  390. return sb.toString();
  391. }
  392. public static void writeArray(ResolvedMember[] members, DataOutputStream s) throws IOException {
  393. s.writeInt(members.length);
  394. for (int i = 0, len = members.length; i < len; i++) {
  395. members[i].write(s);
  396. }
  397. }
  398. public static ResolvedMemberImpl readResolvedMember(VersionedDataInputStream s, ISourceContext sourceContext) throws IOException {
  399. ResolvedMemberImpl m = new ResolvedMemberImpl(MemberKind.read(s), UnresolvedType.read(s), s.readInt(),
  400. s.readUTF(), s.readUTF());
  401. m.checkedExceptions = UnresolvedType.readArray(s);
  402. m.start = s.readInt();
  403. m.end = s.readInt();
  404. m.sourceContext = sourceContext;
  405. if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
  406. if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150M4) {
  407. boolean isvarargs = s.readBoolean();
  408. if (isvarargs) m.setVarargsMethod();
  409. }
  410. int tvcount = s.readInt();
  411. if (tvcount!=0) {
  412. m.typeVariables = new TypeVariable[tvcount];
  413. for (int i=0;i<tvcount;i++) {
  414. m.typeVariables[i]=TypeVariable.read(s);
  415. m.typeVariables[i].setDeclaringElement(m);
  416. }
  417. }
  418. if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150M4) {
  419. boolean hasAGenericSignature = s.readBoolean();
  420. if (hasAGenericSignature) {
  421. int ps = s.readInt();
  422. UnresolvedType[] params = new UnresolvedType[ps];
  423. for (int i = 0; i < params.length; i++) {
  424. UnresolvedType type = params[i];
  425. params[i]=TypeFactory.createTypeFromSignature(s.readUTF());
  426. }
  427. UnresolvedType rt = TypeFactory.createTypeFromSignature(s.readUTF());
  428. m.parameterTypes = params;
  429. m.returnType = rt;
  430. }
  431. }
  432. }
  433. return m;
  434. }
  435. public static ResolvedMember[] readResolvedMemberArray(VersionedDataInputStream s, ISourceContext context) throws IOException {
  436. int len = s.readInt();
  437. ResolvedMember[] members = new ResolvedMember[len];
  438. for (int i=0; i < len; i++) {
  439. members[i] = ResolvedMemberImpl.readResolvedMember(s, context);
  440. }
  441. return members;
  442. }
  443. public ResolvedMember resolve(World world) {
  444. // make sure all the pieces of a resolvedmember really are resolved
  445. try {
  446. if (typeVariables!=null && typeVariables.length>0) {
  447. for (int i = 0; i < typeVariables.length; i++) {
  448. typeVariables[i] = typeVariables[i].resolve(world);
  449. }
  450. }
  451. world.setTypeVariableLookupScope(this);
  452. if (annotationTypes!=null) {
  453. Set r = new HashSet();
  454. for (Iterator iter = annotationTypes.iterator(); iter.hasNext();) {
  455. UnresolvedType element = (UnresolvedType) iter.next();
  456. r.add(world.resolve(element));
  457. }
  458. annotationTypes = r;
  459. }
  460. declaringType = declaringType.resolve(world);
  461. if (declaringType.isRawType()) declaringType = ((ReferenceType)declaringType).getGenericType();
  462. if (parameterTypes!=null && parameterTypes.length>0) {
  463. for (int i = 0; i < parameterTypes.length; i++) {
  464. parameterTypes[i] = parameterTypes[i].resolve(world);
  465. }
  466. }
  467. returnType = returnType.resolve(world);
  468. } finally {
  469. world.setTypeVariableLookupScope(null);
  470. }
  471. return this;
  472. }
  473. public ISourceContext getSourceContext(World world) {
  474. return getDeclaringType().resolve(world).getSourceContext();
  475. }
  476. public String[] getParameterNames() {
  477. return parameterNames;
  478. }
  479. public final void setParameterNames(String[] pnames) {
  480. parameterNames = pnames;
  481. }
  482. public final String[] getParameterNames(World world) {
  483. return getParameterNames();
  484. }
  485. public AjAttribute.EffectiveSignatureAttribute getEffectiveSignature() {
  486. return null;
  487. }
  488. public ISourceLocation getSourceLocation() {
  489. //System.out.println("get context: " + this + " is " + sourceContext);
  490. if (getSourceContext() == null) {
  491. //System.err.println("no context: " + this);
  492. return null;
  493. }
  494. return getSourceContext().makeSourceLocation(this);
  495. }
  496. public int getEnd() {
  497. return end;
  498. }
  499. public ISourceContext getSourceContext() {
  500. return sourceContext;
  501. }
  502. public int getStart() {
  503. return start;
  504. }
  505. public void setPosition(int sourceStart, int sourceEnd) {
  506. this.start = sourceStart;
  507. this.end = sourceEnd;
  508. }
  509. public void setDeclaringType(ReferenceType rt) {
  510. declaringType = rt;
  511. }
  512. public void setSourceContext(ISourceContext sourceContext) {
  513. this.sourceContext = sourceContext;
  514. }
  515. public boolean isAbstract() {
  516. return Modifier.isAbstract(modifiers);
  517. }
  518. public boolean isPublic() {
  519. return Modifier.isPublic(modifiers);
  520. }
  521. public boolean isProtected() {
  522. return Modifier.isProtected(modifiers);
  523. }
  524. public boolean isNative() {
  525. return Modifier.isNative(modifiers);
  526. }
  527. public boolean isDefault() {
  528. return !(isPublic() || isProtected() || isPrivate());
  529. }
  530. public boolean isVisible(ResolvedType fromType) {
  531. World world = fromType.getWorld();
  532. return ResolvedType.isVisible(getModifiers(), getDeclaringType().resolve(world),
  533. fromType);
  534. }
  535. public void setCheckedExceptions(UnresolvedType[] checkedExceptions) {
  536. this.checkedExceptions = checkedExceptions;
  537. }
  538. public void setAnnotatedElsewhere(boolean b) {
  539. if (b) bits|=IS_ANNOTATED_ELSEWHERE;
  540. else bits&=IS_ANNOTATED_ELSEWHERE_INV;
  541. // isAnnotatedElsewhere = b;
  542. }
  543. public boolean isAnnotatedElsewhere() {
  544. return (bits&IS_ANNOTATED_ELSEWHERE)!=0;
  545. // return isAnnotatedElsewhere;
  546. }
  547. /**
  548. * Get the UnresolvedType for the return type, taking generic signature into account
  549. */
  550. public UnresolvedType getGenericReturnType() {
  551. return getReturnType();
  552. }
  553. /**
  554. * Get the TypeXs of the parameter types, taking generic signature into account
  555. */
  556. public UnresolvedType[] getGenericParameterTypes() {
  557. return getParameterTypes();
  558. }
  559. public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters,ResolvedType newDeclaringType, boolean isParameterized) {
  560. return parameterizedWith(typeParameters,newDeclaringType,isParameterized,null);
  561. }
  562. /**
  563. * Return a resolvedmember in which all the type variables in the signature
  564. * have been replaced with the given bindings.
  565. * The 'isParameterized' flag tells us whether we are creating a raw type
  566. * version or not. if (isParameterized) then List<T> will turn into
  567. * List<String> (for example) - if (!isParameterized) then List<T> will turn
  568. * into List.
  569. */
  570. public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters,ResolvedType newDeclaringType, boolean isParameterized,List aliases) {
  571. if (//isParameterized && <-- might need this bit...
  572. !getDeclaringType().isGenericType()) {
  573. throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: "+getDeclaringType()+" kind("+getDeclaringType().typeKind+")");
  574. }
  575. TypeVariable[] typeVariables = getDeclaringType().getTypeVariables();
  576. if (isParameterized && (typeVariables.length != typeParameters.length)) {
  577. throw new IllegalStateException("Wrong number of type parameters supplied");
  578. }
  579. Map typeMap = new HashMap();
  580. boolean typeParametersSupplied = typeParameters!=null && typeParameters.length>0;
  581. if (typeVariables!=null) {
  582. // If no 'replacements' were supplied in the typeParameters array then collapse
  583. // type variables to their first bound.
  584. for (int i = 0; i < typeVariables.length; i++) {
  585. UnresolvedType ut = (!typeParametersSupplied?typeVariables[i].getFirstBound():typeParameters[i]);
  586. typeMap.put(typeVariables[i].getName(),ut);
  587. }
  588. }
  589. // For ITDs on generic types that use type variables from the target type, the aliases
  590. // record the alternative names used throughout the ITD expression that must map to
  591. // the same value as the type variables real name.
  592. if (aliases!=null) {
  593. int posn = 0;
  594. for (Iterator iter = aliases.iterator(); iter.hasNext();) {
  595. String typeVariableAlias = (String) iter.next();
  596. typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[posn].getFirstBound():typeParameters[posn]));
  597. posn++;
  598. }
  599. }
  600. UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),typeMap,isParameterized);
  601. UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length];
  602. UnresolvedType[] genericParameterTypes = getGenericParameterTypes();
  603. for (int i = 0; i < parameterizedParameterTypes.length; i++) {
  604. parameterizedParameterTypes[i] =
  605. parameterize(genericParameterTypes[i], typeMap,isParameterized);
  606. }
  607. ResolvedMemberImpl ret = new ResolvedMemberImpl(
  608. getKind(),
  609. newDeclaringType,
  610. getModifiers(),
  611. parameterizedReturnType,
  612. getName(),
  613. parameterizedParameterTypes,
  614. getExceptions(),
  615. this
  616. );
  617. ret.setTypeVariables(getTypeVariables());
  618. ret.setSourceContext(getSourceContext());
  619. ret.setPosition(getStart(),getEnd());
  620. ret.setParameterNames(getParameterNames());
  621. return ret;
  622. }
  623. /**
  624. * Replace occurrences of type variables in the signature with values contained in the map. The map is of the form A=String,B=Integer and
  625. * so a signature List<A> Foo.m(B i) {} would become List<String> Foo.m(Integer i) {}
  626. */
  627. public ResolvedMember parameterizedWith(Map m, World w) {
  628. // if (//isParameterized && <-- might need this bit...
  629. // !getDeclaringType().isGenericType()) {
  630. // throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: "+getDeclaringType()+" kind("+getDeclaringType().typeKind+")");
  631. // }
  632. declaringType = declaringType.resolve(w);
  633. if (declaringType.isRawType()) declaringType = ((ResolvedType)declaringType).getGenericType();
  634. TypeVariable[] typeVariables = getDeclaringType().getTypeVariables();
  635. // if (isParameterized && (typeVariables.length != typeParameters.length)) {
  636. // throw new IllegalStateException("Wrong number of type parameters supplied");
  637. // }
  638. // Map typeMap = new HashMap();
  639. // boolean typeParametersSupplied = typeParameters!=null && typeParameters.length>0;
  640. // if (typeVariables!=null) {
  641. // // If no 'replacements' were supplied in the typeParameters array then collapse
  642. // // type variables to their first bound.
  643. // for (int i = 0; i < typeVariables.length; i++) {
  644. // UnresolvedType ut = (!typeParametersSupplied?typeVariables[i].getFirstBound():typeParameters[i]);
  645. // typeMap.put(typeVariables[i].getName(),ut);
  646. // }
  647. // }
  648. // // For ITDs on generic types that use type variables from the target type, the aliases
  649. // // record the alternative names used throughout the ITD expression that must map to
  650. // // the same value as the type variables real name.
  651. // if (aliases!=null) {
  652. // int posn = 0;
  653. // for (Iterator iter = aliases.iterator(); iter.hasNext();) {
  654. // String typeVariableAlias = (String) iter.next();
  655. // typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[posn].getFirstBound():typeParameters[posn]));
  656. // posn++;
  657. // }
  658. // }
  659. UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),m,true,w);
  660. UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length];
  661. UnresolvedType[] genericParameterTypes = getGenericParameterTypes();
  662. for (int i = 0; i < parameterizedParameterTypes.length; i++) {
  663. parameterizedParameterTypes[i] =
  664. parameterize(genericParameterTypes[i], m,true,w);
  665. }
  666. ResolvedMemberImpl ret = new ResolvedMemberImpl(
  667. getKind(),
  668. declaringType,
  669. getModifiers(),
  670. parameterizedReturnType,
  671. getName(),
  672. parameterizedParameterTypes,
  673. getExceptions(),
  674. this
  675. );
  676. ret.setTypeVariables(getTypeVariables());
  677. ret.setSourceContext(getSourceContext());
  678. ret.setPosition(getStart(),getEnd());
  679. ret.setParameterNames(getParameterNames());
  680. return ret;
  681. }
  682. public void setTypeVariables(TypeVariable[] tvars) {
  683. typeVariables = tvars;
  684. }
  685. public TypeVariable[] getTypeVariables() {
  686. return typeVariables;
  687. }
  688. protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) {
  689. return parameterize(aType,typeVariableMap,inParameterizedType,null);
  690. }
  691. protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType,World w) {
  692. if (aType instanceof TypeVariableReference) {
  693. String variableName = ((TypeVariableReference)aType).getTypeVariable().getName();
  694. if (!typeVariableMap.containsKey(variableName)) {
  695. return aType; // if the type variable comes from the method (and not the type) thats OK
  696. }
  697. return (UnresolvedType) typeVariableMap.get(variableName);
  698. } else if (aType.isParameterizedType()) {
  699. if (inParameterizedType) {
  700. // if (!(getDeclaringType() instanceof ResolvedType)) {
  701. // int stop = 1;
  702. // }
  703. if (aType instanceof UnresolvedType) {
  704. if (w!=null) aType = aType.resolve(w);
  705. else {
  706. aType= aType.resolve(((ResolvedType)getDeclaringType()).getWorld());
  707. }
  708. }
  709. return aType.parameterize(typeVariableMap);
  710. } else {
  711. return aType.getRawType();
  712. }
  713. } else if (aType.isArray()) {
  714. // The component type might be a type variable (pr150095)
  715. int dims = 1;
  716. String sig = aType.getSignature();
  717. while (sig.charAt(dims)=='[') dims++;
  718. UnresolvedType componentSig = UnresolvedType.forSignature(sig.substring(dims));
  719. UnresolvedType arrayType = ResolvedType.makeArray(parameterize(componentSig,typeVariableMap,inParameterizedType),dims);
  720. return arrayType;
  721. }
  722. return aType;
  723. }
  724. /**
  725. * If this member is defined by a parameterized super-type, return the erasure
  726. * of that member.
  727. * For example:
  728. * interface I<T> { T foo(T aTea); }
  729. * class C implements I<String> {
  730. * String foo(String aString) { return "something"; }
  731. * }
  732. * The resolved member for C.foo has signature String foo(String). The
  733. * erasure of that member is Object foo(Object) -- use upper bound of type
  734. * variable.
  735. * A type is a supertype of itself.
  736. */
  737. public ResolvedMember getErasure() {
  738. if ((bits&HAVE_CALCULATED_MY_ERASURE)!=0) {
  739. if ((bits&HAS_ERASURE)!=0) return metaInfo.myErasure;
  740. return null;
  741. // return myErasure;
  742. }
  743. bits|=HAVE_CALCULATED_MY_ERASURE;
  744. // if (calculatedMyErasure) return myErasure;
  745. // calculatedMyErasure = true;
  746. ResolvedType resolvedDeclaringType = (ResolvedType) getDeclaringType();
  747. // this next test is fast, and the result is cached.
  748. if (!resolvedDeclaringType.hasParameterizedSuperType()) {
  749. return null;
  750. } else {
  751. // we have one or more parameterized super types.
  752. // this member may be defined by one of them... we need to find out.
  753. Collection declaringTypes = this.getDeclaringTypes(resolvedDeclaringType.getWorld());
  754. for (Iterator iter = declaringTypes.iterator(); iter.hasNext();) {
  755. ResolvedType aDeclaringType = (ResolvedType) iter.next();
  756. if (aDeclaringType.isParameterizedType()) {
  757. // we've found the (a?) parameterized type that defines this member.
  758. // now get the erasure of it
  759. ResolvedMemberImpl matchingMember = (ResolvedMemberImpl) aDeclaringType.lookupMemberNoSupers(this);
  760. if (matchingMember != null && matchingMember.hasBackingGenericMember()) {
  761. ResolvedMember myErasure = matchingMember.getBackingGenericMember();
  762. if (myErasure!=null) {
  763. bits|=HAS_ERASURE;
  764. if (metaInfo == null) metaInfo = new RMMetaInfo();
  765. metaInfo.myErasure = myErasure;
  766. }
  767. return myErasure;
  768. }
  769. }
  770. }
  771. }
  772. return null;
  773. }
  774. public boolean hasBackingGenericMember() {
  775. if ((bits&HAS_BACKING_GENERIC_MEMBER)==0) return false;
  776. return metaInfo.backingGenericMember!=null;
  777. }
  778. public ResolvedMember getBackingGenericMember() {
  779. if ((bits&HAS_BACKING_GENERIC_MEMBER)==0) return null;
  780. return metaInfo.backingGenericMember;
  781. }
  782. /**
  783. * For ITDs, we use the default factory methods to build a resolved member, then alter a couple of characteristics
  784. * using this method - this is safe.
  785. */
  786. public void resetName(String newName) {this.name = newName;}
  787. public void resetKind(MemberKind newKind) {this.kind=newKind; }
  788. public void resetModifiers(int newModifiers) {this.modifiers=newModifiers;}
  789. public void resetReturnTypeToObjectArray() {
  790. returnType = UnresolvedType.OBJECTARRAY;
  791. }
  792. /**
  793. * Returns a copy of this member but with the declaring type swapped.
  794. * Copy only needs to be shallow.
  795. * @param newDeclaringType
  796. */
  797. public JoinPointSignature withSubstituteDeclaringType(ResolvedType newDeclaringType) {
  798. JoinPointSignature ret = new JoinPointSignature(this,newDeclaringType);
  799. return ret;
  800. }
  801. /**
  802. * Returns true if this member matches the other. The matching takes into account
  803. * name and parameter types only. When comparing parameter types, we allow any type
  804. * variable to match any other type variable regardless of bounds.
  805. */
  806. public boolean matches(ResolvedMember aCandidateMatch) {
  807. ResolvedMemberImpl candidateMatchImpl = (ResolvedMemberImpl)aCandidateMatch;
  808. if (!getName().equals(aCandidateMatch.getName())) return false;
  809. UnresolvedType[] myParameterTypes = getGenericParameterTypes();
  810. UnresolvedType[] candidateParameterTypes = aCandidateMatch.getGenericParameterTypes();
  811. if (myParameterTypes.length != candidateParameterTypes.length) return false;
  812. String myParameterSignature = getParameterSigWithBoundsRemoved();
  813. String candidateParameterSignature = candidateMatchImpl.getParameterSigWithBoundsRemoved();
  814. if (myParameterSignature.equals(candidateParameterSignature)) {
  815. return true;
  816. } else {
  817. // try erasure
  818. myParameterSignature = getParameterSigErasure();
  819. candidateParameterSignature = candidateMatchImpl.getParameterSigErasure();
  820. return myParameterSignature.equals(candidateParameterSignature);
  821. }
  822. }
  823. // does NOT produce a meaningful java signature, but does give a unique string suitable for
  824. // comparison.
  825. private String getParameterSigWithBoundsRemoved() {
  826. if (myParameterSignatureWithBoundsRemoved != null) return myParameterSignatureWithBoundsRemoved;
  827. StringBuffer sig = new StringBuffer();
  828. UnresolvedType[] myParameterTypes = getGenericParameterTypes();
  829. for (int i = 0; i < myParameterTypes.length; i++) {
  830. appendSigWithTypeVarBoundsRemoved(myParameterTypes[i], sig, new HashSet());
  831. }
  832. myParameterSignatureWithBoundsRemoved = sig.toString();
  833. return myParameterSignatureWithBoundsRemoved;
  834. }
  835. private String getParameterSigErasure() {
  836. if (myParameterSignatureErasure != null) return myParameterSignatureErasure;
  837. StringBuffer sig = new StringBuffer();
  838. UnresolvedType[] myParameterTypes = getParameterTypes();
  839. for (int i = 0; i < myParameterTypes.length; i++) {
  840. UnresolvedType thisParameter = myParameterTypes[i];
  841. if (thisParameter.isTypeVariableReference()) {
  842. sig.append(thisParameter.getUpperBound().getSignature());
  843. } else {
  844. sig.append(thisParameter.getSignature());
  845. }
  846. }
  847. myParameterSignatureErasure = sig.toString();
  848. return myParameterSignatureErasure;
  849. }
  850. // does NOT produce a meaningful java signature, but does give a unique string suitable for
  851. // comparison.
  852. public static void appendSigWithTypeVarBoundsRemoved(UnresolvedType aType, StringBuffer toBuffer, Set alreadyUsedTypeVars) {
  853. if (aType.isTypeVariableReference()) {
  854. // pr204505
  855. if (alreadyUsedTypeVars.contains(aType)) {
  856. toBuffer.append("...");
  857. } else {
  858. alreadyUsedTypeVars.add(aType);
  859. appendSigWithTypeVarBoundsRemoved(aType.getUpperBound(), toBuffer, alreadyUsedTypeVars);
  860. }
  861. // toBuffer.append("T;");
  862. } else if (aType.isParameterizedType()) {
  863. toBuffer.append(aType.getRawType().getSignature());
  864. toBuffer.append("<");
  865. for (int i = 0; i < aType.getTypeParameters().length; i++) {
  866. appendSigWithTypeVarBoundsRemoved(aType.getTypeParameters()[i], toBuffer, alreadyUsedTypeVars);
  867. }
  868. toBuffer.append(">;");
  869. } else {
  870. toBuffer.append(aType.getSignature());
  871. }
  872. }
  873. /**
  874. * Useful for writing tests, returns *everything* we know about this member.
  875. */
  876. public String toDebugString() {
  877. StringBuffer r = new StringBuffer();
  878. // modifiers
  879. int mods = modifiers;
  880. if ((mods & 4096)>0) mods = mods -4096; // remove synthetic (added in the ASM case but not in the BCEL case...)
  881. if ((mods & 512)>0) mods = mods -512; // remove interface (added in the BCEL case but not in the ASM case...)
  882. if ((mods & 131072)>0) mods = mods -131072; // remove deprecated (added in the ASM case but not in the BCEL case...)
  883. String modsStr = Modifier.toString(mods);
  884. if (modsStr.length()!=0) r.append(modsStr).append("("+mods+")").append(" ");
  885. // type variables
  886. if (typeVariables!=null && typeVariables.length>0) {
  887. r.append("<");
  888. for (int i = 0; i < typeVariables.length; i++) {
  889. if (i>0) r.append(",");
  890. TypeVariable t = typeVariables[i];
  891. r.append(t.toDebugString());
  892. }
  893. r.append("> ");
  894. }
  895. // 'declaring' type
  896. r.append(getGenericReturnType().toDebugString());
  897. r.append(' ');
  898. // name
  899. r.append(declaringType.getName());
  900. r.append('.');
  901. r.append(name);
  902. // parameter signature if a method
  903. if (kind != FIELD) {
  904. r.append("(");
  905. UnresolvedType[] params = getGenericParameterTypes();
  906. boolean parameterNamesExist = showParameterNames && parameterNames!=null && parameterNames.length==params.length;
  907. if (params.length != 0) {
  908. for (int i=0, len = params.length; i < len; i++) {
  909. if (i>0) r.append(", ");
  910. r.append(params[i].toDebugString());
  911. if (parameterNamesExist) r.append(" ").append(parameterNames[i]);
  912. }
  913. }
  914. r.append(")");
  915. }
  916. return r.toString();
  917. }
  918. public String toGenericString() {
  919. StringBuffer buf = new StringBuffer();
  920. buf.append(getGenericReturnType().getSimpleName());
  921. buf.append(' ');
  922. buf.append(declaringType.getName());
  923. buf.append('.');
  924. buf.append(name);
  925. if (kind != FIELD) {
  926. buf.append("(");
  927. UnresolvedType[] params = getGenericParameterTypes();
  928. if (params.length != 0) {
  929. buf.append(params[0].getSimpleName());
  930. for (int i=1, len = params.length; i < len; i++) {
  931. buf.append(", ");
  932. buf.append(params[i].getSimpleName());
  933. }
  934. }
  935. buf.append(")");
  936. }
  937. return buf.toString();
  938. }
  939. public TypeVariable getTypeVariableNamed(String name) {
  940. // Check locally...
  941. if (typeVariables!=null) {
  942. for (int i = 0; i < typeVariables.length; i++) {
  943. if (typeVariables[i].getName().equals(name)) return typeVariables[i];
  944. }
  945. }
  946. // check the declaring type!
  947. return declaringType.getTypeVariableNamed(name);
  948. // Do generic aspects with ITDs that share type variables with the aspect and the target type and have their own tvars cause this to be messier?
  949. }
  950. public void evictWeavingState() { }
  951. public String getAnnotationDefaultValue() {
  952. throw new UnsupportedOperationException("You should resolve this member and call getAnnotationDefaultValue() on the result...");
  953. }
  954. }