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.

ThisOrTargetAnnotationPointcut.java 11KB

преди 15 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 9 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 9 години
преди 15 години
преди 9 години
преди 15 години
преди 14 години
преди 9 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 9 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
преди 14 години
преди 15 години
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. * ******************************************************************/
  10. package org.aspectj.weaver.patterns;
  11. import java.io.IOException;
  12. import java.util.ArrayList;
  13. import java.util.Collections;
  14. import java.util.List;
  15. import java.util.Map;
  16. import org.aspectj.bridge.IMessage;
  17. import org.aspectj.bridge.MessageUtil;
  18. import org.aspectj.util.FuzzyBoolean;
  19. import org.aspectj.weaver.CompressingDataOutputStream;
  20. import org.aspectj.weaver.ISourceContext;
  21. import org.aspectj.weaver.IntMap;
  22. import org.aspectj.weaver.ResolvedType;
  23. import org.aspectj.weaver.Shadow;
  24. import org.aspectj.weaver.ShadowMunger;
  25. import org.aspectj.weaver.UnresolvedType;
  26. import org.aspectj.weaver.VersionedDataInputStream;
  27. import org.aspectj.weaver.WeaverMessages;
  28. import org.aspectj.weaver.World;
  29. import org.aspectj.weaver.ast.Literal;
  30. import org.aspectj.weaver.ast.Test;
  31. import org.aspectj.weaver.ast.Var;
  32. /**
  33. * @author colyer
  34. *
  35. * TODO To change the template for this generated type comment go to Window - Preferences - Java - Code Style - Code
  36. * Templates
  37. */
  38. public class ThisOrTargetAnnotationPointcut extends NameBindingPointcut {
  39. private boolean isThis;
  40. private boolean alreadyWarnedAboutDEoW = false;
  41. private ExactAnnotationTypePattern annotationTypePattern;
  42. private String declarationText;
  43. private static final int thisKindSet;
  44. private static final int targetKindSet;
  45. static {
  46. int thisFlags = Shadow.ALL_SHADOW_KINDS_BITS;
  47. int targFlags = Shadow.ALL_SHADOW_KINDS_BITS;
  48. for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) {
  49. Shadow.Kind kind = Shadow.SHADOW_KINDS[i];
  50. if (kind.neverHasThis()) {
  51. thisFlags -= kind.bit;
  52. }
  53. if (kind.neverHasTarget()) {
  54. targFlags -= kind.bit;
  55. }
  56. }
  57. thisKindSet = thisFlags;
  58. targetKindSet = targFlags;
  59. }
  60. /**
  61. *
  62. */
  63. public ThisOrTargetAnnotationPointcut(boolean isThis, ExactAnnotationTypePattern type) {
  64. super();
  65. this.isThis = isThis;
  66. this.annotationTypePattern = type;
  67. this.pointcutKind = ATTHIS_OR_TARGET;
  68. buildDeclarationText();
  69. }
  70. public ThisOrTargetAnnotationPointcut(boolean isThis, ExactAnnotationTypePattern type, ShadowMunger munger) {
  71. this(isThis, type);
  72. }
  73. public ExactAnnotationTypePattern getAnnotationTypePattern() {
  74. return annotationTypePattern;
  75. }
  76. @Override
  77. public int couldMatchKinds() {
  78. return isThis ? thisKindSet : targetKindSet;
  79. }
  80. @Override
  81. public Pointcut parameterizeWith(Map<String,UnresolvedType> typeVariableMap, World w) {
  82. ExactAnnotationTypePattern newPattern = (ExactAnnotationTypePattern) this.annotationTypePattern.parameterizeWith(
  83. typeVariableMap, w);
  84. if (newPattern.getAnnotationType() instanceof ResolvedType) {
  85. verifyRuntimeRetention(newPattern.getResolvedAnnotationType());
  86. }
  87. ThisOrTargetAnnotationPointcut ret = new ThisOrTargetAnnotationPointcut(isThis,
  88. (ExactAnnotationTypePattern) annotationTypePattern.parameterizeWith(typeVariableMap, w));
  89. ret.copyLocationFrom(this);
  90. return ret;
  91. }
  92. /*
  93. * (non-Javadoc)
  94. *
  95. * @see org.aspectj.weaver.patterns.Pointcut#fastMatch(org.aspectj.weaver.patterns.FastMatchInfo)
  96. */
  97. @Override
  98. public FuzzyBoolean fastMatch(FastMatchInfo info) {
  99. return FuzzyBoolean.MAYBE;
  100. }
  101. /*
  102. * (non-Javadoc)
  103. *
  104. * @see org.aspectj.weaver.patterns.Pointcut#match(org.aspectj.weaver.Shadow)
  105. */
  106. @Override
  107. protected FuzzyBoolean matchInternal(Shadow shadow) {
  108. if (!couldMatch(shadow)) {
  109. return FuzzyBoolean.NO;
  110. }
  111. ResolvedType toMatchAgainst = (isThis ? shadow.getThisType() : shadow.getTargetType()).resolve(shadow.getIWorld());
  112. annotationTypePattern.resolve(shadow.getIWorld());
  113. if (annotationTypePattern.matchesRuntimeType(toMatchAgainst).alwaysTrue()) {
  114. return FuzzyBoolean.YES;
  115. } else {
  116. // a subtype may match at runtime
  117. return FuzzyBoolean.MAYBE;
  118. }
  119. }
  120. public boolean isThis() {
  121. return isThis;
  122. }
  123. /*
  124. * (non-Javadoc)
  125. *
  126. * @see org.aspectj.weaver.patterns.Pointcut#resolveBindings(org.aspectj.weaver.patterns.IScope,
  127. * org.aspectj.weaver.patterns.Bindings)
  128. */
  129. @Override
  130. protected void resolveBindings(IScope scope, Bindings bindings) {
  131. if (!scope.getWorld().isInJava5Mode()) {
  132. scope.message(MessageUtil.error(WeaverMessages.format(isThis ? WeaverMessages.ATTHIS_ONLY_SUPPORTED_AT_JAVA5_LEVEL
  133. : WeaverMessages.ATTARGET_ONLY_SUPPORTED_AT_JAVA5_LEVEL), getSourceLocation()));
  134. return;
  135. }
  136. annotationTypePattern = (ExactAnnotationTypePattern) annotationTypePattern.resolveBindings(scope, bindings, true);
  137. // must be either a Var, or an annotation type pattern
  138. // if annotationType does not have runtime retention, this is an error
  139. if (annotationTypePattern.annotationType == null) {
  140. // it's a formal with a binding error
  141. return;
  142. }
  143. ResolvedType rAnnotationType = (ResolvedType) annotationTypePattern.annotationType;
  144. if (rAnnotationType.isTypeVariableReference()) {
  145. return; // we'll deal with this next check when the type var is actually bound...
  146. }
  147. verifyRuntimeRetention(rAnnotationType);
  148. }
  149. private void verifyRuntimeRetention(ResolvedType rAnnotationType) {
  150. if (!(rAnnotationType.isAnnotationWithRuntimeRetention())) {
  151. IMessage m = MessageUtil.error(WeaverMessages.format(WeaverMessages.BINDING_NON_RUNTIME_RETENTION_ANNOTATION,
  152. rAnnotationType.getName()), getSourceLocation());
  153. rAnnotationType.getWorld().getMessageHandler().handleMessage(m);
  154. }
  155. }
  156. /*
  157. * (non-Javadoc)
  158. *
  159. * @see org.aspectj.weaver.patterns.Pointcut#concretize1(org.aspectj.weaver.ResolvedType, org.aspectj.weaver.IntMap)
  160. */
  161. @Override
  162. protected Pointcut concretize1(ResolvedType inAspect, ResolvedType declaringType, IntMap bindings) {
  163. if (isDeclare(bindings.getEnclosingAdvice())) {
  164. // Enforce rule about which designators are supported in declare
  165. if (!alreadyWarnedAboutDEoW) {
  166. inAspect.getWorld().showMessage(IMessage.ERROR,
  167. WeaverMessages.format(WeaverMessages.THIS_OR_TARGET_IN_DECLARE, isThis ? "this" : "target"),
  168. bindings.getEnclosingAdvice().getSourceLocation(), null);
  169. alreadyWarnedAboutDEoW = true;
  170. }
  171. return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
  172. }
  173. ExactAnnotationTypePattern newType = (ExactAnnotationTypePattern) annotationTypePattern.remapAdviceFormals(bindings);
  174. ThisOrTargetAnnotationPointcut ret = new ThisOrTargetAnnotationPointcut(isThis, newType, bindings.getEnclosingAdvice());
  175. ret.alreadyWarnedAboutDEoW = alreadyWarnedAboutDEoW;
  176. ret.copyLocationFrom(this);
  177. return ret;
  178. }
  179. /*
  180. * (non-Javadoc)
  181. *
  182. * @see org.aspectj.weaver.patterns.Pointcut#findResidue(org.aspectj.weaver.Shadow, org.aspectj.weaver.patterns.ExposedState)
  183. */
  184. /**
  185. * The guard here is going to be the hasAnnotation() test - if it gets through (which we cannot determine until runtime) then we
  186. * must have a TypeAnnotationAccessVar in place - this means we must *always* have one in place.
  187. */
  188. @Override
  189. protected Test findResidueInternal(Shadow shadow, ExposedState state) {
  190. if (!couldMatch(shadow)) {
  191. return Literal.FALSE;
  192. }
  193. boolean alwaysMatches = match(shadow).alwaysTrue();
  194. Var var = isThis ? shadow.getThisVar() : shadow.getTargetVar();
  195. Var annVar = null;
  196. // Are annotations being bound?
  197. UnresolvedType annotationType = annotationTypePattern.annotationType;
  198. if (annotationTypePattern instanceof BindingAnnotationTypePattern) {
  199. BindingAnnotationTypePattern btp = (BindingAnnotationTypePattern) annotationTypePattern;
  200. annotationType = btp.annotationType;
  201. annVar = isThis ? shadow.getThisAnnotationVar(annotationType) : shadow.getTargetAnnotationVar(annotationType);
  202. if (annVar == null) {
  203. throw new RuntimeException("Impossible!");
  204. }
  205. state.set(btp.getFormalIndex(), annVar);
  206. }
  207. if (alwaysMatches && (annVar == null)) {// change check to verify if its the 'generic' annVar that is being used
  208. return Literal.TRUE;
  209. } else {
  210. ResolvedType rType = annotationType.resolve(shadow.getIWorld());
  211. return Test.makeHasAnnotation(var, rType);
  212. }
  213. }
  214. private boolean couldMatch(Shadow shadow) {
  215. return isThis ? shadow.hasThis() : shadow.hasTarget();
  216. }
  217. /*
  218. * (non-Javadoc)
  219. *
  220. * @see org.aspectj.weaver.patterns.NameBindingPointcut#getBindingAnnotationTypePatterns()
  221. */
  222. @Override
  223. public List<BindingPattern> getBindingAnnotationTypePatterns() {
  224. if (annotationTypePattern instanceof BindingAnnotationTypePattern) {
  225. List<BindingPattern> l = new ArrayList<BindingPattern>();
  226. l.add((BindingPattern)annotationTypePattern);
  227. return l;
  228. } else {
  229. return Collections.emptyList();
  230. }
  231. }
  232. /*
  233. * (non-Javadoc)
  234. *
  235. * @see org.aspectj.weaver.patterns.NameBindingPointcut#getBindingTypePatterns()
  236. */
  237. @Override
  238. public List<BindingTypePattern> getBindingTypePatterns() {
  239. return Collections.emptyList();
  240. }
  241. /*
  242. * (non-Javadoc)
  243. *
  244. * @see org.aspectj.weaver.patterns.PatternNode#write(java.io.DataOutputStream)
  245. */
  246. @Override
  247. public void write(CompressingDataOutputStream s) throws IOException {
  248. s.writeByte(Pointcut.ATTHIS_OR_TARGET);
  249. s.writeBoolean(isThis);
  250. annotationTypePattern.write(s);
  251. writeLocation(s);
  252. }
  253. public static Pointcut read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  254. boolean isThis = s.readBoolean();
  255. AnnotationTypePattern type = AnnotationTypePattern.read(s, context);
  256. ThisOrTargetAnnotationPointcut ret = new ThisOrTargetAnnotationPointcut(isThis, (ExactAnnotationTypePattern) type);
  257. ret.readLocation(context, s);
  258. return ret;
  259. }
  260. /*
  261. * (non-Javadoc)
  262. *
  263. * @see java.lang.Object#equals(java.lang.Object)
  264. */
  265. @Override
  266. public boolean equals(Object obj) {
  267. if (!(obj instanceof ThisOrTargetAnnotationPointcut)) {
  268. return false;
  269. }
  270. ThisOrTargetAnnotationPointcut other = (ThisOrTargetAnnotationPointcut) obj;
  271. return (other.annotationTypePattern.equals(this.annotationTypePattern) && (other.isThis == this.isThis));
  272. }
  273. /*
  274. * (non-Javadoc)
  275. *
  276. * @see java.lang.Object#hashCode()
  277. */
  278. @Override
  279. public int hashCode() {
  280. return 17 + 37 * annotationTypePattern.hashCode() + (isThis ? 49 : 13);
  281. }
  282. /*
  283. * (non-Javadoc)
  284. *
  285. * @see java.lang.Object#toString()
  286. */
  287. private void buildDeclarationText() {
  288. StringBuffer buf = new StringBuffer();
  289. buf.append(isThis ? "@this(" : "@target(");
  290. String annPatt = annotationTypePattern.toString();
  291. buf.append(annPatt.startsWith("@") ? annPatt.substring(1) : annPatt);
  292. buf.append(")");
  293. this.declarationText = buf.toString();
  294. }
  295. @Override
  296. public String toString() {
  297. return this.declarationText;
  298. }
  299. @Override
  300. public Object accept(PatternNodeVisitor visitor, Object data) {
  301. return visitor.visit(this, data);
  302. }
  303. }