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.

ResolvedType.java 78KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121
  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. * Alexandre Vasseur @AspectJ ITDs
  12. * ******************************************************************/
  13. package org.aspectj.weaver;
  14. import java.lang.reflect.Modifier;
  15. import java.util.ArrayList;
  16. import java.util.Arrays;
  17. import java.util.Collection;
  18. import java.util.Collections;
  19. import java.util.HashMap;
  20. import java.util.HashSet;
  21. import java.util.Iterator;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.Set;
  25. import org.aspectj.bridge.IMessage;
  26. import org.aspectj.bridge.ISourceLocation;
  27. import org.aspectj.bridge.Message;
  28. import org.aspectj.bridge.MessageUtil;
  29. import org.aspectj.util.FuzzyBoolean;
  30. import org.aspectj.weaver.patterns.Declare;
  31. import org.aspectj.weaver.patterns.PerClause;
  32. public abstract class ResolvedType extends UnresolvedType implements AnnotatedElement {
  33. public static final ResolvedType[] EMPTY_RESOLVED_TYPE_ARRAY = new ResolvedType[0];
  34. public static final String PARAMETERIZED_TYPE_IDENTIFIER = "P";
  35. private ResolvedType[] resolvedTypeParams;
  36. private String binaryPath;
  37. protected World world;
  38. protected ResolvedType(String signature, World world) {
  39. super(signature);
  40. this.world = world;
  41. }
  42. protected ResolvedType(String signature, String signatureErasure, World world) {
  43. super(signature,signatureErasure);
  44. this.world = world;
  45. }
  46. // ---- things that don't require a world
  47. /**
  48. * Returns an iterator through ResolvedType objects representing all the direct
  49. * supertypes of this type. That is, through the superclass, if any, and
  50. * all declared interfaces.
  51. */
  52. public final Iterator getDirectSupertypes() {
  53. Iterator ifacesIterator = Iterators.array(getDeclaredInterfaces());
  54. ResolvedType superclass = getSuperclass();
  55. if (superclass == null) {
  56. return ifacesIterator;
  57. } else {
  58. return Iterators.snoc(ifacesIterator, superclass);
  59. }
  60. }
  61. public abstract ResolvedMember[] getDeclaredFields();
  62. public abstract ResolvedMember[] getDeclaredMethods();
  63. public abstract ResolvedType[] getDeclaredInterfaces();
  64. public abstract ResolvedMember[] getDeclaredPointcuts();
  65. /**
  66. * Returns a ResolvedType object representing the superclass of this type, or null.
  67. * If this represents a java.lang.Object, a primitive type, or void, this
  68. * method returns null.
  69. */
  70. public abstract ResolvedType getSuperclass();
  71. /**
  72. * Returns the modifiers for this type.
  73. * <p/>
  74. * See {@link Class#getModifiers()} for a description
  75. * of the weirdness of this methods on primitives and arrays.
  76. *
  77. * @param world the {@link World} in which the lookup is made.
  78. * @return an int representing the modifiers for this type
  79. * @see java.lang.reflect.Modifier
  80. */
  81. public abstract int getModifiers();
  82. // return true if this resolved type couldn't be found (but we know it's name maybe)
  83. public boolean isMissing() {
  84. return false;
  85. }
  86. // FIXME asc I wonder if in some circumstances MissingWithKnownSignature should not be considered
  87. // 'really' missing as some code can continue based solely on the signature
  88. public static boolean isMissing (UnresolvedType unresolved) {
  89. if (unresolved instanceof ResolvedType) {
  90. ResolvedType resolved = (ResolvedType)unresolved;
  91. return resolved.isMissing();
  92. }
  93. else return (unresolved == MISSING);
  94. }
  95. public ResolvedType[] getAnnotationTypes() {
  96. return EMPTY_RESOLVED_TYPE_ARRAY;
  97. }
  98. public final UnresolvedType getSuperclass(World world) {
  99. return getSuperclass();
  100. }
  101. // This set contains pairs of types whose signatures are concatenated
  102. // together, this means with a fast lookup we can tell if two types
  103. // are equivalent.
  104. static Set validBoxing = new HashSet();
  105. static {
  106. validBoxing.add("Ljava/lang/Byte;B");
  107. validBoxing.add("Ljava/lang/Character;C");
  108. validBoxing.add("Ljava/lang/Double;D");
  109. validBoxing.add("Ljava/lang/Float;F");
  110. validBoxing.add("Ljava/lang/Integer;I");
  111. validBoxing.add("Ljava/lang/Long;J");
  112. validBoxing.add("Ljava/lang/Short;S");
  113. validBoxing.add("Ljava/lang/Boolean;Z");
  114. validBoxing.add("BLjava/lang/Byte;");
  115. validBoxing.add("CLjava/lang/Character;");
  116. validBoxing.add("DLjava/lang/Double;");
  117. validBoxing.add("FLjava/lang/Float;");
  118. validBoxing.add("ILjava/lang/Integer;");
  119. validBoxing.add("JLjava/lang/Long;");
  120. validBoxing.add("SLjava/lang/Short;");
  121. validBoxing.add("ZLjava/lang/Boolean;");
  122. }
  123. // utilities
  124. public ResolvedType getResolvedComponentType() {
  125. return null;
  126. }
  127. public World getWorld() {
  128. return world;
  129. }
  130. // ---- things from object
  131. public final boolean equals(Object other) {
  132. if (other instanceof ResolvedType) {
  133. return this == other;
  134. } else {
  135. return super.equals(other);
  136. }
  137. }
  138. // ---- difficult things
  139. /**
  140. * returns an iterator through all of the fields of this type, in order
  141. * for checking from JVM spec 2ed 5.4.3.2. This means that the order is
  142. * <p/>
  143. * <ul><li> fields from current class </li>
  144. * <li> recur into direct superinterfaces </li>
  145. * <li> recur into superclass </li>
  146. * </ul>
  147. * <p/>
  148. * We keep a hashSet of interfaces that we've visited so we don't spiral
  149. * out into 2^n land.
  150. */
  151. public Iterator getFields() {
  152. final Iterators.Filter dupFilter = Iterators.dupFilter();
  153. Iterators.Getter typeGetter = new Iterators.Getter() {
  154. public Iterator get(Object o) {
  155. return
  156. dupFilter.filter(
  157. ((ResolvedType)o).getDirectSupertypes());
  158. }
  159. };
  160. Iterators.Getter fieldGetter = new Iterators.Getter() {
  161. public Iterator get(Object o) {
  162. return Iterators.array(((ResolvedType)o).getDeclaredFields());
  163. }
  164. };
  165. return
  166. Iterators.mapOver(
  167. Iterators.recur(this, typeGetter),
  168. fieldGetter);
  169. }
  170. /**
  171. * returns an iterator through all of the methods of this type, in order
  172. * for checking from JVM spec 2ed 5.4.3.3. This means that the order is
  173. * <p/>
  174. * <ul><li> methods from current class </li>
  175. * <li> recur into superclass, all the way up, not touching interfaces </li>
  176. * <li> recur into all superinterfaces, in some unspecified order </li>
  177. * </ul>
  178. * <p/>
  179. * We keep a hashSet of interfaces that we've visited so we don't spiral
  180. * out into 2^n land.
  181. * NOTE: Take a look at the javadoc on getMethodsWithoutIterator() to see if
  182. * you are sensitive to a quirk in getMethods()
  183. */
  184. public Iterator getMethods() {
  185. final Iterators.Filter dupFilter = Iterators.dupFilter();
  186. Iterators.Getter ifaceGetter = new Iterators.Getter() {
  187. public Iterator get(Object o) {
  188. return
  189. dupFilter.filter(
  190. Iterators.array(((ResolvedType)o).getDeclaredInterfaces())
  191. );
  192. }
  193. };
  194. Iterators.Getter methodGetter = new Iterators.Getter() {
  195. public Iterator get(Object o) {
  196. return Iterators.array(((ResolvedType)o).getDeclaredMethods());
  197. }
  198. };
  199. return
  200. Iterators.mapOver(
  201. Iterators.append(
  202. new Iterator() {
  203. ResolvedType curr = ResolvedType.this;
  204. public boolean hasNext() {
  205. return curr != null;
  206. }
  207. public Object next() {
  208. ResolvedType ret = curr;
  209. curr = curr.getSuperclass();
  210. return ret;
  211. }
  212. public void remove() {
  213. throw new UnsupportedOperationException();
  214. }
  215. },
  216. Iterators.recur(this, ifaceGetter)),
  217. methodGetter);
  218. }
  219. /**
  220. * Return a list of methods, first those declared on this class, then those declared on the superclass (recurse) and then those declared
  221. * on the superinterfaces. The getMethods() call above doesn't quite work the same as it will (through the iterator) return methods
  222. * declared on *this* class twice, once at the start and once at the end - I couldn't debug that problem, so created this alternative.
  223. */
  224. public List getMethodsWithoutIterator(boolean includeITDs, boolean allowMissing) {
  225. List methods = new ArrayList();
  226. Set knowninterfaces = new HashSet();
  227. addAndRecurse(knowninterfaces,methods,this,includeITDs,allowMissing);
  228. return methods;
  229. }
  230. private void addAndRecurse(Set knowninterfaces,List collector, ResolvedType rtx, boolean includeITDs, boolean allowMissing) {
  231. collector.addAll(Arrays.asList(rtx.getDeclaredMethods())); // Add the methods declared on this type
  232. // now add all the inter-typed members too
  233. if (includeITDs && rtx.interTypeMungers != null) {
  234. for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
  235. ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
  236. ResolvedMember rm = tm.getSignature();
  237. if (rm != null) { // new parent type munger can have null signature...
  238. collector.add(tm.getSignature());
  239. }
  240. }
  241. }
  242. if (!rtx.equals(ResolvedType.OBJECT)) {
  243. ResolvedType superType = rtx.getSuperclass();
  244. if (superType != null && !superType.isMissing()) {
  245. addAndRecurse(knowninterfaces,collector,superType,includeITDs,allowMissing); // Recurse if we aren't at the top
  246. }
  247. }
  248. ResolvedType[] interfaces = rtx.getDeclaredInterfaces(); // Go through the interfaces on the way back down
  249. for (int i = 0; i < interfaces.length; i++) {
  250. ResolvedType iface = interfaces[i];
  251. // we need to know if it is an interface from Parent kind munger
  252. // as those are used for @AJ ITD and we precisely want to skip those
  253. boolean shouldSkip = false;
  254. for (int j = 0; j < rtx.interTypeMungers.size(); j++) {
  255. ConcreteTypeMunger munger = (ConcreteTypeMunger) rtx.interTypeMungers.get(j);
  256. if (munger.getMunger()!=null && munger.getMunger().getKind() == ResolvedTypeMunger.Parent) {
  257. shouldSkip = true;
  258. break;
  259. }
  260. }
  261. if (!shouldSkip && !knowninterfaces.contains(iface)) { // Dont do interfaces more than once
  262. knowninterfaces.add(iface);
  263. if (allowMissing && iface.isMissing()) {
  264. if (iface instanceof MissingResolvedTypeWithKnownSignature) {
  265. ((MissingResolvedTypeWithKnownSignature)iface).raiseWarningOnMissingInterfaceWhilstFindingMethods();
  266. }
  267. } else {
  268. addAndRecurse(knowninterfaces,collector,iface,includeITDs,allowMissing);
  269. }
  270. }
  271. }
  272. }
  273. public ResolvedType[] getResolvedTypeParameters() {
  274. if (resolvedTypeParams == null) {
  275. resolvedTypeParams = world.resolve(typeParameters);
  276. }
  277. return resolvedTypeParams;
  278. }
  279. /**
  280. * described in JVM spec 2ed 5.4.3.2
  281. */
  282. public ResolvedMember lookupField(Member m) {
  283. return lookupMember(m, getFields());
  284. }
  285. /**
  286. * described in JVM spec 2ed 5.4.3.3.
  287. * Doesnt check ITDs.
  288. */
  289. public ResolvedMember lookupMethod(Member m) {
  290. return lookupMember(m, getMethods());
  291. }
  292. public ResolvedMember lookupMethodInITDs(Member m) {
  293. if (interTypeMungers != null) {
  294. for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
  295. ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
  296. if (matches(tm.getSignature(), m)) {
  297. return tm.getSignature();
  298. }
  299. }
  300. }
  301. return null;
  302. }
  303. /**
  304. * return null if not found
  305. */
  306. private ResolvedMember lookupMember(Member m, Iterator i) {
  307. while (i.hasNext()) {
  308. ResolvedMember f = (ResolvedMember) i.next();
  309. if (matches(f, m)) return f;
  310. if (f.hasBackingGenericMember() && m.getName().equals(f.getName())) { // might be worth checking the method behind the parameterized method (see pr137496)
  311. if (matches(f.getBackingGenericMember(),m)) return f;
  312. }
  313. }
  314. return null; //ResolvedMember.Missing;
  315. //throw new BCException("can't find " + m);
  316. }
  317. /**
  318. * return null if not found
  319. */
  320. private ResolvedMember lookupMember(Member m, ResolvedMember[] a) {
  321. for (int i = 0; i < a.length; i++) {
  322. ResolvedMember f = a[i];
  323. if (matches(f, m)) return f;
  324. }
  325. return null;
  326. }
  327. /**
  328. * Looks for the first member in the hierarchy matching aMember. This method
  329. * differs from lookupMember(Member) in that it takes into account parameters
  330. * which are type variables - which clearly an unresolved Member cannot do since
  331. * it does not know anything about type variables.
  332. */
  333. public ResolvedMember lookupResolvedMember(ResolvedMember aMember,boolean allowMissing) {
  334. Iterator toSearch = null;
  335. ResolvedMember found = null;
  336. if ((aMember.getKind() == Member.METHOD) || (aMember.getKind() == Member.CONSTRUCTOR)) {
  337. toSearch = getMethodsWithoutIterator(true,allowMissing).iterator();
  338. } else {
  339. if (aMember.getKind() != Member.FIELD)
  340. throw new IllegalStateException("I didn't know you would look for members of kind " + aMember.getKind());
  341. toSearch = getFields();
  342. }
  343. while(toSearch.hasNext()) {
  344. ResolvedMemberImpl candidate = (ResolvedMemberImpl) toSearch.next();
  345. if (candidate.matches(aMember)) {
  346. found = candidate;
  347. break;
  348. }
  349. }
  350. return found;
  351. }
  352. public static boolean matches(Member m1, Member m2) {
  353. if (m1 == null) return m2 == null;
  354. if (m2 == null) return false;
  355. // Check the names
  356. boolean equalNames = m1.getName().equals(m2.getName());
  357. if (!equalNames) return false;
  358. // Check the signatures
  359. boolean equalSignatures = m1.getSignature().equals(m2.getSignature());
  360. if (equalSignatures) return true;
  361. // If they aren't the same, we need to allow for covariance ... where one sig might be ()LCar; and
  362. // the subsig might be ()LFastCar; - where FastCar is a subclass of Car
  363. boolean equalCovariantSignatures = m1.getParameterSignature().equals(m2.getParameterSignature());
  364. if (equalCovariantSignatures) return true;
  365. return false;
  366. }
  367. public static boolean conflictingSignature(Member m1, Member m2) {
  368. if (m1 == null || m2 == null) return false;
  369. if (!m1.getName().equals(m2.getName())) {
  370. return false;
  371. }
  372. if (m1.getKind() != m2.getKind()) {
  373. return false;
  374. }
  375. if (m1.getKind() == Member.FIELD) {
  376. return m1.getDeclaringType().equals(m2.getDeclaringType());
  377. } else if (m1.getKind() == Member.POINTCUT) {
  378. return true;
  379. }
  380. UnresolvedType[] p1 = m1.getGenericParameterTypes();
  381. UnresolvedType[] p2 = m2.getGenericParameterTypes();
  382. if (p1==null) p1 = m1.getParameterTypes();
  383. if (p2==null) p2 = m2.getParameterTypes();
  384. int n = p1.length;
  385. if (n != p2.length) return false;
  386. for (int i=0; i < n; i++) {
  387. if (!p1[i].equals(p2[i])) return false;
  388. }
  389. return true;
  390. }
  391. /**
  392. * returns an iterator through all of the pointcuts of this type, in order
  393. * for checking from JVM spec 2ed 5.4.3.2 (as for fields). This means that the order is
  394. * <p/>
  395. * <ul><li> pointcuts from current class </li>
  396. * <li> recur into direct superinterfaces </li>
  397. * <li> recur into superclass </li>
  398. * </ul>
  399. * <p/>
  400. * We keep a hashSet of interfaces that we've visited so we don't spiral
  401. * out into 2^n land.
  402. */
  403. public Iterator getPointcuts() {
  404. final Iterators.Filter dupFilter = Iterators.dupFilter();
  405. // same order as fields
  406. Iterators.Getter typeGetter = new Iterators.Getter() {
  407. public Iterator get(Object o) {
  408. return
  409. dupFilter.filter(
  410. ((ResolvedType)o).getDirectSupertypes());
  411. }
  412. };
  413. Iterators.Getter pointcutGetter = new Iterators.Getter() {
  414. public Iterator get(Object o) {
  415. //System.err.println("getting for " + o);
  416. return Iterators.array(((ResolvedType)o).getDeclaredPointcuts());
  417. }
  418. };
  419. return
  420. Iterators.mapOver(
  421. Iterators.recur(this, typeGetter),
  422. pointcutGetter);
  423. }
  424. public ResolvedPointcutDefinition findPointcut(String name) {
  425. //System.err.println("looking for pointcuts " + this);
  426. for (Iterator i = getPointcuts(); i.hasNext(); ) {
  427. ResolvedPointcutDefinition f = (ResolvedPointcutDefinition) i.next();
  428. //System.err.println(f);
  429. if (name.equals(f.getName())) {
  430. return f;
  431. }
  432. }
  433. // pr120521
  434. if (!getOutermostType().equals(this)) {
  435. ResolvedType outerType = getOutermostType().resolve(world);
  436. ResolvedPointcutDefinition rpd = outerType.findPointcut(name);
  437. return rpd;
  438. }
  439. return null; // should we throw an exception here?
  440. }
  441. // all about collecting CrosscuttingMembers
  442. //??? collecting data-structure, shouldn't really be a field
  443. public CrosscuttingMembers crosscuttingMembers;
  444. public CrosscuttingMembers collectCrosscuttingMembers(boolean shouldConcretizeIfNeeded) {
  445. crosscuttingMembers = new CrosscuttingMembers(this,shouldConcretizeIfNeeded);
  446. crosscuttingMembers.setPerClause(getPerClause());
  447. crosscuttingMembers.addShadowMungers(collectShadowMungers());
  448. crosscuttingMembers.addTypeMungers(getTypeMungers());
  449. //FIXME AV - skip but needed ?? or ?? crosscuttingMembers.addLateTypeMungers(getLateTypeMungers());
  450. crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
  451. crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
  452. //System.err.println("collected cc members: " + this + ", " + collectDeclares());
  453. return crosscuttingMembers;
  454. }
  455. public final Collection collectDeclares(boolean includeAdviceLike) {
  456. if (! this.isAspect() ) return Collections.EMPTY_LIST;
  457. ArrayList ret = new ArrayList();
  458. //if (this.isAbstract()) {
  459. // for (Iterator i = getDeclares().iterator(); i.hasNext();) {
  460. // Declare dec = (Declare) i.next();
  461. // if (!dec.isAdviceLike()) ret.add(dec);
  462. // }
  463. //
  464. // if (!includeAdviceLike) return ret;
  465. if (!this.isAbstract()) {
  466. //ret.addAll(getDeclares());
  467. final Iterators.Filter dupFilter = Iterators.dupFilter();
  468. Iterators.Getter typeGetter = new Iterators.Getter() {
  469. public Iterator get(Object o) {
  470. return
  471. dupFilter.filter(
  472. ((ResolvedType)o).getDirectSupertypes());
  473. }
  474. };
  475. Iterator typeIterator = Iterators.recur(this, typeGetter);
  476. while (typeIterator.hasNext()) {
  477. ResolvedType ty = (ResolvedType) typeIterator.next();
  478. //System.out.println("super: " + ty + ", " + );
  479. for (Iterator i = ty.getDeclares().iterator(); i.hasNext();) {
  480. Declare dec = (Declare) i.next();
  481. if (dec.isAdviceLike()) {
  482. if (includeAdviceLike) ret.add(dec);
  483. } else {
  484. ret.add(dec);
  485. }
  486. }
  487. }
  488. }
  489. return ret;
  490. }
  491. private final Collection collectShadowMungers() {
  492. if (! this.isAspect() || this.isAbstract() || this.doesNotExposeShadowMungers()) return Collections.EMPTY_LIST;
  493. ArrayList acc = new ArrayList();
  494. final Iterators.Filter dupFilter = Iterators.dupFilter();
  495. Iterators.Getter typeGetter = new Iterators.Getter() {
  496. public Iterator get(Object o) {
  497. return
  498. dupFilter.filter(
  499. ((ResolvedType)o).getDirectSupertypes());
  500. }
  501. };
  502. Iterator typeIterator = Iterators.recur(this, typeGetter);
  503. while (typeIterator.hasNext()) {
  504. ResolvedType ty = (ResolvedType) typeIterator.next();
  505. acc.addAll(ty.getDeclaredShadowMungers());
  506. }
  507. return acc;
  508. }
  509. protected boolean doesNotExposeShadowMungers() {
  510. return false;
  511. }
  512. public PerClause getPerClause() {
  513. return null;
  514. }
  515. protected Collection getDeclares() {
  516. return Collections.EMPTY_LIST;
  517. }
  518. protected Collection getTypeMungers() {
  519. return Collections.EMPTY_LIST;
  520. }
  521. protected Collection getPrivilegedAccesses() {
  522. return Collections.EMPTY_LIST;
  523. }
  524. // ---- useful things
  525. public final boolean isInterface() {
  526. return Modifier.isInterface(getModifiers());
  527. }
  528. public final boolean isAbstract() {
  529. return Modifier.isAbstract(getModifiers());
  530. }
  531. public boolean isClass() {
  532. return false;
  533. }
  534. public boolean isAspect() {
  535. return false;
  536. }
  537. public boolean isAnnotationStyleAspect() {
  538. return false;
  539. }
  540. /**
  541. * Note: Only overridden by Name subtype.
  542. */
  543. public boolean isEnum() {
  544. return false;
  545. }
  546. /**
  547. * Note: Only overridden by Name subtype.
  548. */
  549. public boolean isAnnotation() {
  550. return false;
  551. }
  552. public boolean isAnonymous() {
  553. return false;
  554. }
  555. public boolean isNested() {
  556. return false;
  557. }
  558. /**
  559. * Note: Only overridden by Name subtype
  560. */
  561. public void addAnnotation(AnnotationX annotationX) {
  562. throw new RuntimeException("ResolvedType.addAnnotation() should never be called");
  563. }
  564. /**
  565. * Note: Only overridden by Name subtype
  566. */
  567. public AnnotationX[] getAnnotations() {
  568. throw new RuntimeException("ResolvedType.getAnnotations() should never be called");
  569. }
  570. /**
  571. * Note: Only overridden by ReferenceType subtype
  572. */
  573. public boolean canAnnotationTargetType() {
  574. return false;
  575. }
  576. /**
  577. * Note: Only overridden by ReferenceType subtype
  578. */
  579. public AnnotationTargetKind[] getAnnotationTargetKinds() {
  580. return null;
  581. }
  582. /**
  583. * Note: Only overridden by Name subtype.
  584. */
  585. public boolean isAnnotationWithRuntimeRetention() {
  586. return false;
  587. }
  588. public boolean isSynthetic() {
  589. return signature.indexOf("$ajc") != -1;
  590. }
  591. public final boolean isFinal() {
  592. return Modifier.isFinal(getModifiers());
  593. }
  594. protected Map /*Type variable name -> UnresolvedType*/ getMemberParameterizationMap() {
  595. if (!isParameterizedType()) return Collections.EMPTY_MAP;
  596. TypeVariable[] tvs = getGenericType().getTypeVariables();
  597. Map parameterizationMap = new HashMap();
  598. for (int i = 0; i < tvs.length; i++) {
  599. parameterizationMap.put(tvs[i].getName(), typeParameters[i]);
  600. }
  601. return parameterizationMap;
  602. }
  603. public Collection getDeclaredAdvice() {
  604. List l = new ArrayList();
  605. ResolvedMember[] methods = getDeclaredMethods();
  606. if (isParameterizedType()) methods = getGenericType().getDeclaredMethods();
  607. Map typeVariableMap = getAjMemberParameterizationMap();
  608. for (int i=0, len = methods.length; i < len; i++) {
  609. ShadowMunger munger = methods[i].getAssociatedShadowMunger();
  610. if (munger != null) {
  611. if (ajMembersNeedParameterization()) {
  612. //munger.setPointcut(munger.getPointcut().parameterizeWith(typeVariableMap));
  613. munger = munger.parameterizeWith(this,typeVariableMap);
  614. if (munger instanceof Advice) {
  615. Advice advice = (Advice) munger;
  616. // update to use the parameterized signature...
  617. UnresolvedType[] ptypes = methods[i].getGenericParameterTypes() ;
  618. UnresolvedType[] newPTypes = new UnresolvedType[ptypes.length];
  619. for (int j = 0; j < ptypes.length; j++) {
  620. if (ptypes[j] instanceof TypeVariableReferenceType) {
  621. TypeVariableReferenceType tvrt = (TypeVariableReferenceType) ptypes[j];
  622. if (typeVariableMap.containsKey(tvrt.getTypeVariable().getName())) {
  623. newPTypes[j] = (UnresolvedType) typeVariableMap.get(tvrt.getTypeVariable().getName());
  624. } else {
  625. newPTypes[j] = ptypes[j];
  626. }
  627. } else {
  628. newPTypes[j] = ptypes[j];
  629. }
  630. }
  631. advice.setBindingParameterTypes(newPTypes);
  632. }
  633. }
  634. munger.setDeclaringType(this);
  635. l.add(munger);
  636. }
  637. }
  638. return l;
  639. }
  640. public Collection getDeclaredShadowMungers() {
  641. Collection c = getDeclaredAdvice();
  642. return c;
  643. }
  644. // ---- only for testing!
  645. public ResolvedMember[] getDeclaredJavaFields() {
  646. return filterInJavaVisible(getDeclaredFields());
  647. }
  648. public ResolvedMember[] getDeclaredJavaMethods() {
  649. return filterInJavaVisible(getDeclaredMethods());
  650. }
  651. public ShadowMunger[] getDeclaredShadowMungersArray() {
  652. List l = (List) getDeclaredShadowMungers();
  653. return (ShadowMunger[]) l.toArray(new ShadowMunger[l.size()]);
  654. }
  655. private ResolvedMember[] filterInJavaVisible(ResolvedMember[] ms) {
  656. List l = new ArrayList();
  657. for (int i=0, len = ms.length; i < len; i++) {
  658. if (! ms[i].isAjSynthetic() && ms[i].getAssociatedShadowMunger() == null) {
  659. l.add(ms[i]);
  660. }
  661. }
  662. return (ResolvedMember[]) l.toArray(new ResolvedMember[l.size()]);
  663. }
  664. public abstract ISourceContext getSourceContext();
  665. // ---- fields
  666. public static final ResolvedType[] NONE = new ResolvedType[0];
  667. public static final Primitive BYTE = new Primitive("B", 1, 0);
  668. public static final Primitive CHAR = new Primitive("C", 1, 1);
  669. public static final Primitive DOUBLE = new Primitive("D", 2, 2);
  670. public static final Primitive FLOAT = new Primitive("F", 1, 3);
  671. public static final Primitive INT = new Primitive("I", 1, 4);
  672. public static final Primitive LONG = new Primitive("J", 2, 5);
  673. public static final Primitive SHORT = new Primitive("S", 1, 6);
  674. public static final Primitive VOID = new Primitive("V", 0, 8);
  675. public static final Primitive BOOLEAN = new Primitive("Z", 1, 7);
  676. public static final Missing MISSING = new Missing();
  677. /** Reset the static state in the primitive types */
  678. public static void resetPrimitives() {
  679. BYTE.world=null;
  680. CHAR.world=null;
  681. DOUBLE.world=null;
  682. FLOAT.world=null;
  683. INT.world=null;
  684. LONG.world=null;
  685. SHORT.world=null;
  686. VOID.world=null;
  687. BOOLEAN.world=null;
  688. }
  689. // ---- types
  690. public static ResolvedType makeArray(ResolvedType type, int dim) {
  691. if (dim == 0) return type;
  692. ResolvedType array = new Array("[" + type.getSignature(),"["+type.getErasureSignature(),type.getWorld(),type);
  693. return makeArray(array,dim-1);
  694. }
  695. static class Array extends ResolvedType {
  696. ResolvedType componentType;
  697. // Sometimes the erasure is different, eg. [TT; and [Ljava/lang/Object;
  698. Array(String sig, String erasureSig,World world, ResolvedType componentType) {
  699. super(sig,erasureSig, world);
  700. this.componentType = componentType;
  701. }
  702. public final ResolvedMember[] getDeclaredFields() {
  703. return ResolvedMember.NONE;
  704. }
  705. public final ResolvedMember[] getDeclaredMethods() {
  706. // ??? should this return clone? Probably not...
  707. // If it ever does, here is the code:
  708. // ResolvedMember cloneMethod =
  709. // new ResolvedMember(Member.METHOD,this,Modifier.PUBLIC,UnresolvedType.OBJECT,"clone",new UnresolvedType[]{});
  710. // return new ResolvedMember[]{cloneMethod};
  711. return ResolvedMember.NONE;
  712. }
  713. public final ResolvedType[] getDeclaredInterfaces() {
  714. return
  715. new ResolvedType[] {
  716. world.getCoreType(CLONEABLE),
  717. world.getCoreType(SERIALIZABLE)
  718. };
  719. }
  720. public final ResolvedMember[] getDeclaredPointcuts() {
  721. return ResolvedMember.NONE;
  722. }
  723. public boolean hasAnnotation(UnresolvedType ofType) {
  724. return false;
  725. }
  726. public final ResolvedType getSuperclass() {
  727. return world.getCoreType(OBJECT);
  728. }
  729. public final boolean isAssignableFrom(ResolvedType o) {
  730. if (! o.isArray()) return false;
  731. if (o.getComponentType().isPrimitiveType()) {
  732. return o.equals(this);
  733. } else {
  734. return getComponentType().resolve(world).isAssignableFrom(o.getComponentType().resolve(world));
  735. }
  736. }
  737. public boolean isAssignableFrom(ResolvedType o, boolean allowMissing) {
  738. return isAssignableFrom(o);
  739. }
  740. public final boolean isCoerceableFrom(ResolvedType o) {
  741. if (o.equals(UnresolvedType.OBJECT) ||
  742. o.equals(UnresolvedType.SERIALIZABLE) ||
  743. o.equals(UnresolvedType.CLONEABLE)) {
  744. return true;
  745. }
  746. if (! o.isArray()) return false;
  747. if (o.getComponentType().isPrimitiveType()) {
  748. return o.equals(this);
  749. } else {
  750. return getComponentType().resolve(world).isCoerceableFrom(o.getComponentType().resolve(world));
  751. }
  752. }
  753. public final int getModifiers() {
  754. int mask = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
  755. return (componentType.getModifiers() & mask) | Modifier.FINAL;
  756. }
  757. public UnresolvedType getComponentType() {
  758. return componentType;
  759. }
  760. public ResolvedType getResolvedComponentType() {
  761. return componentType;
  762. }
  763. public ISourceContext getSourceContext() {
  764. return getResolvedComponentType().getSourceContext();
  765. }
  766. }
  767. static class Primitive extends ResolvedType {
  768. private int size;
  769. private int index;
  770. Primitive(String signature, int size, int index) {
  771. super(signature, null);
  772. this.size = size;
  773. this.index = index;
  774. this.typeKind=TypeKind.PRIMITIVE;
  775. }
  776. public final int getSize() {
  777. return size;
  778. }
  779. public final int getModifiers() {
  780. return Modifier.PUBLIC | Modifier.FINAL;
  781. }
  782. public final boolean isPrimitiveType() {
  783. return true;
  784. }
  785. public boolean hasAnnotation(UnresolvedType ofType) {
  786. return false;
  787. }
  788. public final boolean isAssignableFrom(ResolvedType other) {
  789. if (!other.isPrimitiveType()) {
  790. if (!world.isInJava5Mode()) return false;
  791. return validBoxing.contains(this.getSignature()+other.getSignature());
  792. }
  793. return assignTable[((Primitive)other).index][index];
  794. }
  795. public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
  796. return isAssignableFrom(other);
  797. }
  798. public final boolean isCoerceableFrom(ResolvedType other) {
  799. if (this == other) return true;
  800. if (! other.isPrimitiveType()) return false;
  801. if (index > 6 || ((Primitive)other).index > 6) return false;
  802. return true;
  803. }
  804. public ResolvedType resolve(World world) {
  805. this.world = world;
  806. return super.resolve(world);
  807. }
  808. public final boolean needsNoConversionFrom(ResolvedType other) {
  809. if (! other.isPrimitiveType()) return false;
  810. return noConvertTable[((Primitive)other).index][index];
  811. }
  812. private static final boolean[][] assignTable =
  813. {// to: B C D F I J S V Z from
  814. { true , true , true , true , true , true , true , false, false }, // B
  815. { false, true , true , true , true , true , false, false, false }, // C
  816. { false, false, true , false, false, false, false, false, false }, // D
  817. { false, false, true , true , false, false, false, false, false }, // F
  818. { false, false, true , true , true , true , false, false, false }, // I
  819. { false, false, true , true , false, true , false, false, false }, // J
  820. { false, false, true , true , true , true , true , false, false }, // S
  821. { false, false, false, false, false, false, false, true , false }, // V
  822. { false, false, false, false, false, false, false, false, true }, // Z
  823. };
  824. private static final boolean[][] noConvertTable =
  825. {// to: B C D F I J S V Z from
  826. { true , true , false, false, true , false, true , false, false }, // B
  827. { false, true , false, false, true , false, false, false, false }, // C
  828. { false, false, true , false, false, false, false, false, false }, // D
  829. { false, false, false, true , false, false, false, false, false }, // F
  830. { false, false, false, false, true , false, false, false, false }, // I
  831. { false, false, false, false, false, true , false, false, false }, // J
  832. { false, false, false, false, true , false, true , false, false }, // S
  833. { false, false, false, false, false, false, false, true , false }, // V
  834. { false, false, false, false, false, false, false, false, true }, // Z
  835. };
  836. // ----
  837. public final ResolvedMember[] getDeclaredFields() {
  838. return ResolvedMember.NONE;
  839. }
  840. public final ResolvedMember[] getDeclaredMethods() {
  841. return ResolvedMember.NONE;
  842. }
  843. public final ResolvedType[] getDeclaredInterfaces() {
  844. return ResolvedType.NONE;
  845. }
  846. public final ResolvedMember[] getDeclaredPointcuts() {
  847. return ResolvedMember.NONE;
  848. }
  849. public final ResolvedType getSuperclass() {
  850. return null;
  851. }
  852. public ISourceContext getSourceContext() {
  853. return null;
  854. }
  855. }
  856. static class Missing extends ResolvedType {
  857. Missing() {
  858. super(MISSING_NAME, null);
  859. }
  860. // public final String toString() {
  861. // return "<missing>";
  862. // }
  863. public final String getName() {
  864. return MISSING_NAME;
  865. }
  866. public final boolean isMissing() {
  867. return true;
  868. }
  869. public boolean hasAnnotation(UnresolvedType ofType) {
  870. return false;
  871. }
  872. public final ResolvedMember[] getDeclaredFields() {
  873. return ResolvedMember.NONE;
  874. }
  875. public final ResolvedMember[] getDeclaredMethods() {
  876. return ResolvedMember.NONE;
  877. }
  878. public final ResolvedType[] getDeclaredInterfaces() {
  879. return ResolvedType.NONE;
  880. }
  881. public final ResolvedMember[] getDeclaredPointcuts() {
  882. return ResolvedMember.NONE;
  883. }
  884. public final ResolvedType getSuperclass() {
  885. return null;
  886. }
  887. public final int getModifiers() {
  888. return 0;
  889. }
  890. public final boolean isAssignableFrom(ResolvedType other) {
  891. return false;
  892. }
  893. public final boolean isAssignableFrom(ResolvedType other, boolean allowMissing) {
  894. return false;
  895. }
  896. public final boolean isCoerceableFrom(ResolvedType other) {
  897. return false;
  898. }
  899. public boolean needsNoConversionFrom(ResolvedType other) {
  900. return false;
  901. }
  902. public ISourceContext getSourceContext() {
  903. return null;
  904. }
  905. }
  906. /**
  907. * Look up a member, takes into account any ITDs on this type.
  908. * return null if not found
  909. */
  910. public ResolvedMember lookupMemberNoSupers(Member member) {
  911. ResolvedMember ret = lookupDirectlyDeclaredMemberNoSupers(member);
  912. if (ret == null && interTypeMungers != null) {
  913. for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
  914. ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
  915. if (matches(tm.getSignature(), member)) {
  916. return tm.getSignature();
  917. }
  918. }
  919. }
  920. return ret;
  921. }
  922. public ResolvedMember lookupMemberWithSupersAndITDs(Member member) {
  923. ResolvedMember ret = lookupMemberNoSupers(member);
  924. if (ret != null) return ret;
  925. ResolvedType supert = getSuperclass();
  926. while (ret==null && supert!=null) {
  927. ret = supert.lookupMemberNoSupers(member);
  928. if (ret==null) supert = supert.getSuperclass();
  929. }
  930. return ret;
  931. }
  932. /**
  933. * as lookupMemberNoSupers, but does not include ITDs
  934. *
  935. * @param member
  936. * @return
  937. */
  938. public ResolvedMember lookupDirectlyDeclaredMemberNoSupers(Member member) {
  939. ResolvedMember ret;
  940. if (member.getKind() == Member.FIELD) {
  941. ret = lookupMember(member, getDeclaredFields());
  942. } else {
  943. // assert member.getKind() == Member.METHOD || member.getKind() == Member.CONSTRUCTOR
  944. ret = lookupMember(member, getDeclaredMethods());
  945. }
  946. return ret;
  947. }
  948. /**
  949. * This lookup has specialized behaviour - a null result tells the
  950. * EclipseTypeMunger that it should make a default implementation of a
  951. * method on this type.
  952. *
  953. * @param member
  954. * @return
  955. */
  956. public ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member) {
  957. return lookupMemberIncludingITDsOnInterfaces(member, this);
  958. }
  959. private ResolvedMember lookupMemberIncludingITDsOnInterfaces(Member member, ResolvedType onType) {
  960. ResolvedMember ret = onType.lookupMemberNoSupers(member);
  961. if (ret != null) {
  962. return ret;
  963. } else {
  964. ResolvedType superType = onType.getSuperclass();
  965. if (superType != null) {
  966. ret = lookupMemberIncludingITDsOnInterfaces(member,superType);
  967. }
  968. if (ret == null) {
  969. // try interfaces then, but only ITDs now...
  970. ResolvedType[] superInterfaces = onType.getDeclaredInterfaces();
  971. for (int i = 0; i < superInterfaces.length; i++) {
  972. ret = superInterfaces[i].lookupMethodInITDs(member);
  973. if (ret != null) return ret;
  974. }
  975. }
  976. }
  977. return ret;
  978. }
  979. protected List interTypeMungers = new ArrayList(0);
  980. public List getInterTypeMungers() {
  981. return interTypeMungers;
  982. }
  983. public List getInterTypeParentMungers() {
  984. List l = new ArrayList();
  985. for (Iterator iter = interTypeMungers.iterator(); iter.hasNext();) {
  986. ConcreteTypeMunger element = (ConcreteTypeMunger) iter.next();
  987. if (element.getMunger() instanceof NewParentTypeMunger) l.add(element);
  988. }
  989. return l;
  990. }
  991. /**
  992. * ??? This method is O(N*M) where N = number of methods and M is number of
  993. * inter-type declarations in my super
  994. */
  995. public List getInterTypeMungersIncludingSupers() {
  996. ArrayList ret = new ArrayList();
  997. collectInterTypeMungers(ret);
  998. return ret;
  999. }
  1000. public List getInterTypeParentMungersIncludingSupers() {
  1001. ArrayList ret = new ArrayList();
  1002. collectInterTypeParentMungers(ret);
  1003. return ret;
  1004. }
  1005. private void collectInterTypeParentMungers(List collector) {
  1006. for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
  1007. ResolvedType superType = (ResolvedType) iter.next();
  1008. superType.collectInterTypeParentMungers(collector);
  1009. }
  1010. collector.addAll(getInterTypeParentMungers());
  1011. }
  1012. protected void collectInterTypeMungers(List collector) {
  1013. for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
  1014. ResolvedType superType = (ResolvedType) iter.next();
  1015. superType.collectInterTypeMungers(collector);
  1016. }
  1017. outer:
  1018. for (Iterator iter1 = collector.iterator(); iter1.hasNext();) {
  1019. ConcreteTypeMunger superMunger = (ConcreteTypeMunger) iter1.next();
  1020. if ( superMunger.getSignature() == null) continue;
  1021. if ( !superMunger.getSignature().isAbstract()) continue;
  1022. for (Iterator iter = getInterTypeMungers().iterator(); iter.hasNext();) {
  1023. ConcreteTypeMunger myMunger = (ConcreteTypeMunger) iter.next();
  1024. if (conflictingSignature(myMunger.getSignature(), superMunger.getSignature())) {
  1025. iter1.remove();
  1026. continue outer;
  1027. }
  1028. }
  1029. if (!superMunger.getSignature().isPublic()) continue;
  1030. for (Iterator iter = getMethods(); iter.hasNext(); ) {
  1031. ResolvedMember method = (ResolvedMember)iter.next();
  1032. if (conflictingSignature(method, superMunger.getSignature())) {
  1033. iter1.remove();
  1034. continue outer;
  1035. }
  1036. }
  1037. }
  1038. collector.addAll(getInterTypeMungers());
  1039. }
  1040. /**
  1041. * Check:
  1042. * 1) That we don't have any abstract type mungers unless this type is abstract.
  1043. * 2) That an abstract ITDM on an interface is declared public. (Compiler limitation) (PR70794)
  1044. */
  1045. public void checkInterTypeMungers() {
  1046. if (isAbstract()) return;
  1047. boolean itdProblem = false;
  1048. for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
  1049. ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
  1050. itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule 2
  1051. }
  1052. if (itdProblem) return; // If the rules above are broken, return right now
  1053. for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
  1054. ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
  1055. if (munger.getSignature() != null && munger.getSignature().isAbstract()) { // Rule 1
  1056. if (munger.getMunger().getKind() == ResolvedTypeMunger.MethodDelegate) {
  1057. ;//ignore for @AJ ITD as munger.getSignature() is the interface method hence abstract
  1058. } else {
  1059. world.getMessageHandler().handleMessage(
  1060. new Message("must implement abstract inter-type declaration: " + munger.getSignature(),
  1061. "", IMessage.ERROR, getSourceLocation(), null,
  1062. new ISourceLocation[] { getMungerLocation(munger) }));
  1063. }
  1064. }
  1065. }
  1066. }
  1067. /**
  1068. * See PR70794. This method checks that if an abstract inter-type method declaration is made on
  1069. * an interface then it must also be public.
  1070. * This is a compiler limitation that could be made to work in the future (if someone
  1071. * provides a worthwhile usecase)
  1072. *
  1073. * @return indicates if the munger failed the check
  1074. */
  1075. private boolean checkAbstractDeclaration(ConcreteTypeMunger munger) {
  1076. if (munger.getMunger()!=null && (munger.getMunger() instanceof NewMethodTypeMunger)) {
  1077. ResolvedMember itdMember = munger.getSignature();
  1078. ResolvedType onType = itdMember.getDeclaringType().resolve(world);
  1079. if (onType.isInterface() && itdMember.isAbstract() && !itdMember.isPublic()) {
  1080. world.getMessageHandler().handleMessage(
  1081. new Message(WeaverMessages.format(WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE,munger.getSignature(),onType),"",
  1082. Message.ERROR,getSourceLocation(),null,
  1083. new ISourceLocation[]{getMungerLocation(munger)})
  1084. );
  1085. return true;
  1086. }
  1087. }
  1088. return false;
  1089. }
  1090. /**
  1091. * Get a source location for the munger.
  1092. * Until intertype mungers remember where they came from, the source location
  1093. * for the munger itself is null. In these cases use the
  1094. * source location for the aspect containing the ITD.
  1095. */
  1096. private ISourceLocation getMungerLocation(ConcreteTypeMunger munger) {
  1097. ISourceLocation sloc = munger.getSourceLocation();
  1098. if (sloc == null) {
  1099. sloc = munger.getAspectType().getSourceLocation();
  1100. }
  1101. return sloc;
  1102. }
  1103. /**
  1104. * Returns a ResolvedType object representing the declaring type of this type, or
  1105. * null if this type does not represent a non-package-level-type.
  1106. * <p/>
  1107. * <strong>Warning</strong>: This is guaranteed to work for all member types.
  1108. * For anonymous/local types, the only guarantee is given in JLS 13.1, where
  1109. * it guarantees that if you call getDeclaringType() repeatedly, you will eventually
  1110. * get the top-level class, but it does not say anything about classes in between.
  1111. *
  1112. * @return the declaring UnresolvedType object, or null.
  1113. */
  1114. public ResolvedType getDeclaringType() {
  1115. if (isArray()) return null;
  1116. String name = getName();
  1117. int lastDollar = name.lastIndexOf('$');
  1118. while (lastDollar >0) { // allow for classes starting '$' (pr120474)
  1119. ResolvedType ret = world.resolve(UnresolvedType.forName(name.substring(0, lastDollar)), true);
  1120. if (!ResolvedType.isMissing(ret)) return ret;
  1121. lastDollar = name.lastIndexOf('$', lastDollar-1);
  1122. }
  1123. return null;
  1124. }
  1125. public static boolean isVisible(int modifiers, ResolvedType targetType, ResolvedType fromType) {
  1126. //System.err.println("mod: " + modifiers + ", " + targetType + " and " + fromType);
  1127. if (Modifier.isPublic(modifiers)) {
  1128. return true;
  1129. } else if (Modifier.isPrivate(modifiers)) {
  1130. return targetType.getOutermostType().equals(fromType.getOutermostType());
  1131. } else if (Modifier.isProtected(modifiers)) {
  1132. return samePackage(targetType, fromType) || targetType.isAssignableFrom(fromType);
  1133. } else { // package-visible
  1134. return samePackage(targetType, fromType);
  1135. }
  1136. }
  1137. public static boolean hasBridgeModifier(int modifiers) {
  1138. return (modifiers & Constants.ACC_BRIDGE)!=0;
  1139. }
  1140. private static boolean samePackage(
  1141. ResolvedType targetType,
  1142. ResolvedType fromType) {
  1143. String p1 = targetType.getPackageName();
  1144. String p2 = fromType.getPackageName();
  1145. if (p1 == null) return p2 == null;
  1146. if (p2 == null) return false;
  1147. return p1.equals(p2);
  1148. }
  1149. /**
  1150. * Checks if the generic type for 'this' and the generic type for 'other' are the same -
  1151. * it can be passed raw or parameterized versions and will just compare the underlying
  1152. * generic type.
  1153. */
  1154. private boolean genericTypeEquals(ResolvedType other) {
  1155. ResolvedType rt = other;
  1156. if (rt.isParameterizedType() || rt.isRawType()) rt.getGenericType();
  1157. if (( (isParameterizedType() || isRawType()) && getGenericType().equals(rt)) ||
  1158. (this.equals(other))) return true;
  1159. return false;
  1160. }
  1161. /**
  1162. * Look up the actual occurence of a particular type in the hierarchy for
  1163. * 'this' type. The input is going to be a generic type, and the caller
  1164. * wants to know if it was used in its RAW or a PARAMETERIZED form in this
  1165. * hierarchy.
  1166. *
  1167. * returns null if it can't be found.
  1168. */
  1169. public ResolvedType discoverActualOccurrenceOfTypeInHierarchy(ResolvedType lookingFor) {
  1170. if (!lookingFor.isGenericType())
  1171. throw new BCException("assertion failed: method should only be called with generic type, but "+lookingFor+" is "+lookingFor.typeKind);
  1172. if (this.equals(ResolvedType.OBJECT)) return null;
  1173. if (genericTypeEquals(lookingFor)) return this;
  1174. ResolvedType superT = getSuperclass();
  1175. if (superT.genericTypeEquals(lookingFor)) return superT;
  1176. ResolvedType[] superIs = getDeclaredInterfaces();
  1177. for (int i = 0; i < superIs.length; i++) {
  1178. ResolvedType superI = superIs[i];
  1179. if (superI.genericTypeEquals(lookingFor)) return superI;
  1180. ResolvedType checkTheSuperI = superI.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
  1181. if (checkTheSuperI!=null) return checkTheSuperI;
  1182. }
  1183. return superT.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
  1184. }
  1185. /**
  1186. * Called for all type mungers but only does something if they share type variables
  1187. * with a generic type which they target. When this happens this routine will check
  1188. * for the target type in the target hierarchy and 'bind' any type parameters as
  1189. * appropriate. For example, for the ITD "List<T> I<T>.x" against a type like this:
  1190. * "class A implements I<String>" this routine will return a parameterized form of
  1191. * the ITD "List<String> I.x"
  1192. */
  1193. public ConcreteTypeMunger fillInAnyTypeParameters(ConcreteTypeMunger munger) {
  1194. boolean debug = false;
  1195. ResolvedMember member = munger.getSignature();
  1196. if (munger.isTargetTypeParameterized()) {
  1197. if (debug) System.err.println("Processing attempted parameterization of "+munger+" targetting type "+this);
  1198. if (debug) System.err.println(" This type is "+this+" ("+typeKind+")");
  1199. // need to tailor this munger instance for the particular target...
  1200. if (debug) System.err.println(" Signature that needs parameterizing: "+member);
  1201. // Retrieve the generic type
  1202. ResolvedType onType = world.resolve(member.getDeclaringType()).getGenericType();
  1203. member.resolve(world); // Ensure all parts of the member are resolved
  1204. if (debug) System.err.println(" Actual target ontype: "+onType+" ("+onType.typeKind+")");
  1205. // quickly find the targettype in the type hierarchy for this type (it will be either RAW or PARAMETERIZED)
  1206. ResolvedType actualTarget = discoverActualOccurrenceOfTypeInHierarchy(onType);
  1207. if (actualTarget==null)
  1208. throw new BCException("assertion failed: asked "+this+" for occurrence of "+onType+" in its hierarchy??");
  1209. // only bind the tvars if its a parameterized type or the raw type (in which case they collapse to bounds) - don't do it for generic types ;)
  1210. if (!actualTarget.isGenericType()) {
  1211. if (debug) System.err.println("Occurrence in "+this+" is actually "+actualTarget+" ("+actualTarget.typeKind+")");
  1212. // parameterize the signature
  1213. // ResolvedMember newOne = member.parameterizedWith(actualTarget.getTypeParameters(),onType,actualTarget.isParameterizedType());
  1214. }
  1215. //if (!actualTarget.isRawType())
  1216. munger = munger.parameterizedFor(actualTarget);
  1217. if (debug) System.err.println("New sig: "+munger.getSignature());
  1218. if (debug) System.err.println("=====================================");
  1219. }
  1220. return munger;
  1221. }
  1222. public void addInterTypeMunger(ConcreteTypeMunger munger) {
  1223. ResolvedMember sig = munger.getSignature();
  1224. if (sig == null || munger.getMunger() == null ||
  1225. munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess)
  1226. {
  1227. interTypeMungers.add(munger);
  1228. return;
  1229. }
  1230. ConcreteTypeMunger originalMunger = munger;
  1231. // we will use the 'parameterized' ITD for all the comparisons but we say the original
  1232. // one passed in actually matched as it will be added to the intertype member finder
  1233. // for the target type. It is possible we only want to do this if a generic type
  1234. // is discovered and the tvar is collapsed to a bound?
  1235. munger = fillInAnyTypeParameters(munger);
  1236. sig = munger.getSignature(); // possibly changed when type parms filled in
  1237. //System.err.println("add: " + munger + " to " + this.getClassName() + " with " + interTypeMungers);
  1238. if (sig.getKind() == Member.METHOD) {
  1239. if (!compareToExistingMembers(munger, getMethodsWithoutIterator(false,true) /*getMethods()*/)) return;
  1240. if (this.isInterface()) {
  1241. if (!compareToExistingMembers(munger,
  1242. Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator())) return;
  1243. }
  1244. } else if (sig.getKind() == Member.FIELD) {
  1245. if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredFields()).iterator())) return;
  1246. } else {
  1247. if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredMethods()).iterator())) return;
  1248. }
  1249. // now compare to existingMungers
  1250. for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
  1251. ConcreteTypeMunger existingMunger = (ConcreteTypeMunger)i.next();
  1252. if (conflictingSignature(existingMunger.getSignature(), munger.getSignature())) {
  1253. //System.err.println("match " + munger + " with " + existingMunger);
  1254. if (isVisible(munger.getSignature().getModifiers(),
  1255. munger.getAspectType(), existingMunger.getAspectType()))
  1256. {
  1257. //System.err.println(" is visible");
  1258. int c = compareMemberPrecedence(sig, existingMunger.getSignature());
  1259. if (c == 0) {
  1260. c = getWorld().compareByPrecedenceAndHierarchy(munger.getAspectType(), existingMunger.getAspectType());
  1261. }
  1262. //System.err.println(" compare: " + c);
  1263. if (c < 0) {
  1264. // the existing munger dominates the new munger
  1265. checkLegalOverride(munger.getSignature(), existingMunger.getSignature());
  1266. return;
  1267. } else if (c > 0) {
  1268. // the new munger dominates the existing one
  1269. checkLegalOverride(existingMunger.getSignature(), munger.getSignature());
  1270. i.remove();
  1271. break;
  1272. } else {
  1273. interTypeConflictError(munger, existingMunger);
  1274. interTypeConflictError(existingMunger, munger);
  1275. return;
  1276. }
  1277. }
  1278. }
  1279. }
  1280. //System.err.println("adding: " + munger + " to " + this);
  1281. // we are adding the parameterized form of the ITD to the list of
  1282. // mungers. Within it, the munger knows the original declared
  1283. // signature for the ITD so it can be retrieved.
  1284. interTypeMungers.add(munger);
  1285. }
  1286. private boolean compareToExistingMembers(ConcreteTypeMunger munger, List existingMembersList) {
  1287. return compareToExistingMembers(munger,existingMembersList.iterator());
  1288. }
  1289. //??? returning too soon
  1290. private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) {
  1291. ResolvedMember sig = munger.getSignature();
  1292. while (existingMembers.hasNext()) {
  1293. ResolvedMember existingMember = (ResolvedMember)existingMembers.next();
  1294. // don't worry about clashing with bridge methods
  1295. if (existingMember.isBridgeMethod()) continue;
  1296. //System.err.println("Comparing munger: "+sig+" with member "+existingMember);
  1297. if (conflictingSignature(existingMember, munger.getSignature())) {
  1298. //System.err.println("conflict: existingMember=" + existingMember + " typeMunger=" + munger);
  1299. //System.err.println(munger.getSourceLocation() + ", " + munger.getSignature() + ", " + munger.getSignature().getSourceLocation());
  1300. if (isVisible(existingMember.getModifiers(), this, munger.getAspectType())) {
  1301. int c = compareMemberPrecedence(sig, existingMember);
  1302. //System.err.println(" c: " + c);
  1303. if (c < 0) {
  1304. // existingMember dominates munger
  1305. checkLegalOverride(munger.getSignature(), existingMember);
  1306. return false;
  1307. } else if (c > 0) {
  1308. // munger dominates existingMember
  1309. checkLegalOverride(existingMember, munger.getSignature());
  1310. //interTypeMungers.add(munger);
  1311. //??? might need list of these overridden abstracts
  1312. continue;
  1313. } else {
  1314. // bridge methods can differ solely in return type.
  1315. // FIXME this whole method seems very hokey - unaware of covariance/varargs/bridging - it
  1316. // could do with a rewrite !
  1317. boolean sameReturnTypes = (existingMember.getReturnType().equals(sig.getReturnType()));
  1318. if (sameReturnTypes)
  1319. getWorld().getMessageHandler().handleMessage(
  1320. MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
  1321. existingMember),
  1322. munger.getSourceLocation())
  1323. );
  1324. }
  1325. } else if (isDuplicateMemberWithinTargetType(existingMember,this,sig)) {
  1326. getWorld().getMessageHandler().handleMessage(
  1327. MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
  1328. existingMember),
  1329. munger.getSourceLocation())
  1330. );
  1331. ;
  1332. }
  1333. //return;
  1334. }
  1335. }
  1336. return true;
  1337. }
  1338. // we know that the member signature matches, but that the member in the target type is not visible to the aspect.
  1339. // this may still be disallowed if it would result in two members within the same declaring type with the same
  1340. // signature AND more than one of them is concrete AND they are both visible within the target type.
  1341. private boolean isDuplicateMemberWithinTargetType(ResolvedMember existingMember, ResolvedType targetType,ResolvedMember itdMember) {
  1342. if ( (existingMember.isAbstract() || itdMember.isAbstract())) return false;
  1343. UnresolvedType declaringType = existingMember.getDeclaringType();
  1344. if (!targetType.equals(declaringType)) return false;
  1345. // now have to test that itdMember is visible from targetType
  1346. if (itdMember.isPrivate()) return false;
  1347. if (itdMember.isPublic()) return true;
  1348. // must be in same package to be visible then...
  1349. if (!targetType.getPackageName().equals(itdMember.getDeclaringType().getPackageName())) return false;
  1350. // trying to put two members with the same signature into the exact same type..., and both visible in that type.
  1351. return true;
  1352. }
  1353. /**
  1354. * @return true if the override is legal
  1355. * note: calling showMessage with two locations issues TWO messages, not ONE message
  1356. * with an additional source location.
  1357. */
  1358. public boolean checkLegalOverride(ResolvedMember parent, ResolvedMember child) {
  1359. //System.err.println("check: " + child.getDeclaringType() + " overrides " + parent.getDeclaringType());
  1360. if (Modifier.isFinal(parent.getModifiers())) {
  1361. world.showMessage(Message.ERROR,
  1362. WeaverMessages.format(WeaverMessages.CANT_OVERRIDE_FINAL_MEMBER,parent),
  1363. child.getSourceLocation(),null);
  1364. return false;
  1365. }
  1366. boolean incompatibleReturnTypes = false;
  1367. // In 1.5 mode, allow for covariance on return type
  1368. if (world.isInJava5Mode() && parent.getKind()==Member.METHOD) {
  1369. // Look at the generic types when doing this comparison
  1370. ResolvedType rtParentReturnType = parent.getGenericReturnType().resolve(world);
  1371. ResolvedType rtChildReturnType = child.getGenericReturnType().resolve(world);
  1372. incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType);
  1373. if (incompatibleReturnTypes) {
  1374. incompatibleReturnTypes = !rtParentReturnType.isAssignableFrom(rtChildReturnType);
  1375. }
  1376. } else {
  1377. incompatibleReturnTypes =!parent.getReturnType().equals(child.getReturnType());
  1378. }
  1379. if (incompatibleReturnTypes) {
  1380. world.showMessage(IMessage.ERROR,
  1381. WeaverMessages.format(WeaverMessages.ITD_RETURN_TYPE_MISMATCH,parent,child),
  1382. child.getSourceLocation(), parent.getSourceLocation());
  1383. return false;
  1384. }
  1385. if (parent.getKind() == Member.POINTCUT) {
  1386. UnresolvedType[] pTypes = parent.getParameterTypes();
  1387. UnresolvedType[] cTypes = child.getParameterTypes();
  1388. if (!Arrays.equals(pTypes, cTypes)) {
  1389. world.showMessage(IMessage.ERROR,
  1390. WeaverMessages.format(WeaverMessages.ITD_PARAM_TYPE_MISMATCH,parent,child),
  1391. child.getSourceLocation(), parent.getSourceLocation());
  1392. return false;
  1393. }
  1394. }
  1395. //System.err.println("check: " + child.getModifiers() + " more visible " + parent.getModifiers());
  1396. if (isMoreVisible(parent.getModifiers(), child.getModifiers())) {
  1397. world.showMessage(IMessage.ERROR,
  1398. WeaverMessages.format(WeaverMessages.ITD_VISIBILITY_REDUCTION,parent,child),
  1399. child.getSourceLocation(), parent.getSourceLocation());
  1400. return false;
  1401. }
  1402. // check declared exceptions
  1403. ResolvedType[] childExceptions = world.resolve(child.getExceptions());
  1404. ResolvedType[] parentExceptions = world.resolve(parent.getExceptions());
  1405. ResolvedType runtimeException = world.resolve("java.lang.RuntimeException");
  1406. ResolvedType error = world.resolve("java.lang.Error");
  1407. outer:
  1408. for (int i = 0, leni = childExceptions.length; i < leni; i++) {
  1409. //System.err.println("checking: " + childExceptions[i]);
  1410. if (runtimeException.isAssignableFrom(childExceptions[i])) continue;
  1411. if (error.isAssignableFrom(childExceptions[i])) continue;
  1412. for (int j = 0, lenj = parentExceptions.length; j < lenj; j++) {
  1413. if (parentExceptions[j].isAssignableFrom(childExceptions[i])) continue outer;
  1414. }
  1415. // this message is now better handled my MethodVerifier in JDT core.
  1416. // world.showMessage(IMessage.ERROR,
  1417. // WeaverMessages.format(WeaverMessages.ITD_DOESNT_THROW,childExceptions[i].getName()),
  1418. // child.getSourceLocation(), null);
  1419. return false;
  1420. }
  1421. if (parent.isStatic() && !child.isStatic()) {
  1422. world.showMessage(IMessage.ERROR,
  1423. WeaverMessages.format(WeaverMessages.ITD_OVERRIDDEN_STATIC,child,parent),
  1424. child.getSourceLocation(),null);
  1425. return false;
  1426. } else if (child.isStatic() && !parent.isStatic()) {
  1427. world.showMessage(IMessage.ERROR,
  1428. WeaverMessages.format(WeaverMessages.ITD_OVERIDDING_STATIC,child,parent),
  1429. child.getSourceLocation(),null);
  1430. return false;
  1431. }
  1432. return true;
  1433. }
  1434. private int compareMemberPrecedence(ResolvedMember m1, ResolvedMember m2) {
  1435. //if (!m1.getReturnType().equals(m2.getReturnType())) return 0;
  1436. // need to allow for the special case of 'clone' - which is like abstract but is
  1437. // not marked abstract. The code below this next line seems to make assumptions
  1438. // about what will have gotten through the compiler based on the normal
  1439. // java rules. clone goes against these...
  1440. if (m2.isProtected() && m2.getName().charAt(0)=='c') {
  1441. UnresolvedType declaring = m2.getDeclaringType();
  1442. if (declaring!=null) {
  1443. if (declaring.getName().equals("java.lang.Object") && m2.getName().equals("clone")) return +1;
  1444. }
  1445. }
  1446. if (Modifier.isAbstract(m1.getModifiers())) return -1;
  1447. if (Modifier.isAbstract(m2.getModifiers())) return +1;
  1448. if (m1.getDeclaringType().equals(m2.getDeclaringType())) return 0;
  1449. ResolvedType t1 = m1.getDeclaringType().resolve(world);
  1450. ResolvedType t2 = m2.getDeclaringType().resolve(world);
  1451. if (t1.isAssignableFrom(t2)) {
  1452. return -1;
  1453. }
  1454. if (t2.isAssignableFrom(t1)) {
  1455. return +1;
  1456. }
  1457. return 0;
  1458. }
  1459. public static boolean isMoreVisible(int m1, int m2) {
  1460. if (Modifier.isPrivate(m1)) return false;
  1461. if (isPackage(m1)) return Modifier.isPrivate(m2);
  1462. if (Modifier.isProtected(m1)) return /* private package */ (Modifier.isPrivate(m2) || isPackage(m2));
  1463. if (Modifier.isPublic(m1)) return /* private package protected */ ! Modifier.isPublic(m2);
  1464. throw new RuntimeException("bad modifier: " + m1);
  1465. }
  1466. private static boolean isPackage(int i) {
  1467. return (0 == (i & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)));
  1468. }
  1469. private void interTypeConflictError(
  1470. ConcreteTypeMunger m1,
  1471. ConcreteTypeMunger m2) {
  1472. //XXX this works only if we ignore separate compilation issues
  1473. //XXX dual errors possible if (this instanceof BcelObjectType) return;
  1474. //System.err.println("conflict at " + m2.getSourceLocation());
  1475. getWorld().showMessage(IMessage.ERROR,
  1476. WeaverMessages.format(WeaverMessages.ITD_CONFLICT,m1.getAspectType().getName(),
  1477. m2.getSignature(),m2.getAspectType().getName()),
  1478. m2.getSourceLocation(), getSourceLocation());
  1479. }
  1480. public ResolvedMember lookupSyntheticMember(Member member) {
  1481. //??? horribly inefficient
  1482. //for (Iterator i =
  1483. //System.err.println("lookup " + member + " in " + interTypeMungers);
  1484. for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
  1485. ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
  1486. ResolvedMember ret = m.getMatchingSyntheticMember(member);
  1487. if (ret != null) {
  1488. //System.err.println(" found: " + ret);
  1489. return ret;
  1490. }
  1491. }
  1492. // Handling members for the new array join point
  1493. if (world.isJoinpointArrayConstructionEnabled() && this.isArray()) {
  1494. if (member.getKind()==Member.CONSTRUCTOR) {
  1495. ResolvedMemberImpl ret =
  1496. new ResolvedMemberImpl(Member.CONSTRUCTOR,this,Modifier.PUBLIC,
  1497. ResolvedType.VOID,"<init>",world.resolve(member.getParameterTypes()));
  1498. return ret;
  1499. }
  1500. }
  1501. // if (this.getSuperclass() != ResolvedType.OBJECT && this.getSuperclass() != null) {
  1502. // return getSuperclass().lookupSyntheticMember(member);
  1503. // }
  1504. return null;
  1505. }
  1506. public void clearInterTypeMungers() {
  1507. if (isRawType()) getGenericType().clearInterTypeMungers();
  1508. interTypeMungers = new ArrayList();
  1509. }
  1510. public boolean isTopmostImplementor(ResolvedType interfaceType) {
  1511. if (isInterface()) return false;
  1512. if (!interfaceType.isAssignableFrom(this,true)) return false;
  1513. // check that I'm truly the topmost implementor
  1514. if (this.getSuperclass().isMissing()) return true; // we don't know anything about supertype, and it can't be exposed to weaver
  1515. if (interfaceType.isAssignableFrom(this.getSuperclass(),true)) {
  1516. return false;
  1517. }
  1518. return true;
  1519. }
  1520. public ResolvedType getTopmostImplementor(ResolvedType interfaceType) {
  1521. if (isInterface()) return null;
  1522. if (!interfaceType.isAssignableFrom(this)) return null;
  1523. // Check if my super class is an implementor?
  1524. ResolvedType higherType = this.getSuperclass().getTopmostImplementor(interfaceType);
  1525. if (higherType!=null) return higherType;
  1526. return this;
  1527. }
  1528. private ResolvedType findHigher(ResolvedType other) {
  1529. if (this == other) return this;
  1530. for(Iterator i = other.getDirectSupertypes(); i.hasNext(); ) {
  1531. ResolvedType rtx = (ResolvedType)i.next();
  1532. boolean b = this.isAssignableFrom(rtx);
  1533. if (b) return rtx;
  1534. }
  1535. return null;
  1536. }
  1537. public List getExposedPointcuts() {
  1538. List ret = new ArrayList();
  1539. if (getSuperclass() != null) ret.addAll(getSuperclass().getExposedPointcuts());
  1540. for (Iterator i = Arrays.asList(getDeclaredInterfaces()).iterator(); i.hasNext(); ) {
  1541. ResolvedType t = (ResolvedType)i.next();
  1542. addPointcutsResolvingConflicts(ret, Arrays.asList(t.getDeclaredPointcuts()), false);
  1543. }
  1544. addPointcutsResolvingConflicts(ret, Arrays.asList(getDeclaredPointcuts()), true);
  1545. for (Iterator i = ret.iterator(); i.hasNext(); ) {
  1546. ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition)i.next();
  1547. // System.err.println("looking at: " + inherited + " in " + this);
  1548. // System.err.println(" " + inherited.isAbstract() + " in " + this.isAbstract());
  1549. if (inherited.isAbstract()) {
  1550. if (!this.isAbstract()) {
  1551. getWorld().showMessage(IMessage.ERROR,
  1552. WeaverMessages.format(WeaverMessages.POINCUT_NOT_CONCRETE,inherited,this.getName()),
  1553. inherited.getSourceLocation(), this.getSourceLocation());
  1554. }
  1555. }
  1556. }
  1557. return ret;
  1558. }
  1559. private void addPointcutsResolvingConflicts(List acc, List added, boolean isOverriding) {
  1560. for (Iterator i = added.iterator(); i.hasNext();) {
  1561. ResolvedPointcutDefinition toAdd =
  1562. (ResolvedPointcutDefinition) i.next();
  1563. //System.err.println("adding: " + toAdd);
  1564. for (Iterator j = acc.iterator(); j.hasNext();) {
  1565. ResolvedPointcutDefinition existing =
  1566. (ResolvedPointcutDefinition) j.next();
  1567. if (existing == toAdd) continue;
  1568. if (!isVisible(existing.getModifiers(),
  1569. existing.getDeclaringType().resolve(getWorld()),
  1570. this)) {
  1571. continue;
  1572. }
  1573. if (conflictingSignature(existing, toAdd)) {
  1574. if (isOverriding) {
  1575. checkLegalOverride(existing, toAdd);
  1576. j.remove();
  1577. } else {
  1578. getWorld().showMessage(
  1579. IMessage.ERROR,
  1580. WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS,this.getName() + toAdd.getSignature()),
  1581. existing.getSourceLocation(),
  1582. toAdd.getSourceLocation());
  1583. j.remove();
  1584. }
  1585. }
  1586. }
  1587. acc.add(toAdd);
  1588. }
  1589. }
  1590. public ISourceLocation getSourceLocation() {
  1591. return null;
  1592. }
  1593. public boolean isExposedToWeaver() {
  1594. return false;
  1595. }
  1596. public WeaverStateInfo getWeaverState() {
  1597. return null;
  1598. }
  1599. /**
  1600. * Overridden by ReferenceType to return a sensible answer for parameterized and raw types.
  1601. *
  1602. * @return
  1603. */
  1604. public ResolvedType getGenericType() {
  1605. if (!(isParameterizedType() || isRawType()))
  1606. throw new BCException("The type "+getBaseName()+" is not parameterized or raw - it has no generic type");
  1607. return null;
  1608. }
  1609. /**
  1610. * overriden by ReferenceType to return the gsig for a generic type
  1611. * @return
  1612. */
  1613. public String getGenericSignature() {
  1614. return "";
  1615. }
  1616. public ResolvedType parameterizedWith(UnresolvedType[] typeParameters) {
  1617. if (!(isGenericType() || isParameterizedType())) return this;
  1618. return TypeFactory.createParameterizedType(this.getGenericType(), typeParameters, getWorld());
  1619. }
  1620. /**
  1621. * Iff I am a parameterized type, and any of my parameters are type variable
  1622. * references, return a version with those type parameters replaced in accordance
  1623. * with the passed bindings.
  1624. */
  1625. public UnresolvedType parameterize(Map typeBindings) {
  1626. if (!isParameterizedType()) return this;//throw new IllegalStateException("Can't parameterize a type that is not a parameterized type");
  1627. boolean workToDo = false;
  1628. for (int i = 0; i < typeParameters.length; i++) {
  1629. if (typeParameters[i].isTypeVariableReference() ||
  1630. (typeParameters[i] instanceof BoundedReferenceType)) {
  1631. workToDo = true;
  1632. }
  1633. }
  1634. if (!workToDo) {
  1635. return this;
  1636. } else {
  1637. UnresolvedType[] newTypeParams = new UnresolvedType[typeParameters.length];
  1638. for (int i = 0; i < newTypeParams.length; i++) {
  1639. newTypeParams[i] = typeParameters[i];
  1640. if (newTypeParams[i].isTypeVariableReference()) {
  1641. TypeVariableReferenceType tvrt = (TypeVariableReferenceType) newTypeParams[i];
  1642. UnresolvedType binding = (UnresolvedType) typeBindings.get(tvrt.getTypeVariable().getName());
  1643. if (binding != null) newTypeParams[i] = binding;
  1644. } else if (newTypeParams[i] instanceof BoundedReferenceType) {
  1645. BoundedReferenceType brType = (BoundedReferenceType)newTypeParams[i];
  1646. newTypeParams[i] = brType.parameterize(typeBindings);
  1647. // brType.parameterize(typeBindings)
  1648. }
  1649. }
  1650. return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld());
  1651. }
  1652. }
  1653. public boolean hasParameterizedSuperType() {
  1654. getParameterizedSuperTypes();
  1655. return parameterizedSuperTypes.length > 0;
  1656. }
  1657. public boolean hasGenericSuperType() {
  1658. ResolvedType[] superTypes = getDeclaredInterfaces();
  1659. for (int i = 0; i < superTypes.length; i++) {
  1660. if (superTypes[i].isGenericType()) return true;
  1661. }
  1662. return false;
  1663. }
  1664. private ResolvedType[] parameterizedSuperTypes = null;
  1665. /**
  1666. * Similar to the above method, but accumulates the super types
  1667. *
  1668. * @return
  1669. */
  1670. public ResolvedType[] getParameterizedSuperTypes() {
  1671. if (parameterizedSuperTypes != null) return parameterizedSuperTypes;
  1672. List accumulatedTypes = new ArrayList();
  1673. accumulateParameterizedSuperTypes(this,accumulatedTypes);
  1674. ResolvedType[] ret = new ResolvedType[accumulatedTypes.size()];
  1675. parameterizedSuperTypes = (ResolvedType[]) accumulatedTypes.toArray(ret);
  1676. return parameterizedSuperTypes;
  1677. }
  1678. private void accumulateParameterizedSuperTypes(ResolvedType forType, List parameterizedTypeList) {
  1679. if (forType.isParameterizedType()) {
  1680. parameterizedTypeList.add(forType);
  1681. }
  1682. if (forType.getSuperclass() != null) {
  1683. accumulateParameterizedSuperTypes(forType.getSuperclass(), parameterizedTypeList);
  1684. }
  1685. ResolvedType[] interfaces = forType.getDeclaredInterfaces();
  1686. for (int i = 0; i < interfaces.length; i++) {
  1687. accumulateParameterizedSuperTypes(interfaces[i], parameterizedTypeList);
  1688. }
  1689. }
  1690. /**
  1691. * Types may have pointcuts just as they have methods and fields.
  1692. */
  1693. public ResolvedPointcutDefinition findPointcut(String name, World world) {
  1694. throw new UnsupportedOperationException("Not yet implemenented");
  1695. }
  1696. /**
  1697. * @return true if assignable to java.lang.Exception
  1698. */
  1699. public boolean isException() {
  1700. return (world.getCoreType(UnresolvedType.JAVA_LANG_EXCEPTION).isAssignableFrom(this));
  1701. }
  1702. /**
  1703. * @return true if it is an exception and it is a checked one, false otherwise.
  1704. */
  1705. public boolean isCheckedException() {
  1706. if (!isException()) return false;
  1707. if (world.getCoreType(UnresolvedType.RUNTIME_EXCEPTION).isAssignableFrom(this)) return false;
  1708. return true;
  1709. }
  1710. /**
  1711. * Determines if variables of this type could be assigned values of another
  1712. * with lots of help.
  1713. * java.lang.Object is convertable from all types.
  1714. * A primitive type is convertable from X iff it's assignable from X.
  1715. * A reference type is convertable from X iff it's coerceable from X.
  1716. * In other words, X isConvertableFrom Y iff the compiler thinks that _some_ value of Y
  1717. * could be assignable to a variable of type X without loss of precision.
  1718. *
  1719. * @param other the other type
  1720. * @param world the {@link World} in which the possible assignment should be checked.
  1721. * @return true iff variables of this type could be assigned values of other with possible conversion
  1722. */
  1723. public final boolean isConvertableFrom(ResolvedType other) {
  1724. // // version from TypeX
  1725. // if (this.equals(OBJECT)) return true;
  1726. // if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
  1727. // return this.isCoerceableFrom(other);
  1728. //
  1729. // version from ResolvedTypeX
  1730. if (this.equals(OBJECT)) return true;
  1731. if (world.isInJava5Mode()) {
  1732. if (this.isPrimitiveType()^other.isPrimitiveType()) { // If one is primitive and the other isnt
  1733. if (validBoxing.contains(this.getSignature()+other.getSignature())) return true;
  1734. }
  1735. }
  1736. if (this.isPrimitiveType() || other.isPrimitiveType()) return this.isAssignableFrom(other);
  1737. return this.isCoerceableFrom(other);
  1738. }
  1739. /**
  1740. * Determines if the variables of this type could be assigned values
  1741. * of another type without casting. This still allows for assignment conversion
  1742. * as per JLS 2ed 5.2. For object types, this means supertypeOrEqual(THIS, OTHER).
  1743. *
  1744. * @param other the other type
  1745. * @param world the {@link World} in which the possible assignment should be checked.
  1746. * @return true iff variables of this type could be assigned values of other without casting
  1747. * @throws NullPointerException if other is null
  1748. */
  1749. public abstract boolean isAssignableFrom(ResolvedType other);
  1750. public abstract boolean isAssignableFrom(ResolvedType other, boolean allowMissing);
  1751. /**
  1752. * Determines if values of another type could possibly be cast to
  1753. * this type. The rules followed are from JLS 2ed 5.5, "Casting Conversion".
  1754. * <p/>
  1755. * <p> This method should be commutative, i.e., for all UnresolvedType a, b and all World w:
  1756. * <p/>
  1757. * <blockquote><pre>
  1758. * a.isCoerceableFrom(b, w) == b.isCoerceableFrom(a, w)
  1759. * </pre></blockquote>
  1760. *
  1761. * @param other the other type
  1762. * @param world the {@link World} in which the possible coersion should be checked.
  1763. * @return true iff values of other could possibly be cast to this type.
  1764. * @throws NullPointerException if other is null.
  1765. */
  1766. public abstract boolean isCoerceableFrom(ResolvedType other);
  1767. public boolean needsNoConversionFrom(ResolvedType o) {
  1768. return isAssignableFrom(o);
  1769. }
  1770. /**
  1771. * Implemented by ReferenceTypes
  1772. */
  1773. public String getSignatureForAttribute() {
  1774. throw new RuntimeException("Cannot ask this type "+this+" for a generic sig attribute");
  1775. }
  1776. private FuzzyBoolean parameterizedWithAMemberTypeVariable = FuzzyBoolean.MAYBE;
  1777. /**
  1778. * return true if the parameterization of this type includes a member type variable. Member
  1779. * type variables occur in generic methods/ctors.
  1780. */
  1781. public boolean isParameterizedWithAMemberTypeVariable() {
  1782. // MAYBE means we haven't worked it out yet...
  1783. if (parameterizedWithAMemberTypeVariable==FuzzyBoolean.MAYBE) {
  1784. // if there are no type parameters then we cant be...
  1785. if (typeParameters==null || typeParameters.length==0) {
  1786. parameterizedWithAMemberTypeVariable = FuzzyBoolean.NO;
  1787. return false;
  1788. }
  1789. for (int i = 0; i < typeParameters.length; i++) {
  1790. UnresolvedType aType = (ResolvedType)typeParameters[i];
  1791. if (aType.isTypeVariableReference() &&
  1792. // assume the worst - if its definetly not a type declared one, it could be anything
  1793. ((TypeVariableReference)aType).getTypeVariable().getDeclaringElementKind()!=TypeVariable.TYPE) {
  1794. parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
  1795. return true;
  1796. }
  1797. if (aType.isParameterizedType()) {
  1798. boolean b = aType.isParameterizedWithAMemberTypeVariable();
  1799. if (b) {
  1800. parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
  1801. return true;
  1802. }
  1803. }
  1804. if (aType.isGenericWildcard()) {
  1805. if (aType.isExtends()) {
  1806. boolean b = false;
  1807. UnresolvedType upperBound = aType.getUpperBound();
  1808. if (upperBound.isParameterizedType()) {
  1809. b = upperBound.isParameterizedWithAMemberTypeVariable();
  1810. } else if (upperBound.isTypeVariableReference() && ((TypeVariableReference)upperBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
  1811. b = true;
  1812. }
  1813. if (b) {
  1814. parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
  1815. return true;
  1816. }
  1817. // FIXME asc need to check additional interface bounds
  1818. }
  1819. if (aType.isSuper()) {
  1820. boolean b = false;
  1821. UnresolvedType lowerBound = aType.getLowerBound();
  1822. if (lowerBound.isParameterizedType()) {
  1823. b = lowerBound.isParameterizedWithAMemberTypeVariable();
  1824. } else if (lowerBound.isTypeVariableReference() && ((TypeVariableReference)lowerBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) {
  1825. b = true;
  1826. }
  1827. if (b) {
  1828. parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES;
  1829. return true;
  1830. }
  1831. }
  1832. }
  1833. }
  1834. parameterizedWithAMemberTypeVariable=FuzzyBoolean.NO;
  1835. }
  1836. return parameterizedWithAMemberTypeVariable.alwaysTrue();
  1837. }
  1838. protected boolean ajMembersNeedParameterization() {
  1839. if (isParameterizedType()) return true;
  1840. if (getSuperclass() != null) return getSuperclass().ajMembersNeedParameterization();
  1841. return false;
  1842. }
  1843. protected Map getAjMemberParameterizationMap() {
  1844. Map myMap = getMemberParameterizationMap();
  1845. if (myMap.size() == 0) {
  1846. // might extend a parameterized aspect that we also need to consider...
  1847. if (getSuperclass() != null) return getSuperclass().getAjMemberParameterizationMap();
  1848. }
  1849. return myMap;
  1850. }
  1851. public void setBinaryPath(String binaryPath) {
  1852. this.binaryPath = binaryPath;
  1853. }
  1854. /**
  1855. * Returns the path to the jar or class file from which this
  1856. * binary aspect came or null if not a binary aspect
  1857. */
  1858. public String getBinaryPath() {
  1859. return binaryPath;
  1860. }
  1861. }