diff options
author | aclement <aclement> | 2004-12-08 14:15:42 +0000 |
---|---|---|
committer | aclement <aclement> | 2004-12-08 14:15:42 +0000 |
commit | 6e6d34c79638763ab180578dd169147fda5011cc (patch) | |
tree | b4a0def4960a386fe5d05c8209ba49419d402e79 | |
parent | 4c20738fbb3560cccf1bc7e5bc0a21618c9559c7 (diff) | |
download | aspectj-6e6d34c79638763ab180578dd169147fda5011cc.tar.gz aspectj-6e6d34c79638763ab180578dd169147fda5011cc.zip |
Annotation matching.
16 files changed, 212 insertions, 22 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java index f5bafb5c4..2efe987b8 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseSourceType.java @@ -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 index 000000000..d252f20fe --- /dev/null +++ b/tests/java5/annotations/AnnotatedType.java @@ -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 Binary files differnew file mode 100644 index 000000000..79c4831ca --- /dev/null +++ b/tests/java5/annotations/Annotation.class diff --git a/tests/java5/annotations/AnnotationAspect02.aj b/tests/java5/annotations/AnnotationAspect02.aj new file mode 100644 index 000000000..ddc3cc48d --- /dev/null +++ b/tests/java5/annotations/AnnotationAspect02.aj @@ -0,0 +1,5 @@ +public aspect AnnotationAspect02 {
+ before(): call(@SimpleAnnotation * *(..)) {}
+
+ before(): call( * *(..)) {}
+}
diff --git a/tests/java5/annotations/build.xml b/tests/java5/annotations/build.xml index 86a30e6ab..8a7a20bcc 100644 --- a/tests/java5/annotations/build.xml +++ b/tests/java5/annotations/build.xml @@ -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> diff --git a/tests/java5/annotations/testcode.jar b/tests/java5/annotations/testcode.jar Binary files differindex 574b25142..5fd363171 100644 --- a/tests/java5/annotations/testcode.jar +++ b/tests/java5/annotations/testcode.jar diff --git a/tests/src/org/aspectj/systemtest/ajc150/AnnotationPointcuts.java b/tests/src/org/aspectj/systemtest/ajc150/AnnotationPointcuts.java new file mode 100644 index 000000000..dba69c367 --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc150/AnnotationPointcuts.java @@ -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 diff --git a/weaver/src/org/aspectj/weaver/ResolvedMember.java b/weaver/src/org/aspectj/weaver/ResolvedMember.java index 3228699de..138f12f5c 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMember.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMember.java @@ -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; } diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java index 3bbd621b9..413292468 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeX.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeX.java @@ -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(); diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelField.java b/weaver/src/org/aspectj/weaver/bcel/BcelField.java index e5f49438e..57fe60b59 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelField.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelField.java @@ -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; + } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java index be054952d..360295c92 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelMethod.java @@ -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; + } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java index 44da5969d..321480ddc 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelObjectType.java @@ -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; + } } diff --git a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java index 2d848f0fb..6b5d17721 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java @@ -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; diff --git a/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java index 145915e19..4b19f24d3 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/WildAnnotationTypePattern.java @@ -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; } diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java index e525f8578..fba58dae0 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/AnnotationPatternMatchingTestCase.java @@ -11,15 +11,14 @@ * ******************************************************************/ 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()); + } } diff --git a/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java b/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java index 46475c3a6..bf1471667 100644 --- a/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/patterns/ParserTestCase.java @@ -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); + } + } |