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.

ResolvedTypeX.java 50KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import java.lang.reflect.Modifier;
  14. import java.util.ArrayList;
  15. import java.util.Arrays;
  16. import java.util.Collection;
  17. import java.util.Collections;
  18. import java.util.Iterator;
  19. import java.util.List;
  20. import org.aspectj.bridge.IMessage;
  21. import org.aspectj.bridge.ISourceLocation;
  22. import org.aspectj.bridge.Message;
  23. import org.aspectj.bridge.MessageUtil;
  24. import org.aspectj.weaver.patterns.Declare;
  25. import org.aspectj.weaver.patterns.PerClause;
  26. public abstract class ResolvedTypeX extends TypeX {
  27. protected World world;
  28. ResolvedTypeX(String signature, World world) {
  29. super(signature);
  30. this.world = world;
  31. }
  32. // ---- things that don't require a world
  33. /** returns Iterator<ResolvedTypeX>
  34. */
  35. public final Iterator getDirectSupertypes() {
  36. Iterator ifacesIterator = Iterators.array(getDeclaredInterfaces());
  37. ResolvedTypeX superclass = getSuperclass();
  38. if (superclass == null) {
  39. return ifacesIterator;
  40. } else {
  41. return Iterators.snoc(ifacesIterator, superclass);
  42. }
  43. }
  44. public abstract ResolvedMember[] getDeclaredFields();
  45. public abstract ResolvedMember[] getDeclaredMethods();
  46. public abstract ResolvedTypeX[] getDeclaredInterfaces();
  47. public abstract ResolvedMember[] getDeclaredPointcuts();
  48. public abstract ResolvedTypeX getSuperclass();
  49. public abstract int getModifiers();
  50. public abstract boolean needsNoConversionFrom(TypeX other);
  51. public abstract boolean isCoerceableFrom(TypeX other);
  52. public abstract boolean isAssignableFrom(TypeX other);
  53. // ---- things that would require a world if I weren't resolved
  54. public final Iterator getDirectSupertypes(World world) {
  55. return getDirectSupertypes();
  56. }
  57. public final ResolvedMember[] getDeclaredFields(World world) {
  58. return getDeclaredFields();
  59. }
  60. public final ResolvedMember[] getDeclaredMethods(World world) {
  61. return getDeclaredMethods();
  62. }
  63. public final TypeX[] getDeclaredInterfaces(World world) {
  64. return getDeclaredInterfaces();
  65. }
  66. public final ResolvedMember[] getDeclaredPointcuts(World world) {
  67. return getDeclaredPointcuts();
  68. }
  69. public final int getModifiers(World world) {
  70. return getModifiers();
  71. }
  72. public final TypeX getSuperclass(World world) {
  73. return getSuperclass();
  74. }
  75. // conversions
  76. public final boolean isAssignableFrom(TypeX other, World world) {
  77. return isAssignableFrom(other);
  78. }
  79. public final boolean isCoerceableFrom(TypeX other, World world) {
  80. return isCoerceableFrom(other);
  81. }
  82. public boolean needsNoConversionFrom(TypeX other, World world) {
  83. return needsNoConversionFrom(other);
  84. }
  85. public final boolean isConvertableFrom(TypeX other) {
  86. if (this.equals(OBJECT) || other.equals(OBJECT)) return true;
  87. return this.isCoerceableFrom(other);
  88. }
  89. // utilities
  90. public ResolvedTypeX getResolvedComponentType() {
  91. return null;
  92. }
  93. public ResolvedTypeX resolve(World world) {
  94. return this;
  95. }
  96. public World getWorld() {
  97. return world;
  98. }
  99. // ---- things from object
  100. public final boolean equals(Object other) {
  101. if (other instanceof ResolvedTypeX) {
  102. return this == other;
  103. } else {
  104. return super.equals(other);
  105. }
  106. }
  107. // ---- difficult things
  108. /**
  109. * returns an iterator through all of the fields of this type, in order
  110. * for checking from JVM spec 2ed 5.4.3.2. This means that the order is
  111. *
  112. * <ul><li> fields from current class </li>
  113. * <li> recur into direct superinterfaces </li>
  114. * <li> recur into superclass </li>
  115. * </ul>
  116. *
  117. * We keep a hashSet of interfaces that we've visited so we don't spiral
  118. * out into 2^n land.
  119. */
  120. public Iterator getFields() {
  121. final Iterators.Filter dupFilter = Iterators.dupFilter();
  122. Iterators.Getter typeGetter = new Iterators.Getter() {
  123. public Iterator get(Object o) {
  124. return
  125. dupFilter.filter(
  126. ((ResolvedTypeX)o).getDirectSupertypes());
  127. }
  128. };
  129. Iterators.Getter fieldGetter = new Iterators.Getter() {
  130. public Iterator get(Object o) {
  131. return Iterators.array(((ResolvedTypeX)o).getDeclaredFields());
  132. }
  133. };
  134. return
  135. Iterators.mapOver(
  136. Iterators.recur(this, typeGetter),
  137. fieldGetter);
  138. }
  139. /**
  140. * returns an iterator through all of the methods of this type, in order
  141. * for checking from JVM spec 2ed 5.4.3.3. This means that the order is
  142. *
  143. * <ul><li> methods from current class </li>
  144. * <li> recur into superclass, all the way up, not touching interfaces </li>
  145. * <li> recur into all superinterfaces, in some unspecified order </li>
  146. * </ul>
  147. *
  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 getMethods() {
  152. final Iterators.Filter dupFilter = Iterators.dupFilter();
  153. Iterators.Getter ifaceGetter = new Iterators.Getter() {
  154. public Iterator get(Object o) {
  155. return
  156. dupFilter.filter(
  157. Iterators.array(((ResolvedTypeX)o).getDeclaredInterfaces())
  158. );
  159. }
  160. };
  161. Iterators.Getter methodGetter = new Iterators.Getter() {
  162. public Iterator get(Object o) {
  163. return Iterators.array(((ResolvedTypeX)o).getDeclaredMethods());
  164. }
  165. };
  166. return
  167. Iterators.mapOver(
  168. Iterators.append(
  169. new Iterator() {
  170. ResolvedTypeX curr = ResolvedTypeX.this;
  171. public boolean hasNext() {
  172. return curr != null;
  173. }
  174. public Object next() {
  175. ResolvedTypeX ret = curr;
  176. curr = curr.getSuperclass();
  177. return ret;
  178. }
  179. public void remove() {
  180. throw new UnsupportedOperationException();
  181. }
  182. },
  183. Iterators.recur(this, ifaceGetter)),
  184. methodGetter);
  185. }
  186. /**
  187. * described in JVM spec 2ed 5.4.3.2
  188. */
  189. public ResolvedMember lookupField(Member m) {
  190. return lookupMember(m, getFields());
  191. }
  192. /**
  193. * described in JVM spec 2ed 5.4.3.3
  194. */
  195. public ResolvedMember lookupMethod(Member m) {
  196. return lookupMember(m, getMethods());
  197. }
  198. /** return null if not found */
  199. private ResolvedMember lookupMember(Member m, Iterator i) {
  200. while (i.hasNext()) {
  201. ResolvedMember f = (ResolvedMember) i.next();
  202. if (matches(f, m)) return f;
  203. }
  204. return null; //ResolvedMember.Missing;
  205. //throw new BCException("can't find " + m);
  206. }
  207. /** return null if not found */
  208. private ResolvedMember lookupMember(Member m, ResolvedMember[] a) {
  209. for (int i = 0; i < a.length; i++) {
  210. ResolvedMember f = a[i];
  211. if (matches(f, m)) return f;
  212. }
  213. return null;
  214. }
  215. public static boolean matches(Member m1, Member m2) {
  216. if (m1 == null) return m2 == null;
  217. if (m2 == null) return false;
  218. return m1.getName().equals(m2.getName()) && m1.getSignature().equals(m2.getSignature());
  219. }
  220. public static boolean conflictingSignature(Member m1, Member m2) {
  221. if (m1 == null || m2 == null) return false;
  222. if (!m1.getName().equals(m2.getName())) { return false; }
  223. if (m1.getKind() != m2.getKind()) { return false; }
  224. if (m1.getKind() == Member.FIELD) {
  225. return m1.getDeclaringType().equals(m2.getDeclaringType());
  226. } else if (m1.getKind() == Member.POINTCUT) {
  227. return true;
  228. }
  229. TypeX[] p1 = m1.getParameterTypes();
  230. TypeX[] p2 = m2.getParameterTypes();
  231. int n = p1.length;
  232. if (n != p2.length) return false;
  233. for (int i=0; i < n; i++) {
  234. if (!p1[i].equals(p2[i])) return false;
  235. }
  236. return true;
  237. }
  238. /**
  239. * returns an iterator through all of the pointcuts of this type, in order
  240. * for checking from JVM spec 2ed 5.4.3.2 (as for fields). This means that the order is
  241. *
  242. * <ul><li> pointcuts from current class </li>
  243. * <li> recur into direct superinterfaces </li>
  244. * <li> recur into superclass </li>
  245. * </ul>
  246. *
  247. * We keep a hashSet of interfaces that we've visited so we don't spiral
  248. * out into 2^n land.
  249. */
  250. public Iterator getPointcuts() {
  251. final Iterators.Filter dupFilter = Iterators.dupFilter();
  252. // same order as fields
  253. Iterators.Getter typeGetter = new Iterators.Getter() {
  254. public Iterator get(Object o) {
  255. return
  256. dupFilter.filter(
  257. ((ResolvedTypeX)o).getDirectSupertypes());
  258. }
  259. };
  260. Iterators.Getter pointcutGetter = new Iterators.Getter() {
  261. public Iterator get(Object o) {
  262. //System.err.println("getting for " + o);
  263. return Iterators.array(((ResolvedTypeX)o).getDeclaredPointcuts());
  264. }
  265. };
  266. return
  267. Iterators.mapOver(
  268. Iterators.recur(this, typeGetter),
  269. pointcutGetter);
  270. }
  271. public ResolvedPointcutDefinition findPointcut(String name) {
  272. //System.err.println("looking for pointcuts " + this);
  273. for (Iterator i = getPointcuts(); i.hasNext(); ) {
  274. ResolvedPointcutDefinition f = (ResolvedPointcutDefinition) i.next();
  275. //System.err.println(f);
  276. if (name.equals(f.getName())) {
  277. return f;
  278. }
  279. }
  280. return null; // should we throw an exception here?
  281. }
  282. // all about collecting CrosscuttingMembers
  283. //??? collecting data-structure, shouldn't really be a field
  284. public CrosscuttingMembers crosscuttingMembers;
  285. public CrosscuttingMembers collectCrosscuttingMembers() {
  286. crosscuttingMembers = new CrosscuttingMembers(this);
  287. crosscuttingMembers.setPerClause(getPerClause());
  288. crosscuttingMembers.addShadowMungers(collectShadowMungers());
  289. crosscuttingMembers.addTypeMungers(getTypeMungers());
  290. crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers()));
  291. crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses());
  292. //System.err.println("collected cc members: " + this + ", " + collectDeclares());
  293. return crosscuttingMembers;
  294. }
  295. public final Collection collectDeclares(boolean includeAdviceLike) {
  296. if (! this.isAspect() ) return Collections.EMPTY_LIST;
  297. ArrayList ret = new ArrayList();
  298. //if (this.isAbstract()) {
  299. for (Iterator i = getDeclares().iterator(); i.hasNext();) {
  300. Declare dec = (Declare) i.next();
  301. if (!dec.isAdviceLike()) ret.add(dec);
  302. }
  303. if (!includeAdviceLike) return ret;
  304. if (!this.isAbstract()) {
  305. //ret.addAll(getDeclares());
  306. final Iterators.Filter dupFilter = Iterators.dupFilter();
  307. Iterators.Getter typeGetter = new Iterators.Getter() {
  308. public Iterator get(Object o) {
  309. return
  310. dupFilter.filter(
  311. ((ResolvedTypeX)o).getDirectSupertypes());
  312. }
  313. };
  314. Iterator typeIterator = Iterators.recur(this, typeGetter);
  315. while (typeIterator.hasNext()) {
  316. ResolvedTypeX ty = (ResolvedTypeX) typeIterator.next();
  317. //System.out.println("super: " + ty + ", " + );
  318. for (Iterator i = ty.getDeclares().iterator(); i.hasNext();) {
  319. Declare dec = (Declare) i.next();
  320. if (dec.isAdviceLike()) ret.add(dec);
  321. }
  322. }
  323. }
  324. return ret;
  325. }
  326. private final Collection collectShadowMungers() {
  327. if (! this.isAspect() || this.isAbstract() || this.doesNotExposeShadowMungers()) return Collections.EMPTY_LIST;
  328. ArrayList acc = new ArrayList();
  329. final Iterators.Filter dupFilter = Iterators.dupFilter();
  330. Iterators.Getter typeGetter = new Iterators.Getter() {
  331. public Iterator get(Object o) {
  332. return
  333. dupFilter.filter(
  334. ((ResolvedTypeX)o).getDirectSupertypes());
  335. }
  336. };
  337. Iterator typeIterator = Iterators.recur(this, typeGetter);
  338. while (typeIterator.hasNext()) {
  339. ResolvedTypeX ty = (ResolvedTypeX) typeIterator.next();
  340. acc.addAll(ty.getDeclaredShadowMungers());
  341. }
  342. return acc;
  343. }
  344. protected boolean doesNotExposeShadowMungers() {
  345. return false;
  346. }
  347. public PerClause getPerClause() { return null; }
  348. protected Collection getDeclares() {
  349. return Collections.EMPTY_LIST;
  350. }
  351. protected Collection getTypeMungers() { return Collections.EMPTY_LIST; }
  352. protected Collection getPrivilegedAccesses() { return Collections.EMPTY_LIST; }
  353. // ---- useful things
  354. public final boolean isInterface() {
  355. return Modifier.isInterface(getModifiers());
  356. }
  357. public final boolean isAbstract() {
  358. return Modifier.isAbstract(getModifiers());
  359. }
  360. public boolean isClass() {
  361. return false;
  362. }
  363. public boolean isAspect() {
  364. return false;
  365. }
  366. public boolean isSynthetic() {
  367. return signature.indexOf("$ajc") != -1;
  368. }
  369. public final boolean isFinal() {
  370. return Modifier.isFinal(getModifiers());
  371. }
  372. public Collection getDeclaredAdvice() {
  373. List l = new ArrayList();
  374. ResolvedMember[] methods = getDeclaredMethods();
  375. for (int i=0, len = methods.length; i < len; i++) {
  376. ShadowMunger munger = methods[i].getAssociatedShadowMunger();
  377. if (munger != null) l.add(munger);
  378. }
  379. return l;
  380. }
  381. private List shadowMungers = new ArrayList(0);
  382. public Collection getDeclaredShadowMungers() {
  383. Collection c = getDeclaredAdvice();
  384. c.addAll(shadowMungers);
  385. return c;
  386. }
  387. public void addShadowMunger(ShadowMunger munger) {
  388. shadowMungers.add(munger);
  389. }
  390. // ---- only for testing!
  391. public ResolvedMember[] getDeclaredJavaFields() {
  392. return filterInJavaVisible(getDeclaredFields());
  393. }
  394. public ResolvedMember[] getDeclaredJavaMethods() {
  395. return filterInJavaVisible(getDeclaredMethods());
  396. }
  397. public ShadowMunger[] getDeclaredShadowMungersArray() {
  398. List l = (List) getDeclaredShadowMungers();
  399. return (ShadowMunger[]) l.toArray(new ShadowMunger[l.size()]);
  400. }
  401. private ResolvedMember[] filterInJavaVisible(ResolvedMember[] ms) {
  402. List l = new ArrayList();
  403. for (int i=0, len = ms.length; i < len; i++) {
  404. if (! ms[i].isAjSynthetic() && ms[i].getAssociatedShadowMunger() == null) {
  405. l.add(ms[i]);
  406. }
  407. }
  408. return (ResolvedMember[]) l.toArray(new ResolvedMember[l.size()]);
  409. }
  410. public abstract ISourceContext getSourceContext();
  411. // ---- fields
  412. public static final ResolvedTypeX[] NONE = new ResolvedTypeX[0];
  413. public static final Primitive BYTE = new Primitive("B", 1, 0);
  414. public static final Primitive CHAR = new Primitive("C", 1, 1);
  415. public static final Primitive DOUBLE = new Primitive("D", 2, 2);
  416. public static final Primitive FLOAT = new Primitive("F", 1, 3);
  417. public static final Primitive INT = new Primitive("I", 1, 4);
  418. public static final Primitive LONG = new Primitive("J", 2, 5);
  419. public static final Primitive SHORT = new Primitive("S", 1, 6);
  420. public static final Primitive VOID = new Primitive("V", 0, 8);
  421. public static final Primitive BOOLEAN = new Primitive("Z", 1, 7);
  422. public static final Missing MISSING = new Missing();
  423. // ---- types
  424. public static class Name extends ResolvedTypeX {
  425. private ConcreteName delegate = null;
  426. private ISourceContext sourceContext = null;
  427. private int startPos = 0;
  428. private int endPos = 0;
  429. //??? should set delegate before any use
  430. public Name(String signature, World world) {
  431. super(signature, world);
  432. }
  433. public final boolean isClass() {
  434. return delegate.isClass();
  435. }
  436. public boolean isAspect() {
  437. return delegate.isAspect();
  438. }
  439. public final boolean needsNoConversionFrom(TypeX o) {
  440. return isAssignableFrom(o);
  441. }
  442. public final boolean isAssignableFrom(TypeX o) {
  443. if (o.isPrimitive()) return false;
  444. ResolvedTypeX other = o.resolve(world);
  445. return isAssignableFrom(other);
  446. }
  447. public final boolean isCoerceableFrom(TypeX o) {
  448. ResolvedTypeX other = o.resolve(world);
  449. if (this.isAssignableFrom(other) || other.isAssignableFrom(this)) {
  450. return true;
  451. }
  452. if (!this.isInterface() && !other.isInterface()) {
  453. return false;
  454. }
  455. if (this.isFinal() || other.isFinal()) {
  456. return false;
  457. }
  458. // ??? needs to be Methods, not just declared methods? JLS 5.5 unclear
  459. ResolvedMember[] a = getDeclaredMethods();
  460. ResolvedMember[] b = other.getDeclaredMethods(); //??? is this cast always safe
  461. for (int ai = 0, alen = a.length; ai < alen; ai++) {
  462. for (int bi = 0, blen = b.length; bi < blen; bi++) {
  463. if (! b[bi].isCompatibleWith(a[ai])) return false;
  464. }
  465. }
  466. return true;
  467. }
  468. private boolean isAssignableFrom(ResolvedTypeX other) {
  469. if (this == other) return true;
  470. for(Iterator i = other.getDirectSupertypes(); i.hasNext(); ) {
  471. if (this.isAssignableFrom((ResolvedTypeX) i.next())) return true;
  472. }
  473. return false;
  474. }
  475. public ISourceContext getSourceContext() {
  476. return sourceContext;
  477. }
  478. public ISourceLocation getSourceLocation() {
  479. if (sourceContext == null) return null;
  480. return sourceContext.makeSourceLocation(new Position(startPos, endPos));
  481. }
  482. public boolean isExposedToWeaver() {
  483. return (delegate == null) || delegate.isExposedToWeaver(); //??? where does this belong
  484. }
  485. public WeaverStateInfo getWeaverState() {
  486. return delegate.getWeaverState();
  487. }
  488. public ResolvedMember[] getDeclaredFields() {
  489. return delegate.getDeclaredFields();
  490. }
  491. public ResolvedTypeX[] getDeclaredInterfaces() {
  492. return delegate.getDeclaredInterfaces();
  493. }
  494. public ResolvedMember[] getDeclaredMethods() {
  495. return delegate.getDeclaredMethods();
  496. }
  497. public ResolvedMember[] getDeclaredPointcuts() {
  498. return delegate.getDeclaredPointcuts();
  499. }
  500. public PerClause getPerClause() { return delegate.getPerClause(); }
  501. protected Collection getDeclares() { return delegate.getDeclares(); }
  502. protected Collection getTypeMungers() { return delegate.getTypeMungers(); }
  503. protected Collection getPrivilegedAccesses() { return delegate.getPrivilegedAccesses(); }
  504. public int getModifiers() {
  505. return delegate.getModifiers();
  506. }
  507. public ResolvedTypeX getSuperclass() {
  508. return delegate.getSuperclass();
  509. }
  510. public ConcreteName getDelegate() {
  511. return delegate;
  512. }
  513. public void setDelegate(ConcreteName delegate) {
  514. this.delegate = delegate;
  515. }
  516. public int getEndPos() {
  517. return endPos;
  518. }
  519. public int getStartPos() {
  520. return startPos;
  521. }
  522. public void setEndPos(int endPos) {
  523. this.endPos = endPos;
  524. }
  525. public void setSourceContext(ISourceContext sourceContext) {
  526. this.sourceContext = sourceContext;
  527. }
  528. public void setStartPos(int startPos) {
  529. this.startPos = startPos;
  530. }
  531. public boolean doesNotExposeShadowMungers() {
  532. return delegate.doesNotExposeShadowMungers();
  533. }
  534. }
  535. public static abstract class ConcreteName {
  536. //protected ISourceContext sourceContext;
  537. protected boolean exposedToWeaver;
  538. protected ResolvedTypeX.Name resolvedTypeX;
  539. public ConcreteName(ResolvedTypeX.Name resolvedTypeX, boolean exposedToWeaver) {
  540. //???super(signature, world);
  541. this.resolvedTypeX = resolvedTypeX;
  542. this.exposedToWeaver = exposedToWeaver;
  543. }
  544. public final boolean isClass() {
  545. return !isAspect() && !isInterface();
  546. }
  547. public abstract boolean isAspect();
  548. public abstract boolean isInterface();
  549. public abstract ResolvedMember[] getDeclaredFields();
  550. public abstract ResolvedTypeX[] getDeclaredInterfaces();
  551. public abstract ResolvedMember[] getDeclaredMethods();
  552. public abstract ResolvedMember[] getDeclaredPointcuts();
  553. public abstract PerClause getPerClause();
  554. protected abstract Collection getDeclares() ;
  555. protected abstract Collection getTypeMungers();
  556. protected abstract Collection getPrivilegedAccesses();
  557. public abstract int getModifiers();
  558. public abstract ResolvedTypeX getSuperclass();
  559. // public abstract ISourceLocation getSourceLocation();
  560. public abstract WeaverStateInfo getWeaverState();
  561. // public ISourceContext getSourceContext() {
  562. // return sourceContext;
  563. // }
  564. /**
  565. * Designed to be overriden by EclipseType to disable collection of shadow mungers
  566. * during pre-weave compilation phase
  567. */
  568. public boolean doesNotExposeShadowMungers() {
  569. return false;
  570. }
  571. public boolean isExposedToWeaver() {
  572. return exposedToWeaver;
  573. }
  574. public ResolvedTypeX.Name getResolvedTypeX() {
  575. return resolvedTypeX;
  576. }
  577. }
  578. static class Array extends ResolvedTypeX {
  579. ResolvedTypeX componentType;
  580. Array(String s, World world, ResolvedTypeX componentType) {
  581. super(s, world);
  582. this.componentType = componentType;
  583. }
  584. public final ResolvedMember[] getDeclaredFields() {
  585. return ResolvedMember.NONE;
  586. }
  587. public final ResolvedMember[] getDeclaredMethods() {
  588. // ??? should this return clone? Probably not...
  589. // If it ever does, here is the code:
  590. // ResolvedMember cloneMethod =
  591. // new ResolvedMember(Member.METHOD,this,Modifier.PUBLIC,TypeX.OBJECT,"clone",new TypeX[]{});
  592. // return new ResolvedMember[]{cloneMethod};
  593. return ResolvedMember.NONE;
  594. }
  595. public final ResolvedTypeX[] getDeclaredInterfaces() {
  596. return
  597. new ResolvedTypeX[] {
  598. world.getCoreType(CLONEABLE),
  599. world.getCoreType(SERIALIZABLE)
  600. };
  601. }
  602. public final ResolvedMember[] getDeclaredPointcuts() {
  603. return ResolvedMember.NONE;
  604. }
  605. public final ResolvedTypeX getSuperclass() {
  606. return world.getCoreType(OBJECT);
  607. }
  608. public final boolean isAssignableFrom(TypeX o) {
  609. if (! o.isArray()) return false;
  610. if (o.getComponentType().isPrimitive()) {
  611. return o.equals(this);
  612. } else {
  613. return getComponentType().isAssignableFrom(o.getComponentType(), world);
  614. }
  615. }
  616. public final boolean isCoerceableFrom(TypeX o) {
  617. if (o.equals(TypeX.OBJECT) ||
  618. o.equals(TypeX.SERIALIZABLE) ||
  619. o.equals(TypeX.CLONEABLE)) {
  620. return true;
  621. }
  622. if (! o.isArray()) return false;
  623. if (o.getComponentType().isPrimitive()) {
  624. return o.equals(this);
  625. } else {
  626. return getComponentType().isCoerceableFrom(o.getComponentType(), world);
  627. }
  628. }
  629. public final boolean needsNoConversionFrom(TypeX o) {
  630. return isAssignableFrom(o);
  631. }
  632. public final int getModifiers() {
  633. int mask = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
  634. return (componentType.getModifiers() & mask) | Modifier.FINAL;
  635. }
  636. public TypeX getComponentType() {
  637. return componentType;
  638. }
  639. public ResolvedTypeX getResolvedComponentType() {
  640. return componentType;
  641. }
  642. public ISourceContext getSourceContext() {
  643. return getResolvedComponentType().getSourceContext();
  644. }
  645. }
  646. static class Primitive extends ResolvedTypeX {
  647. private int size;
  648. private int index;
  649. Primitive(String signature, int size, int index) {
  650. super(signature, null);
  651. this.size = size;
  652. this.index = index;
  653. }
  654. public final int getSize() {
  655. return size;
  656. }
  657. public final int getModifiers() {
  658. return Modifier.PUBLIC | Modifier.FINAL;
  659. }
  660. public final boolean isPrimitive() {
  661. return true;
  662. }
  663. public final boolean isAssignableFrom(TypeX other) {
  664. if (! other.isPrimitive()) return false;
  665. return assignTable[((Primitive)other).index][index];
  666. }
  667. public final boolean isCoerceableFrom(TypeX other) {
  668. if (this == other) return true;
  669. if (! other.isPrimitive()) return false;
  670. if (index > 6 || ((Primitive)other).index > 6) return false;
  671. return true;
  672. }
  673. public final boolean needsNoConversionFrom(TypeX other) {
  674. if (! other.isPrimitive()) return false;
  675. return noConvertTable[((Primitive)other).index][index];
  676. }
  677. private static final boolean[][] assignTable =
  678. {// to: B C D F I J S V Z from
  679. { true , true , true , true , true , true , true , false, false }, // B
  680. { false, true , true , true , true , true , false, false, false }, // C
  681. { false, false, true , false, false, false, false, false, false }, // D
  682. { false, false, true , true , false, false, false, false, false }, // F
  683. { false, false, true , true , true , true , false, false, false }, // I
  684. { false, false, true , true , false, true , false, false, false }, // J
  685. { false, false, true , true , true , true , true , false, false }, // S
  686. { false, false, false, false, false, false, false, true , false }, // V
  687. { false, false, false, false, false, false, false, false, true }, // Z
  688. };
  689. private static final boolean[][] noConvertTable =
  690. {// to: B C D F I J S V Z from
  691. { true , true , false, false, true , false, true , false, false }, // B
  692. { false, true , false, false, true , false, false, false, false }, // C
  693. { false, false, true , false, false, false, false, false, false }, // D
  694. { false, false, false, true , false, false, false, false, false }, // F
  695. { false, false, false, false, true , false, false, false, false }, // I
  696. { false, false, false, false, false, true , false, false, false }, // J
  697. { false, false, false, false, true , false, true , false, false }, // S
  698. { false, false, false, false, false, false, false, true , false }, // V
  699. { false, false, false, false, false, false, false, false, true }, // Z
  700. };
  701. // ----
  702. public final ResolvedMember[] getDeclaredFields() {
  703. return ResolvedMember.NONE;
  704. }
  705. public final ResolvedMember[] getDeclaredMethods() {
  706. return ResolvedMember.NONE;
  707. }
  708. public final ResolvedTypeX[] getDeclaredInterfaces() {
  709. return ResolvedTypeX.NONE;
  710. }
  711. public final ResolvedMember[] getDeclaredPointcuts() {
  712. return ResolvedMember.NONE;
  713. }
  714. public final ResolvedTypeX getSuperclass() {
  715. return null;
  716. }
  717. public ISourceContext getSourceContext() {
  718. return null;
  719. }
  720. }
  721. static class Missing extends ResolvedTypeX {
  722. Missing() {
  723. super(MISSING_NAME, null);
  724. }
  725. // public final String toString() {
  726. // return "<missing>";
  727. // }
  728. public final String getName() {
  729. return MISSING_NAME;
  730. }
  731. public final ResolvedMember[] getDeclaredFields() {
  732. return ResolvedMember.NONE;
  733. }
  734. public final ResolvedMember[] getDeclaredMethods() {
  735. return ResolvedMember.NONE;
  736. }
  737. public final ResolvedTypeX[] getDeclaredInterfaces() {
  738. return ResolvedTypeX.NONE;
  739. }
  740. public final ResolvedMember[] getDeclaredPointcuts() {
  741. return ResolvedMember.NONE;
  742. }
  743. public final ResolvedTypeX getSuperclass() {
  744. return null;
  745. }
  746. public final int getModifiers() {
  747. return 0;
  748. }
  749. public final boolean isAssignableFrom(TypeX other) {
  750. return false;
  751. }
  752. public final boolean isCoerceableFrom(TypeX other) {
  753. return false;
  754. }
  755. public boolean needsNoConversionFrom(TypeX other) {
  756. return false;
  757. }
  758. public ISourceContext getSourceContext() {
  759. return null;
  760. }
  761. }
  762. /** return null if not found */
  763. public ResolvedMember lookupMemberNoSupers(Member member) {
  764. ResolvedMember ret;
  765. if (member.getKind() == Member.FIELD) {
  766. ret = lookupMember(member, getDeclaredFields());
  767. } else {
  768. // assert member.getKind() == Member.METHOD || member.getKind() == Member.CONSTRUCTOR
  769. ret = lookupMember(member, getDeclaredMethods());
  770. }
  771. if (ret == null && interTypeMungers != null) {
  772. for (Iterator i = interTypeMungers.iterator(); i.hasNext();) {
  773. ConcreteTypeMunger tm = (ConcreteTypeMunger) i.next();
  774. if (matches(tm.getSignature(), member)) {
  775. return tm.getSignature();
  776. }
  777. }
  778. }
  779. return ret;
  780. }
  781. protected List interTypeMungers = new ArrayList(0);
  782. public List getInterTypeMungers() {
  783. return interTypeMungers;
  784. }
  785. /**
  786. * ??? This method is O(N*M) where N = number of methods and M is number of
  787. * inter-type declarations in my super
  788. */
  789. public List getInterTypeMungersIncludingSupers() {
  790. ArrayList ret = new ArrayList();
  791. collectInterTypeMungers(ret);
  792. return ret;
  793. }
  794. private void collectInterTypeMungers(List collector) {
  795. for (Iterator iter = getDirectSupertypes(); iter.hasNext();) {
  796. ResolvedTypeX superType = (ResolvedTypeX) iter.next();
  797. superType.collectInterTypeMungers(collector);
  798. }
  799. outer: for (Iterator iter1 = collector.iterator(); iter1.hasNext(); ) {
  800. ConcreteTypeMunger superMunger = (ConcreteTypeMunger) iter1.next();
  801. if ( superMunger.getSignature() == null) continue;
  802. if ( !superMunger.getSignature().isAbstract()) continue;
  803. for (Iterator iter = getInterTypeMungers().iterator(); iter.hasNext();) {
  804. ConcreteTypeMunger myMunger = (ConcreteTypeMunger) iter.next();
  805. if (conflictingSignature(myMunger.getSignature(), superMunger.getSignature())) {
  806. iter1.remove();
  807. continue outer;
  808. }
  809. }
  810. if (!superMunger.getSignature().isPublic()) continue;
  811. for (Iterator iter = getMethods(); iter.hasNext(); ) {
  812. ResolvedMember method = (ResolvedMember)iter.next();
  813. if (conflictingSignature(method, superMunger.getSignature())) {
  814. iter1.remove();
  815. continue outer;
  816. }
  817. }
  818. }
  819. collector.addAll(getInterTypeMungers());
  820. }
  821. /**
  822. * Check:
  823. * 1) That we don't have any abstract type mungers unless this type is abstract.
  824. * 2) That an abstract ITDM on an interface is declared public. (Compiler limitation) (PR70794)
  825. */
  826. public void checkInterTypeMungers() {
  827. if (isAbstract()) return;
  828. boolean itdProblem = false;
  829. for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
  830. ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
  831. itdProblem = checkAbstractDeclaration(munger) || itdProblem; // Rule 2
  832. }
  833. if (itdProblem) return; // If the rules above are broken, return right now
  834. for (Iterator iter = getInterTypeMungersIncludingSupers().iterator(); iter.hasNext();) {
  835. ConcreteTypeMunger munger = (ConcreteTypeMunger) iter.next();
  836. if (munger.getSignature() != null && munger.getSignature().isAbstract()) { // Rule 1
  837. world.getMessageHandler().handleMessage(
  838. new Message("must implement abstract inter-type declaration: " + munger.getSignature(),
  839. "", IMessage.ERROR, getSourceLocation(), null,
  840. new ISourceLocation[] { getMungerLocation(munger) }));
  841. }
  842. }
  843. }
  844. /**
  845. * See PR70794. This method checks that if an abstract inter-type method declaration is made on
  846. * an interface then it must also be public.
  847. * This is a compiler limitation that could be made to work in the future (if someone
  848. * provides a worthwhile usecase)
  849. *
  850. * @return indicates if the munger failed the check
  851. */
  852. private boolean checkAbstractDeclaration(ConcreteTypeMunger munger) {
  853. if (munger.getMunger()!=null && (munger.getMunger() instanceof NewMethodTypeMunger)) {
  854. ResolvedMember itdMember = munger.getSignature();
  855. ResolvedTypeX onType = itdMember.getDeclaringType().resolve(world);
  856. if (onType.isInterface() && itdMember.isAbstract() && !itdMember.isPublic()) {
  857. world.getMessageHandler().handleMessage(
  858. new Message(WeaverMessages.format(WeaverMessages.ITD_ABSTRACT_MUST_BE_PUBLIC_ON_INTERFACE,munger.getSignature(),onType),"",
  859. Message.ERROR,getSourceLocation(),null,
  860. new ISourceLocation[]{getMungerLocation(munger)})
  861. );
  862. return true;
  863. }
  864. }
  865. return false;
  866. }
  867. /**
  868. * Get a source location for the munger.
  869. * Until intertype mungers remember where they came from, the source location
  870. * for the munger itself is null. In these cases use the
  871. * source location for the aspect containing the ITD.
  872. *
  873. */
  874. private ISourceLocation getMungerLocation(ConcreteTypeMunger munger) {
  875. ISourceLocation sloc = munger.getSourceLocation();
  876. if (sloc == null) {
  877. sloc = munger.getAspectType().getSourceLocation();
  878. }
  879. return sloc;
  880. }
  881. /**
  882. * Returns a ResolvedTypeX object representing the declaring type of this type, or
  883. * null if this type does not represent a non-package-level-type.
  884. *
  885. * <strong>Warning</strong>: This is guaranteed to work for all member types.
  886. * For anonymous/local types, the only guarantee is given in JLS 13.1, where
  887. * it guarantees that if you call getDeclaringType() repeatedly, you will eventually
  888. * get the top-level class, but it does not say anything about classes in between.
  889. *
  890. * @return the declaring TypeX object, or null.
  891. */
  892. public ResolvedTypeX getDeclaringType() {
  893. if (isArray()) return null;
  894. String name = getName();
  895. int lastDollar = name.lastIndexOf('$');
  896. while (lastDollar != -1) {
  897. ResolvedTypeX ret = world.resolve(TypeX.forName(name.substring(0, lastDollar)), true);
  898. if (ret != ResolvedTypeX.MISSING) return ret;
  899. lastDollar = name.lastIndexOf('$', lastDollar-1);
  900. }
  901. return null;
  902. }
  903. public static boolean isVisible(int modifiers, ResolvedTypeX targetType, ResolvedTypeX fromType) {
  904. //System.err.println("mod: " + modifiers + ", " + targetType + " and " + fromType);
  905. if (Modifier.isPublic(modifiers)) {
  906. return true;
  907. } else if (Modifier.isPrivate(modifiers)) {
  908. return targetType.getOutermostType().equals(fromType.getOutermostType());
  909. } else if (Modifier.isProtected(modifiers)) {
  910. return samePackage(targetType, fromType) || targetType.isAssignableFrom(fromType);
  911. } else { // package-visible
  912. return samePackage(targetType, fromType);
  913. }
  914. }
  915. public static boolean hasBridgeModifier(int modifiers) {
  916. return (modifiers & Constants.ACC_BRIDGE)!=0;
  917. }
  918. private static boolean samePackage(
  919. ResolvedTypeX targetType,
  920. ResolvedTypeX fromType)
  921. {
  922. String p1 = targetType.getPackageName();
  923. String p2 = fromType.getPackageName();
  924. if (p1 == null) return p2 == null;
  925. if (p2 == null) return false;
  926. return p1.equals(p2);
  927. }
  928. public void addInterTypeMunger(ConcreteTypeMunger munger) {
  929. ResolvedMember sig = munger.getSignature();
  930. if (sig == null || munger.getMunger() == null ||
  931. munger.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess)
  932. {
  933. interTypeMungers.add(munger);
  934. return;
  935. }
  936. //System.err.println("add: " + munger + " to " + this.getClassName() + " with " + interTypeMungers);
  937. if (sig.getKind() == Member.METHOD) {
  938. if (!compareToExistingMembers(munger, getMethods())) return;
  939. if (this.isInterface()) {
  940. if (!compareToExistingMembers(munger,
  941. Arrays.asList(world.getCoreType(OBJECT).getDeclaredMethods()).iterator())) return;
  942. }
  943. } else if (sig.getKind() == Member.FIELD) {
  944. if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredFields()).iterator())) return;
  945. } else {
  946. if (!compareToExistingMembers(munger, Arrays.asList(getDeclaredMethods()).iterator())) return;
  947. }
  948. // now compare to existingMungers
  949. for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
  950. ConcreteTypeMunger existingMunger = (ConcreteTypeMunger)i.next();
  951. if (conflictingSignature(existingMunger.getSignature(), munger.getSignature())) {
  952. //System.err.println("match " + munger + " with " + existingMunger);
  953. if (isVisible(munger.getSignature().getModifiers(),
  954. munger.getAspectType(), existingMunger.getAspectType()))
  955. {
  956. //System.err.println(" is visible");
  957. int c = compareMemberPrecedence(sig, existingMunger.getSignature());
  958. if (c == 0) {
  959. c = getWorld().comparePrecedence(munger.getAspectType(), existingMunger.getAspectType());
  960. }
  961. //System.err.println(" compare: " + c);
  962. if (c < 0) {
  963. // the existing munger dominates the new munger
  964. checkLegalOverride(munger.getSignature(), existingMunger.getSignature());
  965. return;
  966. } else if (c > 0) {
  967. // the new munger dominates the existing one
  968. checkLegalOverride(existingMunger.getSignature(), munger.getSignature());
  969. i.remove();
  970. break;
  971. } else {
  972. interTypeConflictError(munger, existingMunger);
  973. interTypeConflictError(existingMunger, munger);
  974. return;
  975. }
  976. }
  977. }
  978. }
  979. //System.err.println("adding: " + munger + " to " + this);
  980. interTypeMungers.add(munger);
  981. }
  982. //??? returning too soon
  983. private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) {
  984. ResolvedMember sig = munger.getSignature();
  985. while (existingMembers.hasNext()) {
  986. ResolvedMember existingMember = (ResolvedMember)existingMembers.next();
  987. //System.err.println("Comparing munger: "+sig+" with member "+existingMember);
  988. if (conflictingSignature(existingMember, munger.getSignature())) {
  989. //System.err.println("conflict: existingMember=" + existingMember + " typeMunger=" + munger);
  990. //System.err.println(munger.getSourceLocation() + ", " + munger.getSignature() + ", " + munger.getSignature().getSourceLocation());
  991. if (isVisible(existingMember.getModifiers(), this, munger.getAspectType())) {
  992. int c = compareMemberPrecedence(sig, existingMember);
  993. //System.err.println(" c: " + c);
  994. if (c < 0) {
  995. // existingMember dominates munger
  996. checkLegalOverride(munger.getSignature(), existingMember);
  997. return false;
  998. } else if (c > 0) {
  999. // munger dominates existingMember
  1000. checkLegalOverride(existingMember, munger.getSignature());
  1001. //interTypeMungers.add(munger);
  1002. //??? might need list of these overridden abstracts
  1003. continue;
  1004. } else {
  1005. //XXX dual errors possible if (this instanceof BcelObjectType) return false; //XXX ignores separate comp
  1006. getWorld().getMessageHandler().handleMessage(
  1007. MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
  1008. existingMember),
  1009. munger.getSourceLocation())
  1010. );
  1011. }
  1012. } else if (isDuplicateMemberWithinTargetType(existingMember,this,sig)) {
  1013. getWorld().getMessageHandler().handleMessage(
  1014. MessageUtil.error(WeaverMessages.format(WeaverMessages.ITD_MEMBER_CONFLICT,munger.getAspectType().getName(),
  1015. existingMember),
  1016. munger.getSourceLocation())
  1017. );;
  1018. }
  1019. //return;
  1020. }
  1021. }
  1022. return true;
  1023. }
  1024. // we know that the member signature matches, but that the member in the target type is not visible to the aspect.
  1025. // this may still be disallowed if it would result in two members within the same declaring type with the same
  1026. // signature AND more than one of them is concrete AND they are both visible within the target type.
  1027. private boolean isDuplicateMemberWithinTargetType(ResolvedMember existingMember, ResolvedTypeX targetType,ResolvedMember itdMember) {
  1028. if ( (existingMember.isAbstract() || itdMember.isAbstract())) return false;
  1029. TypeX declaringType = existingMember.getDeclaringType();
  1030. if (!targetType.equals(declaringType)) return false;
  1031. // now have to test that itdMember is visible from targetType
  1032. if (itdMember.isPrivate()) return false;
  1033. if (itdMember.isPublic()) return true;
  1034. // must be in same package to be visible then...
  1035. if (!targetType.getPackageName().equals(itdMember.getDeclaringType().getPackageName())) return false;
  1036. // trying to put two members with the same signature into the exact same type..., and both visible in that type.
  1037. return true;
  1038. }
  1039. public boolean checkLegalOverride(ResolvedMember parent, ResolvedMember child) {
  1040. //System.err.println("check: " + child.getDeclaringType() + " overrides " + parent.getDeclaringType());
  1041. if (!parent.getReturnType().equals(child.getReturnType())) {
  1042. world.showMessage(IMessage.ERROR,
  1043. WeaverMessages.format(WeaverMessages.ITD_RETURN_TYPE_MISMATCH,parent,child),
  1044. child.getSourceLocation(), parent.getSourceLocation());
  1045. return false;
  1046. }
  1047. if (parent.getKind() == Member.POINTCUT) {
  1048. TypeX[] pTypes = parent.getParameterTypes();
  1049. TypeX[] cTypes = child.getParameterTypes();
  1050. if (!Arrays.equals(pTypes, cTypes)) {
  1051. world.showMessage(IMessage.ERROR,
  1052. WeaverMessages.format(WeaverMessages.ITD_PARAM_TYPE_MISMATCH,parent,child),
  1053. child.getSourceLocation(), parent.getSourceLocation());
  1054. return false;
  1055. }
  1056. }
  1057. //System.err.println("check: " + child.getModifiers() + " more visible " + parent.getModifiers());
  1058. if (isMoreVisible(parent.getModifiers(), child.getModifiers())) {
  1059. world.showMessage(IMessage.ERROR,
  1060. WeaverMessages.format(WeaverMessages.ITD_VISIBILITY_REDUCTION,parent,child),
  1061. child.getSourceLocation(), parent.getSourceLocation());
  1062. return false;
  1063. }
  1064. // check declared exceptions
  1065. ResolvedTypeX[] childExceptions = world.resolve(child.getExceptions());
  1066. ResolvedTypeX[] parentExceptions = world.resolve(parent.getExceptions());
  1067. ResolvedTypeX runtimeException = world.resolve("java.lang.RuntimeException");
  1068. ResolvedTypeX error = world.resolve("java.lang.Error");
  1069. outer: for (int i=0, leni = childExceptions.length; i < leni; i++) {
  1070. //System.err.println("checking: " + childExceptions[i]);
  1071. if (runtimeException.isAssignableFrom(childExceptions[i])) continue;
  1072. if (error.isAssignableFrom(childExceptions[i])) continue;
  1073. for (int j = 0, lenj = parentExceptions.length; j < lenj; j++) {
  1074. if (parentExceptions[j].isAssignableFrom(childExceptions[i])) continue outer;
  1075. }
  1076. world.showMessage(IMessage.ERROR,
  1077. WeaverMessages.format(WeaverMessages.ITD_DOESNT_THROW,childExceptions[i].getName()),
  1078. child.getSourceLocation(), null);
  1079. return false;
  1080. }
  1081. if (parent.isStatic() && !child.isStatic()) {
  1082. world.showMessage(IMessage.ERROR,
  1083. WeaverMessages.format(WeaverMessages.ITD_OVERRIDDEN_STATIC,child,parent),
  1084. child.getSourceLocation(),null);
  1085. } else if (child.isStatic() && !parent.isStatic()) {
  1086. world.showMessage(IMessage.ERROR,
  1087. WeaverMessages.format(WeaverMessages.ITD_OVERIDDING_STATIC,child,parent),
  1088. child.getSourceLocation(),null);
  1089. }
  1090. return true;
  1091. }
  1092. private int compareMemberPrecedence(ResolvedMember m1, ResolvedMember m2) {
  1093. //if (!m1.getReturnType().equals(m2.getReturnType())) return 0;
  1094. if (Modifier.isAbstract(m1.getModifiers())) return -1;
  1095. if (Modifier.isAbstract(m2.getModifiers())) return +1;
  1096. if (m1.getDeclaringType().equals(m2.getDeclaringType())) return 0;
  1097. ResolvedTypeX t1 = m1.getDeclaringType().resolve(world);
  1098. ResolvedTypeX t2 = m2.getDeclaringType().resolve(world);
  1099. if (t1.isAssignableFrom(t2)) {
  1100. return -1;
  1101. }
  1102. if (t2.isAssignableFrom(t1)) {
  1103. return +1;
  1104. }
  1105. return 0;
  1106. }
  1107. public static boolean isMoreVisible(int m1, int m2) {
  1108. if (Modifier.isPrivate(m1)) return false;
  1109. if (isPackage(m1)) return Modifier.isPrivate(m2);
  1110. if (Modifier.isProtected(m1)) return /* private package */ (Modifier.isPrivate(m2) || isPackage(m2));
  1111. if (Modifier.isPublic(m1)) return /* private package protected */ ! Modifier.isPublic(m2);
  1112. throw new RuntimeException("bad modifier: " + m1);
  1113. }
  1114. private static boolean isPackage(int i) {
  1115. return (0 == (i & (Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED)));
  1116. }
  1117. private void interTypeConflictError(
  1118. ConcreteTypeMunger m1,
  1119. ConcreteTypeMunger m2)
  1120. {
  1121. //XXX this works only if we ignore separate compilation issues
  1122. //XXX dual errors possible if (this instanceof BcelObjectType) return;
  1123. //System.err.println("conflict at " + m2.getSourceLocation());
  1124. getWorld().showMessage(IMessage.ERROR,
  1125. WeaverMessages.format(WeaverMessages.ITD_CONFLICT,m1.getAspectType().getName(),
  1126. m2.getSignature(),m2.getAspectType().getName()),
  1127. m2.getSourceLocation(), getSourceLocation());
  1128. }
  1129. public ResolvedMember lookupSyntheticMember(Member member) {
  1130. //??? horribly inefficient
  1131. //for (Iterator i =
  1132. //System.err.println("lookup " + member + " in " + interTypeMungers);
  1133. for (Iterator i = interTypeMungers.iterator(); i.hasNext(); ) {
  1134. ConcreteTypeMunger m = (ConcreteTypeMunger)i.next();
  1135. ResolvedMember ret = m.getMatchingSyntheticMember(member);
  1136. if (ret != null) {
  1137. //System.err.println(" found: " + ret);
  1138. return ret;
  1139. }
  1140. }
  1141. return null;
  1142. }
  1143. public void clearInterTypeMungers() {
  1144. interTypeMungers = new ArrayList();
  1145. }
  1146. public boolean isTopmostImplementor(ResolvedTypeX interfaceType) {
  1147. if (isInterface()) return false;
  1148. if (!interfaceType.isAssignableFrom(this)) return false;
  1149. // check that I'm truly the topmost implementor
  1150. if (interfaceType.isAssignableFrom(this.getSuperclass())) {
  1151. return false;
  1152. }
  1153. return true;
  1154. }
  1155. public ResolvedTypeX getTopmostImplementor(ResolvedTypeX interfaceType) {
  1156. if (isInterface()) return null;
  1157. if (!interfaceType.isAssignableFrom(this)) return null;
  1158. // Check if my super class is an implementor?
  1159. ResolvedTypeX higherType = this.getSuperclass().getTopmostImplementor(interfaceType);
  1160. if (higherType!=null) return higherType;
  1161. return this;
  1162. }
  1163. private ResolvedTypeX findHigher(ResolvedTypeX other) {
  1164. if (this == other) return this;
  1165. for(Iterator i = other.getDirectSupertypes(); i.hasNext(); ) {
  1166. ResolvedTypeX rtx = (ResolvedTypeX)i.next();
  1167. boolean b = this.isAssignableFrom(rtx);
  1168. if (b) return rtx;
  1169. }
  1170. return null;
  1171. }
  1172. public List getExposedPointcuts() {
  1173. List ret = new ArrayList();
  1174. if (getSuperclass() != null) ret.addAll(getSuperclass().getExposedPointcuts());
  1175. for (Iterator i = Arrays.asList(getDeclaredInterfaces()).iterator(); i.hasNext(); ) {
  1176. ResolvedTypeX t = (ResolvedTypeX)i.next();
  1177. addPointcutsResolvingConflicts(ret, Arrays.asList(t.getDeclaredPointcuts()), false);
  1178. }
  1179. addPointcutsResolvingConflicts(ret, Arrays.asList(getDeclaredPointcuts()), true);
  1180. for (Iterator i = ret.iterator(); i.hasNext(); ) {
  1181. ResolvedPointcutDefinition inherited = (ResolvedPointcutDefinition)i.next();
  1182. // System.err.println("looking at: " + inherited + " in " + this);
  1183. // System.err.println(" " + inherited.isAbstract() + " in " + this.isAbstract());
  1184. if (inherited.isAbstract()) {
  1185. if (!this.isAbstract()) {
  1186. getWorld().showMessage(IMessage.ERROR,
  1187. WeaverMessages.format(WeaverMessages.POINCUT_NOT_CONCRETE,inherited,this.getName()),
  1188. inherited.getSourceLocation(), this.getSourceLocation());
  1189. }
  1190. }
  1191. }
  1192. return ret;
  1193. }
  1194. private void addPointcutsResolvingConflicts(List acc, List added, boolean isOverriding) {
  1195. for (Iterator i = added.iterator(); i.hasNext();) {
  1196. ResolvedPointcutDefinition toAdd =
  1197. (ResolvedPointcutDefinition) i.next();
  1198. //System.err.println("adding: " + toAdd);
  1199. for (Iterator j = acc.iterator(); j.hasNext();) {
  1200. ResolvedPointcutDefinition existing =
  1201. (ResolvedPointcutDefinition) j.next();
  1202. if (existing == toAdd) continue;
  1203. if (!isVisible(existing.getModifiers(),
  1204. existing.getDeclaringType().resolve(getWorld()),
  1205. this)) {
  1206. continue;
  1207. }
  1208. if (conflictingSignature(existing, toAdd)) {
  1209. if (isOverriding) {
  1210. checkLegalOverride(existing, toAdd);
  1211. j.remove();
  1212. } else {
  1213. getWorld().showMessage(
  1214. IMessage.ERROR,
  1215. WeaverMessages.format(WeaverMessages.CONFLICTING_INHERITED_POINTCUTS,this.getName() + toAdd.getSignature()),
  1216. existing.getSourceLocation(),
  1217. toAdd.getSourceLocation());
  1218. j.remove();
  1219. }
  1220. }
  1221. }
  1222. acc.add(toAdd);
  1223. }
  1224. }
  1225. public ISourceLocation getSourceLocation() { return null; }
  1226. public boolean isExposedToWeaver() { return false; }
  1227. public WeaverStateInfo getWeaverState() {
  1228. return null;
  1229. }
  1230. }