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.

AjLookupEnvironment.java 67KB

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