Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

IfPointcut.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.patterns;
  13. import java.io.DataOutputStream;
  14. import java.io.IOException;
  15. import java.lang.reflect.Member;
  16. import java.util.ArrayList;
  17. import java.util.Collections;
  18. import java.util.List;
  19. import java.util.Set;
  20. import org.aspectj.bridge.IMessage;
  21. import org.aspectj.lang.JoinPoint;
  22. import org.aspectj.util.FuzzyBoolean;
  23. import org.aspectj.weaver.Advice;
  24. import org.aspectj.weaver.ISourceContext;
  25. import org.aspectj.weaver.IntMap;
  26. import org.aspectj.weaver.ResolvedMember;
  27. import org.aspectj.weaver.ResolvedPointcutDefinition;
  28. import org.aspectj.weaver.ResolvedTypeX;
  29. import org.aspectj.weaver.Shadow;
  30. import org.aspectj.weaver.ShadowMunger;
  31. import org.aspectj.weaver.VersionedDataInputStream;
  32. import org.aspectj.weaver.WeaverMessages;
  33. import org.aspectj.weaver.ast.Expr;
  34. import org.aspectj.weaver.ast.Literal;
  35. import org.aspectj.weaver.ast.Test;
  36. import org.aspectj.weaver.ast.Var;
  37. public class IfPointcut extends Pointcut {
  38. public ResolvedMember testMethod;
  39. public int extraParameterFlags;
  40. public Pointcut residueSource;
  41. int baseArgsCount;
  42. //XXX some way to compute args
  43. public IfPointcut(ResolvedMember testMethod, int extraParameterFlags) {
  44. this.testMethod = testMethod;
  45. this.extraParameterFlags = extraParameterFlags;
  46. this.pointcutKind = IF;
  47. }
  48. public Set couldMatchKinds() {
  49. return Shadow.ALL_SHADOW_KINDS;
  50. }
  51. public FuzzyBoolean fastMatch(FastMatchInfo type) {
  52. return FuzzyBoolean.MAYBE;
  53. }
  54. protected FuzzyBoolean matchInternal(Shadow shadow) {
  55. //??? this is not maximally efficient
  56. return FuzzyBoolean.MAYBE;
  57. }
  58. public boolean alwaysFalse() {
  59. return false;
  60. }
  61. public boolean alwaysTrue() {
  62. return false;
  63. }
  64. /* (non-Javadoc)
  65. * @see org.aspectj.weaver.patterns.Pointcut#matchesDynamically(java.lang.Object, java.lang.Object, java.lang.Object[])
  66. */
  67. public boolean matchesDynamically(Object thisObject, Object targetObject,
  68. Object[] args) {
  69. throw new UnsupportedOperationException("If pointcut matching not supported by this operation");
  70. }
  71. /* (non-Javadoc)
  72. * @see org.aspectj.weaver.patterns.Pointcut#matchesStatically(java.lang.String, java.lang.reflect.Member, java.lang.Class, java.lang.Class, java.lang.reflect.Member)
  73. */
  74. public FuzzyBoolean matchesStatically(
  75. String joinpointKind, Member member, Class thisClass,
  76. Class targetClass, Member withinCode) {
  77. throw new UnsupportedOperationException("If pointcut matching not supported by this operation");
  78. }
  79. public void write(DataOutputStream s) throws IOException {
  80. s.writeByte(Pointcut.IF);
  81. testMethod.write(s);
  82. s.writeByte(extraParameterFlags);
  83. writeLocation(s);
  84. }
  85. public static Pointcut read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  86. IfPointcut ret = new IfPointcut(ResolvedMember.readResolvedMember(s, context), s.readByte());
  87. ret.readLocation(context, s);
  88. return ret;
  89. }
  90. public void resolveBindings(IScope scope, Bindings bindings) {
  91. //??? all we need is good error messages in here in cflow contexts
  92. }
  93. public void resolveBindingsFromRTTI() {}
  94. public boolean equals(Object other) {
  95. if (!(other instanceof IfPointcut)) return false;
  96. IfPointcut o = (IfPointcut)other;
  97. return o.testMethod.equals(this.testMethod);
  98. }
  99. public int hashCode() {
  100. int result = 17;
  101. result = 37*result + testMethod.hashCode();
  102. return result;
  103. }
  104. public String toString() {
  105. return "if(" + testMethod + ")";
  106. }
  107. //??? The implementation of name binding and type checking in if PCDs is very convoluted
  108. // There has to be a better way...
  109. private boolean findingResidue = false;
  110. protected Test findResidueInternal(Shadow shadow, ExposedState state) {
  111. if (findingResidue) return Literal.TRUE;
  112. findingResidue = true;
  113. try {
  114. ExposedState myState = new ExposedState(baseArgsCount);
  115. //System.out.println(residueSource);
  116. //??? we throw out the test that comes from this walk. All we want here
  117. // is bindings for the arguments
  118. residueSource.findResidue(shadow, myState);
  119. //System.out.println(myState);
  120. Test ret = Literal.TRUE;
  121. List args = new ArrayList();
  122. for (int i=0; i < baseArgsCount; i++) {
  123. Var v = myState.get(i);
  124. args.add(v);
  125. ret = Test.makeAnd(ret,
  126. Test.makeInstanceof(v,
  127. testMethod.getParameterTypes()[i].resolve(shadow.getIWorld())));
  128. }
  129. // handle thisJoinPoint parameters
  130. if ((extraParameterFlags & Advice.ThisJoinPoint) != 0) {
  131. args.add(shadow.getThisJoinPointVar());
  132. }
  133. if ((extraParameterFlags & Advice.ThisJoinPointStaticPart) != 0) {
  134. args.add(shadow.getThisJoinPointStaticPartVar());
  135. }
  136. if ((extraParameterFlags & Advice.ThisEnclosingJoinPointStaticPart) != 0) {
  137. args.add(shadow.getThisEnclosingJoinPointStaticPartVar());
  138. }
  139. ret = Test.makeAnd(ret, Test.makeCall(testMethod, (Expr[])args.toArray(new Expr[args.size()])));
  140. return ret;
  141. } finally {
  142. findingResidue = false;
  143. }
  144. }
  145. // amc - the only reason this override seems to be here is to stop the copy, but
  146. // that can be prevented by overriding shouldCopyLocationForConcretization,
  147. // allowing me to make the method final in Pointcut.
  148. // public Pointcut concretize(ResolvedTypeX inAspect, IntMap bindings) {
  149. // return this.concretize1(inAspect, bindings);
  150. // }
  151. protected boolean shouldCopyLocationForConcretize() {
  152. return false;
  153. }
  154. private IfPointcut partiallyConcretized = null;
  155. public Pointcut concretize1(ResolvedTypeX inAspect, IntMap bindings) {
  156. //System.err.println("concretize: " + this + " already: " + partiallyConcretized);
  157. if (isDeclare(bindings.getEnclosingAdvice())) {
  158. // Enforce rule about which designators are supported in declare
  159. inAspect.getWorld().showMessage(IMessage.ERROR,
  160. WeaverMessages.format(WeaverMessages.IF_IN_DECLARE),
  161. bindings.getEnclosingAdvice().getSourceLocation(),
  162. null);
  163. return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
  164. }
  165. if (partiallyConcretized != null) {
  166. return partiallyConcretized;
  167. }
  168. IfPointcut ret = new IfPointcut(testMethod, extraParameterFlags);
  169. ret.copyLocationFrom(this);
  170. partiallyConcretized = ret;
  171. // It is possible to directly code your pointcut expression in a per clause
  172. // rather than defining a pointcut declaration and referencing it in your
  173. // per clause. If you do this, we have problems (bug #62458). For now,
  174. // let's police that you are trying to code a pointcut in a per clause and
  175. // put out a compiler error.
  176. if (bindings.directlyInAdvice() && bindings.getEnclosingAdvice()==null) {
  177. // Assumption: if() is in a per clause if we say we are directly in advice
  178. // but we have no enclosing advice.
  179. inAspect.getWorld().showMessage(IMessage.ERROR,
  180. WeaverMessages.format(WeaverMessages.IF_IN_PERCLAUSE),
  181. this.getSourceLocation(),null);
  182. return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
  183. }
  184. if (bindings.directlyInAdvice()) {
  185. ShadowMunger advice = bindings.getEnclosingAdvice();
  186. if (advice instanceof Advice) {
  187. ret.baseArgsCount = ((Advice)advice).getBaseParameterCount();
  188. } else {
  189. ret.baseArgsCount = 0;
  190. }
  191. ret.residueSource = advice.getPointcut().concretize(inAspect, ret.baseArgsCount, advice);
  192. } else {
  193. ResolvedPointcutDefinition def = bindings.peekEnclosingDefinitition();
  194. if (def == CflowPointcut.CFLOW_MARKER) {
  195. inAspect.getWorld().showMessage(IMessage.ERROR,
  196. WeaverMessages.format(WeaverMessages.IF_LEXICALLY_IN_CFLOW),
  197. getSourceLocation(), null);
  198. return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
  199. }
  200. ret.baseArgsCount = def.getParameterTypes().length;
  201. IntMap newBindings = IntMap.idMap(ret.baseArgsCount);
  202. newBindings.copyContext(bindings);
  203. ret.residueSource = def.getPointcut().concretize(inAspect, newBindings);
  204. }
  205. return ret;
  206. }
  207. // public static Pointcut MatchesNothing = new MatchesNothingPointcut();
  208. // ??? there could possibly be some good optimizations to be done at this point
  209. public static IfPointcut makeIfFalsePointcut(State state) {
  210. IfPointcut ret = new IfFalsePointcut();
  211. ret.state = state;
  212. return ret;
  213. }
  214. private static class IfFalsePointcut extends IfPointcut {
  215. public IfFalsePointcut() {
  216. super(null,0);
  217. }
  218. public Set couldMatchKinds() {
  219. return Collections.EMPTY_SET;
  220. }
  221. public boolean alwaysFalse() {
  222. return true;
  223. }
  224. protected Test findResidueInternal(Shadow shadow, ExposedState state) {
  225. return Literal.FALSE; // can only get here if an earlier error occurred
  226. }
  227. public FuzzyBoolean fastMatch(FastMatchInfo type) {
  228. return FuzzyBoolean.NO;
  229. }
  230. protected FuzzyBoolean matchInternal(Shadow shadow) {
  231. return FuzzyBoolean.NO;
  232. }
  233. public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
  234. return FuzzyBoolean.NO;
  235. }
  236. public void resolveBindings(IScope scope, Bindings bindings) {
  237. }
  238. public void resolveBindingsFromRTTI() {
  239. }
  240. public void postRead(ResolvedTypeX enclosingType) {
  241. }
  242. public Pointcut concretize1(
  243. ResolvedTypeX inAspect,
  244. IntMap bindings) {
  245. if (isDeclare(bindings.getEnclosingAdvice())) {
  246. // Enforce rule about which designators are supported in declare
  247. inAspect.getWorld().showMessage(IMessage.ERROR,
  248. WeaverMessages.format(WeaverMessages.IF_IN_DECLARE),
  249. bindings.getEnclosingAdvice().getSourceLocation(),
  250. null);
  251. return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
  252. }
  253. return makeIfFalsePointcut(state);
  254. }
  255. public void write(DataOutputStream s) throws IOException {
  256. s.writeByte(Pointcut.IF_FALSE);
  257. }
  258. public int hashCode() {
  259. int result = 17;
  260. return result;
  261. }
  262. public String toString() {
  263. return "if(false)";
  264. }
  265. }
  266. public static IfPointcut makeIfTruePointcut(State state) {
  267. IfPointcut ret = new IfTruePointcut();
  268. ret.state = state;
  269. return ret;
  270. }
  271. private static class IfTruePointcut extends IfPointcut {
  272. public IfTruePointcut() {
  273. super(null,0);
  274. }
  275. public boolean alwaysTrue() {
  276. return true;
  277. }
  278. protected Test findResidueInternal(Shadow shadow, ExposedState state) {
  279. return Literal.TRUE; // can only get here if an earlier error occurred
  280. }
  281. public FuzzyBoolean fastMatch(FastMatchInfo type) {
  282. return FuzzyBoolean.YES;
  283. }
  284. protected FuzzyBoolean matchInternal(Shadow shadow) {
  285. return FuzzyBoolean.YES;
  286. }
  287. public FuzzyBoolean match(JoinPoint.StaticPart jpsp) {
  288. return FuzzyBoolean.YES;
  289. }
  290. public void resolveBindings(IScope scope, Bindings bindings) {
  291. }
  292. public void resolveBindingsFromRTTI() {
  293. }
  294. public void postRead(ResolvedTypeX enclosingType) {
  295. }
  296. public Pointcut concretize1(
  297. ResolvedTypeX inAspect,
  298. IntMap bindings) {
  299. if (isDeclare(bindings.getEnclosingAdvice())) {
  300. // Enforce rule about which designators are supported in declare
  301. inAspect.getWorld().showMessage(IMessage.ERROR,
  302. WeaverMessages.format(WeaverMessages.IF_IN_DECLARE),
  303. bindings.getEnclosingAdvice().getSourceLocation(),
  304. null);
  305. return Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
  306. }
  307. return makeIfTruePointcut(state);
  308. }
  309. public void write(DataOutputStream s) throws IOException {
  310. s.writeByte(IF_TRUE);
  311. }
  312. public int hashCode() {
  313. int result = 37;
  314. return result;
  315. }
  316. public String toString() {
  317. return "if(true)";
  318. }
  319. }
  320. }