Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

AjLookupEnvironment.java 65KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609
  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.ajdt.internal.compiler.lookup;
  13. import java.lang.reflect.Modifier;
  14. import java.util.ArrayList;
  15. import java.util.Collection;
  16. import java.util.HashMap;
  17. import java.util.HashSet;
  18. import java.util.Iterator;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.Set;
  22. import org.aspectj.ajdt.internal.compiler.CommonPrinter;
  23. import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
  24. import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
  25. import org.aspectj.asm.AsmManager;
  26. import org.aspectj.bridge.IMessage;
  27. import org.aspectj.bridge.WeaveMessage;
  28. import org.aspectj.bridge.context.CompilationAndWeavingContext;
  29. import org.aspectj.bridge.context.ContextToken;
  30. import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
  31. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  32. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
  33. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
  34. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
  35. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
  36. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
  37. import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
  38. import org.aspectj.org.eclipse.jdt.internal.compiler.env.AccessRestriction;
  39. import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType;
  40. import org.aspectj.org.eclipse.jdt.internal.compiler.env.INameEnvironment;
  41. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
  42. import org.aspectj.org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
  43. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
  44. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
  45. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
  46. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
  47. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
  48. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
  49. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
  50. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
  51. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
  52. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
  53. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
  54. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
  55. import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
  56. import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
  57. import org.aspectj.weaver.AnnotationAJ;
  58. import org.aspectj.weaver.ConcreteTypeMunger;
  59. import org.aspectj.weaver.ReferenceType;
  60. import org.aspectj.weaver.ReferenceTypeDelegate;
  61. import org.aspectj.weaver.ResolvedMember;
  62. import org.aspectj.weaver.ResolvedType;
  63. import org.aspectj.weaver.ResolvedTypeMunger;
  64. import org.aspectj.weaver.UnresolvedType;
  65. import org.aspectj.weaver.WeaverMessages;
  66. import org.aspectj.weaver.WeaverStateInfo;
  67. import org.aspectj.weaver.World;
  68. import org.aspectj.weaver.bcel.BcelAnnotation;
  69. import org.aspectj.weaver.bcel.BcelObjectType;
  70. import org.aspectj.weaver.bcel.FakeAnnotation;
  71. import org.aspectj.weaver.bcel.LazyClassGen;
  72. import org.aspectj.weaver.patterns.DeclareAnnotation;
  73. import org.aspectj.weaver.patterns.DeclareParents;
  74. /**
  75. * Overrides the default eclipse LookupEnvironment for two purposes.
  76. *
  77. * 1. To provide some additional phases to <code>completeTypeBindings</code> that weave declare parents and inter-type declarations
  78. * at the correct time.
  79. *
  80. * 2. To intercept the loading of new binary types to ensure the they will have declare parents and inter-type declarations woven
  81. * when appropriate.
  82. *
  83. * @author Jim Hugunin
  84. */
  85. public class AjLookupEnvironment extends LookupEnvironment implements AnonymousClassCreationListener {
  86. public EclipseFactory factory = null;
  87. // private boolean builtInterTypesAndPerClauses = false;
  88. private final List<SourceTypeBinding> pendingTypesToWeave = new ArrayList<SourceTypeBinding>();
  89. // Q: What are dangerousInterfaces?
  90. // A: An interface is considered dangerous if an ITD has been made upon it
  91. // and that ITD
  92. // requires the top most implementors of the interface to be woven *and yet*
  93. // the aspect
  94. // responsible for the ITD is not in the 'world'.
  95. // Q: Err, how can that happen?
  96. // A: When a type is on the inpath, it is 'processed' when completing type
  97. // bindings. At this
  98. // point we look at any type mungers it was affected by previously (stored
  99. // in the weaver
  100. // state info attribute). Effectively we are working with a type munger and
  101. // yet may not have its
  102. // originating aspect in the world. This is a problem if, for example, the
  103. // aspect supplied
  104. // a 'body' for a method targetting an interface - since the top most
  105. // implementors should
  106. // be woven by the munger from the aspect. When this happens we store the
  107. // interface name here
  108. // in the map - if we later process a type that is the topMostImplementor of
  109. // a dangerous
  110. // interface then we put out an error message.
  111. /**
  112. * interfaces targetted by ITDs that have to be implemented by accessing the topMostImplementor of the interface, yet the aspect
  113. * where the ITD originated is not in the world
  114. */
  115. private final Map dangerousInterfaces = new HashMap();
  116. public AjLookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions options, ProblemReporter problemReporter,
  117. INameEnvironment nameEnvironment) {
  118. super(typeRequestor, options, problemReporter, nameEnvironment);
  119. }
  120. // ??? duplicates some of super's code
  121. public void completeTypeBindings() {
  122. AsmManager.setCompletingTypeBindings(true);
  123. ContextToken completeTypeBindingsToken = CompilationAndWeavingContext.enteringPhase(
  124. CompilationAndWeavingContext.COMPLETING_TYPE_BINDINGS, "");
  125. // builtInterTypesAndPerClauses = false;
  126. // pendingTypesToWeave = new ArrayList();
  127. stepCompleted = BUILD_TYPE_HIERARCHY;
  128. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  129. ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CHECK_AND_SET_IMPORTS,
  130. units[i].compilationResult.fileName);
  131. units[i].scope.checkAndSetImports();
  132. CompilationAndWeavingContext.leavingPhase(tok);
  133. }
  134. stepCompleted = CHECK_AND_SET_IMPORTS;
  135. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  136. ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CONNECTING_TYPE_HIERARCHY,
  137. units[i].compilationResult.fileName);
  138. units[i].scope.connectTypeHierarchy();
  139. CompilationAndWeavingContext.leavingPhase(tok);
  140. }
  141. stepCompleted = CONNECT_TYPE_HIERARCHY;
  142. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  143. ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.BUILDING_FIELDS_AND_METHODS,
  144. units[i].compilationResult.fileName);
  145. // units[i].scope.checkParameterizedTypes(); do this check a little
  146. // later, after ITDs applied to stbs
  147. units[i].scope.buildFieldsAndMethods();
  148. CompilationAndWeavingContext.leavingPhase(tok);
  149. }
  150. // would like to gather up all TypeDeclarations at this point and put
  151. // them in the factory
  152. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  153. SourceTypeBinding[] b = units[i].scope.topLevelTypes;
  154. for (int j = 0; j < b.length; j++) {
  155. factory.addSourceTypeBinding(b[j], units[i]);
  156. if (b[j].superclass instanceof MissingTypeBinding) {
  157. // e37: Undoing the work in ClassScope.connectSuperClass() as it will lead to cascade errors
  158. // TODO allow MissingTypeBinding through here and cope with it in all situations later?
  159. b[j].superclass = units[i].scope.getJavaLangObject();
  160. }
  161. }
  162. }
  163. // We won't find out about anonymous types until later though, so
  164. // register to be
  165. // told about them when they turn up.
  166. AnonymousClassPublisher.aspectOf().setAnonymousClassCreationListener(this);
  167. // need to build inter-type declarations for all AspectDeclarations at
  168. // this point
  169. // this MUST be done in order from super-types to subtypes
  170. List<SourceTypeBinding> typesToProcess = new ArrayList<SourceTypeBinding>();
  171. List<SourceTypeBinding> aspectsToProcess = new ArrayList<SourceTypeBinding>();
  172. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  173. CompilationUnitScope cus = units[i].scope;
  174. SourceTypeBinding[] stbs = cus.topLevelTypes;
  175. for (int j = 0; j < stbs.length; j++) {
  176. SourceTypeBinding stb = stbs[j];
  177. typesToProcess.add(stb);
  178. TypeDeclaration typeDeclaration = stb.scope.referenceContext;
  179. if (typeDeclaration instanceof AspectDeclaration) {
  180. aspectsToProcess.add(stb);
  181. }
  182. }
  183. }
  184. factory.getWorld().getCrosscuttingMembersSet().reset();
  185. // Need to do these before the other ITDs
  186. for (SourceTypeBinding aspectToProcess : aspectsToProcess) {
  187. processInterTypeMemberTypes(aspectToProcess.scope);
  188. }
  189. while (typesToProcess.size() > 0) {
  190. // removes types from the list as they are processed...
  191. collectAllITDsAndDeclares(typesToProcess.get(0), typesToProcess);
  192. }
  193. factory.finishTypeMungers();
  194. // now do weaving
  195. List<ConcreteTypeMunger> typeMungers = factory.getTypeMungers();
  196. List<DeclareParents> declareParents = factory.getDeclareParents();
  197. List<DeclareAnnotation> declareAnnotationOnTypes = factory.getDeclareAnnotationOnTypes();
  198. doPendingWeaves();
  199. // We now have some list of types to process, and we are about to apply
  200. // the type mungers.
  201. // There can be situations where the order of types passed to the
  202. // compiler causes the
  203. // output from the compiler to vary - THIS IS BAD. For example, if we
  204. // have class A
  205. // and class B extends A. Also, an aspect that 'declare parents: A+
  206. // implements Serializable'
  207. // then depending on whether we see A first, we may or may not make B
  208. // serializable.
  209. // The fix is to process them in the right order, ensuring that for a
  210. // type we process its
  211. // supertypes and superinterfaces first. This algorithm may have
  212. // problems with:
  213. // - partial hierarchies (e.g. suppose types A,B,C are in a hierarchy
  214. // and A and C are to be woven but not B)
  215. // - weaving that brings new types in for processing (see
  216. // pendingTypesToWeave.add() calls) after we thought
  217. // we had the full list.
  218. //
  219. // but these aren't common cases (he bravely said...)
  220. boolean typeProcessingOrderIsImportant = declareParents.size() > 0 || declareAnnotationOnTypes.size() > 0; // DECAT
  221. if (typeProcessingOrderIsImportant) {
  222. typesToProcess = new ArrayList<SourceTypeBinding>();
  223. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  224. CompilationUnitScope cus = units[i].scope;
  225. SourceTypeBinding[] stbs = cus.topLevelTypes;
  226. for (int j = 0; j < stbs.length; j++) {
  227. SourceTypeBinding stb = stbs[j];
  228. typesToProcess.add(stb);
  229. }
  230. }
  231. List<SourceTypeBinding> stb2 = new ArrayList<SourceTypeBinding>();
  232. stb2.addAll(typesToProcess);
  233. while (typesToProcess.size() > 0) {
  234. // A side effect of weaveIntertypes() is that the processed type is removed from the collection
  235. weaveIntertypes(typesToProcess, typesToProcess.get(0), typeMungers, declareParents, declareAnnotationOnTypes, 1);
  236. }
  237. while (stb2.size() > 0) {
  238. // A side effect of weaveIntertypes() is that the processed type is removed from the collection
  239. weaveIntertypes(stb2, stb2.get(0), typeMungers, declareParents, declareAnnotationOnTypes, 2);
  240. }
  241. } else {
  242. // Order isn't important
  243. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  244. weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents, declareAnnotationOnTypes);
  245. }
  246. }
  247. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  248. units[i].scope.checkParameterizedTypes();
  249. }
  250. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  251. SourceTypeBinding[] b = units[i].scope.topLevelTypes;
  252. for (int j = 0; j < b.length; j++) {
  253. ContextToken tok = CompilationAndWeavingContext.enteringPhase(
  254. CompilationAndWeavingContext.RESOLVING_POINTCUT_DECLARATIONS, b[j].sourceName);
  255. resolvePointcutDeclarations(b[j].scope);
  256. CompilationAndWeavingContext.leavingPhase(tok);
  257. }
  258. }
  259. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  260. SourceTypeBinding[] b = units[i].scope.topLevelTypes;
  261. for (int j = 0; j < b.length; j++) {
  262. ContextToken tok = CompilationAndWeavingContext.enteringPhase(
  263. CompilationAndWeavingContext.ADDING_DECLARE_WARNINGS_AND_ERRORS, b[j].sourceName);
  264. addAdviceLikeDeclares(b[j].scope);
  265. CompilationAndWeavingContext.leavingPhase(tok);
  266. }
  267. }
  268. for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
  269. units[i] = null; // release unnecessary reference to the parsed unit
  270. }
  271. stepCompleted = BUILD_FIELDS_AND_METHODS;
  272. lastCompletedUnitIndex = lastUnitIndex;
  273. AsmManager.setCompletingTypeBindings(false);
  274. factory.getWorld().getCrosscuttingMembersSet().verify();
  275. CompilationAndWeavingContext.leavingPhase(completeTypeBindingsToken);
  276. }
  277. // /**
  278. // * For any given sourcetypebinding, this method checks that if it is a
  279. // parameterized aspect that
  280. // * the type parameters specified for any supertypes meet the bounds for
  281. // the generic type
  282. // * variables.
  283. // */
  284. // private void verifyAnyTypeParametersMeetBounds(SourceTypeBinding
  285. // sourceType) {
  286. // ResolvedType onType = factory.fromEclipse(sourceType);
  287. // if (onType.isAspect()) {
  288. // ResolvedType superType = factory.fromEclipse(sourceType.superclass);
  289. // // Don't need to check if it was used in its RAW form or isnt generic
  290. // if (superType.isGenericType() || superType.isParameterizedType()) {
  291. // TypeVariable[] typeVariables = superType.getTypeVariables();
  292. // UnresolvedType[] typeParams = superType.getTypeParameters();
  293. // if (typeVariables!=null && typeParams!=null) {
  294. // for (int i = 0; i < typeVariables.length; i++) {
  295. // boolean ok =
  296. // typeVariables[i].canBeBoundTo(typeParams[i].resolve(factory.getWorld()));
  297. // if (!ok) { // the supplied parameter violates the bounds
  298. // // Type {0} does not meet the specification for type parameter {1} ({2})
  299. // in generic type {3}
  300. // String msg =
  301. // WeaverMessages.format(
  302. // WeaverMessages.VIOLATES_TYPE_VARIABLE_BOUNDS,
  303. // typeParams[i],
  304. // new Integer(i+1),
  305. // typeVariables[i].getDisplayName(),
  306. // superType.getGenericType().getName());
  307. // factory.getWorld().getMessageHandler().handleMessage(MessageUtil.error(msg
  308. // ,onType.getSourceLocation()));
  309. // }
  310. // }
  311. // }
  312. // }
  313. // }
  314. // }
  315. public void doSupertypesFirst(ReferenceBinding rb, Collection yetToProcess) {
  316. if (rb instanceof SourceTypeBinding) {
  317. if (yetToProcess.contains(rb)) {
  318. collectAllITDsAndDeclares((SourceTypeBinding) rb, yetToProcess);
  319. }
  320. } else if (rb instanceof ParameterizedTypeBinding) {
  321. // If its a PTB we need to pull the SourceTypeBinding out of it.
  322. ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) rb;
  323. if (ptb.type instanceof SourceTypeBinding && yetToProcess.contains(ptb.type)) {
  324. collectAllITDsAndDeclares((SourceTypeBinding) ptb.type, yetToProcess);
  325. }
  326. }
  327. }
  328. /**
  329. * Find all the ITDs and Declares, but it is important we do this from the supertypes down to the subtypes.
  330. *
  331. * @param sourceType
  332. * @param yetToProcess
  333. */
  334. private void collectAllITDsAndDeclares(SourceTypeBinding sourceType, Collection yetToProcess) {
  335. // Look at the supertype first
  336. ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.COLLECTING_ITDS_AND_DECLARES,
  337. sourceType.sourceName);
  338. yetToProcess.remove(sourceType);
  339. // look out our direct supertype
  340. doSupertypesFirst(sourceType.superclass(), yetToProcess);
  341. // now check our membertypes (pr119570)
  342. ReferenceBinding[] memberTypes = sourceType.memberTypes;
  343. for (int i = 0, length = memberTypes.length; i < length; i++) {
  344. SourceTypeBinding rb = (SourceTypeBinding) memberTypes[i];
  345. if (!rb.superclass().equals(sourceType)) {
  346. doSupertypesFirst(rb.superclass(), yetToProcess);
  347. }
  348. }
  349. buildInterTypeAndPerClause(sourceType.scope);
  350. addCrosscuttingStructures(sourceType.scope);
  351. CompilationAndWeavingContext.leavingPhase(tok);
  352. }
  353. /**
  354. * Weave the parents and intertype decls into a given type. This method looks at the supertype and superinterfaces for the
  355. * specified type and recurses to weave those first if they are in the full list of types we are going to process during this
  356. * compile... it stops recursing the first time it hits a type we aren't going to process during this compile. This could cause
  357. * problems if you supply 'pieces' of a hierarchy, i.e. the bottom and the top, but not the middle - but what the hell are you
  358. * doing if you do that?
  359. *
  360. * @param mode 0=do everything, 1=do declare parents, 2=do ITDs
  361. */
  362. private void weaveIntertypes(List<SourceTypeBinding> typesToProcess, SourceTypeBinding typeToWeave,
  363. List<ConcreteTypeMunger> typeMungers, List<DeclareParents> declareParents,
  364. List<DeclareAnnotation> declareAnnotationOnTypes, int mode) {
  365. // Look at the supertype first
  366. ReferenceBinding superType = typeToWeave.superclass();
  367. if (typesToProcess.contains(superType) && superType instanceof SourceTypeBinding) {
  368. // System.err.println("Recursing to supertype "+new
  369. // String(superType.getFileName()));
  370. weaveIntertypes(typesToProcess, (SourceTypeBinding) superType, typeMungers, declareParents, declareAnnotationOnTypes,
  371. mode);
  372. }
  373. // Then look at the superinterface list
  374. ReferenceBinding[] interfaceTypes = typeToWeave.superInterfaces();
  375. for (int i = 0; i < interfaceTypes.length; i++) {
  376. ReferenceBinding binding = interfaceTypes[i];
  377. if (typesToProcess.contains(binding) && binding instanceof SourceTypeBinding) {
  378. // System.err.println("Recursing to superinterface "+new
  379. // String(binding.getFileName()));
  380. weaveIntertypes(typesToProcess, (SourceTypeBinding) binding, typeMungers, declareParents, declareAnnotationOnTypes,
  381. mode);
  382. }
  383. else if (binding instanceof ParameterizedTypeBinding && (((ParameterizedTypeBinding)binding).type instanceof SourceTypeBinding) && typesToProcess.contains(((ParameterizedTypeBinding)binding).type)) {
  384. weaveIntertypes(typesToProcess, (SourceTypeBinding) ((ParameterizedTypeBinding)binding).type, typeMungers, declareParents, declareAnnotationOnTypes, mode);
  385. }
  386. }
  387. weaveInterTypeDeclarations(typeToWeave, typeMungers, declareParents, declareAnnotationOnTypes, false, mode);
  388. typesToProcess.remove(typeToWeave);
  389. }
  390. private void doPendingWeaves() {
  391. for (SourceTypeBinding t: pendingTypesToWeave) {
  392. ContextToken tok = CompilationAndWeavingContext.enteringPhase(
  393. CompilationAndWeavingContext.WEAVING_INTERTYPE_DECLARATIONS, t.sourceName);
  394. weaveInterTypeDeclarations(t);
  395. CompilationAndWeavingContext.leavingPhase(tok);
  396. }
  397. pendingTypesToWeave.clear();
  398. }
  399. private void addAdviceLikeDeclares(ClassScope s) {
  400. TypeDeclaration dec = s.referenceContext;
  401. if (dec instanceof AspectDeclaration) {
  402. ResolvedType typeX = factory.fromEclipse(dec.binding);
  403. factory.getWorld().getCrosscuttingMembersSet().addAdviceLikeDeclares(typeX);
  404. }
  405. SourceTypeBinding sourceType = s.referenceContext.binding;
  406. ReferenceBinding[] memberTypes = sourceType.memberTypes;
  407. for (int i = 0, length = memberTypes.length; i < length; i++) {
  408. addAdviceLikeDeclares(((SourceTypeBinding) memberTypes[i]).scope);
  409. }
  410. }
  411. private void addCrosscuttingStructures(ClassScope s) {
  412. TypeDeclaration dec = s.referenceContext;
  413. if (dec instanceof AspectDeclaration) {
  414. ResolvedType typeX = factory.fromEclipse(dec.binding);
  415. factory.getWorld().getCrosscuttingMembersSet().addOrReplaceAspect(typeX, false);
  416. if (typeX.getSuperclass().isAspect() && !typeX.getSuperclass().isExposedToWeaver()) {
  417. factory.getWorld().getCrosscuttingMembersSet().addOrReplaceAspect(typeX.getSuperclass(), false);
  418. }
  419. }
  420. SourceTypeBinding sourceType = s.referenceContext.binding;
  421. ReferenceBinding[] memberTypes = sourceType.memberTypes;
  422. for (int i = 0, length = memberTypes.length; i < length; i++) {
  423. addCrosscuttingStructures(((SourceTypeBinding) memberTypes[i]).scope);
  424. }
  425. }
  426. private void resolvePointcutDeclarations(ClassScope s) {
  427. TypeDeclaration dec = s.referenceContext;
  428. SourceTypeBinding sourceType = s.referenceContext.binding;
  429. boolean hasPointcuts = false;
  430. AbstractMethodDeclaration[] methods = dec.methods;
  431. boolean initializedMethods = false;
  432. if (methods != null) {
  433. for (int i = 0; i < methods.length; i++) {
  434. if (methods[i] instanceof PointcutDeclaration) {
  435. hasPointcuts = true;
  436. if (!initializedMethods) {
  437. sourceType.methods(); // force initialization
  438. initializedMethods = true;
  439. }
  440. ((PointcutDeclaration) methods[i]).resolvePointcut(s);
  441. }
  442. }
  443. }
  444. if (hasPointcuts || dec instanceof AspectDeclaration || couldBeAnnotationStyleAspectDeclaration(dec)) {
  445. ReferenceType name = (ReferenceType) factory.fromEclipse(sourceType);
  446. EclipseSourceType eclipseSourceType = (EclipseSourceType) name.getDelegate();
  447. eclipseSourceType.checkPointcutDeclarations();
  448. }
  449. ReferenceBinding[] memberTypes = sourceType.memberTypes;
  450. for (int i = 0, length = memberTypes.length; i < length; i++) {
  451. resolvePointcutDeclarations(((SourceTypeBinding) memberTypes[i]).scope);
  452. }
  453. }
  454. /**
  455. * Return true if the declaration has @Aspect annotation. Called 'couldBe' rather than 'is' because someone else may have
  456. * defined an annotation called Aspect - we can't verify the full name (including package name) because it may not have been
  457. * resolved just yet and rather going through expensive resolution when we dont have to, this gives us a cheap check that tells
  458. * us whether to bother.
  459. */
  460. private boolean couldBeAnnotationStyleAspectDeclaration(TypeDeclaration dec) {
  461. Annotation[] annotations = dec.annotations;
  462. boolean couldBeAtAspect = false;
  463. if (annotations != null) {
  464. for (int i = 0; i < annotations.length && !couldBeAtAspect; i++) {
  465. if (annotations[i].toString().equals("@Aspect")) {
  466. couldBeAtAspect = true;
  467. }
  468. }
  469. }
  470. return couldBeAtAspect;
  471. }
  472. /**
  473. * Applies any intertype member type declarations up front.
  474. */
  475. private void processInterTypeMemberTypes(ClassScope classScope) {
  476. TypeDeclaration dec = classScope.referenceContext;
  477. if (dec instanceof AspectDeclaration) {
  478. ((AspectDeclaration) dec).processIntertypeMemberTypes(classScope);
  479. }
  480. // if we are going to support nested aspects making itd member types, copy the logic from the end of
  481. // buildInterTypeAndPerClause() which walks members
  482. }
  483. private void buildInterTypeAndPerClause(ClassScope s) {
  484. TypeDeclaration dec = s.referenceContext;
  485. if (dec instanceof AspectDeclaration) {
  486. ((AspectDeclaration) dec).buildInterTypeAndPerClause(s);
  487. }
  488. SourceTypeBinding sourceType = s.referenceContext.binding;
  489. // test classes don't extend aspects
  490. if (sourceType.superclass != null) {
  491. ResolvedType parent = factory.fromEclipse(sourceType.superclass);
  492. if (parent.isAspect() && !isAspect(dec)) {
  493. factory.showMessage(IMessage.ERROR, "class \'" + new String(sourceType.sourceName) + "\' can not extend aspect \'"
  494. + parent.getName() + "\'", factory.fromEclipse(sourceType).getSourceLocation(), null);
  495. }
  496. }
  497. ReferenceBinding[] memberTypes = sourceType.memberTypes;
  498. if (memberTypes == null) {
  499. System.err.println("Unexpectedly found null for memberTypes of " + sourceType.debugName());
  500. }
  501. if (memberTypes != null) {
  502. for (int i = 0, length = memberTypes.length; i < length; i++) {
  503. buildInterTypeAndPerClause(((SourceTypeBinding) memberTypes[i]).scope);
  504. }
  505. }
  506. }
  507. private boolean isAspect(TypeDeclaration decl) {
  508. if ((decl instanceof AspectDeclaration)) {
  509. return true;
  510. } else if (decl.annotations == null) {
  511. return false;
  512. } else {
  513. for (int i = 0; i < decl.annotations.length; i++) {
  514. Annotation ann = decl.annotations[i];
  515. if (ann.type instanceof SingleTypeReference) {
  516. if (CharOperation.equals("Aspect".toCharArray(), ((SingleTypeReference) ann.type).token)) {
  517. return true;
  518. }
  519. } else if (ann.type instanceof QualifiedTypeReference) {
  520. QualifiedTypeReference qtr = (QualifiedTypeReference) ann.type;
  521. if (qtr.tokens.length != 5) {
  522. return false;
  523. }
  524. if (!CharOperation.equals("org".toCharArray(), qtr.tokens[0])) {
  525. return false;
  526. }
  527. if (!CharOperation.equals("aspectj".toCharArray(), qtr.tokens[1])) {
  528. return false;
  529. }
  530. if (!CharOperation.equals("lang".toCharArray(), qtr.tokens[2])) {
  531. return false;
  532. }
  533. if (!CharOperation.equals("annotation".toCharArray(), qtr.tokens[3])) {
  534. return false;
  535. }
  536. if (!CharOperation.equals("Aspect".toCharArray(), qtr.tokens[4])) {
  537. return false;
  538. }
  539. return true;
  540. }
  541. }
  542. }
  543. return false;
  544. }
  545. private void weaveInterTypeDeclarations(CompilationUnitScope unit, List<ConcreteTypeMunger> typeMungers,
  546. List<DeclareParents> declareParents, List<DeclareAnnotation> declareAnnotationOnTypes) {
  547. for (int i = 0, length = unit.topLevelTypes.length; i < length; i++) {
  548. weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents, declareAnnotationOnTypes, false, 0);
  549. }
  550. }
  551. private void weaveInterTypeDeclarations(SourceTypeBinding sourceType) {
  552. if (!factory.areTypeMungersFinished()) {
  553. if (!pendingTypesToWeave.contains(sourceType)) {
  554. pendingTypesToWeave.add(sourceType);
  555. // inner type ITD support - may need this for some incremental cases...
  556. // List<ConcreteTypeMunger> ctms = factory.getWorld().getCrosscuttingMembersSet().getTypeMungersOfKind(
  557. // ResolvedTypeMunger.InnerClass);
  558. // // List<ConcreteTypeMunger> innerTypeMungers = new ArrayList<ConcreteTypeMunger>();
  559. // // for (ConcreteTypeMunger ctm : ctms) {
  560. // // if (ctm.getMunger() != null && ctm.getMunger().getKind() == ResolvedTypeMunger.InnerClass) {
  561. // // innerTypeMungers.add(ctm);
  562. // // }
  563. // // }
  564. // // that includes the innertype one...
  565. // // doPendingWeaves at this level is about applying inner class
  566. // BinaryTypeBinding t = (BinaryTypeBinding) sourceType;
  567. // for (ConcreteTypeMunger ctm : innerTypeMungers) {
  568. // NewMemberClassTypeMunger nmctm = (NewMemberClassTypeMunger) ctm.getMunger();
  569. // ReferenceBinding[] rbs = t.memberTypes;
  570. // UnresolvedType ut = factory.fromBinding(t);
  571. // if (ut.equals(nmctm.getTargetType())) {
  572. // // got a match here
  573. // SourceTypeBinding aspectTypeBinding = (SourceTypeBinding) factory.makeTypeBinding(ctm.getAspectType());
  574. //
  575. // char[] mungerMemberTypeName = ("$" + nmctm.getMemberTypeName()).toCharArray();
  576. // ReferenceBinding innerTypeBinding = null;
  577. // for (ReferenceBinding innerType : aspectTypeBinding.memberTypes) {
  578. // char[] compounded = CharOperation.concatWith(innerType.compoundName, '.');
  579. // if (org.aspectj.org.eclipse.jdt.core.compiler.CharOperation.endsWith(compounded, mungerMemberTypeName)) {
  580. // innerTypeBinding = innerType;
  581. // break;
  582. // }
  583. // }
  584. // // may be unresolved if the aspect type binding was a BinaryTypeBinding
  585. // if (innerTypeBinding instanceof UnresolvedReferenceBinding) {
  586. // innerTypeBinding = BinaryTypeBinding
  587. // .resolveType(innerTypeBinding, factory.getLookupEnvironment(), true);
  588. // }
  589. // t.memberTypes(); // cause initialization
  590. // t.memberTypes = new ReferenceBinding[] { innerTypeBinding };
  591. //
  592. // int stop = 1;
  593. // // The inner type from the aspect should be put into the membertypebindings for this
  594. //
  595. // }
  596. // }
  597. }
  598. } else {
  599. weaveInterTypeDeclarations(sourceType, factory.getTypeMungers(), factory.getDeclareParents(),
  600. factory.getDeclareAnnotationOnTypes(), true, 0);
  601. }
  602. }
  603. /**
  604. * @param mode 0=do everything, 1=do declare parents, 2=do ITDs
  605. */
  606. private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, List<ConcreteTypeMunger> typeMungers,
  607. List<DeclareParents> declareParents, List<DeclareAnnotation> declareAnnotationOnTypes, boolean skipInners, int mode) {
  608. ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_INTERTYPE_DECLARATIONS,
  609. sourceType.sourceName);
  610. ResolvedType onType = factory.fromEclipse(sourceType);
  611. // AMC we shouldn't need this when generic sigs are fixed??
  612. if (onType.isRawType()) {
  613. onType = onType.getGenericType();
  614. }
  615. WeaverStateInfo info = onType.getWeaverState();
  616. if (mode < 2) {
  617. // this test isnt quite right - there will be a case where we fail to
  618. // flag a problem
  619. // with a 'dangerous interface' because the type is reweavable when we
  620. // should have
  621. // because the type wasn't going to be rewoven... if that happens, we
  622. // should perhaps
  623. // move this test and dangerous interface processing to the end of this
  624. // method and
  625. // make it conditional on whether any of the typeMungers passed into
  626. // here actually
  627. // matched this type.
  628. if (info != null && !info.isOldStyle() && !info.isReweavable()) {
  629. processTypeMungersFromExistingWeaverState(sourceType, onType);
  630. CompilationAndWeavingContext.leavingPhase(tok);
  631. return;
  632. }
  633. // Check if the type we are looking at is the topMostImplementor of a
  634. // dangerous interface -
  635. // report a problem if it is.
  636. for (Iterator i = dangerousInterfaces.entrySet().iterator(); i.hasNext();) {
  637. Map.Entry entry = (Map.Entry) i.next();
  638. ResolvedType interfaceType = (ResolvedType) entry.getKey();
  639. if (onType.isTopmostImplementor(interfaceType)) {
  640. factory.showMessage(IMessage.ERROR, onType + ": " + entry.getValue(), onType.getSourceLocation(), null);
  641. }
  642. }
  643. boolean needOldStyleWarning = (info != null && info.isOldStyle());
  644. onType.clearInterTypeMungers();
  645. onType.ensureConsistent();
  646. // FIXME asc perf Could optimize here, after processing the expected set
  647. // of types we may bring
  648. // binary types that are not exposed to the weaver, there is no need to
  649. // attempt declare parents
  650. // or declare annotation really - unless we want to report the
  651. // not-exposed to weaver
  652. // messages...
  653. List<DeclareParents> decpToRepeat = new ArrayList<DeclareParents>();
  654. List<DeclareAnnotation> decaToRepeat = new ArrayList<DeclareAnnotation>();
  655. boolean anyNewParents = false;
  656. boolean anyNewAnnotations = false;
  657. // first pass
  658. // try and apply all decps - if they match, then great. If they don't
  659. // then
  660. // check if they are starred-annotation patterns. If they are not
  661. // starred
  662. // annotation patterns then they might match later...remember that...
  663. for (DeclareParents decp : declareParents) {
  664. if (!decp.isMixin()) {
  665. boolean didSomething = doDeclareParents(decp, sourceType);
  666. if (didSomething) {
  667. if (factory.pushinCollector != null) {
  668. factory.pushinCollector.tagAsMunged(sourceType, decp.getParents().get(0));
  669. }
  670. anyNewParents = true;
  671. } else {
  672. if (!decp.getChild().isStarAnnotation()) {
  673. decpToRepeat.add(decp);
  674. }
  675. }
  676. }
  677. }
  678. for (DeclareAnnotation deca : declareAnnotationOnTypes) {
  679. boolean didSomething = doDeclareAnnotations(deca, sourceType, true);
  680. if (didSomething) {
  681. anyNewAnnotations = true;
  682. } else {
  683. if (!deca.getTypePattern().isStar()) {
  684. decaToRepeat.add(deca);
  685. }
  686. }
  687. }
  688. List forRemoval = new ArrayList();
  689. // now lets loop over and over until we have done all we can
  690. while ((anyNewAnnotations || anyNewParents) && (!decpToRepeat.isEmpty() || !decaToRepeat.isEmpty())) {
  691. anyNewParents = anyNewAnnotations = false;
  692. forRemoval.clear();
  693. for (DeclareParents decp : decpToRepeat) {
  694. boolean didSomething = doDeclareParents(decp, sourceType);
  695. if (didSomething) {
  696. if (factory.pushinCollector != null) {
  697. factory.pushinCollector.tagAsMunged(sourceType, decp.getParents().get(0));
  698. }
  699. anyNewParents = true;
  700. forRemoval.add(decp);
  701. }
  702. }
  703. decpToRepeat.removeAll(forRemoval);
  704. forRemoval.clear();
  705. for (DeclareAnnotation deca : decaToRepeat) {
  706. boolean didSomething = doDeclareAnnotations(deca, sourceType, false);
  707. if (didSomething) {
  708. if (factory.pushinCollector != null) {
  709. factory.pushinCollector.tagAsMunged(sourceType, deca.getAnnotationString());
  710. }
  711. anyNewAnnotations = true;
  712. forRemoval.add(deca);
  713. }
  714. }
  715. decaToRepeat.removeAll(forRemoval);
  716. }
  717. }
  718. if (mode == 0 || mode == 2) {
  719. for (Iterator<ConcreteTypeMunger> i = typeMungers.iterator(); i.hasNext();) {
  720. EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
  721. if (munger.matches(onType)) {
  722. // if (needOldStyleWarning) {
  723. // factory.showMessage(IMessage.WARNING, "The class for " + onType
  724. // + " should be recompiled with ajc-1.1.1 for best results", onType.getSourceLocation(), null);
  725. // needOldStyleWarning = false;
  726. // }
  727. onType.addInterTypeMunger(munger, true);
  728. if (munger.getMunger() != null && munger.getMunger().getKind() == ResolvedTypeMunger.InnerClass) {
  729. // Must do these right now, because if we do an ITD member afterwards it may attempt to reference the
  730. // type being applied (the call above 'addInterTypeMunger' will fail for these ITDs if it needed
  731. // it to be in place)
  732. if (munger.munge(sourceType, onType)) {
  733. if (factory.pushinCollector != null) {
  734. factory.pushinCollector.tagAsMunged(sourceType, munger.getSourceMethod());
  735. }
  736. }
  737. }
  738. }
  739. }
  740. onType.checkInterTypeMungers();
  741. for (Iterator i = onType.getInterTypeMungers().iterator(); i.hasNext();) {
  742. EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
  743. if (munger.getMunger() == null || munger.getMunger().getKind() != ResolvedTypeMunger.InnerClass) {
  744. if (munger.munge(sourceType, onType)) {
  745. if (factory.pushinCollector != null) {
  746. factory.pushinCollector.tagAsMunged(sourceType, munger.getSourceMethod());
  747. }
  748. }
  749. }
  750. }
  751. }
  752. // Call if you would like to do source weaving of declare
  753. // @method/@constructor
  754. // at source time... no need to do this as it can't impact anything, but
  755. // left here for
  756. // future generations to enjoy. Method source is commented out at the
  757. // end of this module
  758. // doDeclareAnnotationOnMethods();
  759. // Call if you would like to do source weaving of declare @field
  760. // at source time... no need to do this as it can't impact anything, but
  761. // left here for
  762. // future generations to enjoy. Method source is commented out at the
  763. // end of this module
  764. // doDeclareAnnotationOnFields();
  765. if (skipInners) {
  766. CompilationAndWeavingContext.leavingPhase(tok);
  767. return;
  768. }
  769. ReferenceBinding[] memberTypes = sourceType.memberTypes;
  770. for (int i = 0, length = memberTypes.length; i < length; i++) {
  771. if (memberTypes[i] instanceof SourceTypeBinding) {
  772. weaveInterTypeDeclarations((SourceTypeBinding) memberTypes[i], typeMungers, declareParents,
  773. declareAnnotationOnTypes, false, mode);
  774. }
  775. }
  776. CompilationAndWeavingContext.leavingPhase(tok);
  777. }
  778. /**
  779. * Called when we discover we are weaving intertype declarations on some type that has an existing 'WeaverStateInfo' object -
  780. * this is typically some previously woven type that has been passed on the inpath.
  781. *
  782. * sourceType and onType are the 'same type' - the former is the 'Eclipse' version and the latter is the 'Weaver' version.
  783. */
  784. private void processTypeMungersFromExistingWeaverState(SourceTypeBinding sourceType, ResolvedType onType) {
  785. List<ConcreteTypeMunger> previouslyAppliedMungers = onType.getWeaverState().getTypeMungers(onType);
  786. for (Iterator<ConcreteTypeMunger> i = previouslyAppliedMungers.iterator(); i.hasNext();) {
  787. ConcreteTypeMunger m = i.next();
  788. EclipseTypeMunger munger = factory.makeEclipseTypeMunger(m);
  789. if (munger.munge(sourceType, onType)) {
  790. if (onType.isInterface() && munger.getMunger().needsAccessToTopmostImplementor()) {
  791. if (!onType.getWorld().getCrosscuttingMembersSet().containsAspect(munger.getAspectType())) {
  792. dangerousInterfaces
  793. .put(onType, "implementors of " + onType + " must be woven by " + munger.getAspectType());
  794. }
  795. }
  796. }
  797. }
  798. }
  799. private boolean doDeclareParents(DeclareParents declareParents, SourceTypeBinding sourceType) {
  800. ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS,
  801. sourceType.sourceName);
  802. ResolvedType resolvedSourceType = factory.fromEclipse(sourceType);
  803. List<ResolvedType> newParents = declareParents.findMatchingNewParents(resolvedSourceType, false);
  804. if (!newParents.isEmpty()) {
  805. for (Iterator<ResolvedType> i = newParents.iterator(); i.hasNext();) {
  806. ResolvedType parent = i.next();
  807. if (dangerousInterfaces.containsKey(parent)) {
  808. ResolvedType onType = factory.fromEclipse(sourceType);
  809. factory.showMessage(IMessage.ERROR, onType + ": " + dangerousInterfaces.get(parent),
  810. onType.getSourceLocation(), null);
  811. }
  812. if (Modifier.isFinal(parent.getModifiers())) {
  813. factory.showMessage(IMessage.ERROR, "cannot extend final class " + parent.getClassName(),
  814. declareParents.getSourceLocation(), null);
  815. } else {
  816. // do not actually do it if the type isn't exposed - this
  817. // will correctly reported as a problem elsewhere
  818. if (!resolvedSourceType.isExposedToWeaver()) {
  819. return false;
  820. }
  821. // AsmRelationshipProvider.getDefault().
  822. // addDeclareParentsRelationship
  823. // (declareParents.getSourceLocation(),
  824. // factory.fromEclipse(sourceType), newParents);
  825. addParent(sourceType, parent);
  826. }
  827. }
  828. CompilationAndWeavingContext.leavingPhase(tok);
  829. return true;
  830. }
  831. CompilationAndWeavingContext.leavingPhase(tok);
  832. return false;
  833. }
  834. private String stringifyTargets(long bits) {
  835. if ((bits & TagBits.AnnotationTargetMASK) == 0) {
  836. return "";
  837. }
  838. Set<String> s = new HashSet<String>();
  839. if ((bits & TagBits.AnnotationForAnnotationType) != 0) {
  840. s.add("ANNOTATION_TYPE");
  841. }
  842. if ((bits & TagBits.AnnotationForConstructor) != 0) {
  843. s.add("CONSTRUCTOR");
  844. }
  845. if ((bits & TagBits.AnnotationForField) != 0) {
  846. s.add("FIELD");
  847. }
  848. if ((bits & TagBits.AnnotationForLocalVariable) != 0) {
  849. s.add("LOCAL_VARIABLE");
  850. }
  851. if ((bits & TagBits.AnnotationForMethod) != 0) {
  852. s.add("METHOD");
  853. }
  854. if ((bits & TagBits.AnnotationForPackage) != 0) {
  855. s.add("PACKAGE");
  856. }
  857. if ((bits & TagBits.AnnotationForParameter) != 0) {
  858. s.add("PARAMETER");
  859. }
  860. if ((bits & TagBits.AnnotationForType) != 0) {
  861. s.add("TYPE");
  862. }
  863. StringBuffer sb = new StringBuffer();
  864. sb.append("{");
  865. for (Iterator<String> iter = s.iterator(); iter.hasNext();) {
  866. String element = iter.next();
  867. sb.append(element);
  868. if (iter.hasNext()) {
  869. sb.append(",");
  870. }
  871. }
  872. sb.append("}");
  873. return sb.toString();
  874. }
  875. private boolean doDeclareAnnotations(DeclareAnnotation decA, SourceTypeBinding sourceType, boolean reportProblems) {
  876. ResolvedType rtx = factory.fromEclipse(sourceType);
  877. if (!decA.matches(rtx)) {
  878. return false;
  879. }
  880. if (!rtx.isExposedToWeaver()) {
  881. return false;
  882. }
  883. ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_ANNOTATIONS,
  884. sourceType.sourceName);
  885. // Get the annotation specified in the declare
  886. UnresolvedType aspectType = decA.getAspect();
  887. if (aspectType instanceof ReferenceType) {
  888. ReferenceType rt = (ReferenceType) aspectType;
  889. if (rt.isParameterizedType() || rt.isRawType()) {
  890. aspectType = rt.getGenericType();
  891. }
  892. }
  893. TypeBinding tb = factory.makeTypeBinding(aspectType);
  894. // Hideousness follows:
  895. // There are multiple situations to consider here and they relate to the
  896. // combinations of
  897. // where the annotation is coming from and where the annotation is going
  898. // to be put:
  899. //
  900. // 1. Straight full build, all from source - the annotation is from a
  901. // dec@type and
  902. // is being put on some type. Both types are real SourceTypeBindings.
  903. // WORKS
  904. // 2. Incremental build, changing the affected type - the annotation is
  905. // from a
  906. // dec@type in a BinaryTypeBinding (so has to be accessed via bcel) and
  907. // the
  908. // affected type is a real SourceTypeBinding. Mostly works (pr128665)
  909. // 3. ?
  910. SourceTypeBinding stb = (SourceTypeBinding) tb;
  911. Annotation[] toAdd = null;
  912. long abits = 0;
  913. AbstractMethodDeclaration methodDecl = null;
  914. // Might have to retrieve the annotation through BCEL and construct an
  915. // eclipse one for it.
  916. if (stb instanceof BinaryTypeBinding) {
  917. toAdd = retrieveAnnotationFromBinaryTypeBinding(decA, stb);
  918. if (toAdd != null && toAdd.length > 0 && toAdd[0].resolvedType != null) {
  919. abits = toAdd[0].resolvedType.getAnnotationTagBits();
  920. }
  921. } else if (stb != null) {
  922. // much nicer, its a real SourceTypeBinding so we can stay in
  923. // eclipse land
  924. // if (decA.getAnnotationMethod() != null) {
  925. char[] declareSelector = decA.getAnnotationMethod().toCharArray();
  926. ReferenceBinding rb = stb;
  927. String declaringAspectName = decA.getDeclaringType().getRawName();
  928. while (rb != null && !new String(CharOperation.concatWith(rb.compoundName, '.')).equals(declaringAspectName)) {
  929. rb = rb.superclass();
  930. }
  931. MethodBinding[] mbs = rb.getMethods(declareSelector);
  932. ReferenceBinding declaringBinding = mbs[0].declaringClass;
  933. if (declaringBinding instanceof ParameterizedTypeBinding) {
  934. // Unwrap - this means we don't allow the type of the annotation to be parameterized, may need to revisit that
  935. declaringBinding = ((ParameterizedTypeBinding) declaringBinding).type;
  936. }
  937. if (declaringBinding instanceof BinaryTypeBinding) {
  938. toAdd = retrieveAnnotationFromBinaryTypeBinding(decA, declaringBinding);
  939. if (toAdd != null && toAdd.length > 0 && toAdd[0].resolvedType != null) {
  940. abits = toAdd[0].resolvedType.getAnnotationTagBits();
  941. }
  942. } else {
  943. abits = mbs[0].getAnnotationTagBits(); // ensure resolved
  944. TypeDeclaration typeDecl = ((SourceTypeBinding) declaringBinding).scope.referenceContext;
  945. methodDecl = typeDecl.declarationOf(mbs[0]);
  946. toAdd = methodDecl.annotations; // this is what to add
  947. toAdd[0] = createAnnotationCopy(toAdd[0]);
  948. if (toAdd[0].resolvedType != null) {
  949. abits = toAdd[0].resolvedType.getAnnotationTagBits();
  950. // }
  951. }
  952. }
  953. }
  954. // This happens if there is another error in the code - that should be reported separately
  955. if (toAdd == null || toAdd[0] == null || toAdd[0].type == null) {
  956. CompilationAndWeavingContext.leavingPhase(tok);
  957. return false;
  958. }
  959. if (sourceType instanceof BinaryTypeBinding) {
  960. // In this case we can't access the source type binding to add a new
  961. // annotation, so let's put something
  962. // on the weaver type temporarily
  963. ResolvedType theTargetType = factory.fromEclipse(sourceType);
  964. TypeBinding theAnnotationType = toAdd[0].resolvedType;
  965. // The annotation type may be null if it could not be resolved (eg. the relevant import has not been added yet)
  966. // In this case an error will be put out about the annotation but not if we crash here
  967. if (theAnnotationType == null) {
  968. return false;
  969. }
  970. String sig = new String(theAnnotationType.signature());
  971. UnresolvedType bcelAnnotationType = UnresolvedType.forSignature(sig);
  972. String name = bcelAnnotationType.getName();
  973. if (theTargetType.hasAnnotation(bcelAnnotationType)) {
  974. CompilationAndWeavingContext.leavingPhase(tok);
  975. return false;
  976. }
  977. // FIXME asc tidy up this code that duplicates whats below!
  978. // Simple checks on the bits
  979. boolean giveupnow = false;
  980. if (((abits & TagBits.AnnotationTargetMASK) != 0)) {
  981. if (isAnnotationTargettingSomethingOtherThanAnnotationOrNormal(abits)) {
  982. // error will have been already reported
  983. giveupnow = true;
  984. } else if ((sourceType.isAnnotationType() && (abits & TagBits.AnnotationForAnnotationType) == 0)
  985. || (!sourceType.isAnnotationType() && (abits & TagBits.AnnotationForType) == 0)) {
  986. if (reportProblems) {
  987. if (decA.isExactPattern()) {
  988. factory.showMessage(IMessage.ERROR, WeaverMessages.format(
  989. WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION, rtx.getName(), toAdd[0].type,
  990. stringifyTargets(abits)), decA.getSourceLocation(), null);
  991. }
  992. // dont put out the lint - the weaving process will do
  993. // that
  994. // else {
  995. // if (factory.getWorld().getLint().
  996. // invalidTargetForAnnotation.isEnabled()) {
  997. // factory.getWorld().getLint().invalidTargetForAnnotation
  998. // .signal(new
  999. // String[]{rtx.getName(),toAdd[0].type.toString(),
  1000. // stringifyTargets
  1001. // (abits)},decA.getSourceLocation(),null);
  1002. // }
  1003. // }
  1004. }
  1005. giveupnow = true;
  1006. }
  1007. }
  1008. if (giveupnow) {
  1009. CompilationAndWeavingContext.leavingPhase(tok);
  1010. return false;
  1011. }
  1012. theTargetType.addAnnotation(new BcelAnnotation(new FakeAnnotation(name, sig,
  1013. (abits & TagBits.AnnotationRuntimeRetention) != 0), factory.getWorld()));
  1014. CompilationAndWeavingContext.leavingPhase(tok);
  1015. return true;
  1016. }
  1017. Annotation currentAnnotations[] = sourceType.scope.referenceContext.annotations;
  1018. if (currentAnnotations != null) {
  1019. for (int i = 0; i < currentAnnotations.length; i++) {
  1020. Annotation annotation = currentAnnotations[i];
  1021. String a = CharOperation.toString(annotation.type.getTypeName());
  1022. String b = CharOperation.toString(toAdd[0].type.getTypeName());
  1023. // FIXME asc we have a lint for attempting to add an annotation
  1024. // twice to a method,
  1025. // we could put it out here *if* we can resolve the problem of
  1026. // errors coming out
  1027. // multiple times if we have cause to loop through here
  1028. if (a.equals(b)) {
  1029. CompilationAndWeavingContext.leavingPhase(tok);
  1030. return false;
  1031. }
  1032. }
  1033. }
  1034. if (((abits & TagBits.AnnotationTargetMASK) != 0)) {
  1035. if ((abits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType)) == 0) {
  1036. // this means it specifies something other than annotation or
  1037. // normal type - error will have been already reported,
  1038. // just resolution process above
  1039. CompilationAndWeavingContext.leavingPhase(tok);
  1040. return false;
  1041. }
  1042. if ((sourceType.isAnnotationType() && (abits & TagBits.AnnotationForAnnotationType) == 0)
  1043. || (!sourceType.isAnnotationType() && (abits & TagBits.AnnotationForType) == 0)) {
  1044. if (reportProblems) {
  1045. if (decA.isExactPattern()) {
  1046. factory.showMessage(IMessage.ERROR, WeaverMessages.format(
  1047. WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION, rtx.getName(), toAdd[0].type,
  1048. stringifyTargets(abits)), decA.getSourceLocation(), null);
  1049. }
  1050. // dont put out the lint - the weaving process will do that
  1051. // else {
  1052. // if
  1053. // (factory.getWorld().getLint().invalidTargetForAnnotation
  1054. // .isEnabled()) {
  1055. // factory.getWorld().getLint().invalidTargetForAnnotation.
  1056. // signal(new
  1057. // String[]{rtx.getName(),toAdd[0].type.toString(),
  1058. // stringifyTargets(abits)},decA.getSourceLocation(),null);
  1059. // }
  1060. // }
  1061. }
  1062. CompilationAndWeavingContext.leavingPhase(tok);
  1063. return false;
  1064. }
  1065. }
  1066. // Build a new array of annotations
  1067. // remember the current set (rememberAnnotations only does something the
  1068. // first time it is called for a type)
  1069. sourceType.scope.referenceContext.rememberAnnotations();
  1070. // AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(
  1071. // decA.getSourceLocation(), rtx.getSourceLocation());
  1072. Annotation abefore[] = sourceType.scope.referenceContext.annotations;
  1073. Annotation[] newset = new Annotation[toAdd.length + (abefore == null ? 0 : abefore.length)];
  1074. System.arraycopy(toAdd, 0, newset, 0, toAdd.length);
  1075. if (abefore != null) {
  1076. System.arraycopy(abefore, 0, newset, toAdd.length, abefore.length);
  1077. }
  1078. sourceType.scope.referenceContext.annotations = newset;
  1079. CompilationAndWeavingContext.leavingPhase(tok);
  1080. if (factory.pushinCollector != null) {
  1081. factory.pushinCollector.tagAsMunged(sourceType, new CommonPrinter((methodDecl == null ? null : methodDecl.scope))
  1082. .printAnnotation(toAdd[0]).toString());
  1083. }
  1084. return true;
  1085. }
  1086. private Annotation[] retrieveAnnotationFromBinaryTypeBinding(DeclareAnnotation decA, ReferenceBinding declaringBinding) {
  1087. ReferenceType rt = (ReferenceType) factory.fromEclipse(declaringBinding);
  1088. ResolvedMember[] methods = rt.getDeclaredMethods();
  1089. ResolvedMember decaMethod = null;
  1090. String nameToLookFor = decA.getAnnotationMethod();
  1091. for (int i = 0; i < methods.length; i++) {
  1092. if (methods[i].getName().equals(nameToLookFor)) {
  1093. decaMethod = methods[i];
  1094. break;
  1095. }
  1096. }
  1097. if (decaMethod != null) { // could assert this ...
  1098. AnnotationAJ[] axs = decaMethod.getAnnotations();
  1099. if (axs != null) { // another error has occurred, dont crash here because of it
  1100. Annotation[] toAdd = new Annotation[1];
  1101. toAdd[0] = createAnnotationFromBcelAnnotation(axs[0], decaMethod.getSourceLocation().getOffset(), factory);
  1102. // BUG BUG BUG - We dont test these abits are correct, in fact
  1103. // we'll be very lucky if they are.
  1104. // What does that mean? It means on an incremental compile you
  1105. // might get away with an
  1106. // annotation that isn't allowed on a type being put on a type.
  1107. // if (toAdd[0].resolvedType != null) {
  1108. // abits = toAdd[0].resolvedType.getAnnotationTagBits();
  1109. // }
  1110. return toAdd;
  1111. }
  1112. }
  1113. return null;
  1114. }
  1115. /**
  1116. * Transform an annotation from its AJ form to an eclipse form. We *DONT* care about the values of the annotation. that is
  1117. * because it is only being stuck on a type during type completion to allow for other constructs (decps, decas) that might be
  1118. * looking for it - when the class actually gets to disk it wont have this new annotation on it and during weave time we will do
  1119. * the right thing copying across values too.
  1120. */
  1121. private static Annotation createAnnotationFromBcelAnnotation(AnnotationAJ annX, int pos, EclipseFactory factory) {
  1122. String name = annX.getTypeName();
  1123. TypeBinding tb = factory.makeTypeBinding(annX.getType());
  1124. // String theName = annX.getSignature().getBaseName();
  1125. char[][] typeName = CharOperation.splitOn('.', name.replace('$', '.').toCharArray()); // pr149293 - not bulletproof...
  1126. long[] positions = new long[typeName.length];
  1127. for (int i = 0; i < positions.length; i++) {
  1128. positions[i] = pos;
  1129. }
  1130. TypeReference annType = new QualifiedTypeReference(typeName, positions);
  1131. NormalAnnotation ann = new NormalAnnotation(annType, pos);
  1132. ann.resolvedType = tb; // yuck - is this OK in all cases?
  1133. // We don't need membervalues...
  1134. // Expression pcExpr = new
  1135. // StringLiteral(pointcutExpression.toCharArray(),pos,pos);
  1136. // MemberValuePair[] mvps = new MemberValuePair[2];
  1137. // mvps[0] = new MemberValuePair("value".toCharArray(),pos,pos,pcExpr);
  1138. // Expression argNamesExpr = new
  1139. // StringLiteral(argNames.toCharArray(),pos,pos);
  1140. // mvps[1] = new
  1141. // MemberValuePair("argNames".toCharArray(),pos,pos,argNamesExpr);
  1142. // ann.memberValuePairs = mvps;
  1143. return ann;
  1144. }
  1145. /**
  1146. * Create a copy of an annotation, not deep but deep enough so we don't copy across fields that will get us into trouble like
  1147. * 'recipient'
  1148. */
  1149. private static Annotation createAnnotationCopy(Annotation ann) {
  1150. NormalAnnotation ann2 = new NormalAnnotation(ann.type, ann.sourceStart);
  1151. ann2.memberValuePairs = ann.memberValuePairs();
  1152. ann2.resolvedType = ann.resolvedType;
  1153. ann2.bits = ann.bits;
  1154. return ann2;
  1155. // String name = annX.getTypeName();
  1156. // TypeBinding tb = factory.makeTypeBinding(annX.getSignature());
  1157. // String theName = annX.getSignature().getBaseName();
  1158. // char[][] typeName =
  1159. // CharOperation.splitOn('.',name.replace('$','.').toCharArray());
  1160. // //pr149293 - not bulletproof...
  1161. // long[] positions = new long[typeName.length];
  1162. // for (int i = 0; i < positions.length; i++) positions[i]=pos;
  1163. // TypeReference annType = new
  1164. // QualifiedTypeReference(typeName,positions);
  1165. // NormalAnnotation ann = new NormalAnnotation(annType,pos);
  1166. // ann.resolvedType=tb; // yuck - is this OK in all cases?
  1167. // // We don't need membervalues...
  1168. // // Expression pcExpr = new
  1169. // StringLiteral(pointcutExpression.toCharArray(),pos,pos);
  1170. // // MemberValuePair[] mvps = new MemberValuePair[2];
  1171. // // mvps[0] = new
  1172. // MemberValuePair("value".toCharArray(),pos,pos,pcExpr);
  1173. // // Expression argNamesExpr = new
  1174. // StringLiteral(argNames.toCharArray(),pos,pos);
  1175. // // mvps[1] = new
  1176. // MemberValuePair("argNames".toCharArray(),pos,pos,argNamesExpr);
  1177. // // ann.memberValuePairs = mvps;
  1178. // return ann;
  1179. }
  1180. private boolean isAnnotationTargettingSomethingOtherThanAnnotationOrNormal(long abits) {
  1181. return (abits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType)) == 0;
  1182. }
  1183. // private void reportDeclareParentsMessage(WeaveMessage.WeaveMessageKind wmk, SourceTypeBinding sourceType, ResolvedType parent) {
  1184. // if (!factory.getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
  1185. // String filename = new String(sourceType.getFileName());
  1186. //
  1187. // int takefrom = filename.lastIndexOf('/');
  1188. // if (takefrom == -1) {
  1189. // takefrom = filename.lastIndexOf('\\');
  1190. // }
  1191. // filename = filename.substring(takefrom + 1);
  1192. //
  1193. // factory.getWorld()
  1194. // .getMessageHandler()
  1195. // .handleMessage(
  1196. // WeaveMessage.constructWeavingMessage(wmk,
  1197. // new String[] { CharOperation.toString(sourceType.compoundName), filename,
  1198. // parent.getClassName(),
  1199. // getShortname(parent.getSourceLocation().getSourceFile().getPath()) }));
  1200. // }
  1201. // }
  1202. // private String getShortname(String path) {
  1203. // int takefrom = path.lastIndexOf('/');
  1204. // if (takefrom == -1) {
  1205. // takefrom = path.lastIndexOf('\\');
  1206. // }
  1207. // return path.substring(takefrom + 1);
  1208. // }
  1209. private void addParent(SourceTypeBinding sourceType, ResolvedType parent) {
  1210. ReferenceBinding parentBinding = (ReferenceBinding) factory.makeTypeBinding(parent);
  1211. if (parentBinding == null) {
  1212. return; // The parent is missing, it will be reported elsewhere.
  1213. }
  1214. // Due to e37 switching to MethodVerifier15 for everything, it is important added types are correctly
  1215. // raw or not. For example, if Comparable is used in generic form compareTo(T) will be used to check
  1216. // methods against in the verifier rather than compareTo(Object)
  1217. if (!factory.getWorld().isInJava5Mode()) {
  1218. parentBinding = (ReferenceBinding)convertToRawType(parentBinding, false /*do not force conversion of enclosing types*/);
  1219. }
  1220. sourceType.rememberTypeHierarchy();
  1221. if (parentBinding.isClass()) {
  1222. sourceType.superclass = parentBinding;
  1223. // this used to be true, but I think I've fixed it now, decp is done
  1224. // at weave time!
  1225. // TAG: WeavingMessage DECLARE PARENTS: EXTENDS
  1226. // Compiler restriction: Can't do EXTENDS at weave time
  1227. // So, only see this message if doing a source compilation
  1228. // reportDeclareParentsMessage(WeaveMessage.
  1229. // WEAVEMESSAGE_DECLAREPARENTSEXTENDS,sourceType,parent);
  1230. } else {
  1231. ReferenceBinding[] oldI = sourceType.superInterfaces;
  1232. ReferenceBinding[] newI;
  1233. if (oldI == null) {
  1234. newI = new ReferenceBinding[1];
  1235. newI[0] = parentBinding;
  1236. } else {
  1237. int n = oldI.length;
  1238. newI = new ReferenceBinding[n + 1];
  1239. System.arraycopy(oldI, 0, newI, 0, n);
  1240. newI[n] = parentBinding;
  1241. }
  1242. sourceType.superInterfaces = newI;
  1243. // warnOnAddedInterface(factory.fromEclipse(sourceType),parent); //
  1244. // now reported at weave time...
  1245. // this used to be true, but I think I've fixed it now, decp is done
  1246. // at weave time!
  1247. // TAG: WeavingMessage DECLARE PARENTS: IMPLEMENTS
  1248. // This message will come out of BcelTypeMunger.munge if doing a
  1249. // binary weave
  1250. // reportDeclareParentsMessage(WeaveMessage.
  1251. // WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS,sourceType,parent);
  1252. }
  1253. // also add it to the bcel delegate if there is one
  1254. if (sourceType instanceof BinaryTypeBinding) {
  1255. ResolvedType onType = factory.fromEclipse(sourceType);
  1256. ReferenceType rt = (ReferenceType) onType;
  1257. ReferenceTypeDelegate rtd = rt.getDelegate();
  1258. if (rtd instanceof BcelObjectType) {
  1259. if (rt.isRawType()) {
  1260. rt = (ReferenceType)rt.getGenericType();
  1261. }
  1262. rt.addParent(parent);
  1263. // ((BcelObjectType) rtd).addParent(parent);
  1264. }
  1265. }
  1266. }
  1267. public void warnOnAddedInterface(ResolvedType type, ResolvedType parent) {
  1268. World world = factory.getWorld();
  1269. ResolvedType serializable = world.getCoreType(UnresolvedType.SERIALIZABLE);
  1270. if (serializable.isAssignableFrom(type) && !serializable.isAssignableFrom(parent)
  1271. && !LazyClassGen.hasSerialVersionUIDField(type)) {
  1272. world.getLint().needsSerialVersionUIDField.signal(new String[] { type.getName().toString(),
  1273. "added interface " + parent.getName().toString() }, null, null);
  1274. }
  1275. }
  1276. private final List pendingTypesToFinish = new ArrayList();
  1277. boolean inBinaryTypeCreationAndWeaving = false;
  1278. boolean processingTheQueue = false;
  1279. public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding,
  1280. boolean needFieldsAndMethods, AccessRestriction accessRestriction) {
  1281. if (inBinaryTypeCreationAndWeaving) {
  1282. BinaryTypeBinding ret = super.createBinaryTypeFrom(binaryType, packageBinding, needFieldsAndMethods, accessRestriction);
  1283. pendingTypesToFinish.add(ret);
  1284. return ret;
  1285. }
  1286. inBinaryTypeCreationAndWeaving = true;
  1287. try {
  1288. BinaryTypeBinding ret = super.createBinaryTypeFrom(binaryType, packageBinding, needFieldsAndMethods, accessRestriction);
  1289. factory.getWorld().validateType(factory.fromBinding(ret));
  1290. // if you need the bytes to pass to validate, here they
  1291. // are:((ClassFileReader)binaryType).getReferenceBytes()
  1292. weaveInterTypeDeclarations(ret);
  1293. return ret;
  1294. } finally {
  1295. inBinaryTypeCreationAndWeaving = false;
  1296. // Start processing the list...
  1297. if (pendingTypesToFinish.size() > 0) {
  1298. processingTheQueue = true;
  1299. while (!pendingTypesToFinish.isEmpty()) {
  1300. BinaryTypeBinding nextVictim = (BinaryTypeBinding) pendingTypesToFinish.remove(0);
  1301. // During this call we may recurse into this method and add
  1302. // more entries to the pendingTypesToFinish list.
  1303. weaveInterTypeDeclarations(nextVictim);
  1304. }
  1305. processingTheQueue = false;
  1306. }
  1307. }
  1308. }
  1309. /**
  1310. * Callback driven when the compiler detects an anonymous type during block resolution. We need to add it to the weaver so that
  1311. * we don't trip up later.
  1312. *
  1313. * @param aBinding
  1314. */
  1315. public void anonymousTypeBindingCreated(LocalTypeBinding aBinding) {
  1316. factory.addSourceTypeBinding(aBinding, null);
  1317. }
  1318. }
  1319. // commented out, supplied as info on how to manipulate annotations in an
  1320. // eclipse world
  1321. //
  1322. // public void doDeclareAnnotationOnMethods() {
  1323. // Do the declare annotation on fields/methods/ctors
  1324. // Collection daoms = factory.getDeclareAnnotationOnMethods();
  1325. // if (daoms!=null && daoms.size()>0 && !(sourceType instanceof
  1326. // BinaryTypeBinding)) {
  1327. // System.err.println("Going through the methods on "+sourceType.debugName()+
  1328. // " looking for DECA matches");
  1329. // // We better take a look through them...
  1330. // for (Iterator iter = daoms.iterator(); iter.hasNext();) {
  1331. // DeclareAnnotation element = (DeclareAnnotation) iter.next();
  1332. // System.err.println("Looking for anything that might match "+element+" on "+
  1333. // sourceType.debugName()+" "+getType(sourceType.
  1334. // compoundName).debugName()+" "+(sourceType instanceof BinaryTypeBinding));
  1335. //
  1336. // ReferenceBinding rbb = getType(sourceType.compoundName);
  1337. // // fix me if we ever uncomment this code... should iterate the other way
  1338. // round, over the methods then over the decas
  1339. // sourceType.methods();
  1340. // MethodBinding sourceMbs[] = sourceType.methods;
  1341. // for (int i = 0; i < sourceMbs.length; i++) {
  1342. // MethodBinding sourceMb = sourceMbs[i];
  1343. // MethodBinding mbbbb =
  1344. // ((SourceTypeBinding)rbb).getExactMethod(sourceMb.selector
  1345. // ,sourceMb.parameters);
  1346. // boolean isCtor = sourceMb.selector[0]=='<';
  1347. //
  1348. // if ((element.isDeclareAtConstuctor() ^ !isCtor)) {
  1349. // System.err.println("Checking "+sourceMb+" ... declaringclass="+sourceMb.
  1350. // declaringClass.debugName()+" rbb="+rbb.debugName()+" "+
  1351. // sourceMb.declaringClass.equals(rbb));
  1352. //
  1353. // ResolvedMember rm = null;
  1354. // rm = EclipseFactory.makeResolvedMember(mbbbb);
  1355. // if (element.matches(rm,factory.getWorld())) {
  1356. // System.err.println("MATCH");
  1357. //
  1358. // // Determine the set of annotations that are currently on the method
  1359. // ReferenceBinding rb = getType(sourceType.compoundName);
  1360. // // TypeBinding tb = factory.makeTypeBinding(decA.getAspect());
  1361. // MethodBinding mb =
  1362. // ((SourceTypeBinding)rb).getExactMethod(sourceMb.selector,sourceMb
  1363. // .parameters);
  1364. // //long abits = mbs[0].getAnnotationTagBits(); // ensure resolved
  1365. // TypeDeclaration typeDecl =
  1366. // ((SourceTypeBinding)sourceMb.declaringClass).scope.referenceContext;
  1367. // AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(sourceMb);
  1368. // Annotation[] currentlyHas = methodDecl.annotations; // this is what to add
  1369. // //abits = toAdd[0].resolvedType.getAnnotationTagBits();
  1370. //
  1371. // // Determine the annotations to add to that method
  1372. // TypeBinding tb = factory.makeTypeBinding(element.getAspect());
  1373. // MethodBinding[] aspectMbs =
  1374. // ((SourceTypeBinding)tb).getMethods(element.getAnnotationMethod
  1375. // ().toCharArray());
  1376. // long abits = aspectMbs[0].getAnnotationTagBits(); // ensure resolved
  1377. // TypeDeclaration typeDecl2 =
  1378. // ((SourceTypeBinding)aspectMbs[0].declaringClass).scope.referenceContext;
  1379. // AbstractMethodDeclaration methodDecl2 =
  1380. // typeDecl2.declarationOf(aspectMbs[0]);
  1381. // Annotation[] toAdd = methodDecl2.annotations; // this is what to add
  1382. // // abits = toAdd[0].resolvedType.getAnnotationTagBits();
  1383. // System.err.println("Has: "+currentlyHas+" toAdd: "+toAdd);
  1384. //
  1385. // // fix me? should check if it already has the annotation
  1386. // //Annotation abefore[] = sourceType.scope.referenceContext.annotations;
  1387. // Annotation[] newset = new
  1388. // Annotation[(currentlyHas==null?0:currentlyHas.length)+1];
  1389. // System.arraycopy(toAdd,0,newset,0,toAdd.length);
  1390. // if (currentlyHas!=null) {
  1391. // System.arraycopy(currentlyHas,0,newset,1,currentlyHas.length);
  1392. // }
  1393. // methodDecl.annotations = newset;
  1394. // System.err.println("New set on "+CharOperation.charToString(sourceMb.selector)
  1395. // +" is "+newset);
  1396. // } else
  1397. // System.err.println("NO MATCH");
  1398. // }
  1399. // }
  1400. // }
  1401. // }
  1402. // }
  1403. // commented out, supplied as info on how to manipulate annotations in an
  1404. // eclipse world
  1405. //
  1406. // public void doDeclareAnnotationOnFields() {
  1407. // Collection daofs = factory.getDeclareAnnotationOnFields();
  1408. // if (daofs!=null && daofs.size()>0 && !(sourceType instanceof
  1409. // BinaryTypeBinding)) {
  1410. // System.err.println("Going through the fields on "+sourceType.debugName()+
  1411. // " looking for DECA matches");
  1412. // // We better take a look through them...
  1413. // for (Iterator iter = daofs.iterator(); iter.hasNext();) {
  1414. // DeclareAnnotation element = (DeclareAnnotation) iter.next();
  1415. // System.err.println("Processing deca "+element+" on "+sourceType.debugName()+
  1416. // " "+getType(sourceType.compoundName).debugName()+" "
  1417. // +(sourceType instanceof BinaryTypeBinding));
  1418. //
  1419. // ReferenceBinding rbb = getType(sourceType.compoundName);
  1420. // // fix me? should iterate the other way round, over the methods then over the
  1421. // decas
  1422. // sourceType.fields(); // resolve the bloody things
  1423. // FieldBinding sourceFbs[] = sourceType.fields;
  1424. // for (int i = 0; i < sourceFbs.length; i++) {
  1425. // FieldBinding sourceFb = sourceFbs[i];
  1426. // //FieldBinding fbbbb =
  1427. // ((SourceTypeBinding)rbb).getgetExactMethod(sourceMb.selector
  1428. // ,sourceMb.parameters);
  1429. //
  1430. // System.err.println("Checking "+sourceFb+" ... declaringclass="+sourceFb.
  1431. // declaringClass.debugName()+" rbb="+rbb.debugName());
  1432. //
  1433. // ResolvedMember rm = null;
  1434. // rm = EclipseFactory.makeResolvedMember(sourceFb);
  1435. // if (element.matches(rm,factory.getWorld())) {
  1436. // System.err.println("MATCH");
  1437. //
  1438. // // Determine the set of annotations that are currently on the field
  1439. // ReferenceBinding rb = getType(sourceType.compoundName);
  1440. // // TypeBinding tb = factory.makeTypeBinding(decA.getAspect());
  1441. // FieldBinding fb = ((SourceTypeBinding)rb).getField(sourceFb.name,true);
  1442. // //long abits = mbs[0].getAnnotationTagBits(); // ensure resolved
  1443. // TypeDeclaration typeDecl =
  1444. // ((SourceTypeBinding)sourceFb.declaringClass).scope.referenceContext;
  1445. // FieldDeclaration fd = typeDecl.declarationOf(sourceFb);
  1446. // //AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(sourceMb);
  1447. // Annotation[] currentlyHas = fd.annotations; // this is what to add
  1448. // //abits = toAdd[0].resolvedType.getAnnotationTagBits();
  1449. //
  1450. // // Determine the annotations to add to that method
  1451. // TypeBinding tb = factory.makeTypeBinding(element.getAspect());
  1452. // MethodBinding[] aspectMbs =
  1453. // ((SourceTypeBinding)tb).getMethods(element.getAnnotationMethod
  1454. // ().toCharArray());
  1455. // long abits = aspectMbs[0].getAnnotationTagBits(); // ensure resolved
  1456. // TypeDeclaration typeDecl2 =
  1457. // ((SourceTypeBinding)aspectMbs[0].declaringClass).scope.referenceContext;
  1458. // AbstractMethodDeclaration methodDecl2 =
  1459. // typeDecl2.declarationOf(aspectMbs[0]);
  1460. // Annotation[] toAdd = methodDecl2.annotations; // this is what to add
  1461. // // abits = toAdd[0].resolvedType.getAnnotationTagBits();
  1462. // System.err.println("Has: "+currentlyHas+" toAdd: "+toAdd);
  1463. //
  1464. // // fix me? check if it already has the annotation
  1465. //
  1466. //
  1467. // //Annotation abefore[] = sourceType.scope.referenceContext.annotations;
  1468. // Annotation[] newset = new
  1469. // Annotation[(currentlyHas==null?0:currentlyHas.length)+1];
  1470. // System.arraycopy(toAdd,0,newset,0,toAdd.length);
  1471. // if (currentlyHas!=null) {
  1472. // System.arraycopy(currentlyHas,0,newset,1,currentlyHas.length);
  1473. // }
  1474. // fd.annotations = newset;
  1475. // System.err.println("New set on "+CharOperation.charToString(sourceFb.name)+
  1476. // " is "+newset);
  1477. // } else
  1478. // System.err.println("NO MATCH");
  1479. // }
  1480. //
  1481. // }
  1482. // }