From: aclement Date: Mon, 24 Jan 2005 09:38:48 +0000 (+0000) Subject: Fix to ensure woven methods don't lose their annotations. X-Git-Tag: Root_AspectJ5_Development~70 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=9367b36e48a91755c82acee5693aae2980de3ded;p=aspectj.git Fix to ensure woven methods don't lose their annotations. --- diff --git a/tests/java5/annotations/attarget/AtTargetAspect.java b/tests/java5/annotations/attarget/AtTargetAspect.java new file mode 100644 index 000000000..8e9238262 --- /dev/null +++ b/tests/java5/annotations/attarget/AtTargetAspect.java @@ -0,0 +1,7 @@ +public aspect AtTargetAspect { + + before(): call(* *(..)) && @target(@MyAnnotation) { + System.err.println("advice running"); + } + +} diff --git a/tests/java5/annotations/attarget/Program.java b/tests/java5/annotations/attarget/Program.java new file mode 100644 index 000000000..a56d5fb5e --- /dev/null +++ b/tests/java5/annotations/attarget/Program.java @@ -0,0 +1,25 @@ +import java.lang.annotation.*; + +@MyAnnotation +public class Program { + + public static void main(String []argv) { + Program p = new Program(); + p.m1(); + p.m2(); + } + + + @MyAnnotation + public void m1() { + System.err.println("m1 method"); + } + + public void m2() { + System.err.println("m2 method"); + } +} + +@Retention(RetentionPolicy.RUNTIME) +@interface MyAnnotation {} + diff --git a/tests/src/org/aspectj/systemtest/ajc150/Ajc150TestsNoHarness.java b/tests/src/org/aspectj/systemtest/ajc150/Ajc150TestsNoHarness.java index 0fa039be0..6ecac5189 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/Ajc150TestsNoHarness.java +++ b/tests/src/org/aspectj/systemtest/ajc150/Ajc150TestsNoHarness.java @@ -14,8 +14,6 @@ import java.io.File; import org.aspectj.apache.bcel.classfile.JavaClass; import org.aspectj.apache.bcel.classfile.Method; -import org.aspectj.apache.bcel.util.ClassPath; -import org.aspectj.apache.bcel.util.SyntheticRepository; import org.aspectj.tools.ajc.CompilationResult; @@ -77,25 +75,4 @@ public class Ajc150TestsNoHarness extends TestUtils { CompilationResult cR = ajc(baseDir,new String[]{"PR83303.java"}); assertTrue("Should be no errors:"+cR,!cR.hasErrorMessages()); } - - - - - - - - - ///////////////////////////////////////// TESTCASE HELPER METHODS BELOW HERE ////////////////////////// - - // Some util methods for accessing .class contents as BCEL objects - - public SyntheticRepository createRepos(File cpentry) { - ClassPath cp = new ClassPath(cpentry+File.pathSeparator+System.getProperty("java.class.path")); - return SyntheticRepository.getInstance(cp); - } - - private JavaClass getClassFrom(File where,String clazzname) throws ClassNotFoundException { - SyntheticRepository repos = createRepos(where); - return repos.loadClass(clazzname); - } } \ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java index a528692bd..9e38feb70 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java +++ b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java @@ -29,7 +29,7 @@ public class AllTestsAspectJ150 { suite.addTest(AccBridgeMethods.suite()); suite.addTestSuite(CovarianceTests.class); suite.addTestSuite(Enums.class); - suite.addTestSuite(Annotations.class); + suite.addTestSuite(AnnotationsBinaryWeaving.class); suite.addTestSuite(AnnotationPointcutsTests.class); suite.addTestSuite(VarargsTests.class); suite.addTestSuite(AnnotationRuntimeTests.class); diff --git a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150_NeedJava15.java b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150_NeedJava15.java index ff0f19202..47a2342f8 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150_NeedJava15.java +++ b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150_NeedJava15.java @@ -23,6 +23,7 @@ public class AllTestsAspectJ150_NeedJava15 { //$JUnit-BEGIN$ suite.addTestSuite(Ajc150TestsRequireJava15.class); suite.addTestSuite(Autoboxing.class); + suite.addTestSuite(Annotations.class); //$JUnit-END$ return suite; diff --git a/tests/src/org/aspectj/systemtest/ajc150/Annotations.java b/tests/src/org/aspectj/systemtest/ajc150/Annotations.java index 1a8b83cc9..9c9c9935a 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/Annotations.java +++ b/tests/src/org/aspectj/systemtest/ajc150/Annotations.java @@ -11,77 +11,62 @@ package org.aspectj.systemtest.ajc150; import java.io.File; +import java.util.ArrayList; +import java.util.List; -import org.aspectj.bridge.IMessage; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.classfile.Method; import org.aspectj.tools.ajc.CompilationResult; - -/** - * Annotations, the rules/tests: - * - * 1. cannot make ITD (C,M or F) on an annotation - * 2. cannot use declare parents to change the super type of an annotation - * 3. cannot use decp to make an annotation type implement an interface - * 4. cannot use decp to dec java.lang.annotation.Annotation as the parent of any type - * 5. cannot extend set of values in an annotation via an ITD like construct - * 6. Compilation error if you explicitly identify an Annotation type. - * 7. Lint warning if a non-explicit type pattern would match an annotation type. - */ public class Annotations extends TestUtils { protected void setUp() throws Exception { super.setUp(); baseDir = new File("../tests/java5/annotations"); } - - // Cannot make ITD (c/m/f) on an annotation - public void test001_itdsOnAnnotationsNotAllowed() { - CompilationResult cR = binaryWeave("testcode.jar","AnnotationAspect01.aj",3,0); - assertTrue("Expected three message about ITDs not allowed on Annotations but got: #"+ - cR.getErrorMessages().size()+": \n"+cR.getErrorMessages(), - cR.getErrorMessages().size()==3); - IMessage msg1_ctor = (IMessage)cR.getErrorMessages().get(0); - IMessage msg2_method = (IMessage)cR.getErrorMessages().get(1); - IMessage msg3_field = (IMessage)cR.getErrorMessages().get(2); - assertTrue("Expected message about ITDCs on annotations not allowed, but got: \n"+msg1_ctor, - msg1_ctor.toString().indexOf("can't make inter-type constructor declarations")!=-1); - assertTrue("Expected message about ITDMs on annotations not allowed, but got: \n"+msg2_method, - msg2_method.toString().indexOf("can't make inter-type method declarations")!=-1); - assertTrue("Expected message about ITDFs on annotations not allowed, but got: \n"+msg3_field, - msg3_field.toString().indexOf("can't make inter-type field declarations")!=-1); - verifyWeavingMessagesOutput(cR,new String[]{}); + + public void testCompilingAnnotation() { + CompilationResult cR = ajc(baseDir,new String[]{"SimpleAnnotation.java","-1.5"}); + MessageSpec ms = new MessageSpec(null,null); + assertMessages(cR,ms); } - // Deals with the cases where an explicit type is specified and it is an annotation type - public void test002_decpOnAnnotationNotAllowed_errors() { - CompilationResult cR = binaryWeave("testcode.jar","AnnotationAspect04.aj",3,0,true,new String[]{"-source","1.5"}); - IMessage msg = (IMessage)cR.getErrorMessages().get(1); - assertTrue("Expected a message about can't use decp to alter supertype of an annotation: "+msg, - msg.toString().indexOf("to alter supertype of annotation type")!=-1); - msg = (IMessage)cR.getErrorMessages().get(2); - assertTrue("Expected a message about can't use decp to make annotation implement interface: "+msg, - msg.toString().indexOf("implement an interface")!=-1); - msg = (IMessage)cR.getErrorMessages().get(0); - assertTrue("Expected a message about can't use decp to make Annotation parent of another type: "+msg, - msg.toString().indexOf("the parent of type")!=-1); - verifyWeavingMessagesOutput(cR,new String[]{}); + public void testCompilingAnnotatedFile() { + CompilationResult cR = ajc(baseDir,new String[]{"AnnotatedType.java","SimpleAnnotation.java","-1.5"}); + MessageSpec ms = new MessageSpec(null,null); + assertMessages(cR,ms); } - //Deals with the cases where an wild type pattern is specified and it hits an annotation type - public void test004_decpOnAnnotationNotAllowed_xlints() { - CompilationResult cR = binaryWeave("testcode.jar","AnnotationAspect05.aj",0,2,false); - IMessage msg = (IMessage)cR.getWarningMessages().get(0); - assertTrue("Expected a message about an annotation type matching a declare parents but being ignored: "+msg, - msg.toString().indexOf("matches a declare parents type pattern")!=-1); - msg = (IMessage)cR.getWarningMessages().get(1); - assertTrue("Expected a message about an annotation type matching a declare parents but being ignored: "+msg, - msg.toString().indexOf("matches a declare parents type pattern")!=-1); - verifyWeavingMessagesOutput(cR,new String[]{}); + public void testCompilingUsingWithinAndAnnotationTypePattern() { + CompilationResult cR = ajc(new File(baseDir+File.separator+"within"), + new String[]{"PlainWithin.java","PlainWithinTests.java","-1.5"}); + List expectedInfoMessages = new ArrayList(); + expectedInfoMessages.add(new Message(21,"positive within match on annotation")); + expectedInfoMessages.add(new Message(25,"negative within match on annotation")); + MessageSpec ms = new MessageSpec(expectedInfoMessages,null); + assertMessages(cR,ms); } - // TODO extra tests: - // declare parents with annotation pattern - // declare soft with annotation pattern - // declare warning with annotation pattern - // declare precedence with annotation pattern + /** + * We had a bug where annotations were not present in the output class file for methods + * that got woven. This was due to unpacking bugs in LazyMethodGen. This test compiles + * a simple program then checks the annotations were copied across. + */ + public void testBugWithAnnotationsLostOnWovenMethods() throws ClassNotFoundException { + CompilationResult cR = ajc(new File(baseDir+File.separator+"attarget"), + new String[]{"Program.java","AtTargetAspect.java","-1.5"}); + System.err.println(cR.getStandardError()); + List expectedInfoMessages = new ArrayList(); + MessageSpec ms = new MessageSpec(null,null); + assertMessages(cR,ms); + + JavaClass jc = getClassFrom(ajc.getSandboxDirectory(),"Program"); + Method[] meths = jc.getMethods(); + for (int i = 0; i < meths.length; i++) { + Method method = meths[i]; + if (method.getName().equals("m1")) { + assertTrue("Didn't have annotations - were they lost? method="+method.getName(),method.getAnnotations().length==1); + } + } + } } \ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/ajc150/AnnotationsBinaryWeaving.java b/tests/src/org/aspectj/systemtest/ajc150/AnnotationsBinaryWeaving.java new file mode 100644 index 000000000..c7510e15e --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc150/AnnotationsBinaryWeaving.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * Andy Clement - initial API and implementation + *******************************************************************************/ +package org.aspectj.systemtest.ajc150; + +import java.io.File; + +import org.aspectj.bridge.IMessage; +import org.aspectj.tools.ajc.CompilationResult; + + +/** + * Annotations, the rules/tests: + * + * 1. cannot make ITD (C,M or F) on an annotation + * 2. cannot use declare parents to change the super type of an annotation + * 3. cannot use decp to make an annotation type implement an interface + * 4. cannot use decp to dec java.lang.annotation.Annotation as the parent of any type + * 5. cannot extend set of values in an annotation via an ITD like construct + * 6. Compilation error if you explicitly identify an Annotation type. + * 7. Lint warning if a non-explicit type pattern would match an annotation type. + */ +public class AnnotationsBinaryWeaving extends TestUtils { + + protected void setUp() throws Exception { + super.setUp(); + baseDir = new File("../tests/java5/annotations"); + } + + // Cannot make ITD (c/m/f) on an annotation + public void test001_itdsOnAnnotationsNotAllowed() { + CompilationResult cR = binaryWeave("testcode.jar","AnnotationAspect01.aj",3,0); + assertTrue("Expected three message about ITDs not allowed on Annotations but got: #"+ + cR.getErrorMessages().size()+": \n"+cR.getErrorMessages(), + cR.getErrorMessages().size()==3); + IMessage msg1_ctor = (IMessage)cR.getErrorMessages().get(0); + IMessage msg2_method = (IMessage)cR.getErrorMessages().get(1); + IMessage msg3_field = (IMessage)cR.getErrorMessages().get(2); + assertTrue("Expected message about ITDCs on annotations not allowed, but got: \n"+msg1_ctor, + msg1_ctor.toString().indexOf("can't make inter-type constructor declarations")!=-1); + assertTrue("Expected message about ITDMs on annotations not allowed, but got: \n"+msg2_method, + msg2_method.toString().indexOf("can't make inter-type method declarations")!=-1); + assertTrue("Expected message about ITDFs on annotations not allowed, but got: \n"+msg3_field, + msg3_field.toString().indexOf("can't make inter-type field declarations")!=-1); + verifyWeavingMessagesOutput(cR,new String[]{}); + } + + // Deals with the cases where an explicit type is specified and it is an annotation type + public void test002_decpOnAnnotationNotAllowed_errors() { + CompilationResult cR = binaryWeave("testcode.jar","AnnotationAspect04.aj",3,0,true,new String[]{"-source","1.5"}); + IMessage msg = (IMessage)cR.getErrorMessages().get(1); + assertTrue("Expected a message about can't use decp to alter supertype of an annotation: "+msg, + msg.toString().indexOf("to alter supertype of annotation type")!=-1); + msg = (IMessage)cR.getErrorMessages().get(2); + assertTrue("Expected a message about can't use decp to make annotation implement interface: "+msg, + msg.toString().indexOf("implement an interface")!=-1); + msg = (IMessage)cR.getErrorMessages().get(0); + assertTrue("Expected a message about can't use decp to make Annotation parent of another type: "+msg, + msg.toString().indexOf("the parent of type")!=-1); + verifyWeavingMessagesOutput(cR,new String[]{}); + } + + //Deals with the cases where an wild type pattern is specified and it hits an annotation type + public void test004_decpOnAnnotationNotAllowed_xlints() { + CompilationResult cR = binaryWeave("testcode.jar","AnnotationAspect05.aj",0,2,false); + IMessage msg = (IMessage)cR.getWarningMessages().get(0); + assertTrue("Expected a message about an annotation type matching a declare parents but being ignored: "+msg, + msg.toString().indexOf("matches a declare parents type pattern")!=-1); + msg = (IMessage)cR.getWarningMessages().get(1); + assertTrue("Expected a message about an annotation type matching a declare parents but being ignored: "+msg, + msg.toString().indexOf("matches a declare parents type pattern")!=-1); + verifyWeavingMessagesOutput(cR,new String[]{}); + } +} \ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/ajc150/TestUtils.java b/tests/src/org/aspectj/systemtest/ajc150/TestUtils.java index 180f9a7c7..69b3b9f4e 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/TestUtils.java +++ b/tests/src/org/aspectj/systemtest/ajc150/TestUtils.java @@ -16,6 +16,9 @@ import java.util.Collection; import java.util.Iterator; import java.util.List; +import org.aspectj.apache.bcel.classfile.JavaClass; +import org.aspectj.apache.bcel.util.ClassPath; +import org.aspectj.apache.bcel.util.SyntheticRepository; import org.aspectj.bridge.IMessage; import org.aspectj.tools.ajc.AjcTestCase; import org.aspectj.tools.ajc.CompilationResult; @@ -119,4 +122,14 @@ public abstract class TestUtils extends AjcTestCase { sb.append("------------------------\n"); return sb.toString(); } + + public SyntheticRepository createRepos(File cpentry) { + ClassPath cp = new ClassPath(cpentry+File.pathSeparator+System.getProperty("java.class.path")); + return SyntheticRepository.getInstance(cp); + } + + protected JavaClass getClassFrom(File where,String clazzname) throws ClassNotFoundException { + SyntheticRepository repos = createRepos(where); + return repos.loadClass(clazzname); + } } diff --git a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java index 5da038ef6..f4b24adff 100644 --- a/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java +++ b/weaver/src/org/aspectj/weaver/bcel/LazyMethodGen.java @@ -49,6 +49,7 @@ import org.aspectj.apache.bcel.generic.MethodGen; import org.aspectj.apache.bcel.generic.ObjectType; 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.weaver.AjAttribute; @@ -82,6 +83,7 @@ public final class LazyMethodGen { private String[] declaredExceptions; private InstructionList body; // leaving null for abstracts private Attribute[] attributes; + private AnnotationGen[] annotations; /* private */ final LazyClassGen enclosingClass; private final BcelMethod memberView; int highestLineNumber = 0; @@ -188,6 +190,7 @@ public final class LazyMethodGen { this.declaredExceptions = gen.getExceptions(); this.attributes = gen.getAttributes(); + this.annotations = gen.getAnnotations(); this.maxLocals = gen.getMaxLocals(); // this.returnType = BcelWorld.makeBcelType(memberView.getReturnType()); @@ -777,10 +780,17 @@ public final class LazyMethodGen { for (int i = 0, len = declaredExceptions.length; i < len; i++) { gen.addException(declaredExceptions[i]); } + for (int i = 0, len = attributes.length; i < len; i++) { gen.addAttribute(attributes[i]); } + if (annotations!=null) { + for (int i = 0, len = annotations.length; i < len; i++) { + gen.addAnnotation(annotations[i]); + } + } + if (isSynthetic) { ConstantPoolGen cpg = gen.getConstantPool(); int index = cpg.addUtf8("Synthetic");