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.

BindingAnnotationFieldTypePattern.java 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /* *******************************************************************
  2. * Copyright (c) 2008 Contributors
  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.io.IOException;
  14. import java.util.Map;
  15. import org.aspectj.bridge.IMessage;
  16. import org.aspectj.bridge.MessageUtil;
  17. import org.aspectj.util.FuzzyBoolean;
  18. import org.aspectj.weaver.AnnotatedElement;
  19. import org.aspectj.weaver.BCException;
  20. import org.aspectj.weaver.CompressingDataOutputStream;
  21. import org.aspectj.weaver.ISourceContext;
  22. import org.aspectj.weaver.IntMap;
  23. import org.aspectj.weaver.ReferenceType;
  24. import org.aspectj.weaver.ResolvedMember;
  25. import org.aspectj.weaver.ResolvedType;
  26. import org.aspectj.weaver.UnresolvedType;
  27. import org.aspectj.weaver.VersionedDataInputStream;
  28. import org.aspectj.weaver.WeaverMessages;
  29. import org.aspectj.weaver.World;
  30. /**
  31. * Represents an attempt to bind the field of an annotation within a pointcut. For example:
  32. * <pre><code>
  33. * before(Level lev): execution(* *(..)) &amp;&amp; @annotation(TraceAnnotation(lev))
  34. * </code></pre>
  35. * <p>This binding annotation type pattern will be for 'lev'.</p>
  36. */
  37. public class BindingAnnotationFieldTypePattern extends ExactAnnotationTypePattern implements BindingPattern {
  38. protected int formalIndex;
  39. UnresolvedType formalType; // In this construct the formal type differs from the annotation type
  40. public BindingAnnotationFieldTypePattern(UnresolvedType formalType, int formalIndex, UnresolvedType theAnnotationType) {
  41. super(theAnnotationType, null);
  42. this.formalIndex = formalIndex;
  43. this.formalType = formalType;
  44. }
  45. public void resolveBinding(World world) {
  46. if (resolved) {
  47. return;
  48. }
  49. resolved = true;
  50. formalType = world.resolve(formalType);
  51. annotationType = world.resolve(annotationType);
  52. ResolvedType annoType = (ResolvedType) annotationType;
  53. if (!annoType.isAnnotation()) {
  54. IMessage m = MessageUtil
  55. .error(WeaverMessages.format(WeaverMessages.REFERENCE_TO_NON_ANNOTATION_TYPE, annoType.getName()),
  56. getSourceLocation());
  57. world.getMessageHandler().handleMessage(m);
  58. resolved = false;
  59. }
  60. }
  61. @Override
  62. public AnnotationTypePattern parameterizeWith(Map typeVariableMap, World w) {
  63. throw new BCException("Parameterization not implemented for annotation field binding construct (compiler limitation)");
  64. // UnresolvedType newAnnotationType = annotationType;
  65. // if (annotationType.isTypeVariableReference()) {
  66. // TypeVariableReference t = (TypeVariableReference) annotationType;
  67. // String key = t.getTypeVariable().getName();
  68. // if (typeVariableMap.containsKey(key)) {
  69. // newAnnotationType = (UnresolvedType) typeVariableMap.get(key);
  70. // }
  71. // } else if (annotationType.isParameterizedType()) {
  72. // newAnnotationType = annotationType.parameterize(typeVariableMap);
  73. // }
  74. // BindingAnnotationTypePattern ret = new BindingAnnotationTypePattern(newAnnotationType, this.formalIndex);
  75. // if (newAnnotationType instanceof ResolvedType) {
  76. // ResolvedType rat = (ResolvedType) newAnnotationType;
  77. // verifyRuntimeRetention(rat.getWorld(), rat);
  78. // }
  79. // ret.copyLocationFrom(this);
  80. // return ret;
  81. }
  82. @Override
  83. public int getFormalIndex() {
  84. return formalIndex;
  85. }
  86. @Override
  87. public boolean equals(Object obj) {
  88. if (!(obj instanceof BindingAnnotationFieldTypePattern)) {
  89. return false;
  90. }
  91. BindingAnnotationFieldTypePattern btp = (BindingAnnotationFieldTypePattern) obj;
  92. return (btp.formalIndex == formalIndex) && (annotationType.equals(btp.annotationType))
  93. && (formalType.equals(btp.formalType));
  94. }
  95. @Override
  96. public int hashCode() {
  97. return (annotationType.hashCode() * 37 + formalIndex * 37) + formalType.hashCode();
  98. }
  99. @Override
  100. public AnnotationTypePattern remapAdviceFormals(IntMap bindings) {
  101. if (!bindings.hasKey(formalIndex)) {
  102. throw new BCException("Annotation field binding reference must be bound (compiler limitation)");
  103. // must be something like returning the unbound form: return new ExactAnnotationTypePattern(annotationType,
  104. // null);
  105. } else {
  106. int newFormalIndex = bindings.get(formalIndex);
  107. BindingAnnotationFieldTypePattern baftp = new BindingAnnotationFieldTypePattern(formalType, newFormalIndex,
  108. annotationType);
  109. baftp.formalName = formalName;
  110. return baftp;
  111. }
  112. }
  113. @Override
  114. public void write(CompressingDataOutputStream s) throws IOException {
  115. s.writeByte(AnnotationTypePattern.BINDINGFIELD2);
  116. formalType.write(s); // the type of the field within the annotation
  117. s.writeShort((short) formalIndex);
  118. annotationType.write(s); // the annotation type
  119. s.writeUTF(formalName);
  120. writeLocation(s);
  121. }
  122. public static AnnotationTypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  123. AnnotationTypePattern ret = new BindingAnnotationFieldTypePattern(UnresolvedType.read(s), s.readShort(),
  124. UnresolvedType.read(s));
  125. ret.readLocation(context, s);
  126. return ret;
  127. }
  128. public static AnnotationTypePattern read2(VersionedDataInputStream s, ISourceContext context) throws IOException {
  129. BindingAnnotationFieldTypePattern ret = new BindingAnnotationFieldTypePattern(UnresolvedType.read(s), s.readShort(),
  130. UnresolvedType.read(s));
  131. ret.formalName = s.readUTF();
  132. ret.readLocation(context, s);
  133. return ret;
  134. }
  135. @Override
  136. public FuzzyBoolean matches(AnnotatedElement annotated, ResolvedType[] parameterAnnotations) {
  137. // Inheritance irrelevant because @annotation(Anno(x)) only supported at method execution join points (compiler limitation)
  138. // boolean checkSupers = false;
  139. // if (getResolvedAnnotationType().hasAnnotation(UnresolvedType.AT_INHERITED)) {
  140. // if (annotated instanceof ResolvedType) {
  141. // checkSupers = true;
  142. // }
  143. // }
  144. //
  145. if (annotated.hasAnnotation(annotationType)) {
  146. if (annotationType instanceof ReferenceType) {
  147. ReferenceType rt = (ReferenceType) annotationType;
  148. if (rt.getRetentionPolicy() != null && rt.getRetentionPolicy().equals("SOURCE")) {
  149. rt.getWorld()
  150. .getMessageHandler()
  151. .handleMessage(
  152. MessageUtil.warn(WeaverMessages.format(WeaverMessages.NO_MATCH_BECAUSE_SOURCE_RETENTION,
  153. annotationType, annotated), getSourceLocation()));
  154. return FuzzyBoolean.NO;
  155. }
  156. ResolvedMember[] methods = rt.getDeclaredMethods();
  157. boolean found = false;
  158. for (int i = 0; i < methods.length && !found; i++) {
  159. if (methods[i].getReturnType().equals(formalType)) {
  160. found = true;
  161. }
  162. }
  163. return (found ? FuzzyBoolean.YES : FuzzyBoolean.NO);
  164. }
  165. }
  166. // else if (checkSupers) {
  167. // ResolvedType toMatchAgainst = ((ResolvedType) annotated).getSuperclass();
  168. // while (toMatchAgainst != null) {
  169. // if (toMatchAgainst.hasAnnotation(annotationType)) {
  170. // return FuzzyBoolean.YES;
  171. // }
  172. // toMatchAgainst = toMatchAgainst.getSuperclass();
  173. // }
  174. // }
  175. //
  176. return FuzzyBoolean.NO;
  177. }
  178. public UnresolvedType getFormalType() {
  179. return formalType;
  180. }
  181. }