You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AnnotationPatternMatchingTestCase.java 8.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /* *******************************************************************
  2. * Copyright (c) 2004 IBM Corporation.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Andy Clement initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.patterns;
  13. import java.util.ArrayList;
  14. import java.util.List;
  15. import org.aspectj.bridge.AbortException;
  16. import org.aspectj.bridge.IMessage;
  17. import org.aspectj.bridge.IMessage.Kind;
  18. import org.aspectj.bridge.IMessageHandler;
  19. import org.aspectj.util.LangUtil;
  20. import org.aspectj.weaver.ResolvedMember;
  21. import org.aspectj.weaver.ResolvedType;
  22. import org.aspectj.weaver.WeaverTestCase;
  23. import org.aspectj.weaver.bcel.BcelWorld;
  24. import junit.framework.TestCase;
  25. /*
  26. * Sample types that this program uses are:
  27. import p.SimpleAnnotation;
  28. @SimpleAnnotation(id=2)
  29. public class AnnotatedClass {
  30. @SimpleAnnotation(id=3)
  31. public void m1() { }
  32. @SimpleAnnotation(id=4)
  33. int i;
  34. }
  35. * with SimpleAnnotation defined as:
  36. package p;
  37. import java.lang.annotation.*;
  38. @Retention(RetentionPolicy.RUNTIME)
  39. public @interface SimpleAnnotation {
  40. int id();
  41. String fruit() default "bananas";
  42. }
  43. *NOTE NOTE NOTE NOTE NOTE NOTE NOTE*
  44. If you need to rebuild the test data code, run 'ant -f build-15.xml' in the
  45. testdata directory.
  46. */
  47. public class AnnotationPatternMatchingTestCase extends TestCase {
  48. private BcelWorld world;
  49. private AnnotationTypePattern fooTP, simpleAnnotationTP;
  50. private ResolvedType loadType(String name) {
  51. if (world == null) {
  52. world = new BcelWorld(WeaverTestCase.TESTDATA_PATH + "/testcode.jar");
  53. world.setBehaveInJava5Way(true);
  54. }
  55. return world.resolve(name);
  56. }
  57. private void initAnnotationTypePatterns() {
  58. PatternParser p = new PatternParser("@Foo");
  59. fooTP = p.maybeParseAnnotationPattern();
  60. fooTP = fooTP.resolveBindings(makeSimpleScope(), new Bindings(3), true);
  61. p = new PatternParser("@p.SimpleAnnotation");
  62. simpleAnnotationTP = p.maybeParseAnnotationPattern();
  63. simpleAnnotationTP = simpleAnnotationTP.resolveBindings(makeSimpleScope(), new Bindings(3), true);
  64. }
  65. public void testAnnotationPatternMatchingOnTypes() {
  66. if (LangUtil.is15VMOrGreater()) {
  67. ResolvedType rtx = loadType("AnnotatedClass");
  68. initAnnotationTypePatterns();
  69. // One should match
  70. assertTrue("@Foo should not match on the AnnotatedClass", fooTP.matches(rtx).alwaysFalse());
  71. assertTrue("@SimpleAnnotation should match on the AnnotatedClass", simpleAnnotationTP.matches(rtx).alwaysTrue());
  72. }
  73. }
  74. static class MyMessageHandler implements IMessageHandler {
  75. public List<IMessage> messages = new ArrayList<IMessage>();
  76. public boolean handleMessage(IMessage message) throws AbortException {
  77. messages.add(message);
  78. return false;
  79. }
  80. public boolean isIgnoring(Kind kind) {
  81. return false;
  82. }
  83. public void dontIgnore(IMessage.Kind kind) {
  84. }
  85. public void ignore(Kind kind) {
  86. }
  87. }
  88. public void testReferenceToNonAnnotationType() {
  89. // ResolvedType rtx =
  90. loadType("AnnotatedClass"); // inits the world
  91. PatternParser p = new PatternParser("@java.lang.String");
  92. MyMessageHandler mh = new MyMessageHandler();
  93. world.setMessageHandler(mh);
  94. AnnotationTypePattern atp = p.maybeParseAnnotationPattern();
  95. atp = atp.resolveBindings(makeSimpleScope(), new Bindings(3), true);
  96. assertTrue("Expected 1 error message but got " + mh.messages.size(), mh.messages.size() == 1);
  97. String expected = "Type referred to is not an annotation type";
  98. String msg = ((IMessage) mh.messages.get(0)).toString();
  99. assertTrue("Expected: " + expected + " but got " + msg, msg.indexOf(expected) != -1);
  100. }
  101. public void testReferenceViaFormalToNonAnnotationType() {
  102. // ResolvedType rtx =
  103. loadType("AnnotatedClass"); // inits the world
  104. PatternParser p = new PatternParser("a");
  105. MyMessageHandler mh = new MyMessageHandler();
  106. world.setMessageHandler(mh);
  107. AnnotationTypePattern atp = p.parseAnnotationNameOrVarTypePattern();
  108. atp = atp.resolveBindings(makeSimpleScope(), new Bindings(3), true);
  109. assertTrue("Expected 3 error messages but got " + mh.messages.size(), mh.messages.size() == 3);
  110. String expected = "Type referred to is not an annotation type";
  111. String msg = ((IMessage) mh.messages.get(0)).toString();
  112. assertTrue("Expected: " + expected + " but got " + msg, msg.indexOf(expected) != -1);
  113. // expected = "Binding not supported in @pcds (1.5.0 M1 limitation): null";
  114. // msg = ((IMessage)mh.messages.get(1)).toString();
  115. // assertTrue("Expected: "+expected+" but got "+msg,msg.indexOf(expected)!=-1);
  116. }
  117. public TestScope makeSimpleScope() {
  118. return new TestScope(new String[] { "int", "java.lang.String" }, new String[] { "a", "b" }, world);
  119. }
  120. public void testUnresolvedAnnotationTypes() {
  121. ResolvedType rtx = loadType("AnnotatedClass");
  122. PatternParser p = new PatternParser("@Foo");
  123. AnnotationTypePattern fooTP = p.maybeParseAnnotationPattern();
  124. try {
  125. fooTP.matches(rtx);
  126. fail("Should have failed with illegal state exception, fooTP is not resolved");
  127. } catch (IllegalStateException ise) {
  128. // Correct!
  129. }
  130. }
  131. public void testAnnotationPatternMatchingOnMethods() {
  132. if (LangUtil.is15VMOrGreater()) {
  133. ResolvedType rtx = loadType("AnnotatedClass");
  134. ResolvedMember aMethod = rtx.getDeclaredMethods()[1];
  135. assertTrue("Haven't got the right method, I'm looking for 'm1()': " + aMethod.getName(), aMethod.getName().equals("m1"));
  136. initAnnotationTypePatterns();
  137. // One should match
  138. assertTrue("@Foo should not match on the AnnotatedClass.m1() method", fooTP.matches(aMethod).alwaysFalse());
  139. assertTrue("@SimpleAnnotation should match on the AnnotatedClass.m1() method", simpleAnnotationTP.matches(aMethod)
  140. .alwaysTrue());
  141. }
  142. }
  143. public void testAnnotationPatternMatchingOnFields() {
  144. if (LangUtil.is15VMOrGreater()) {
  145. ResolvedType rtx = loadType("AnnotatedClass");
  146. ResolvedMember aField = rtx.getDeclaredFields()[0];
  147. assertTrue("Haven't got the right field, I'm looking for 'i'" + aField.getName(), aField.getName().equals("i"));
  148. initAnnotationTypePatterns();
  149. // One should match
  150. assertTrue("@Foo should not match on the AnnotatedClass.i field", fooTP.matches(aField).alwaysFalse());
  151. assertTrue("@SimpleAnnotation should match on the AnnotatedClass.i field", simpleAnnotationTP.matches(aField)
  152. .alwaysTrue());
  153. }
  154. }
  155. public void testAnnotationTypeResolutionOnTypes() {
  156. ResolvedType rtx = loadType("AnnotatedClass");
  157. ResolvedType[] types = rtx.getAnnotationTypes();
  158. assertTrue("Did not expect null", types != null);
  159. assertTrue("Expected 1 entry but got " + types.length, types.length == 1);
  160. assertTrue("Should be 'p.SimpleAnnotation' but is " + types[0], types[0].equals(world.resolve("p.SimpleAnnotation")));
  161. }
  162. public void testAnnotationTypeResolutionOnMethods() {
  163. ResolvedType rtx = loadType("AnnotatedClass");
  164. ResolvedMember aMethod = rtx.getDeclaredMethods()[1];
  165. assertTrue("Haven't got the right method, I'm looking for 'm1()': " + aMethod.getName(), aMethod.getName().equals("m1"));
  166. ResolvedType[] types = aMethod.getAnnotationTypes();
  167. assertTrue("Did not expect null", types != null);
  168. assertTrue("Expected 1 entry but got " + types.length, types.length == 1);
  169. assertTrue("Should be 'p.SimpleAnnotation' but is " + types[0], types[0].equals(world.resolve("p.SimpleAnnotation")));
  170. }
  171. public void testAnnotationTypeResolutionOnFields() {
  172. ResolvedType rtx = loadType("AnnotatedClass");
  173. ResolvedMember aField = rtx.getDeclaredFields()[0];
  174. assertTrue("Haven't got the right field, I'm looking for 'i'" + aField.getName(), aField.getName().equals("i"));
  175. ResolvedType[] types = aField.getAnnotationTypes();
  176. assertTrue("Did not expect null", types != null);
  177. assertTrue("Expected 1 entry but got " + types.length, types.length == 1);
  178. assertTrue("Should be 'p.SimpleAnnotation' but is " + types[0], types[0].equals(world.resolve("p.SimpleAnnotation")));
  179. }
  180. public void testWildPatternMatchingOnTypes() {
  181. ResolvedType rtx = loadType("AnnotatedClass");
  182. initAnnotationTypePatterns();
  183. // Let's create something wild
  184. PatternParser p = new PatternParser("@(Foo || Boo)");
  185. AnnotationTypePattern ap = p.maybeParseAnnotationPattern();
  186. ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true);
  187. assertTrue("shouldnt match the type AnnotatedClass", ap.matches(rtx).alwaysFalse());
  188. p = new PatternParser("@(p.SimpleAnnotation || Boo)");
  189. ap = p.maybeParseAnnotationPattern();
  190. ap = ap.resolveBindings(makeSimpleScope(), new Bindings(3), true);
  191. assertTrue("should match the type AnnotatedClass", ap.matches(rtx).alwaysTrue());
  192. }
  193. }