From 06fba267432633331ff211b7f9e29b594bccf553 Mon Sep 17 00:00:00 2001 From: aclement Date: Thu, 10 Mar 2005 20:36:56 +0000 Subject: [PATCH] Declare annotation: source weaving of declare @type. Includes (commented out) declare @method/constructor/field implementations for possible future use - not required right now as applying them early (during compiling rather than weaving) makes no sense. --- .../compiler/lookup/AjLookupEnvironment.java | 333 +++++++++++++++++- 1 file changed, 318 insertions(+), 15 deletions(-) diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java index cb24fe5c5..2365ef452 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java @@ -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"); +// } +// +// } +// } -- 2.39.5