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