@@ -0,0 +1,29 @@ | |||
import java.lang.annotation.*; | |||
import java.lang.reflect.*; | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@interface Ann {} | |||
aspect X { | |||
@Ann public void AtItd2.m() {} | |||
} | |||
public class AtItd2 { | |||
public static void main(String []argv) { | |||
try { | |||
Method m = AtItd2.class.getDeclaredMethod("m",null); | |||
System.err.println("Method is "+m); | |||
Annotation[] as = m.getDeclaredAnnotations(); | |||
System.err.println("Number of annotations "+ | |||
(as==null?"0":new Integer(as.length).toString())); | |||
Annotation aa = m.getAnnotation(Ann.class); | |||
System.err.println("Ann.class retrieved is: "+aa); | |||
if (as.length==0) | |||
throw new RuntimeException("Couldn't find annotation on member!"); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
} |
@@ -0,0 +1,37 @@ | |||
import java.lang.annotation.*; | |||
import java.lang.reflect.*; | |||
@Retention(RetentionPolicy.RUNTIME) | |||
@interface Ann { | |||
String id() default "hello"; | |||
int anInt() default 5; | |||
} | |||
aspect X { | |||
@Ann(id="goodbye",anInt=4) public void AtItd3.m() {} | |||
} | |||
public class AtItd3 { | |||
public static void main(String []argv) { | |||
try { | |||
Method m = AtItd3.class.getDeclaredMethod("m",null); | |||
System.err.println("Method is "+m); | |||
Annotation[] as = m.getDeclaredAnnotations(); | |||
System.err.println("Number of annotations "+ | |||
(as==null?"0":new Integer(as.length).toString())); | |||
Annotation aa = m.getAnnotation(Ann.class); | |||
System.err.println("Ann.class retrieved is: "+aa); | |||
if (!aa.toString().equals("@Ann(id=goodbye, anInt=4)")) | |||
throw new RuntimeException("Incorrect output, expected:"+ | |||
"@Ann(id=goodbye, anInt=4) but got "+aa.toString()); | |||
if (as.length==0) | |||
throw new RuntimeException("Couldn't find annotation on member!"); | |||
} catch (Exception e) { | |||
e.printStackTrace(); | |||
throw new RuntimeException(e); | |||
} | |||
} | |||
} |
@@ -78,7 +78,19 @@ public class Annotations extends XMLBasedAjcTestCase { | |||
public void testAnnotatedITDs() { | |||
runTest("annotated itds"); | |||
} | |||
public void testAnnotatedITDs2() { | |||
runTest("annotated public itds"); | |||
} | |||
public void testAnnotatedITDs3() { | |||
runTest("annotated public itds - values"); | |||
} | |||
public void testAnnotatedITDs4() { | |||
runTest("annotated public itds - multiple complex annotations"); | |||
} | |||
public void testAnnotatedITDsWithWrongAnnotationType() { | |||
runTest("annotated itds with bad target"); | |||
} |
@@ -19,6 +19,7 @@ import java.util.List; | |||
import java.util.Set; | |||
import org.aspectj.apache.bcel.Constants; | |||
import org.aspectj.apache.bcel.classfile.annotation.Annotation; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
import org.aspectj.apache.bcel.generic.FieldGen; | |||
import org.aspectj.apache.bcel.generic.INVOKESPECIAL; | |||
@@ -27,6 +28,7 @@ import org.aspectj.apache.bcel.generic.InstructionFactory; | |||
import org.aspectj.apache.bcel.generic.InstructionHandle; | |||
import org.aspectj.apache.bcel.generic.InstructionList; | |||
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.Message; | |||
@@ -34,7 +36,9 @@ import org.aspectj.bridge.MessageUtil; | |||
import org.aspectj.bridge.WeaveMessage; | |||
import org.aspectj.weaver.AjcMemberMaker; | |||
import org.aspectj.weaver.AnnotationOnTypeMunger; | |||
import org.aspectj.weaver.AnnotationX; | |||
import org.aspectj.weaver.AsmRelationshipProvider; | |||
import org.aspectj.weaver.BCException; | |||
import org.aspectj.weaver.ConcreteTypeMunger; | |||
import org.aspectj.weaver.Member; | |||
import org.aspectj.weaver.NameMangler; | |||
@@ -704,7 +708,7 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
private boolean mungeNewMethod(BcelClassWeaver weaver, NewMethodTypeMunger munger) { | |||
ResolvedMember signature = munger.getSignature(); | |||
ResolvedMember dispatchMethod = munger.getDispatchMethod(aspectType); | |||
LazyClassGen gen = weaver.getLazyClassGen(); | |||
ResolvedTypeX onType = weaver.getWorld().resolve(signature.getDeclaringType(),munger.getSourceLocation()); | |||
@@ -724,7 +728,27 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
ResolvedMember introMethod = | |||
AjcMemberMaker.interMethod(signature, aspectType, onInterface); | |||
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().behaveInJava5Way && !onInterface && munger.getSignature().isPublic() && !munger.getSignature().isAbstract()) { | |||
ResolvedMember realMember = getRealMemberForITDFromAspect(aspectType,dispatchMethod); | |||
if (realMember==null) throw new BCException("Couldn't find ITD holder member '"+ | |||
dispatchMethod+"' 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 (!onInterface && !Modifier.isAbstract(introMethod.getModifiers())) { | |||
InstructionList body = mg.getBody(); | |||
@@ -814,6 +838,16 @@ public class BcelTypeMunger extends ConcreteTypeMunger { | |||
return false; | |||
} | |||
} | |||
private ResolvedMember getRealMemberForITDFromAspect(ResolvedTypeX aspectType,ResolvedMember dispatchMethod) { | |||
ResolvedMember aspectMethods[] = aspectType.getDeclaredMethods(); | |||
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; | |||
} | |||
return realMember; | |||
} | |||
private void addNeededSuperCallMethods( | |||
BcelClassWeaver weaver, |
@@ -86,7 +86,7 @@ public final class LazyMethodGen { | |||
private String[] declaredExceptions; | |||
private InstructionList body; // leaving null for abstracts | |||
private Attribute[] attributes; | |||
// private AnnotationGen[] annotations; | |||
private List newAnnotations; | |||
private final LazyClassGen enclosingClass; | |||
private BcelMethod memberView; | |||
int highestLineNumber = 0; | |||
@@ -208,16 +208,25 @@ public final class LazyMethodGen { | |||
public void addAnnotation(AnnotationX ax) { | |||
initialize(); | |||
if (memberView==null) { | |||
System.err.println("REPORT THIS! 01: Lost annotation: "+ax+" cant be put onto "+this); | |||
return; | |||
// If member view is null, we manage them in newAnnotations | |||
if (newAnnotations==null) newAnnotations = new ArrayList(); | |||
newAnnotations.add(ax); | |||
} else { | |||
memberView.addAnnotation(ax); | |||
} | |||
memberView.addAnnotation(ax); | |||
} | |||
public boolean hasAnnotation(TypeX annotationTypeX) { | |||
initialize(); | |||
if (memberView==null) { | |||
// Check local annotations first | |||
if (newAnnotations!=null) { | |||
for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) { | |||
AnnotationX element = (AnnotationX) iter.next(); | |||
if (element.getBcelAnnotation().getTypeName().equals(annotationTypeX.getName())) return true; | |||
} | |||
} | |||
memberView = new BcelMethod(getEnclosingClass().getBcelObjectType(), getMethod()); | |||
return memberView.hasAnnotation(annotationTypeX); | |||
} | |||
@@ -831,16 +840,13 @@ public final class LazyMethodGen { | |||
gen.addAttribute(attributes[i]); | |||
} | |||
// We don't manage our own set of annotations... | |||
// if (annotations!=null) { | |||
// for (int i = 0, len = annotations.length; i < len; i++) { | |||
// gen.addAnnotation(annotations[i]); | |||
// } | |||
// } | |||
if (newAnnotations!=null) { | |||
for (Iterator iter = newAnnotations.iterator(); iter.hasNext();) { | |||
AnnotationX element = (AnnotationX) iter.next(); | |||
gen.addAnnotation(new AnnotationGen(element.getBcelAnnotation(),gen.getConstantPool(),true)); | |||
} | |||
} | |||
// work with the annotations from the memberView rather | |||
// than any set we know about. This assumes we only work with | |||
// annotations on LazyMethodGens that represent real members. | |||
if (memberView!=null && memberView.getAnnotations()!=null && memberView.getAnnotations().length!=0) { | |||
AnnotationX[] ans = memberView.getAnnotations(); | |||
for (int i = 0, len = ans.length; i < len; i++) { |