Browse Source

Fix for pr98901: copying annotations to new members created via ITD !!

tags/V1_5_0M3
aclement 19 years ago
parent
commit
211806608a

+ 9
- 2
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeMethodDeclaration.java View 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;

+ 1
- 0
tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java View 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());

+ 115
- 63
weaver/src/org/aspectj/weaver/bcel/BcelClassWeaver.java View 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();
}

+ 67
- 47
weaver/src/org/aspectj/weaver/bcel/BcelShadow.java View 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);

+ 132
- 42
weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java View 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)) {

Loading…
Cancel
Save