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