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.

CrosscuttingMembers.java 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import java.util.ArrayList;
  14. import java.util.Collection;
  15. import java.util.HashSet;
  16. import java.util.Hashtable;
  17. import java.util.Iterator;
  18. import java.util.LinkedHashSet;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.Set;
  22. import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
  23. import org.aspectj.weaver.patterns.Declare;
  24. import org.aspectj.weaver.patterns.DeclareAnnotation;
  25. import org.aspectj.weaver.patterns.DeclareErrorOrWarning;
  26. import org.aspectj.weaver.patterns.DeclareParents;
  27. import org.aspectj.weaver.patterns.DeclarePrecedence;
  28. import org.aspectj.weaver.patterns.DeclareSoft;
  29. import org.aspectj.weaver.patterns.DeclareTypeErrorOrWarning;
  30. import org.aspectj.weaver.patterns.PerClause;
  31. import org.aspectj.weaver.patterns.Pointcut;
  32. import org.aspectj.weaver.patterns.PointcutRewriter;
  33. /**
  34. * This holds on to all members that have an invasive effect outside of there own compilation unit. These members need to be all
  35. * gathered up and in a world before any weaving can take place.
  36. *
  37. * They are also important in the compilation process and need to be gathered up before the inter-type declaration weaving stage
  38. * (unsurprisingly).
  39. *
  40. * All members are concrete.
  41. *
  42. * @author Jim Hugunin
  43. */
  44. public class CrosscuttingMembers {
  45. private final ResolvedType inAspect;
  46. private final World world;
  47. private PerClause perClause;
  48. private List<ShadowMunger> shadowMungers = new ArrayList<ShadowMunger>(4);
  49. private List<ConcreteTypeMunger> typeMungers = new ArrayList<ConcreteTypeMunger>(4);
  50. private List<ConcreteTypeMunger> lateTypeMungers = new ArrayList<ConcreteTypeMunger>(0);
  51. private Set<DeclareParents> declareParents = new HashSet<DeclareParents>();
  52. private Set<DeclareSoft> declareSofts = new HashSet<DeclareSoft>();
  53. private List<Declare> declareDominates = new ArrayList<Declare>(4);
  54. // These are like declare parents type mungers
  55. private Set<DeclareAnnotation> declareAnnotationsOnType = new LinkedHashSet<DeclareAnnotation>();
  56. private Set<DeclareAnnotation> declareAnnotationsOnField = new LinkedHashSet<DeclareAnnotation>();
  57. private Set<DeclareAnnotation> declareAnnotationsOnMethods = new LinkedHashSet<DeclareAnnotation>();
  58. // declareAnnotationsOnMethods includes constructors too
  59. private Set<DeclareTypeErrorOrWarning> declareTypeEow = new HashSet<DeclareTypeErrorOrWarning>();
  60. private boolean shouldConcretizeIfNeeded = true;
  61. public CrosscuttingMembers(ResolvedType inAspect, boolean shouldConcretizeIfNeeded) {
  62. this.inAspect = inAspect;
  63. world = inAspect.getWorld();
  64. this.shouldConcretizeIfNeeded = shouldConcretizeIfNeeded;
  65. }
  66. private final Hashtable<String, Object> cflowFields = new Hashtable<String, Object>();
  67. private final Hashtable<String, Object> cflowBelowFields = new Hashtable<String, Object>();
  68. // public void addConcreteShadowMungers(Collection c) {
  69. // shadowMungers.addAll(c);
  70. // }
  71. public void addConcreteShadowMunger(ShadowMunger m) {
  72. // assert m is concrete
  73. shadowMungers.add(m);
  74. }
  75. public void addShadowMungers(Collection<ShadowMunger> c) {
  76. for (ShadowMunger munger : c) {
  77. addShadowMunger(munger);
  78. }
  79. }
  80. private void addShadowMunger(ShadowMunger m) {
  81. if (inAspect.isAbstract()) {
  82. return; // mungers for abstract aspects are not added
  83. }
  84. addConcreteShadowMunger(m.concretize(inAspect, world, perClause));
  85. }
  86. public void addTypeMungers(Collection<ConcreteTypeMunger> c) {
  87. typeMungers.addAll(c);
  88. }
  89. public void addTypeMunger(ConcreteTypeMunger m) {
  90. if (m == null) {
  91. throw new Error("FIXME AV - should not happen or what ?");// return;
  92. }
  93. typeMungers.add(m);
  94. }
  95. public void addLateTypeMungers(Collection<ConcreteTypeMunger> c) {
  96. lateTypeMungers.addAll(c);
  97. }
  98. public void addLateTypeMunger(ConcreteTypeMunger m) {
  99. lateTypeMungers.add(m);
  100. }
  101. public void addDeclares(Collection<Declare> declares) {
  102. for (Declare declare : declares) {
  103. addDeclare(declare);
  104. }
  105. }
  106. public void addDeclare(Declare declare) {
  107. // this is not extensible, oh well
  108. if (declare instanceof DeclareErrorOrWarning) {
  109. ShadowMunger m = new Checker((DeclareErrorOrWarning) declare);
  110. m.setDeclaringType(declare.getDeclaringType());
  111. addShadowMunger(m);
  112. } else if (declare instanceof DeclarePrecedence) {
  113. declareDominates.add(declare);
  114. } else if (declare instanceof DeclareParents) {
  115. DeclareParents dp = (DeclareParents) declare;
  116. exposeTypes(dp.getParents().getExactTypes());
  117. declareParents.add(dp);
  118. } else if (declare instanceof DeclareSoft) {
  119. DeclareSoft d = (DeclareSoft) declare;
  120. // Ordered so that during concretization we can check the related
  121. // munger
  122. ShadowMunger m = Advice.makeSoftener(world, d.getPointcut(), d.getException(), inAspect, d);
  123. m.setDeclaringType(d.getDeclaringType());
  124. Pointcut concretePointcut = d.getPointcut().concretize(inAspect, d.getDeclaringType(), 0, m);
  125. m.pointcut = concretePointcut;
  126. declareSofts.add(new DeclareSoft(d.getException(), concretePointcut));
  127. addConcreteShadowMunger(m);
  128. } else if (declare instanceof DeclareAnnotation) {
  129. // FIXME asc perf Possible Improvement. Investigate why this is
  130. // called twice in a weave ?
  131. DeclareAnnotation da = (DeclareAnnotation) declare;
  132. if (da.getAspect() == null) {
  133. da.setAspect(inAspect);
  134. }
  135. if (da.isDeclareAtType()) {
  136. declareAnnotationsOnType.add(da);
  137. } else if (da.isDeclareAtField()) {
  138. declareAnnotationsOnField.add(da);
  139. } else if (da.isDeclareAtMethod() || da.isDeclareAtConstuctor()) {
  140. declareAnnotationsOnMethods.add(da);
  141. }
  142. } else if (declare instanceof DeclareTypeErrorOrWarning) {
  143. declareTypeEow.add((DeclareTypeErrorOrWarning) declare);
  144. } else {
  145. throw new RuntimeException("unimplemented");
  146. }
  147. }
  148. public void exposeTypes(List<UnresolvedType> typesToExpose) {
  149. for (UnresolvedType typeToExpose : typesToExpose) {
  150. exposeType(typeToExpose);
  151. }
  152. }
  153. public void exposeType(UnresolvedType typeToExpose) {
  154. if (ResolvedType.isMissing(typeToExpose)) {
  155. return;
  156. }
  157. if (typeToExpose.isParameterizedType() || typeToExpose.isRawType()) {
  158. if (typeToExpose instanceof ResolvedType) {
  159. typeToExpose = ((ResolvedType) typeToExpose).getGenericType();
  160. } else {
  161. typeToExpose = UnresolvedType.forSignature(typeToExpose.getErasureSignature());
  162. }
  163. }
  164. // Check we haven't already got a munger for this:
  165. String signatureToLookFor = typeToExpose.getSignature();
  166. for (Iterator<ConcreteTypeMunger> iterator = typeMungers.iterator(); iterator.hasNext();) {
  167. ConcreteTypeMunger cTM = iterator.next();
  168. ResolvedTypeMunger rTM = cTM.getMunger();
  169. if (rTM != null && rTM instanceof ExposeTypeMunger) {
  170. String exposedType = ((ExposeTypeMunger) rTM).getExposedTypeSignature();
  171. if (exposedType.equals(signatureToLookFor)) {
  172. return; // dont need to bother
  173. }
  174. }
  175. }
  176. addTypeMunger(world.getWeavingSupport().concreteTypeMunger(new ExposeTypeMunger(typeToExpose), inAspect));
  177. // ResolvedMember member = new ResolvedMemberImpl(
  178. // Member.STATIC_INITIALIZATION, typeToExpose, 0, UnresolvedType.VOID,
  179. // "<clinit>", UnresolvedType.NONE);
  180. // addTypeMunger(world.concreteTypeMunger(
  181. // new PrivilegedAccessMunger(member), inAspect));
  182. }
  183. public void addPrivilegedAccesses(Collection<ResolvedMember> accessedMembers) {
  184. int version = inAspect.getCompilerVersion();
  185. for (ResolvedMember member : accessedMembers) {
  186. // Looking it up ensures we get the annotations - the accessedMembers are just retrieved from the attribute and
  187. // don't have that information
  188. ResolvedMember resolvedMember = world.resolve(member);
  189. // pr333469
  190. // If the member is for an ITD (e.g. serialVersionUID) then during resolution we may resolve it on
  191. // a supertype because it doesn't yet exist on the target.
  192. // For example: MyList extends ArrayList<String> and the ITD is on MyList - after resolution it may be:
  193. // ArrayList<String>.serialVersionUID, we need to avoid that happening
  194. if (resolvedMember == null) {
  195. // can happen for ITDs - are there many privileged access ITDs??
  196. resolvedMember = member;
  197. if (resolvedMember.hasBackingGenericMember()) {
  198. resolvedMember = resolvedMember.getBackingGenericMember();
  199. }
  200. } else {
  201. UnresolvedType unresolvedDeclaringType = member.getDeclaringType().getRawType();
  202. UnresolvedType resolvedDeclaringType = resolvedMember.getDeclaringType().getRawType();
  203. if (!unresolvedDeclaringType.equals(resolvedDeclaringType)) {
  204. resolvedMember = member;
  205. }
  206. }
  207. PrivilegedAccessMunger privilegedAccessMunger = new PrivilegedAccessMunger(resolvedMember,
  208. version >= WeaverVersionInfo.WEAVER_VERSION_AJ169);
  209. ConcreteTypeMunger concreteTypeMunger = world.getWeavingSupport().concreteTypeMunger(privilegedAccessMunger, inAspect);
  210. addTypeMunger(concreteTypeMunger);
  211. }
  212. }
  213. public Collection<ShadowMunger> getCflowEntries() {
  214. List<ShadowMunger> ret = new ArrayList<ShadowMunger>();
  215. for (ShadowMunger m : shadowMungers) {
  216. if (m instanceof Advice) {
  217. Advice a = (Advice) m;
  218. if (a.getKind().isCflow()) {
  219. ret.add(a);
  220. }
  221. }
  222. }
  223. return ret;
  224. }
  225. /**
  226. * Updates the records if something has changed. This is called at most twice, firstly whilst collecting ITDs and declares. At
  227. * this point the CrosscuttingMembers we're comparing ourselves with doesn't know about shadowmungers. Therefore a straight
  228. * comparison with the existing list of shadowmungers would return that something has changed even though it might not have, so
  229. * in this first round we ignore the shadowMungers. The second time this is called is whilst we're preparing to weave. At this
  230. * point we know everything in the system and so we're able to compare the shadowMunger list. (see bug 129163)
  231. *
  232. * @param other
  233. * @param careAboutShadowMungers
  234. * @return true if something has changed since the last time this method was called, false otherwise
  235. */
  236. public boolean replaceWith(CrosscuttingMembers other, boolean careAboutShadowMungers) {
  237. boolean changed = false;
  238. if (careAboutShadowMungers) {
  239. if (perClause == null || !perClause.equals(other.perClause)) {
  240. changed = true;
  241. perClause = other.perClause;
  242. }
  243. }
  244. // XXX all of the below should be set equality rather than list equality
  245. // System.err.println("old: " + shadowMungers + " new: " +
  246. // other.shadowMungers);
  247. if (careAboutShadowMungers) {
  248. // bug 129163: use set equality rather than list equality
  249. Set<ShadowMunger> theseShadowMungers = new HashSet<ShadowMunger>();
  250. Set<ShadowMunger> theseInlinedAroundMungers = new HashSet<ShadowMunger>();
  251. for (ShadowMunger munger : shadowMungers) {
  252. if (munger instanceof Advice) {
  253. Advice adviceMunger = (Advice) munger;
  254. // bug 154054: if we're around advice that has been inlined
  255. // then we need to do more checking than existing equals
  256. // methods allow
  257. if (!world.isXnoInline() && adviceMunger.getKind().equals(AdviceKind.Around)) {
  258. theseInlinedAroundMungers.add(adviceMunger);
  259. } else {
  260. theseShadowMungers.add(adviceMunger);
  261. }
  262. } else {
  263. theseShadowMungers.add(munger);
  264. }
  265. }
  266. Set<ShadowMunger> tempSet = new HashSet<ShadowMunger>();
  267. tempSet.addAll(other.shadowMungers);
  268. Set<ShadowMunger> otherShadowMungers = new HashSet<ShadowMunger>();
  269. Set<ShadowMunger> otherInlinedAroundMungers = new HashSet<ShadowMunger>();
  270. for (ShadowMunger munger : tempSet) {
  271. if (munger instanceof Advice) {
  272. Advice adviceMunger = (Advice) munger;
  273. // bug 154054: if we're around advice that has been inlined
  274. // then we need to do more checking than existing equals
  275. // methods allow
  276. if (!world.isXnoInline() && adviceMunger.getKind().equals(AdviceKind.Around)) {
  277. otherInlinedAroundMungers.add(rewritePointcutInMunger(adviceMunger));
  278. } else {
  279. otherShadowMungers.add(rewritePointcutInMunger(adviceMunger));
  280. }
  281. } else {
  282. otherShadowMungers.add(rewritePointcutInMunger(munger));
  283. }
  284. }
  285. if (!theseShadowMungers.equals(otherShadowMungers)) {
  286. changed = true;
  287. }
  288. if (!equivalent(theseInlinedAroundMungers, otherInlinedAroundMungers)) {
  289. changed = true;
  290. }
  291. // bug 158573 - if there are no changes then preserve whether
  292. // or not a particular shadowMunger has matched something.
  293. if (!changed) {
  294. for (ShadowMunger munger : shadowMungers) {
  295. int i = other.shadowMungers.indexOf(munger);
  296. ShadowMunger otherMunger = other.shadowMungers.get(i);
  297. if (munger instanceof Advice) {
  298. ((Advice) otherMunger).setHasMatchedSomething(((Advice) munger).hasMatchedSomething());
  299. }
  300. }
  301. }
  302. // replace the existing list of shadowmungers with the
  303. // new ones in case anything like the sourcelocation has
  304. // changed, however, don't want this flagged as a change
  305. // which will force a full build - bug 134541
  306. shadowMungers = other.shadowMungers;
  307. }
  308. // bug 129163: use set equality rather than list equality and
  309. // if we dont care about shadow mungers then ignore those
  310. // typeMungers which are created to help with the implementation
  311. // of shadowMungers
  312. Set<Object> theseTypeMungers = new HashSet<Object>();
  313. Set<Object> otherTypeMungers = new HashSet<Object>();
  314. if (!careAboutShadowMungers) {
  315. for (Iterator<ConcreteTypeMunger> iter = typeMungers.iterator(); iter.hasNext();) {
  316. Object o = iter.next();
  317. if (o instanceof ConcreteTypeMunger) {
  318. ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) o;
  319. if (!typeMunger.existsToSupportShadowMunging()) {
  320. theseTypeMungers.add(typeMunger);
  321. }
  322. } else {
  323. theseTypeMungers.add(o);
  324. }
  325. }
  326. for (Iterator<ConcreteTypeMunger> iter = other.typeMungers.iterator(); iter.hasNext();) {
  327. Object o = iter.next();
  328. if (o instanceof ConcreteTypeMunger) {
  329. ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) o;
  330. if (!typeMunger.existsToSupportShadowMunging()) {
  331. otherTypeMungers.add(typeMunger);
  332. }
  333. } else {
  334. otherTypeMungers.add(o);
  335. }
  336. }
  337. } else {
  338. theseTypeMungers.addAll(typeMungers);
  339. otherTypeMungers.addAll(other.typeMungers);
  340. }
  341. // initial go at equivalence logic rather than set compare (see
  342. // pr133532)
  343. if (theseTypeMungers.size() != otherTypeMungers.size()) {
  344. changed = true;
  345. typeMungers = other.typeMungers;
  346. } else {
  347. boolean shouldOverwriteThis = false;
  348. boolean foundInequality = false;
  349. for (Iterator<Object> iter = theseTypeMungers.iterator(); iter.hasNext() && !foundInequality;) {
  350. Object thisOne = iter.next();
  351. boolean foundInOtherSet = false;
  352. for (Object otherOne : otherTypeMungers) {
  353. if (thisOne instanceof ConcreteTypeMunger) {
  354. if (((ConcreteTypeMunger) thisOne).shouldOverwrite()) {
  355. shouldOverwriteThis = true;
  356. }
  357. }
  358. if (thisOne instanceof ConcreteTypeMunger && otherOne instanceof ConcreteTypeMunger) {
  359. if (((ConcreteTypeMunger) thisOne).equivalentTo(otherOne)) {
  360. foundInOtherSet = true;
  361. } else if (thisOne.equals(otherOne)) {
  362. foundInOtherSet = true;
  363. }
  364. } else {
  365. if (thisOne.equals(otherOne)) {
  366. foundInOtherSet = true;
  367. }
  368. }
  369. }
  370. if (!foundInOtherSet) {
  371. foundInequality = true;
  372. }
  373. }
  374. if (foundInequality) {
  375. // System.out.println("type munger change");
  376. changed = true;
  377. }
  378. if (shouldOverwriteThis) {
  379. typeMungers = other.typeMungers;
  380. }
  381. }
  382. // if (!theseTypeMungers.equals(otherTypeMungers)) {
  383. // changed = true;
  384. // typeMungers = other.typeMungers;
  385. // }
  386. if (!lateTypeMungers.equals(other.lateTypeMungers)) {
  387. changed = true;
  388. lateTypeMungers = other.lateTypeMungers;
  389. }
  390. if (!declareDominates.equals(other.declareDominates)) {
  391. changed = true;
  392. declareDominates = other.declareDominates;
  393. }
  394. if (!declareParents.equals(other.declareParents)) {
  395. // Are the differences just because of a mixin? These are not created until weave time so should be gotten rid of for
  396. // the up front comparison
  397. if (!careAboutShadowMungers) {
  398. // this means we are in front end compilation and if the differences are purely mixin parents, we can continue OK
  399. Set<DeclareParents> trimmedThis = new HashSet<DeclareParents>();
  400. for (Iterator<DeclareParents> iterator = declareParents.iterator(); iterator.hasNext();) {
  401. DeclareParents decp = iterator.next();
  402. if (!decp.isMixin()) {
  403. trimmedThis.add(decp);
  404. }
  405. }
  406. Set<DeclareParents> trimmedOther = new HashSet<DeclareParents>();
  407. for (Iterator<DeclareParents> iterator = other.declareParents.iterator(); iterator.hasNext();) {
  408. DeclareParents decp = iterator.next();
  409. if (!decp.isMixin()) {
  410. trimmedOther.add(decp);
  411. }
  412. }
  413. if (!trimmedThis.equals(trimmedOther)) {
  414. changed = true;
  415. declareParents = other.declareParents;
  416. }
  417. } else {
  418. changed = true;
  419. declareParents = other.declareParents;
  420. }
  421. }
  422. if (!declareSofts.equals(other.declareSofts)) {
  423. changed = true;
  424. declareSofts = other.declareSofts;
  425. }
  426. // DECAT for when attempting to replace an aspect
  427. if (!declareAnnotationsOnType.equals(other.declareAnnotationsOnType)) {
  428. changed = true;
  429. declareAnnotationsOnType = other.declareAnnotationsOnType;
  430. }
  431. if (!declareAnnotationsOnField.equals(other.declareAnnotationsOnField)) {
  432. changed = true;
  433. declareAnnotationsOnField = other.declareAnnotationsOnField;
  434. }
  435. if (!declareAnnotationsOnMethods.equals(other.declareAnnotationsOnMethods)) {
  436. changed = true;
  437. declareAnnotationsOnMethods = other.declareAnnotationsOnMethods;
  438. }
  439. if (!declareTypeEow.equals(other.declareTypeEow)) {
  440. changed = true;
  441. declareTypeEow = other.declareTypeEow;
  442. }
  443. return changed;
  444. }
  445. private boolean equivalent(Set<ShadowMunger> theseInlinedAroundMungers, Set<ShadowMunger> otherInlinedAroundMungers) {
  446. if (theseInlinedAroundMungers.size() != otherInlinedAroundMungers.size()) {
  447. return false;
  448. }
  449. for (Iterator<ShadowMunger> iter = theseInlinedAroundMungers.iterator(); iter.hasNext();) {
  450. Advice thisAdvice = (Advice) iter.next();
  451. boolean foundIt = false;
  452. for (Iterator<ShadowMunger> iterator = otherInlinedAroundMungers.iterator(); iterator.hasNext();) {
  453. Advice otherAdvice = (Advice) iterator.next();
  454. if (thisAdvice.equals(otherAdvice)) {
  455. if (thisAdvice.getSignature() instanceof ResolvedMemberImpl) {
  456. if (((ResolvedMemberImpl) thisAdvice.getSignature()).isEquivalentTo(otherAdvice.getSignature())) {
  457. foundIt = true;
  458. continue;
  459. }
  460. }
  461. return false;
  462. }
  463. }
  464. if (!foundIt) {
  465. return false;
  466. }
  467. }
  468. return true;
  469. }
  470. private ShadowMunger rewritePointcutInMunger(ShadowMunger munger) {
  471. PointcutRewriter pr = new PointcutRewriter();
  472. Pointcut p = munger.getPointcut();
  473. Pointcut newP = pr.rewrite(p);
  474. if (p.m_ignoreUnboundBindingForNames.length != 0) {
  475. // *sigh* dirty fix for dirty hacky implementation pr149305
  476. newP.m_ignoreUnboundBindingForNames = p.m_ignoreUnboundBindingForNames;
  477. }
  478. munger.setPointcut(newP);
  479. return munger;
  480. }
  481. public void setPerClause(PerClause perClause) {
  482. if (shouldConcretizeIfNeeded) {
  483. this.perClause = perClause.concretize(inAspect);
  484. } else {
  485. this.perClause = perClause;
  486. }
  487. }
  488. public List<Declare> getDeclareDominates() {
  489. return declareDominates;
  490. }
  491. public Collection<DeclareParents> getDeclareParents() {
  492. return declareParents;
  493. }
  494. public Collection<DeclareSoft> getDeclareSofts() {
  495. return declareSofts;
  496. }
  497. public List<ShadowMunger> getShadowMungers() {
  498. return shadowMungers;
  499. }
  500. public List<ConcreteTypeMunger> getTypeMungers() {
  501. return typeMungers;
  502. }
  503. public List<ConcreteTypeMunger> getLateTypeMungers() {
  504. return lateTypeMungers;
  505. }
  506. public Collection<DeclareAnnotation> getDeclareAnnotationOnTypes() {
  507. return declareAnnotationsOnType;
  508. }
  509. public Collection<DeclareAnnotation> getDeclareAnnotationOnFields() {
  510. return declareAnnotationsOnField;
  511. }
  512. /**
  513. * includes declare @method and @constructor
  514. */
  515. public Collection<DeclareAnnotation> getDeclareAnnotationOnMethods() {
  516. return declareAnnotationsOnMethods;
  517. }
  518. public Collection<DeclareTypeErrorOrWarning> getDeclareTypeErrorOrWarning() {
  519. return declareTypeEow;
  520. }
  521. public Map<String, Object> getCflowBelowFields() {
  522. return cflowBelowFields;
  523. }
  524. public Map<String, Object> getCflowFields() {
  525. return cflowFields;
  526. }
  527. public void clearCaches() {
  528. cflowFields.clear();
  529. cflowBelowFields.clear();
  530. }
  531. }