]> source.dussan.org Git - aspectj.git/commitdiff
Declare annotation: source weaving of declare @type. Includes (commented out) declar...
authoraclement <aclement>
Thu, 10 Mar 2005 20:36:56 +0000 (20:36 +0000)
committeraclement <aclement>
Thu, 10 Mar 2005 20:36:56 +0000 (20:36 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java

index cb24fe5c59b13525fa49deb21d0fd644c2c6713f..2365ef4524c2c339d2409edd002a3c592490eb4f 100644 (file)
@@ -16,9 +16,11 @@ package org.aspectj.ajdt.internal.compiler.lookup;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
 import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
@@ -26,6 +28,7 @@ import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.WeaveMessage;
 import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.AccessRestriction;
 import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType;
@@ -36,18 +39,23 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
 import org.aspectj.weaver.AsmRelationshipProvider;
 import org.aspectj.weaver.ConcreteTypeMunger;
 import org.aspectj.weaver.ResolvedTypeMunger;
 import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.TypeX;
+import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.WeaverStateInfo;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.bcel.LazyClassGen;
+import org.aspectj.weaver.patterns.DeclareAnnotation;
 import org.aspectj.weaver.patterns.DeclareParents;
 
 /**
@@ -119,6 +127,7 @@ public class AjLookupEnvironment extends LookupEnvironment {
                Collection typeMungers = factory.getTypeMungers();
                
                Collection declareParents = factory.getDeclareParents();
+               Collection declareAnnotationOnTypes = factory.getDeclareAnnotationOnTypes();
 
                doPendingWeaves();
                
@@ -135,7 +144,7 @@ public class AjLookupEnvironment extends LookupEnvironment {
                //   we had the full list.
                // 
                // but these aren't common cases (he bravely said...)
-               boolean typeProcessingOrderIsImportant = declareParents.size()>0;
+               boolean typeProcessingOrderIsImportant = declareParents.size()>0 || declareAnnotationOnTypes.size()>0; //DECAT
                
                if (typeProcessingOrderIsImportant) {
                        List typesToProcess = new ArrayList();
@@ -150,14 +159,14 @@ public class AjLookupEnvironment extends LookupEnvironment {
 
                        while (typesToProcess.size()>0) {
                                // A side effect of weaveIntertypes() is that the processed type is removed from the collection
-                               weaveIntertypes(typesToProcess,(SourceTypeBinding)typesToProcess.get(0),typeMungers,declareParents);
+                               weaveIntertypes(typesToProcess,(SourceTypeBinding)typesToProcess.get(0),typeMungers,declareParents,declareAnnotationOnTypes);
                        }
                
                } else {
                        // Order isn't important
                        for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
                                //System.err.println("Working on "+new String(units[i].getFileName()));
-                               weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents);
+                               weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents,declareAnnotationOnTypes);
                        }
                }
                
@@ -191,13 +200,13 @@ public class AjLookupEnvironment extends LookupEnvironment {
         * if you supply 'pieces' of a hierarchy, i.e. the bottom and the top, but not the middle - but what the hell
         * are you doing if you do that?
         */
-       private void weaveIntertypes(List typesToProcess,SourceTypeBinding typeToWeave,Collection typeMungers,Collection declareParents) {
+       private void weaveIntertypes(List typesToProcess,SourceTypeBinding typeToWeave,Collection typeMungers,
+                                            Collection declareParents,Collection declareAnnotationOnTypes) {
                // Look at the supertype first
            ReferenceBinding superType = typeToWeave.superclass();
-           //System.err.println("Been asked to weave "+new String(typeToWeave.getFileName()));
            if (typesToProcess.contains(superType) && superType instanceof SourceTypeBinding) {
                //System.err.println("Recursing to supertype "+new String(superType.getFileName()));
-               weaveIntertypes(typesToProcess,(SourceTypeBinding)superType,typeMungers,declareParents);
+               weaveIntertypes(typesToProcess,(SourceTypeBinding)superType,typeMungers,declareParents,declareAnnotationOnTypes);
            }
            // Then look at the superinterface list
                ReferenceBinding[] interfaceTypes = typeToWeave.superInterfaces();
@@ -205,10 +214,10 @@ public class AjLookupEnvironment extends LookupEnvironment {
                ReferenceBinding binding = interfaceTypes[i];
                if (typesToProcess.contains(binding) && binding instanceof SourceTypeBinding) {
                        //System.err.println("Recursing to superinterface "+new String(binding.getFileName()));
-                       weaveIntertypes(typesToProcess,(SourceTypeBinding)binding,typeMungers,declareParents);
+                       weaveIntertypes(typesToProcess,(SourceTypeBinding)binding,typeMungers,declareParents,declareAnnotationOnTypes);
                }
                }
-           weaveInterTypeDeclarations(typeToWeave,typeMungers,declareParents,false);
+           weaveInterTypeDeclarations(typeToWeave,typeMungers,declareParents,declareAnnotationOnTypes,false);
            typesToProcess.remove(typeToWeave);
        }
 
@@ -311,9 +320,10 @@ public class AjLookupEnvironment extends LookupEnvironment {
                }
        }
                
-       private void weaveInterTypeDeclarations(CompilationUnitScope unit, Collection typeMungers, Collection declareParents) {
+       private void weaveInterTypeDeclarations(CompilationUnitScope unit, Collection typeMungers, 
+                                                       Collection declareParents, Collection declareAnnotationOnTypes) {
                for (int i = 0, length = unit.topLevelTypes.length; i < length; i++) {
-                   weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents, false);
+                   weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents, declareAnnotationOnTypes,false);
                }
        }
        
@@ -321,11 +331,12 @@ public class AjLookupEnvironment extends LookupEnvironment {
                if (!factory.areTypeMungersFinished()) {
                        if (!pendingTypesToWeave.contains(sourceType)) pendingTypesToWeave.add(sourceType);
                } else {
-                       weaveInterTypeDeclarations(sourceType, factory.getTypeMungers(), factory.getDeclareParents(), true);
+                       weaveInterTypeDeclarations(sourceType, factory.getTypeMungers(), factory.getDeclareParents(), factory.getDeclareAnnotationOnTypes(),true);
                }
        }
        
-       private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, Collection declareParents, boolean skipInners) {
+       private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, Collection typeMungers, 
+                       Collection declareParents, Collection declareAnnotationOnTypes, boolean skipInners) {
                ResolvedTypeX onType = factory.fromEclipse(sourceType);
                WeaverStateInfo info = onType.getWeaverState();
 
@@ -370,10 +381,68 @@ public class AjLookupEnvironment extends LookupEnvironment {
                
                onType.clearInterTypeMungers();
                
+               // FIXME asc perf Could optimize here, after processing the expected set of types we may bring
+               // binary types that are not exposed to the weaver, there is no need to attempt declare parents
+               // or declare annotation really - unless we want to report the not-exposed to weaver
+               // messages...
+               
+               List decpToRepeat = new ArrayList();
+               List decaToRepeat = new ArrayList();
+               boolean anyNewParents = false;
+               boolean anyNewAnnotations = false;
+
+               // first pass 
+               // try and apply all decps - if they match, then great.  If they don't then
+               // check if they are starred-annotation patterns.  If they are not starred
+               // annotation patterns then they might match later...remember that...
                for (Iterator i = declareParents.iterator(); i.hasNext();) {
-                       doDeclareParents((DeclareParents)i.next(), sourceType);
+                       DeclareParents decp = (DeclareParents)i.next();
+                       boolean didSomething = doDeclareParents(decp, sourceType);
+                       if (didSomething) {
+                               anyNewParents = true;
+                       } else {
+                               if (!decp.getChild().isStarAnnotation()) decpToRepeat.add(decp);
+                       }
+               }
+
+               for (Iterator i = declareAnnotationOnTypes.iterator(); i.hasNext();) {
+                       DeclareAnnotation deca = (DeclareAnnotation)i.next();
+                       boolean didSomething = doDeclareAnnotations(deca, sourceType,true);
+                       if (didSomething) {
+                               anyNewAnnotations = true;
+                       } else {
+                               if (!deca.getTypePattern().isStar()) decaToRepeat.add(deca);
+                       }
+               }
+               
+        // now lets loop over and over until we have done all we can
+               while ((anyNewAnnotations || anyNewParents) && 
+                               (!decpToRepeat.isEmpty() || !decaToRepeat.isEmpty())) {
+                       anyNewParents = anyNewAnnotations = false;
+                       List forRemoval = new ArrayList();
+                       for (Iterator i = decpToRepeat.iterator(); i.hasNext();) {
+                               DeclareParents decp = (DeclareParents)i.next();
+                               boolean didSomething = doDeclareParents(decp, sourceType);
+                               if (didSomething) {
+                                       anyNewParents = true;
+                                       forRemoval.add(decp);
+                               }
+                       }
+                       decpToRepeat.removeAll(forRemoval);
+
+            forRemoval = new ArrayList();
+                       for (Iterator i = declareAnnotationOnTypes.iterator(); i.hasNext();) {
+                               DeclareAnnotation deca = (DeclareAnnotation)i.next();
+                               boolean didSomething = doDeclareAnnotations(deca, sourceType,false);
+                               if (didSomething) {
+                                       anyNewAnnotations = true;
+                                       forRemoval.add(deca);
+                               } 
+                       }
+                       decaToRepeat.removeAll(forRemoval);
                }
                
+               
                for (Iterator i = typeMungers.iterator(); i.hasNext();) {
                        EclipseTypeMunger munger = (EclipseTypeMunger) i.next();
                        if (munger.matches(onType)) {
@@ -398,6 +467,7 @@ public class AjLookupEnvironment extends LookupEnvironment {
                        }
                }
                
+               
         //???onType.checkInterTypeMungers();
         onType.checkInterTypeMungers();
                for (Iterator i = onType.getInterTypeMungers().iterator(); i.hasNext();) {
@@ -406,17 +476,27 @@ public class AjLookupEnvironment extends LookupEnvironment {
                        munger.munge(sourceType);
                }
                
+               // Call if you would like to do source weaving of declare @method/@constructor 
+               // at source time... no need to do this as it can't impact anything, but left here for
+               // future generations to enjoy.  Method source is commented out at the end of this module
+               // doDeclareAnnotationOnMethods();
+     
+               // Call if you would like to do source weaving of declare @field 
+               // at source time... no need to do this as it can't impact anything, but left here for
+               // future generations to enjoy.  Method source is commented out at the end of this module
+               // doDeclareAnnotationOnFields();
+
                if (skipInners) return;
 
                ReferenceBinding[] memberTypes = sourceType.memberTypes;
                for (int i = 0, length = memberTypes.length; i < length; i++) {
                        if (memberTypes[i] instanceof SourceTypeBinding) {
-                               weaveInterTypeDeclarations((SourceTypeBinding) memberTypes[i], typeMungers, declareParents, false);
+                               weaveInterTypeDeclarations((SourceTypeBinding) memberTypes[i], typeMungers, declareParents,declareAnnotationOnTypes, false);
                        }
                }
        }
        
-       private void doDeclareParents(DeclareParents declareParents, SourceTypeBinding sourceType) {
+       private boolean doDeclareParents(DeclareParents declareParents, SourceTypeBinding sourceType) {
                List newParents = declareParents.findMatchingNewParents(factory.fromEclipse(sourceType),false);
                if (!newParents.isEmpty()) {
                        for (Iterator i = newParents.iterator(); i.hasNext(); ) {
@@ -430,8 +510,100 @@ public class AjLookupEnvironment extends LookupEnvironment {
                                AsmRelationshipProvider.getDefault().addDeclareParentsRelationship(declareParents.getSourceLocation(),factory.fromEclipse(sourceType), newParents);
                                addParent(sourceType, parent);
                        }
+                       return true;
+               }
+               return false;
+       }
+       
+       private String stringifyTargets(long bits) {
+               if ((bits & TagBits.AnnotationTargetMASK)==0) return "";
+               Set s = new HashSet();
+               if ((bits&TagBits.AnnotationForAnnotationType)!=0) s.add("ANNOTATION_TYPE");
+               if ((bits&TagBits.AnnotationForConstructor)!=0) s.add("CONSTRUCTOR");
+               if ((bits&TagBits.AnnotationForField)!=0) s.add("FIELD");
+               if ((bits&TagBits.AnnotationForLocalVariable)!=0) s.add("LOCAL_VARIABLE");
+               if ((bits&TagBits.AnnotationForMethod)!=0) s.add("METHOD");
+               if ((bits&TagBits.AnnotationForPackage)!=0) s.add("PACKAGE");
+               if ((bits&TagBits.AnnotationForParameter)!=0) s.add("PARAMETER");
+               if ((bits&TagBits.AnnotationForType)!=0) s.add("TYPE");
+               StringBuffer sb = new StringBuffer();
+               sb.append("{");
+               for (Iterator iter = s.iterator(); iter.hasNext();) {
+                       String element = (String) iter.next();
+                       sb.append(element);
+                       if (iter.hasNext()) sb.append(",");
+               }
+               sb.append("}");
+               return sb.toString();
+       }
+       
+       private boolean doDeclareAnnotations(DeclareAnnotation decA, SourceTypeBinding sourceType,boolean reportProblems) {
+               ResolvedTypeX rtx = factory.fromEclipse(sourceType);
+               if (!decA.matches(rtx)) return false;
+               if (!rtx.isExposedToWeaver()) return false;
+
+               
+               // Get the annotation specified in the declare
+               TypeBinding tb = factory.makeTypeBinding(decA.getAspect());
+               MethodBinding[] mbs = ((SourceTypeBinding)tb).getMethods(decA.getAnnotationMethod().toCharArray());
+               long abits = mbs[0].getAnnotationTagBits(); // ensure resolved
+               TypeDeclaration typeDecl = ((SourceTypeBinding)mbs[0].declaringClass).scope.referenceContext;
+               AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(mbs[0]);
+               Annotation[] toAdd = methodDecl.annotations; // this is what to add
+               abits = toAdd[0].resolvedType.getAnnotationTagBits();
+               
+               Annotation currentAnnotations[] = sourceType.scope.referenceContext.annotations;
+               if (currentAnnotations!=null) 
+               for (int i = 0; i < currentAnnotations.length; i++) {
+                       Annotation annotation = currentAnnotations[i];
+                       String a = CharOperation.toString(annotation.type.getTypeName());
+                       String b = CharOperation.toString(toAdd[0].type.getTypeName());
+                       // FIXME asc we have a lint for attempting to add an annotation twice to a method,
+                       // we could put it out here *if* we can resolve the problem of errors coming out
+                       // multiple times if we have cause to loop through here
+                       if (a.equals(b)) return false;
+               }
+               
+               if (((abits & TagBits.AnnotationTargetMASK)!=0)) {
+                       if ( (abits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType))==0) {
+                               // this means it specifies something other than annotation or normal type - error will have been already reported, just resolution process above
+                               return false;
+                       }
+                       if (  (sourceType.isAnnotationType() && (abits & TagBits.AnnotationForAnnotationType)==0) ||
+                             (!sourceType.isAnnotationType() && (abits & TagBits.AnnotationForType)==0) ) {
+                       
+                       if (reportProblems) {
+                         if (decA.isExactPattern()) {
+                           factory.showMessage(IMessage.ERROR,
+                                       WeaverMessages.format(WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION,rtx.getName(),toAdd[0].type,stringifyTargets(abits)),
+                                       decA.getSourceLocation(), null);
+                         } 
+                         // dont put out the lint - the weaving process will do that
+//                       else {
+//                             if (factory.getWorld().getLint().invalidTargetForAnnotation.isEnabled()) {
+//                                     factory.getWorld().getLint().invalidTargetForAnnotation.signal(new String[]{rtx.getName(),toAdd[0].type.toString(),stringifyTargets(abits)},decA.getSourceLocation(),null);
+//                             }
+//                       }
+                       }
+                       return false;
+                 }
                }
+               
+               // Build a new array of annotations
+               // FIXME asc Should be caching the old set of annotations in the type so the class file
+               // generated doesn't have the annotation, it will then be added again during
+               // binary weaving? (similar to declare parents handling...)
+               AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decA.getSourceLocation(),rtx.getSourceLocation());
+               Annotation abefore[] = sourceType.scope.referenceContext.annotations;
+               Annotation[] newset = new Annotation[toAdd.length+(abefore==null?0:abefore.length)];
+               System.arraycopy(toAdd,0,newset,0,toAdd.length);
+               if (abefore!=null) {
+                       System.arraycopy(abefore,0,newset,toAdd.length,abefore.length);
+               }
+               sourceType.scope.referenceContext.annotations = newset;
+               return true;
        }
+       
 
        private void reportDeclareParentsMessage(WeaveMessage.WeaveMessageKind wmk,SourceTypeBinding sourceType,ResolvedTypeX parent) {
                if (!factory.getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) {
@@ -561,3 +733,134 @@ public class AjLookupEnvironment extends LookupEnvironment {
                }               
        }
 }
+
+// commented out, supplied as info on how to manipulate annotations in an eclipse world
+//
+// public void doDeclareAnnotationOnMethods() {
+// Do the declare annotation on fields/methods/ctors
+//Collection daoms = factory.getDeclareAnnotationOnMethods();
+//if (daoms!=null && daoms.size()>0 && !(sourceType instanceof BinaryTypeBinding)) {
+//     System.err.println("Going through the methods on "+sourceType.debugName()+" looking for DECA matches");
+//     // We better take a look through them...
+//     for (Iterator iter = daoms.iterator(); iter.hasNext();) {
+//             DeclareAnnotation element = (DeclareAnnotation) iter.next();
+//             System.err.println("Looking for anything that might match "+element+" on "+sourceType.debugName()+"  "+getType(sourceType.compoundName).debugName()+"  "+(sourceType instanceof BinaryTypeBinding));
+//             
+//             ReferenceBinding rbb = getType(sourceType.compoundName);
+//             // fix me if we ever uncomment this code... should iterate the other way round, over the methods then over the decas
+//             sourceType.methods();
+//             MethodBinding sourceMbs[] = sourceType.methods;
+//             for (int i = 0; i < sourceMbs.length; i++) {
+//                     MethodBinding sourceMb = sourceMbs[i];
+//                     MethodBinding mbbbb = ((SourceTypeBinding)rbb).getExactMethod(sourceMb.selector,sourceMb.parameters);
+//                     boolean isCtor = sourceMb.selector[0]=='<';
+//                     
+//                     if ((element.isDeclareAtConstuctor() ^ !isCtor)) {
+//                     System.err.println("Checking "+sourceMb+" ... declaringclass="+sourceMb.declaringClass.debugName()+" rbb="+rbb.debugName()+"  "+sourceMb.declaringClass.equals(rbb));
+//                     
+//                     ResolvedMember rm = null;
+//                     rm = EclipseFactory.makeResolvedMember(mbbbb);
+//                     if (element.matches(rm,factory.getWorld())) {
+//                             System.err.println("MATCH");
+//                             
+//                             // Determine the set of annotations that are currently on the method
+//                             ReferenceBinding rb = getType(sourceType.compoundName);
+////                           TypeBinding tb = factory.makeTypeBinding(decA.getAspect());
+//                             MethodBinding mb = ((SourceTypeBinding)rb).getExactMethod(sourceMb.selector,sourceMb.parameters);
+//                             //long abits = mbs[0].getAnnotationTagBits(); // ensure resolved
+//                             TypeDeclaration typeDecl = ((SourceTypeBinding)sourceMb.declaringClass).scope.referenceContext;
+//                             AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(sourceMb);
+//                             Annotation[] currentlyHas = methodDecl.annotations; // this is what to add
+//                             //abits = toAdd[0].resolvedType.getAnnotationTagBits();
+//                             
+//                             // Determine the annotations to add to that method
+//                             TypeBinding tb = factory.makeTypeBinding(element.getAspect());
+//                             MethodBinding[] aspectMbs = ((SourceTypeBinding)tb).getMethods(element.getAnnotationMethod().toCharArray());
+//                             long abits = aspectMbs[0].getAnnotationTagBits(); // ensure resolved
+//                             TypeDeclaration typeDecl2 = ((SourceTypeBinding)aspectMbs[0].declaringClass).scope.referenceContext;
+//                             AbstractMethodDeclaration methodDecl2 = typeDecl2.declarationOf(aspectMbs[0]);
+//                             Annotation[] toAdd = methodDecl2.annotations; // this is what to add
+//                             // abits = toAdd[0].resolvedType.getAnnotationTagBits();
+//System.err.println("Has: "+currentlyHas+"    toAdd: "+toAdd);
+//                             
+//                             // fix me? should check if it already has the annotation
+//                             //Annotation abefore[] = sourceType.scope.referenceContext.annotations;
+//                             Annotation[] newset = new Annotation[(currentlyHas==null?0:currentlyHas.length)+1];
+//                             System.arraycopy(toAdd,0,newset,0,toAdd.length);
+//                             if (currentlyHas!=null) {
+//                                     System.arraycopy(currentlyHas,0,newset,1,currentlyHas.length);
+//                             }
+//                             methodDecl.annotations = newset;
+//                             System.err.println("New set on "+CharOperation.charToString(sourceMb.selector)+" is "+newset);
+//                     } else
+//                             System.err.println("NO MATCH");
+//             }
+//     }
+//     }
+//}
+//}
+
+// commented out, supplied as info on how to manipulate annotations in an eclipse world
+//
+// public void doDeclareAnnotationOnFields() {
+//             Collection daofs = factory.getDeclareAnnotationOnFields();
+//             if (daofs!=null && daofs.size()>0 && !(sourceType instanceof BinaryTypeBinding)) {
+//                     System.err.println("Going through the fields on "+sourceType.debugName()+" looking for DECA matches");
+//                     // We better take a look through them...
+//                     for (Iterator iter = daofs.iterator(); iter.hasNext();) {
+//                             DeclareAnnotation element = (DeclareAnnotation) iter.next();
+//                             System.err.println("Processing deca "+element+" on "+sourceType.debugName()+"  "+getType(sourceType.compoundName).debugName()+"  "+(sourceType instanceof BinaryTypeBinding));
+//                             
+//                             ReferenceBinding rbb = getType(sourceType.compoundName);
+//                             // fix me? should iterate the other way round, over the methods then over the decas
+//                             sourceType.fields(); // resolve the bloody things
+//                             FieldBinding sourceFbs[] = sourceType.fields;
+//                             for (int i = 0; i < sourceFbs.length; i++) {
+//                                     FieldBinding sourceFb = sourceFbs[i];
+//                                     //FieldBinding fbbbb = ((SourceTypeBinding)rbb).getgetExactMethod(sourceMb.selector,sourceMb.parameters);
+//                                     
+//                                     System.err.println("Checking "+sourceFb+" ... declaringclass="+sourceFb.declaringClass.debugName()+" rbb="+rbb.debugName());
+//                                     
+//                                     ResolvedMember rm = null;
+//                                     rm = EclipseFactory.makeResolvedMember(sourceFb);
+//                                     if (element.matches(rm,factory.getWorld())) {
+//                                             System.err.println("MATCH");
+//                                             
+//                                             // Determine the set of annotations that are currently on the field
+//                                             ReferenceBinding rb = getType(sourceType.compoundName);
+////                                           TypeBinding tb = factory.makeTypeBinding(decA.getAspect());
+//                                             FieldBinding fb = ((SourceTypeBinding)rb).getField(sourceFb.name,true);
+//                                             //long abits = mbs[0].getAnnotationTagBits(); // ensure resolved
+//                                             TypeDeclaration typeDecl = ((SourceTypeBinding)sourceFb.declaringClass).scope.referenceContext;
+//                                             FieldDeclaration fd = typeDecl.declarationOf(sourceFb);
+//                                             //AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(sourceMb);
+//                                             Annotation[] currentlyHas = fd.annotations; // this is what to add
+//                                             //abits = toAdd[0].resolvedType.getAnnotationTagBits();
+//                                             
+//                                             // Determine the annotations to add to that method
+//                                             TypeBinding tb = factory.makeTypeBinding(element.getAspect());
+//                                             MethodBinding[] aspectMbs = ((SourceTypeBinding)tb).getMethods(element.getAnnotationMethod().toCharArray());
+//                                             long abits = aspectMbs[0].getAnnotationTagBits(); // ensure resolved
+//                                             TypeDeclaration typeDecl2 = ((SourceTypeBinding)aspectMbs[0].declaringClass).scope.referenceContext;
+//                                             AbstractMethodDeclaration methodDecl2 = typeDecl2.declarationOf(aspectMbs[0]);
+//                                             Annotation[] toAdd = methodDecl2.annotations; // this is what to add
+//                                             // abits = toAdd[0].resolvedType.getAnnotationTagBits();
+//System.err.println("Has: "+currentlyHas+"    toAdd: "+toAdd);
+//                                             
+//                                             // fix me? check if it already has the annotation
+//
+//
+//                                             //Annotation abefore[] = sourceType.scope.referenceContext.annotations;
+//                                             Annotation[] newset = new Annotation[(currentlyHas==null?0:currentlyHas.length)+1];
+//                                             System.arraycopy(toAdd,0,newset,0,toAdd.length);
+//                                             if (currentlyHas!=null) {
+//                                                     System.arraycopy(currentlyHas,0,newset,1,currentlyHas.length);
+//                                             }
+//                                             fd.annotations = newset;
+//                                             System.err.println("New set on "+CharOperation.charToString(sourceFb.name)+" is "+newset);
+//                                     } else
+//                                             System.err.println("NO MATCH");
+//                             }
+//                     
+//                     }
+//             }