]> source.dussan.org Git - aspectj.git/commitdiff
Annotation matching.
authoraclement <aclement>
Wed, 8 Dec 2004 14:15:42 +0000 (14:15 +0000)
committeraclement <aclement>
Wed, 8 Dec 2004 14:15:42 +0000 (14:15 +0000)
16 files changed:
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java
tests/java5/annotations/AnnotatedType.java [new file with mode: 0644]
tests/java5/annotations/Annotation.class [new file with mode: 0644]
tests/java5/annotations/AnnotationAspect02.aj [new file with mode: 0644]
tests/java5/annotations/build.xml
tests/java5/annotations/testcode.jar
tests/src/org/aspectj/systemtest/ajc150/AnnotationPointcuts.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/ResolvedMember.java
weaver/src/org/aspectj/weaver/ResolvedTypeX.java
weaver/src/org/aspectj/weaver/bcel/BcelField.java
weaver/src/org/aspectj/weaver/bcel/BcelMethod.java
weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java
weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java
weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java
weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java
weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java

index f5bafb5c4aa2d7201cdb4555dbb54eeb66c57475..2efe987b8d1218983777c5e821d510c1a758e222 100644 (file)
@@ -224,6 +224,10 @@ public class EclipseSourceType extends ResolvedTypeX.ConcreteName {
        public boolean hasAnnotation(ResolvedTypeX ofType) {
                throw new RuntimeException("How to implement this?  Needs to ask eclipse!");
        }
+       
+       public ResolvedTypeX[] getAnnotationTypes() {
+               throw new RuntimeException("How to implement this?  Needs to ask eclipse!");
+       }
 
        public PerClause getPerClause() {
                //should probably be: ((AspectDeclaration)declaration).perClause;
diff --git a/tests/java5/annotations/AnnotatedType.java b/tests/java5/annotations/AnnotatedType.java
new file mode 100644 (file)
index 0000000..d252f20
--- /dev/null
@@ -0,0 +1,11 @@
+public class AnnotatedType {
+  public static void main(String[] argv) {
+    method1();
+    method2();
+  }
+
+  @SimpleAnnotation(id=1)
+  public static void method1() { }
+
+  public static void method2() { }
+}
diff --git a/tests/java5/annotations/Annotation.class b/tests/java5/annotations/Annotation.class
new file mode 100644 (file)
index 0000000..79c4831
Binary files /dev/null and b/tests/java5/annotations/Annotation.class differ
diff --git a/tests/java5/annotations/AnnotationAspect02.aj b/tests/java5/annotations/AnnotationAspect02.aj
new file mode 100644 (file)
index 0000000..ddc3cc4
--- /dev/null
@@ -0,0 +1,5 @@
+public aspect AnnotationAspect02 {\r
+  before(): call(@SimpleAnnotation * *(..)) {}\r
+\r
+  before(): call( * *(..)) {}\r
+}\r
index 86a30e6ab66b1684dd9bedc1e9f06bf970de8001..8a7a20bccfe951b9e4a01f9c1f00175dadcb1045 100644 (file)
@@ -5,6 +5,7 @@
        <mkdir dir="output"/>
        <javac destdir="output" debug="on" srcdir="." includes="SimpleAnnotation.java"/>
        <javac destdir="output" debug="on" srcdir="." includes="Annotation.java"/>
+       <javac destdir="output" debug="on" srcdir="." includes="AnnotatedType.java"/>
        <zip file="testcode.jar" basedir="output" includes="**/*"/>
        <delete dir="output"/>
     </target>
index 574b25142529547256fdb4e469e35883cf253df5..5fd363171f65175e02e1637a245dee196a3b69a0 100644 (file)
Binary files a/tests/java5/annotations/testcode.jar and b/tests/java5/annotations/testcode.jar differ
diff --git a/tests/src/org/aspectj/systemtest/ajc150/AnnotationPointcuts.java b/tests/src/org/aspectj/systemtest/ajc150/AnnotationPointcuts.java
new file mode 100644 (file)
index 0000000..dba69c3
--- /dev/null
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * 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;
+
+
+/**
+ * Tests the use of Annotations in pointcuts
+ */
+public class AnnotationPointcuts extends TestUtils {
+       
+  protected void setUp() throws Exception {
+       super.setUp();
+       baseDir = new File("../tests/java5/annotations");
+  }
+       
+  // before(): call(@SimpleAnnotation * *(..)) { }
+//  public void test001_usingAnnotationsInPointcuts() {
+//     CompilationResult cR = binaryWeave("testcode.jar","AnnotationAspect02.aj",0,0);
+//     System.err.println(cR.getStandardError());
+//     System.err.println(cR.getErrorMessages());
+//     System.err.println(cR.getInfoMessages());
+//     verifyWeavingMessagesOutput(cR,new String[]{});
+////   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[]{});
+//  }
+}
\ No newline at end of file
index 3228699de8017d3b758e58a6fcd96243f4ecd65d..138f12f5cc2578f764356721a2240afa2efaecc2 100644 (file)
@@ -110,6 +110,14 @@ public class ResolvedMember extends Member implements IHasPosition, AnnotatedEle
        return false;
     }
     
+    public ResolvedTypeX[] getAnnotationTypes() {
+       // The ctors don't allow annotations to be specified ... yet - but
+       // that doesn't mean it is an error to call this method.
+       // Normally the weaver will be working with subtypes of
+       // this type - BcelField/BcelMethod
+       return null;
+    }
+    
     public boolean isBridgeMethod() {
        return (modifiers & Constants.ACC_BRIDGE)!=0;
     }
index 3bbd621b94ded086637c9cff6e47a2d7685344c8..413292468451da8fbffb5924ff5e5204faf9da29 100644 (file)
@@ -564,6 +564,10 @@ public abstract class ResolvedTypeX extends TypeX implements AnnotatedElement {
                return delegate.hasAnnotation(ofType);
            }
            
+           public ResolvedTypeX[] getAnnotationTypes() {
+               return delegate.getAnnotationTypes(); 
+           }
+           
            public boolean isAspect() {
                return delegate.isAspect();
            }
@@ -722,6 +726,7 @@ public abstract class ResolvedTypeX extends TypeX implements AnnotatedElement {
            public abstract boolean isAnnotation();
            
            public abstract boolean hasAnnotation(ResolvedTypeX ofType);
+           public abstract ResolvedTypeX[] getAnnotationTypes();
 
                public abstract ResolvedMember[] getDeclaredFields();
 
index e5f49438ed1b53f274c779464248629f01688c65..57fe60b593db7acd570ec802ecd531baa33f1f27 100644 (file)
@@ -32,6 +32,8 @@ final class BcelField extends ResolvedMember {
        private Field field;
        private boolean isAjSynthetic;
        private boolean isSynthetic = false;
+       private ResolvedTypeX[] resolvedAnnotations;
+       private World world;
 
        BcelField(BcelObjectType declaringType, Field field) {
                super(
@@ -41,7 +43,8 @@ final class BcelField extends ResolvedMember {
                        field.getName(), 
                        field.getSignature());
                this.field = field;
-               unpackAttributes(declaringType.getResolvedTypeX().getWorld());
+               this.world = declaringType.getResolvedTypeX().getWorld();
+               unpackAttributes(world);
                checkedExceptions = TypeX.NONE;
        }
 
@@ -84,4 +87,17 @@ final class BcelField extends ResolvedMember {
                }
                return false;
        }
+       
+       public ResolvedTypeX[] getAnnotationTypes() {
+               if (resolvedAnnotations == null) {
+                       Annotation[] annotations = field.getAnnotations();
+                       resolvedAnnotations = new ResolvedTypeX[annotations.length];
+                       for (int i = 0; i < annotations.length; i++) {
+                               Annotation annotation = annotations[i];
+                               ResolvedTypeX rtx = world.resolve(TypeX.forName(annotation.getTypeName()));
+                               resolvedAnnotations[i] = rtx;
+                       }
+               }
+               return resolvedAnnotations;
+    }
 }
index be054952d069713a5539ef6d59fb8b174d316042..360295c9279ad23058c9030298a5e221ca442161 100644 (file)
@@ -37,6 +37,8 @@ final class BcelMethod extends ResolvedMember {
        private ShadowMunger associatedShadowMunger;
        private AjAttribute.EffectiveSignatureAttribute effectiveSignature;
        private AjAttribute.MethodDeclarationLineNumberAttribute declarationLineNumber;
+       private ResolvedTypeX[] resolvedAnnotations;
+       private World world;
 
        BcelMethod(BcelObjectType declaringType, Method method) {
                super(
@@ -49,7 +51,8 @@ final class BcelMethod extends ResolvedMember {
                        method.getName(), 
                        method.getSignature());
                this.method = method;
-               unpackAjAttributes(declaringType.getResolvedTypeX().getWorld());
+               this.world = declaringType.getResolvedTypeX().getWorld();
+               unpackAjAttributes(world);
                unpackJavaAttributes();
        }
 
@@ -146,4 +149,18 @@ final class BcelMethod extends ResolvedMember {
                }
                return false;
        }
+       
+       
+        public ResolvedTypeX[] getAnnotationTypes() {
+               if (resolvedAnnotations == null) {
+                       Annotation[] annotations = method.getAnnotations();
+                       resolvedAnnotations = new ResolvedTypeX[annotations.length];
+                       for (int i = 0; i < annotations.length; i++) {
+                               Annotation annotation = annotations[i];
+                               ResolvedTypeX rtx = world.resolve(TypeX.forName(annotation.getTypeName()));
+                               resolvedAnnotations[i] = rtx;
+                       }
+               }
+               return resolvedAnnotations;
+    }
 }
index 44da5969dedbafb2e6762845f99104852cc12007..321480ddce0d3090e5f5cdde1ef6ac15d3b6f6cb 100644 (file)
@@ -47,6 +47,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
     private ResolvedTypeX superClass = null;
     private ResolvedMember[] fields = null;
     private ResolvedMember[] methods = null;
+    private ResolvedTypeX[] resolvedAnnotations = null;
             
     // strangely non-lazy
     private ResolvedPointcutDefinition[] pointcuts = null;
@@ -320,18 +321,7 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
                //if (lazyClassGen != null) lazyClassGen.print();
        }
 
-//     public Annotation[] getAnnotations() {
-//     if (annotations == null) {
-//             annotations = javaClass.getAnnotations();
-////  This would be how to resolve annotations ...
-////                   annotationsTypeXs = new ResolvedTypeX[annotations.length];
-////                   for (int i = 0; i < annotations.length; i++) {
-////                           Annotation annotation = annotations[i];
-////                           getResolvedTypeX().getWorld().resolve(TypeX.forName(annotation.getTypeName()));
-////                   }
-//     }
-//     return annotations;
-//    }
+
 
        public boolean hasAnnotation(ResolvedTypeX ofType) {
                Annotation[] annotationsOnThisType = javaClass.getAnnotations();
@@ -341,6 +331,19 @@ public class BcelObjectType extends ResolvedTypeX.ConcreteName {
                }
                return false;
        }
+       
+       public ResolvedTypeX[] getAnnotationTypes() {
+       if (resolvedAnnotations == null) {
+               Annotation annotations[] = javaClass.getAnnotations();
+               resolvedAnnotations = new ResolvedTypeX[annotations.length];
+               for (int i = 0; i < annotations.length; i++) {
+                               Annotation annotation = annotations[i];
+                               ResolvedTypeX rtx = getResolvedTypeX().getWorld().resolve(TypeX.forName(annotation.getTypeName()));
+                               resolvedAnnotations[i] = rtx;
+                       }
+       }
+       return resolvedAnnotations;
+    }
 } 
     
     
index 2d848f0fbcfbb269c3ca49fb49c094c16309d431..6b5d17721bcbf756e05f25fb60219253714da507 100644 (file)
@@ -21,13 +21,13 @@ import java.lang.reflect.Modifier;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.MessageUtil;
 import org.aspectj.util.FuzzyBoolean;
-import org.aspectj.weaver.ShadowMunger;
 import org.aspectj.weaver.BCException;
 import org.aspectj.weaver.ISourceContext;
 import org.aspectj.weaver.IntMap;
 import org.aspectj.weaver.ResolvedPointcutDefinition;
 import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.Shadow;
+import org.aspectj.weaver.ShadowMunger;
 import org.aspectj.weaver.TypeX;
 import org.aspectj.weaver.WeaverMessages;
 import org.aspectj.weaver.ast.Test;
index 145915e195ab681a0d8ea5cd3fbebb245a001952..4b19f24d35a12a416bd2191879bcb053d17ccf50 100644 (file)
@@ -77,7 +77,7 @@ public class WildAnnotationTypePattern extends AnnotationTypePattern {
                                scope.getWorld().getMessageHandler().handleMessage(m);
                                resolved = false;
                        }
-               return new ExactAnnotationTypePattern(et.getExactType());
+               return new ExactAnnotationTypePattern(et.getExactType().resolve(scope.getWorld()));
        } else {
                return this;
        }
index e525f857850cb746c469ff2d21670f6ce194b349..fba58dae02377cc69326decc984fcdf7e4d45f68 100644 (file)
  * ******************************************************************/
 package org.aspectj.weaver.patterns;
 
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
 
 import junit.framework.TestCase;
 
 import org.aspectj.bridge.AbortException;
 import org.aspectj.bridge.IMessage;
 import org.aspectj.bridge.IMessageHandler;
-import org.aspectj.bridge.MessageHandler;
 import org.aspectj.bridge.IMessage.Kind;
 import org.aspectj.weaver.BcweaverTests;
 import org.aspectj.weaver.ResolvedMember;
@@ -186,5 +185,61 @@ public class AnnotationPatternMatchingTestCase extends TestCase {
                                   simpleAnnotationTP.matches(aField).alwaysTrue());
 
        }
+       
+       public void testAnnotationTypeResolutionOnTypes() {
+               ResolvedTypeX rtx = loadType("AnnotatedClass");
+               ResolvedTypeX[] types = rtx.getAnnotationTypes();
+               assertTrue("Did not expect null",types!=null);
+               assertTrue("Expected 1 entry but got "+types.length,types.length==1);
+               assertTrue("Should be 'p.SimpleAnnotation' but is "+types[0],
+                               types[0].equals(world.resolve("p.SimpleAnnotation")));
+       }
+       
+       public void testAnnotationTypeResolutionOnMethods() {
+               ResolvedTypeX rtx = loadType("AnnotatedClass");
+
+               ResolvedMember aMethod = rtx.getDeclaredMethods()[1];
+               assertTrue("Haven't got the right method, I'm looking for 'm1()': "+aMethod.getName(),
+                               aMethod.getName().equals("m1"));
+               
+               ResolvedTypeX[] types = aMethod.getAnnotationTypes();
+               assertTrue("Did not expect null",types!=null);
+               assertTrue("Expected 1 entry but got "+types.length,types.length==1);
+               assertTrue("Should be 'p.SimpleAnnotation' but is "+types[0],
+                               types[0].equals(world.resolve("p.SimpleAnnotation")));
+       }
+       
+       public void testAnnotationTypeResolutionOnFields() {
+               ResolvedTypeX rtx = loadType("AnnotatedClass");
+
+               ResolvedMember aField = rtx.getDeclaredFields()[0];
+
+               assertTrue("Haven't got the right field, I'm looking for 'i'"+aField.getName(),
+                                  aField.getName().equals("i"));
+                               
+               ResolvedTypeX[] types = aField.getAnnotationTypes();
+               assertTrue("Did not expect null",types!=null);
+               assertTrue("Expected 1 entry but got "+types.length,types.length==1);
+               assertTrue("Should be 'p.SimpleAnnotation' but is "+types[0],
+                               types[0].equals(world.resolve("p.SimpleAnnotation")));
+       }
+       
+       public void testWildPatternMatchingOnTypes() {
+               
+               ResolvedTypeX rtx = loadType("AnnotatedClass");
+        initAnnotationTypePatterns();          
+        
+        // Let's create something wild
+               PatternParser p = new PatternParser("@Foo || @Boo");
+               AnnotationTypePattern ap = p.maybeParseAnnotationPattern();
+               ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true);
+               assertTrue("shouldnt match the type AnnotatedClass",ap.matches(rtx).alwaysFalse());
+               
+               
+               p = new PatternParser("@p.SimpleAnnotation || @Boo");
+               ap = p.maybeParseAnnotationPattern();
+               ap = ap.resolveBindings(makeSimpleScope(),new Bindings(3),true);
+               assertTrue("should match the type AnnotatedClass",ap.matches(rtx).alwaysTrue());
+       }
 
 }
index 46475c3a6cae096126ca50e1edbf54ebb99f9c8c..bf14716679b6628db480f979cae1c13e4322efb0 100644 (file)
@@ -15,6 +15,8 @@ package org.aspectj.weaver.patterns;
 
 import junit.framework.TestCase;
 
+import org.aspectj.weaver.BcweaverTests;
+import org.aspectj.weaver.ResolvedTypeX;
 import org.aspectj.weaver.World;
 import org.aspectj.weaver.bcel.BcelShadow;
 import org.aspectj.weaver.bcel.BcelWorld;
@@ -33,7 +35,7 @@ public class ParserTestCase extends TestCase {
                super(arg0);
        }
        
-       World world = new BcelWorld();
+       World world = new BcelWorld(BcweaverTests.TESTDATA_PATH + "/testcode.jar");
        
        public void testNamePatterns() {
                
@@ -58,10 +60,23 @@ public class ParserTestCase extends TestCase {
                } catch (ParserException pe) {
                        // good
                }
-
-               
-               
        }
+       
+       public void testParseWithAnnotation() {
+               PatternParser parser = new PatternParser("execution(@p.SimpleAnnotation void Hello.*(..))");
+               KindedPointcut p = (KindedPointcut) parser.parsePointcut();
+               // XXX - needs finishing...
+               // p.resolveBindings(makeSimpleScope(),new Bindings(3));
+//             System.err.println(p);
+//             assertEquals(p.kind, BcelShadow.MethodExecution);
+//             assertTrue(p.signature.getName().matches("foobar"));
+//             p.signature.resolveBindings(makeSimpleScope(),new Bindings(3));         
+       }
+       
+       public TestScope makeSimpleScope() {
+               return new TestScope(new String[] {"int", "java.lang.String"}, new String[] {"a", "b"}, world);
+       }
+
 }