]> source.dussan.org Git - aspectj.git/commitdiff
Fix for pr98901: copying annotations to new members created via ITD !!
authoraclement <aclement>
Mon, 8 Aug 2005 09:54:54 +0000 (09:54 +0000)
committeraclement <aclement>
Mon, 8 Aug 2005 09:54:54 +0000 (09:54 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java
tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java

index 21c5f210668569069fbf2b8bd1923a1b51896262..cac14243dc09507c920b9a8596243a1321da356f 100644 (file)
@@ -156,9 +156,10 @@ public class InterTypeMethodDeclaration extends InterTypeDeclaration {
                classFile.extraAttributes.add(new EclipseAttributeAdapter(makeAttribute()));
                
                if (!Modifier.isAbstract(declaredModifiers)) {
-                       super.generateCode(classScope, classFile);
+                       super.generateCode(classScope, classFile); // this makes the interMethodBody
                }
                
+               // annotations on the ITD declaration get put on this method 
                generateDispatchMethod(classScope, classFile);
        }
        
@@ -176,7 +177,13 @@ public class InterTypeMethodDeclaration extends InterTypeDeclaration {
                
                classFile.generateMethodInfoHeader(dispatchBinding);
                int methodAttributeOffset = classFile.contentsOffset;
-               int attributeNumber = classFile.generateMethodInfoAttribute(dispatchBinding,
+               
+               
+               // Watch out!  We are passing in 'binding' here (instead of dispatchBinding) so that
+               // the dispatch binding attributes will include the annotations from the 'binding'.
+               // There is a chance that something else on the binding (e.g. throws clause) might
+               // damage the attributes generated for the dispatch binding.
+               int attributeNumber = classFile.generateMethodInfoAttribute(binding,
                                false,
                                makeEffectiveSignatureAttribute(signature, Shadow.MethodCall, false));
                int codeAttributeOffset = classFile.contentsOffset;
index 6069f845a33d7ebfc8657f4ea5f6dcab4ea16178..c677fd3465be683886aa06956b615d8172d45fd4 100644 (file)
@@ -42,6 +42,7 @@ public class AllTestsAspectJ150 {
                suite.addTest(Autoboxing.suite());              
                suite.addTest(Annotations.suite());
                suite.addTest(AnnotationBinding.suite());
+               suite.addTest(RuntimeAnnotations.suite());
                
                suite.addTest(SuppressedWarnings.suite());
                suite.addTest(DeclareAnnotationTests.suite());
index c10b2f16d0efce77dcabaceefb72ec7aa23fad3c..f9c2eabcb8cd2574b4a287d57036ad8dc06b109b 100644 (file)
@@ -27,9 +27,12 @@ import java.util.Set;
 
 import org.aspectj.apache.bcel.Constants;
 import org.aspectj.apache.bcel.classfile.Field;
+import org.aspectj.apache.bcel.classfile.Method;
+import org.aspectj.apache.bcel.classfile.annotation.Annotation;
 import org.aspectj.apache.bcel.generic.BranchInstruction;
 import org.aspectj.apache.bcel.generic.CPInstruction;
 import org.aspectj.apache.bcel.generic.ConstantPoolGen;
+import org.aspectj.apache.bcel.generic.FieldGen;
 import org.aspectj.apache.bcel.generic.FieldInstruction;
 import org.aspectj.apache.bcel.generic.INVOKESPECIAL;
 import org.aspectj.apache.bcel.generic.IndexedInstruction;
@@ -41,6 +44,7 @@ import org.aspectj.apache.bcel.generic.InstructionList;
 import org.aspectj.apache.bcel.generic.InstructionTargeter;
 import org.aspectj.apache.bcel.generic.InvokeInstruction;
 import org.aspectj.apache.bcel.generic.LocalVariableInstruction;
+import org.aspectj.apache.bcel.generic.MethodGen;
 import org.aspectj.apache.bcel.generic.NEW;
 import org.aspectj.apache.bcel.generic.ObjectType;
 import org.aspectj.apache.bcel.generic.PUTFIELD;
@@ -49,6 +53,7 @@ import org.aspectj.apache.bcel.generic.RET;
 import org.aspectj.apache.bcel.generic.ReturnInstruction;
 import org.aspectj.apache.bcel.generic.Select;
 import org.aspectj.apache.bcel.generic.Type;
+import org.aspectj.apache.bcel.generic.annotation.AnnotationGen;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.bridge.WeaveMessage;
@@ -66,8 +71,8 @@ import org.aspectj.weaver.NewConstructorTypeMunger;
 import org.aspectj.weaver.NewFieldTypeMunger;
 import org.aspectj.weaver.NewMethodTypeMunger;
 import org.aspectj.weaver.ResolvedMember;
-import org.aspectj.weaver.ResolvedTypeMunger;
 import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.ResolvedTypeMunger;
 import org.aspectj.weaver.Shadow;
 import org.aspectj.weaver.ShadowMunger;
 import org.aspectj.weaver.UnresolvedType;
@@ -463,46 +468,55 @@ class BcelClassWeaver implements IClassWeaver {
           for (int memberCounter = 0;memberCounter<members.size();memberCounter++) {
             LazyMethodGen mg = (LazyMethodGen)members.get(memberCounter);
             if (!mg.getName().startsWith(NameMangler.PREFIX)) {
-
-            // Single first pass
-            List worthRetrying = new ArrayList();
-            boolean modificationOccured = false;
-            
-            for (Iterator iter = decaMs.iterator(); iter.hasNext();) {
-                               DeclareAnnotation decaM = (DeclareAnnotation) iter.next();
-                               
-                               if (decaM.matches(mg.getMemberView(),world)) {
-                                       if (doesAlreadyHaveAnnotation(mg.getMemberView(),decaM,reportedProblems)) continue; // skip this one...
-                                       mg.addAnnotation(decaM.getAnnotationX());
-                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod());
-                    
-                                       reportMethodCtorWeavingMessage(clazz, mg, decaM);
-                                       isChanged = true;
-                                       modificationOccured = true;
-                               } else {
-                                       if (!decaM.isStarredAnnotationPattern()) 
-                                               worthRetrying.add(decaM); // an annotation is specified that might be put on by a subsequent decaf
-                               }
-                       }
-                       
-            // Multiple secondary passes
-            while (!worthRetrying.isEmpty() && modificationOccured) {
-              modificationOccured = false;
-              // lets have another go
-              List forRemoval = new ArrayList();
-              for (Iterator iter = worthRetrying.iterator(); iter.hasNext();) {
-                               DeclareAnnotation decaM = (DeclareAnnotation) iter.next();
-                               if (decaM.matches(mg.getMemberView(),world)) {
-                                       if (doesAlreadyHaveAnnotation(mg.getMemberView(),decaM,reportedProblems)) continue; // skip this one...
-                                       mg.addAnnotation(decaM.getAnnotationX());
-                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod());
-                                       isChanged = true;
-                                       modificationOccured = true;
-                                       forRemoval.add(decaM);
-                               }
-                         }
-                         worthRetrying.removeAll(forRemoval);
-            }
+               
+               // Single first pass
+               List worthRetrying = new ArrayList();
+               boolean modificationOccured = false;
+               
+               for (Iterator iter = decaMs.iterator(); iter.hasNext();) {
+                       DeclareAnnotation decaM = (DeclareAnnotation) iter.next();
+                       
+                       if (decaM.matches(mg.getMemberView(),world)) {
+                               if (doesAlreadyHaveAnnotation(mg.getMemberView(),decaM,reportedProblems)) continue; // skip this one...
+                               
+                               Annotation a = decaM.getAnnotationX().getBcelAnnotation();
+                               AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true);
+                               Method oldMethod = mg.getMethod();
+                               MethodGen myGen = new MethodGen(oldMethod,clazz.getClassName(),clazz.getConstantPoolGen());
+                               myGen.addAnnotation(ag);
+                               Method newMethod = myGen.getMethod();
+                               mg.addAnnotation(decaM.getAnnotationX());
+                               members.set(memberCounter,new LazyMethodGen(newMethod,clazz));
+                               
+                               AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod());
+                               
+                               reportMethodCtorWeavingMessage(clazz, mg, decaM);
+                               isChanged = true;
+                               modificationOccured = true;
+                       } else {
+                               if (!decaM.isStarredAnnotationPattern()) 
+                                       worthRetrying.add(decaM); // an annotation is specified that might be put on by a subsequent decaf
+                       }
+               }
+               
+               // Multiple secondary passes
+               while (!worthRetrying.isEmpty() && modificationOccured) {
+                       modificationOccured = false;
+                       // lets have another go
+                       List forRemoval = new ArrayList();
+                       for (Iterator iter = worthRetrying.iterator(); iter.hasNext();) {
+                               DeclareAnnotation decaM = (DeclareAnnotation) iter.next();
+                               if (decaM.matches(mg.getMemberView(),world)) {
+                                       if (doesAlreadyHaveAnnotation(mg.getMemberView(),decaM,reportedProblems)) continue; // skip this one...
+                                       mg.addAnnotation(decaM.getAnnotationX());
+                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaM.getSourceLocation(),clazz.getName(),mg.getMethod());
+                                       isChanged = true;
+                                       modificationOccured = true;
+                                       forRemoval.add(decaM);
+                               }
+                       }
+                       worthRetrying.removeAll(forRemoval);
+               }
             }
           }
         }
@@ -599,14 +613,16 @@ class BcelClassWeaver implements IClassWeaver {
        // FIXME asc refactor this to neaten it up
        public LazyMethodGen locateAnnotationHolderForMethodCtorMunger(LazyClassGen clazz,BcelTypeMunger methodCtorMunger) {
                if (methodCtorMunger.getMunger() instanceof NewMethodTypeMunger) {
-               NewMethodTypeMunger nftm = (NewMethodTypeMunger)methodCtorMunger.getMunger();
-               ResolvedMember lookingFor =AjcMemberMaker.interMethodBody(nftm.getSignature(),methodCtorMunger.getAspectType());
-               List meths = clazz.getMethodGens();
-               for (Iterator iter = meths.iterator(); iter.hasNext();) {
-                       LazyMethodGen element = (LazyMethodGen) iter.next();
-                       if (element.getName().equals(lookingFor.getName()) && element.getParameterSignature().equals(lookingFor.getParameterSignature())) return element;
-               }
-               return null;
+                       NewMethodTypeMunger nftm = (NewMethodTypeMunger)methodCtorMunger.getMunger();
+                       
+                       ResolvedMember lookingFor = AjcMemberMaker.interMethodDispatcher(nftm.getSignature(),methodCtorMunger.getAspectType());
+                       
+                       List meths = clazz.getMethodGens();
+                       for (Iterator iter = meths.iterator(); iter.hasNext();) {
+                               LazyMethodGen element = (LazyMethodGen) iter.next();
+                               if (element.getName().equals(lookingFor.getName()) && element.getParameterSignature().equals(lookingFor.getParameterSignature())) return element;
+                       }
+                       return null;
                } else if (methodCtorMunger.getMunger() instanceof NewConstructorTypeMunger) {
                        NewConstructorTypeMunger nftm = (NewConstructorTypeMunger)methodCtorMunger.getMunger();
                        ResolvedMember lookingFor =AjcMemberMaker.postIntroducedConstructor(methodCtorMunger.getAspectType(),nftm.getSignature().getDeclaringType(),nftm.getSignature().getParameterTypes());
@@ -683,20 +699,20 @@ class BcelClassWeaver implements IClassWeaver {
                boolean isChanged = false;
                for (Iterator iter = itdMethodsCtors.iterator(); iter.hasNext();) {
                        BcelTypeMunger methodctorMunger = (BcelTypeMunger) iter.next();
-                       ResolvedMember itdIsActually = methodctorMunger.getSignature();
+                       ResolvedMember unMangledInterMethod = methodctorMunger.getSignature();
                        List worthRetrying = new ArrayList();
                        boolean modificationOccured = false;
                        
                        for (Iterator iter2 = decaMCs.iterator(); iter2.hasNext();) {
                                DeclareAnnotation decaMC = (DeclareAnnotation) iter2.next();
-                               
-                               if (decaMC.matches(itdIsActually,world)) {
+                               if (decaMC.matches(unMangledInterMethod,world)) {
                                        LazyMethodGen annotationHolder = locateAnnotationHolderForMethodCtorMunger(clazz,methodctorMunger);
-                                       if (doesAlreadyHaveAnnotation(annotationHolder,itdIsActually,decaMC,reportedErrors)) continue; // skip this one...
+                                       if (annotationHolder == null || doesAlreadyHaveAnnotation(annotationHolder,unMangledInterMethod,decaMC,reportedErrors)){
+                                               continue; // skip this one...
+                                       }
                                        annotationHolder.addAnnotation(decaMC.getAnnotationX());
-                                       itdIsActually.addAnnotation(decaMC.getAnnotationX());
                                        isChanged=true;
-                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaMC.getSourceLocation(),itdIsActually.getSourceLocation());
+                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaMC.getSourceLocation(),unMangledInterMethod.getSourceLocation());
                                        modificationOccured = true;                                     
                                } else {
                                        if (!decaMC.isStarredAnnotationPattern()) 
@@ -709,12 +725,12 @@ class BcelClassWeaver implements IClassWeaver {
                 List forRemoval = new ArrayList();
                 for (Iterator iter2 = worthRetrying.iterator(); iter.hasNext();) {
                                  DeclareAnnotation decaMC = (DeclareAnnotation) iter2.next();
-                                 if (decaMC.matches(itdIsActually,world)) {
+                                 if (decaMC.matches(unMangledInterMethod,world)) {
                                        LazyMethodGen annotationHolder = locateAnnotationHolderForFieldMunger(clazz,methodctorMunger);
-                                       if (doesAlreadyHaveAnnotation(annotationHolder,itdIsActually,decaMC,reportedErrors)) continue; // skip this one...
+                                       if (doesAlreadyHaveAnnotation(annotationHolder,unMangledInterMethod,decaMC,reportedErrors)) continue; // skip this one...
                                        annotationHolder.addAnnotation(decaMC.getAnnotationX());
-                                       itdIsActually.addAnnotation(decaMC.getAnnotationX());
-                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaMC.getSourceLocation(),itdIsActually.getSourceLocation());
+                                       unMangledInterMethod.addAnnotation(decaMC.getAnnotationX());
+                                       AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaMC.getSourceLocation(),unMangledInterMethod.getSourceLocation());
                                        isChanged = true;
                                        modificationOccured = true;
                                        forRemoval.add(decaMC);
@@ -726,6 +742,16 @@ class BcelClassWeaver implements IClassWeaver {
              return isChanged;
        }
        
+       private boolean dontAddTwice(DeclareAnnotation decaF, Annotation [] dontAddMeTwice){
+               for (int i = 0; i < dontAddMeTwice.length; i++){
+                       Annotation ann = dontAddMeTwice[i];
+                       if (ann != null && decaF.getAnnotationX().getTypeName().equals(ann.getTypeName())){
+                               dontAddMeTwice[i] = null; // incase it really has been added twice!
+                               return true;
+                       }
+               }
+               return false;
+       }
        
        /**
         * Weave any declare @field statements into the fields of the supplied class
@@ -769,12 +795,37 @@ class BcelClassWeaver implements IClassWeaver {
             // Single first pass
             List worthRetrying = new ArrayList();
             boolean modificationOccured = false;
+            
+            Annotation [] dontAddMeTwice = fields[fieldCounter].getAnnotations();
+            
             // go through all the declare @field statements
             for (Iterator iter = decaFs.iterator(); iter.hasNext();) {
                                DeclareAnnotation decaF = (DeclareAnnotation) iter.next();
                                if (decaF.matches(aBcelField,world)) {
-                                       if (doesAlreadyHaveAnnotation(aBcelField,decaF,reportedProblems)) continue; // skip this one...
-                                       aBcelField.addAnnotation(decaF.getAnnotationX());
+                                       
+                                       if (!dontAddTwice(decaF,dontAddMeTwice)){
+                                               if (doesAlreadyHaveAnnotation(aBcelField,decaF,reportedProblems)){
+                                                       continue;
+                                               }
+                                               
+                                               if(decaF.getAnnotationX().isRuntimeVisible()){ // isAnnotationWithRuntimeRetention(clazz.getJavaClass(world))){
+                                               //if(decaF.getAnnotationTypeX().isAnnotationWithRuntimeRetention(world)){                                               
+                                                       // it should be runtime visible, so put it on the Field
+                                                       Annotation a = decaF.getAnnotationX().getBcelAnnotation();
+                                                       AnnotationGen ag = new AnnotationGen(a,clazz.getConstantPoolGen(),true);
+                                                       FieldGen myGen = new FieldGen(fields[fieldCounter],clazz.getConstantPoolGen());
+                                                       myGen.addAnnotation(ag);
+                                                       Field newField = myGen.getField();
+                                                       
+                                                       aBcelField.addAnnotation(decaF.getAnnotationX());
+                                                       clazz.replaceField(fields[fieldCounter],newField);
+                                                       fields[fieldCounter]=newField;
+                                                       
+                                               } else{
+                                                       aBcelField.addAnnotation(decaF.getAnnotationX());
+                                               }
+                                       }
+                                       
                                        AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),fields[fieldCounter]);
                                        reportFieldAnnotationWeavingMessage(clazz, fields, fieldCounter, decaF);                
                                        isChanged = true;
@@ -793,6 +844,7 @@ class BcelClassWeaver implements IClassWeaver {
               for (Iterator iter = worthRetrying.iterator(); iter.hasNext();) {
                                DeclareAnnotation decaF = (DeclareAnnotation) iter.next();
                                if (decaF.matches(aBcelField,world)) {
+                                       // below code is for recursive things
                                        if (doesAlreadyHaveAnnotation(aBcelField,decaF,reportedProblems)) continue; // skip this one...
                                        aBcelField.addAnnotation(decaF.getAnnotationX());
                                        AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(decaF.getSourceLocation(),clazz.getName(),fields[fieldCounter]);
@@ -846,7 +898,7 @@ class BcelClassWeaver implements IClassWeaver {
        }
        
        private boolean doesAlreadyHaveAnnotation(LazyMethodGen rm,ResolvedMember itdfieldsig,DeclareAnnotation deca,List reportedProblems) {
-                 if (rm.hasAnnotation(deca.getAnnotationTypeX())) {
+                 if (rm != null && rm.hasAnnotation(deca.getAnnotationTypeX())) {
                          if (world.getLint().elementAlreadyAnnotated.isEnabled()) {
                                  Integer uniqueID = new Integer(rm.hashCode()*deca.hashCode());
                                  if (!reportedProblems.contains(uniqueID)) {
@@ -1592,7 +1644,7 @@ class BcelClassWeaver implements IClassWeaver {
                                        ResolvedMember resolvedDooberry = world.resolve(declaredSig);
                                        annotations = resolvedDooberry.getAnnotationTypes();
                                } else {
-                                       ResolvedMember realthing = AjcMemberMaker.interMethodBody(rm,memberHostType);
+                                       ResolvedMember realthing = AjcMemberMaker.interMethodDispatcher(rm,memberHostType);
                                        ResolvedMember resolvedDooberry = world.resolve(realthing);
                                        annotations = resolvedDooberry.getAnnotationTypes();
                                }
index afafc943ab1120da599570fc3e771c6c99bf99df..495656bba4a9c356b0560039b345e1a118d069ed 100644 (file)
@@ -1336,6 +1336,68 @@ public class BcelShadow extends Shadow {
                        // what the full set of annotations could be (due to static/dynamic type differences...)
                }
     }
+    
+    protected Member getRelevantMember(Member relevantMember, ResolvedType relevantType){
+       if (relevantMember != null){
+               return relevantMember;
+       }
+       
+       relevantMember = getSignature().resolve(world);
+       
+       // check the ITD'd dooberries
+       List mungers = relevantType.resolve(world).getInterTypeMungers();
+       for (Iterator iter = mungers.iterator(); iter.hasNext();) {
+               BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
+               if (typeMunger.getMunger() instanceof NewMethodTypeMunger ||
+                               typeMunger.getMunger() instanceof NewConstructorTypeMunger) {
+                       ResolvedMember fakerm = typeMunger.getSignature();
+                       if (fakerm.getName().equals(getSignature().getName()) &&
+                                       fakerm.getParameterSignature().equals(getSignature().getParameterSignature())){
+                               if (relevantMember.getKind()==ResolvedMember.CONSTRUCTOR){
+                                       relevantMember = AjcMemberMaker.interConstructor(
+                                                       relevantType,
+                                                       (ResolvedMember)relevantMember,
+                                                       typeMunger.getAspectType());
+                               } else {
+                                       relevantMember = AjcMemberMaker.interMethod((ResolvedMember)relevantMember,
+                                                       typeMunger.getAspectType(), false);
+                               }
+                               // in the above.. what about if it's on an Interface? Can that happen?
+                       // then the last arg of the above should be true
+                               return relevantMember;
+                       }
+               }
+       }
+       return null;
+    }
+    
+    protected ResolvedType [] getAnnotations(Member relevantMember, ResolvedType relevantType){
+       if (relevantMember == null){
+               // check the ITD'd dooberries
+               List mungers = relevantType.resolve(world).getInterTypeMungers();
+               for (Iterator iter = mungers.iterator(); iter.hasNext();) {
+                       BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
+                       if (typeMunger.getMunger() instanceof NewMethodTypeMunger ||
+                                       typeMunger.getMunger() instanceof NewConstructorTypeMunger) {
+                               ResolvedMember fakerm = typeMunger.getSignature();
+                               //if (fakerm.hasAnnotations()) 
+                               
+                               ResolvedMember ajcMethod = (getSignature().getKind()==ResolvedMember.CONSTRUCTOR?
+                                               AjcMemberMaker.postIntroducedConstructor(typeMunger.getAspectType(),fakerm.getDeclaringType(),fakerm.getParameterTypes()):
+                                                       AjcMemberMaker.interMethodDispatcher(fakerm,typeMunger.getAspectType()));
+                               //AjcMemberMaker.interMethodBody(fakerm,typeMunger.getAspectType()));
+                               ResolvedMember rmm = findMethod(typeMunger.getAspectType(),ajcMethod);
+                               if (fakerm.getName().equals(getSignature().getName()) &&
+                                               fakerm.getParameterSignature().equals(getSignature().getParameterSignature())) {
+                                       relevantType = typeMunger.getAspectType();
+                                       relevantMember = rmm;
+                                       return relevantMember.getAnnotationTypes();
+                               }
+                       }
+               }
+       }
+       return relevantMember.getAnnotationTypes();
+    }
        
     public void initializeKindedAnnotationVars() {
        if (kindedAnnotationVars != null) return;
@@ -1355,30 +1417,9 @@ public class BcelShadow extends Shadow {
                
        } else if (getKind() == Shadow.MethodCall  || getKind() == Shadow.ConstructorCall) {
             relevantMember = findMethod2(relevantType.resolve(world).getDeclaredMethods(),getSignature());
-               
-                       if (relevantMember == null) {
-                               // check the ITD'd dooberries
-                               List mungers = relevantType.resolve(world).getInterTypeMungers();
-                               for (Iterator iter = mungers.iterator(); iter.hasNext();) {
-                                       BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
-                                       if (typeMunger.getMunger() instanceof NewMethodTypeMunger ||
-                                               typeMunger.getMunger() instanceof NewConstructorTypeMunger) {
-                                         ResolvedMember fakerm = typeMunger.getSignature();
-                                         //if (fakerm.hasAnnotations()) 
-                                          
-                                         ResolvedMember ajcMethod = (getSignature().getKind()==ResolvedMember.CONSTRUCTOR?
-                                                 AjcMemberMaker.postIntroducedConstructor(typeMunger.getAspectType(),fakerm.getDeclaringType(),fakerm.getParameterTypes()):
-                                                 AjcMemberMaker.interMethodBody(fakerm,typeMunger.getAspectType()));
-                                         ResolvedMember rmm       = findMethod(typeMunger.getAspectType(),ajcMethod);
-                                         if (fakerm.getName().equals(getSignature().getName()) &&
-                                                 fakerm.getParameterSignature().equals(getSignature().getParameterSignature())) {
-                                               relevantType = typeMunger.getAspectType();
-                                               relevantMember = rmm;
-                                         }
-                                       }
-                               }
-                       }
-               annotations = relevantMember.getAnnotationTypes();
+       
+            annotations = getAnnotations(relevantMember,relevantType);
+            relevantMember = getRelevantMember(relevantMember,relevantType);
                
        } else if (getKind() == Shadow.FieldSet || getKind() == Shadow.FieldGet) {
                relevantMember = findField(relevantType.getDeclaredFields(),getSignature());
@@ -1407,29 +1448,8 @@ public class BcelShadow extends Shadow {
                ResolvedMember rm[] = relevantType.getDeclaredMethods();
                relevantMember = findMethod2(relevantType.getDeclaredMethods(),getSignature());
                
-                       if (relevantMember == null) {
-                               // check the ITD'd dooberries
-                               List mungers = relevantType.resolve(world).getInterTypeMungers();
-                               for (Iterator iter = mungers.iterator(); iter.hasNext();) {
-                                       BcelTypeMunger typeMunger = (BcelTypeMunger) iter.next();
-                                       if (typeMunger.getMunger() instanceof NewMethodTypeMunger ||
-                                               typeMunger.getMunger() instanceof NewConstructorTypeMunger) {
-                                         ResolvedMember fakerm = typeMunger.getSignature();
-                                         //if (fakerm.hasAnnotations()) 
-                                         
-                                         ResolvedMember ajcMethod = (getSignature().getKind()==ResolvedMember.CONSTRUCTOR?
-                                                 AjcMemberMaker.postIntroducedConstructor(typeMunger.getAspectType(),fakerm.getDeclaringType(),fakerm.getParameterTypes()):
-                                                 AjcMemberMaker.interMethodBody(fakerm,typeMunger.getAspectType()));
-                                         ResolvedMember rmm       = findMethod(typeMunger.getAspectType(),ajcMethod);
-                                         if (fakerm.getName().equals(getSignature().getName()) &&
-                                                 fakerm.getParameterSignature().equals(getSignature().getParameterSignature())) {
-                                               relevantType = typeMunger.getAspectType();
-                                               relevantMember = rmm;
-                                         }
-                                       }
-                               }
-                       }
-               annotations = relevantMember.getAnnotationTypes();
+               annotations = getAnnotations(relevantMember,relevantType);
+            relevantMember = getRelevantMember(relevantMember,relevantType);
                
        } else if (getKind() == Shadow.ExceptionHandler) {
                relevantType = getSignature().getParameterTypes()[0].resolve(world);
index 8ea410091dd8c5b1965829515f1c5c513f3d7daa..5de5b10652401f8e93753ebdc2ec273f3a0b4077 100644 (file)
@@ -55,6 +55,7 @@ import org.aspectj.weaver.ResolvedType;
 import org.aspectj.weaver.UnresolvedType;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.WeaverStateInfo;
+import org.aspectj.weaver.patterns.DeclareAnnotation;
 import org.aspectj.weaver.patterns.Pointcut;
 
 
@@ -708,13 +709,14 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
        }
        
        private boolean mungeNewMethod(BcelClassWeaver weaver, NewMethodTypeMunger munger) {
-               ResolvedMember signature = munger.getSignature();
-               // TODO asc I'm confused? Why do we treat the 'real method' (the inter method body) as the dispatch method?
-               ResolvedMember dispatchMethod = munger.getInterMethodBody(aspectType);
-
+               ResolvedMember unMangledInterMethod = munger.getSignature();
+               // do matching on the unMangled one, but actually add them to the mangled method
+               ResolvedMember interMethodBody = munger.getInterMethodBody(aspectType);
+               ResolvedMember interMethodDispatcher = munger.getInterMethodDispatcher(aspectType);
+               
                LazyClassGen gen = weaver.getLazyClassGen();
                
-               ResolvedType onType = weaver.getWorld().resolve(signature.getDeclaringType(),munger.getSourceLocation());
+               ResolvedType onType = weaver.getWorld().resolve(unMangledInterMethod.getDeclaringType(),munger.getSourceLocation());
                if (onType.isRawType()) onType = onType.getGenericType();
 
                boolean onInterface = onType.isInterface();
@@ -730,50 +732,62 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                }
                
                if (onType.equals(gen.getType())) {
-                       ResolvedMember introMethod = 
-                                       AjcMemberMaker.interMethod(signature, aspectType, onInterface);
+                       ResolvedMember mangledInterMethod =
+                                       AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, onInterface);
             
-                       AnnotationX annotationsOnRealMember[] = null;
+                       
+                       LazyMethodGen mg = makeMethodGen(gen, mangledInterMethod);
+                       
                        // pr98901
                    // For copying the annotations across, we have to discover the real member in the aspect
                    // which is holding them.
-                       if (weaver.getWorld().isInJava5Mode() && !onInterface && munger.getSignature().isPublic() && !munger.getSignature().isAbstract()) {
-                               ResolvedMember realMember = getRealMemberForITDFromAspect(aspectType,dispatchMethod);
+                       if (weaver.getWorld().isInJava5Mode()){
+                               AnnotationX annotationsOnRealMember[] = null;
+                               ResolvedMember realMember = getRealMemberForITDFromAspect(aspectType,interMethodDispatcher);
                                if (realMember==null) throw new BCException("Couldn't find ITD holder member '"+
-                                                                                   dispatchMethod+"' on aspect "+aspectType);
+                                               interMethodDispatcher+"' on aspect "+aspectType);
                                annotationsOnRealMember = realMember.getAnnotations();
-                       }
-
-                       LazyMethodGen mg = makeMethodGen(gen, introMethod);
-                       
-                       if (annotationsOnRealMember!=null) {
-                               for (int i = 0; i < annotationsOnRealMember.length; i++) {
-                                       AnnotationX annotationX = annotationsOnRealMember[i];
-                                       Annotation a = annotationX.getBcelAnnotation();
-                                       AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
-                                       mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
+                               
+                               if (annotationsOnRealMember!=null) {
+                                       for (int i = 0; i < annotationsOnRealMember.length; i++) {
+                                               AnnotationX annotationX = annotationsOnRealMember[i];
+                                               Annotation a = annotationX.getBcelAnnotation();
+                                               AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
+                                               mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
+                                       }
+                               }
+                               // the below loop fixes the very special (and very stupid)
+                               // case where an aspect declares an annotation
+                               // on an ITD it declared on itself.
+                               List allDecams = weaver.getWorld().getDeclareAnnotationOnMethods();
+                               for (Iterator i = allDecams.iterator(); i.hasNext();){
+                                       DeclareAnnotation decaMC = (DeclareAnnotation) i.next();        
+                                       if (decaMC.matches(unMangledInterMethod,weaver.getWorld())
+                                                       && mg.getEnclosingClass().getType() == aspectType) {
+                                               mg.addAnnotation(decaMC.getAnnotationX());
+                                       }
                                }
                        }
 
-                       if (!onInterface && !Modifier.isAbstract(introMethod.getModifiers())) {
+                       if (!onInterface && !Modifier.isAbstract(mangledInterMethod.getModifiers())) {
                                InstructionList body = mg.getBody();
                                InstructionFactory fact = gen.getFactory();
                                int pos = 0;
        
-                               if (!signature.isStatic()) {
+                               if (!unMangledInterMethod.isStatic()) {
                                        body.append(InstructionFactory.createThis());
                                        pos++;
                                }
-                               Type[] paramTypes = BcelWorld.makeBcelTypes(introMethod.getParameterTypes());
+                               Type[] paramTypes = BcelWorld.makeBcelTypes(mangledInterMethod.getParameterTypes());
                                for (int i = 0, len = paramTypes.length; i < len; i++) {
                                        Type paramType = paramTypes[i];
                                        body.append(InstructionFactory.createLoad(paramType, pos));
                                        pos+=paramType.getSize();
                                }
-                               body.append(Utility.createInvoke(fact, weaver.getWorld(), dispatchMethod));
+                               body.append(Utility.createInvoke(fact, weaver.getWorld(), interMethodBody));
                                body.append(
                                        InstructionFactory.createReturn(
-                                               BcelWorld.makeBcelType(introMethod.getReturnType())));
+                                               BcelWorld.makeBcelType(mangledInterMethod.getReturnType())));
                        } else {
                                //??? this is okay
                                //if (!(mg.getBody() == null)) throw new RuntimeException("bas");
@@ -788,7 +802,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                        
                return true;
                
-               } else if (onInterface && !Modifier.isAbstract(signature.getModifiers())) {
+               } else if (onInterface && !Modifier.isAbstract(unMangledInterMethod.getModifiers())) {
                        
                        // This means the 'gen' should be the top most implementor
                        // - if it is *not* then something went wrong after we worked
@@ -808,19 +822,19 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                                return false;
                } else {
                
-                         ResolvedMember introMethod = 
-                                       AjcMemberMaker.interMethod(signature, aspectType, false);
+                         ResolvedMember mangledInterMethod =
+                                       AjcMemberMaker.interMethod(unMangledInterMethod, aspectType, false);
                        
-                         LazyMethodGen mg = makeMethodGen(gen, introMethod);
+                         LazyMethodGen mg = makeMethodGen(gen, mangledInterMethod);
                                                
-                         Type[] paramTypes = BcelWorld.makeBcelTypes(introMethod.getParameterTypes());
-                         Type returnType = BcelWorld.makeBcelType(introMethod.getReturnType());
+                         Type[] paramTypes = BcelWorld.makeBcelTypes(mangledInterMethod.getParameterTypes());
+                         Type returnType = BcelWorld.makeBcelType(mangledInterMethod.getReturnType());
                        
                          InstructionList body = mg.getBody();
                          InstructionFactory fact = gen.getFactory();
                          int pos = 0;
 
-                         if (!introMethod.isStatic()) {
+                         if (!mangledInterMethod.isStatic()) {
                                body.append(InstructionFactory.createThis());
                                pos++;
                          }
@@ -829,7 +843,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                                body.append(InstructionFactory.createLoad(paramType, pos));
                                pos+=paramType.getSize();
                          }
-                         body.append(Utility.createInvoke(fact, weaver.getWorld(), dispatchMethod));
+                         body.append(Utility.createInvoke(fact, weaver.getWorld(), interMethodBody));
                          body.append(InstructionFactory.createReturn(returnType));
                          mg.definingType = onType;
                        
@@ -844,12 +858,28 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                }
        }
        
-       private ResolvedMember getRealMemberForITDFromAspect(ResolvedType aspectType,ResolvedMember dispatchMethod) {
+       private ResolvedMember getRealMemberForITDFromAspect(ResolvedType aspectType,ResolvedMember lookingFor) {
                ResolvedMember aspectMethods[] = aspectType.getDeclaredMethods();
+               UnresolvedType [] lookingForParams = lookingFor.getParameterTypes();
+               
                ResolvedMember realMember = null;
                for (int i = 0; realMember==null && i < aspectMethods.length; i++) {
                        ResolvedMember member = aspectMethods[i];
-                       if (member.getName().equals(dispatchMethod.getName())) realMember = member;
+                       if (member.getName().equals(lookingFor.getName())){
+                               UnresolvedType [] memberParams = member.getParameterTypes();
+                               if (memberParams.length == lookingForParams.length){
+                                       boolean matchOK = true;
+                                       for (int j = 0; j < memberParams.length && matchOK; j++){
+                                               UnresolvedType memberParam = memberParams[j];
+                                               UnresolvedType lookingForParam = lookingForParams[j].resolve(aspectType.getWorld());
+                                               if (lookingForParam.isTypeVariableReference()) lookingForParam = lookingForParam.getUpperBound();
+                                               if (!memberParam.equals(lookingForParam)){
+                                                       matchOK=false;
+                                               }
+                                       }
+                                       if (matchOK) realMember = member;
+                               }
+                       }
                }
                return realMember;
        }
@@ -898,6 +928,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                BcelClassWeaver weaver,
                NewConstructorTypeMunger newConstructorTypeMunger) 
        {
+               
                final LazyClassGen currentClass = weaver.getLazyClassGen();
                final InstructionFactory fact = currentClass.getFactory();
 
@@ -919,17 +950,50 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
 
                ResolvedMember explicitConstructor = newConstructorTypeMunger.getExplicitConstructor();
                //int declaredParameterCount = newConstructorTypeMunger.getDeclaredParameterCount();
-               LazyMethodGen freshConstructor = 
+               LazyMethodGen mg = 
                        makeMethodGen(currentClass, newConstructorMember);
-               currentClass.addMethodGen(freshConstructor);
+               
+//              pr98901
+           // For copying the annotations across, we have to discover the real member in the aspect
+           // which is holding them.
+               if (weaver.getWorld().isInJava5Mode()){
+                       
+                       ResolvedMember interMethodDispatcher =AjcMemberMaker.postIntroducedConstructor(aspectType,onType,newConstructorTypeMunger.getSignature().getParameterTypes());
+                       AnnotationX annotationsOnRealMember[] = null;
+                       ResolvedMember realMember = getRealMemberForITDFromAspect(aspectType,interMethodDispatcher);
+                       if (realMember==null) throw new BCException("Couldn't find ITD holder member '"+
+                                       interMethodDispatcher+"' on aspect "+aspectType);
+                       annotationsOnRealMember = realMember.getAnnotations();
+                       if (annotationsOnRealMember!=null) {
+                               for (int i = 0; i < annotationsOnRealMember.length; i++) {
+                                       AnnotationX annotationX = annotationsOnRealMember[i];
+                                       Annotation a = annotationX.getBcelAnnotation();
+                                       AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);
+                                       mg.addAnnotation(new AnnotationX(ag.getAnnotation(),weaver.getWorld()));
+                               }
+                       }
+                       // the below loop fixes the very special (and very stupid)
+                       // case where an aspect declares an annotation
+                       // on an ITD it declared on itself.
+                       List allDecams = weaver.getWorld().getDeclareAnnotationOnMethods();
+                       for (Iterator i = allDecams.iterator(); i.hasNext();){
+                               DeclareAnnotation decaMC = (DeclareAnnotation) i.next();        
+                               if (decaMC.matches(explicitConstructor,weaver.getWorld())
+                                               && mg.getEnclosingClass().getType() == aspectType) {
+                                       mg.addAnnotation(decaMC.getAnnotationX());
+                               }
+                       }
+               }
+               
+               currentClass.addMethodGen(mg);
                //weaver.addLazyMethodGen(freshConstructor);
                
-               InstructionList body = freshConstructor.getBody();
+               InstructionList body = mg.getBody();
                
                // add to body:  push arts for call to pre, from actual args starting at 1 (skipping this), going to 
                //               declared argcount + 1
                UnresolvedType[] declaredParams = newConstructorTypeMunger.getSignature().getParameterTypes();
-               Type[] paramTypes = freshConstructor.getArgumentTypes();
+               Type[] paramTypes = mg.getArgumentTypes();
                int frameIndex = 1;
                for (int i = 0, len = declaredParams.length; i < len; i++) {
                        body.append(InstructionFactory.createLoad(paramTypes[i], frameIndex));
@@ -941,7 +1005,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                body.append(Utility.createInvoke(fact, null, preMethod));
                
                // create a local, and store return pre stuff into it.
-               int arraySlot = freshConstructor.allocateLocal(1);
+               int arraySlot = mg.allocateLocal(1);
                body.append(InstructionFactory.createStore(Type.OBJECT, arraySlot));
                
                // put this on the stack
@@ -1063,6 +1127,21 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                        return false;
                }
                
+               
+               ResolvedMember interMethodBody = munger.getInitMethod(aspectType);
+               
+               AnnotationX annotationsOnRealMember[] = null;
+               // pr98901
+           // For copying the annotations across, we have to discover the real member in the aspect
+           // which is holding them.
+               if (weaver.getWorld().isInJava5Mode()){
+                               // the below line just gets the method with the same name in aspectType.getDeclaredMethods();
+                               ResolvedMember realMember = getRealMemberForITDFromAspect(aspectType,interMethodBody);
+                               if (realMember==null) throw new BCException("Couldn't find ITD init member '"+
+                                               interMethodBody+"' on aspect "+aspectType);
+                               annotationsOnRealMember = realMember.getAnnotations();
+               }
+               
                if (onType.equals(gen.getType())) {
                        if (onInterface) {
                                LazyMethodGen mg = makeMethodGen(gen, 
@@ -1076,7 +1155,18 @@ public class BcelTypeMunger extends ConcreteTypeMunger {
                                weaver.addInitializer(this);
                                FieldGen fg = makeFieldGen(gen,
                                        AjcMemberMaker.interFieldClassField(field, aspectType));
-                       gen.addField(fg.getField(),getSourceLocation());
+                               
+                               if (annotationsOnRealMember!=null) {
+                                       for (int i = 0; i < annotationsOnRealMember.length; i++) {
+                                               AnnotationX annotationX = annotationsOnRealMember[i];
+                                               Annotation a = annotationX.getBcelAnnotation();
+                                               AnnotationGen ag = new AnnotationGen(a,weaver.getLazyClassGen().getConstantPoolGen(),true);     
+                                               fg.addAnnotation(ag);
+                                       }
+                               }
+                               
+                               gen.addField(fg.getField(),getSourceLocation());
+                       
                        }
                return true;
                } else if (onInterface && gen.getType().isTopmostImplementor(onType)) {