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

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