From 57e97a0d145110253538f0239213b314ec815f46 Mon Sep 17 00:00:00 2001 From: aclement Date: Wed, 8 Jun 2005 14:21:45 +0000 Subject: [PATCH] Tests and fixes for 98901: annotation copying on public ITDs --- tests/java5/annotations/itds/AtItd2.aj | 29 +++++++++++++++ tests/java5/annotations/itds/AtItd3.aj | 37 +++++++++++++++++++ .../systemtest/ajc150/Annotations.java | 12 ++++++ .../aspectj/weaver/bcel/BcelTypeMunger.java | 36 +++++++++++++++++- .../aspectj/weaver/bcel/LazyMethodGen.java | 32 +++++++++------- 5 files changed, 132 insertions(+), 14 deletions(-) create mode 100644 tests/java5/annotations/itds/AtItd2.aj create mode 100644 tests/java5/annotations/itds/AtItd3.aj diff --git a/tests/java5/annotations/itds/AtItd2.aj b/tests/java5/annotations/itds/AtItd2.aj new file mode 100644 index 000000000..d96984c72 --- /dev/null +++ b/tests/java5/annotations/itds/AtItd2.aj @@ -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); + } + } + +} diff --git a/tests/java5/annotations/itds/AtItd3.aj b/tests/java5/annotations/itds/AtItd3.aj new file mode 100644 index 000000000..bc6c671f9 --- /dev/null +++ b/tests/java5/annotations/itds/AtItd3.aj @@ -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); + } + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc150/Annotations.java b/tests/src/org/aspectj/systemtest/ajc150/Annotations.java index 3a099a2ab..8c9fc2256 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/Annotations.java +++ b/tests/src/org/aspectj/systemtest/ajc150/Annotations.java @@ -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"); } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index ced005ed5..01d6d7e70 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -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, diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java index 8aae4570a..46bddecdd 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java @@ -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++) { -- 2.39.5