summaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authoraclement <aclement>2005-08-08 09:54:54 +0000
committeraclement <aclement>2005-08-08 09:54:54 +0000
commit211806608a60557fb6180d55f9c9802a79ab490d (patch)
treefd0f1d15a449dca5dfafb667554ec1202e54dfcc /weaver
parent64f0a5bd91915a3c626a49841c9e4eb64d7f6de9 (diff)
downloadaspectj-211806608a60557fb6180d55f9c9802a79ab490d.tar.gz
aspectj-211806608a60557fb6180d55f9c9802a79ab490d.zip
Fix for pr98901: copying annotations to new members created via ITD !!
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java178
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelShadow.java114
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java174
3 files changed, 314 insertions, 152 deletions
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
index c10b2f16d..f9c2eabcb 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java
@@ -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();
}
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
index afafc943a..495656bba 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
@@ -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);
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
index 8ea410091..5de5b1065 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java
@@ -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)) {