Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

Advice.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  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;
  13. import java.util.Collections;
  14. import java.util.List;
  15. import org.aspectj.bridge.IMessage;
  16. import org.aspectj.weaver.patterns.AndPointcut;
  17. import org.aspectj.weaver.patterns.PerClause;
  18. import org.aspectj.weaver.patterns.Pointcut;
  19. import org.aspectj.weaver.patterns.TypePattern;
  20. public abstract class Advice extends ShadowMunger {
  21. protected AjAttribute.AdviceAttribute attribute; // the pointcut field is ignored
  22. protected AdviceKind kind; // alias of attribute.getKind()
  23. protected Member signature;
  24. // not necessarily declaring aspect, this is a semantics change from 1.0
  25. protected ResolvedTypeX concreteAspect; // null until after concretize
  26. protected List innerCflowEntries = Collections.EMPTY_LIST; // just for cflow*Entry kinds
  27. protected int nFreeVars; // just for cflow*Entry kinds
  28. protected TypePattern exceptionType; // just for Softener kind
  29. public static Advice makeCflowEntry(World world, Pointcut entry, boolean isBelow, Member stackField, int nFreeVars, List innerCflowEntries, ResolvedTypeX inAspect){
  30. Advice ret = world.concreteAdvice(isBelow ? AdviceKind.CflowBelowEntry : AdviceKind.CflowEntry,
  31. entry, stackField, 0, entry);
  32. //0);
  33. ret.innerCflowEntries = innerCflowEntries;
  34. ret.nFreeVars = nFreeVars;
  35. ret.concreteAspect = inAspect;
  36. return ret;
  37. }
  38. public static Advice makePerCflowEntry(World world, Pointcut entry, boolean isBelow,
  39. Member stackField, ResolvedTypeX inAspect, List innerCflowEntries)
  40. {
  41. Advice ret = world.concreteAdvice(isBelow ? AdviceKind.PerCflowBelowEntry : AdviceKind.PerCflowEntry,
  42. entry, stackField, 0, entry);
  43. ret.innerCflowEntries = innerCflowEntries;
  44. ret.concreteAspect = inAspect;
  45. return ret;
  46. }
  47. public static Advice makePerObjectEntry(World world, Pointcut entry, boolean isThis,
  48. ResolvedTypeX inAspect)
  49. {
  50. Advice ret = world.concreteAdvice(isThis ? AdviceKind.PerThisEntry : AdviceKind.PerTargetEntry,
  51. entry, null, 0, entry);
  52. ret.concreteAspect = inAspect;
  53. return ret;
  54. }
  55. // PTWIMPL per type within entry advice is what initializes the aspect instance in the matched type
  56. public static Advice makePerTypeWithinEntry(World world, Pointcut p, ResolvedTypeX inAspect) {
  57. Advice ret = world.concreteAdvice(AdviceKind.PerTypeWithinEntry,p,null,0,p);
  58. ret.concreteAspect = inAspect;
  59. return ret;
  60. }
  61. public static Advice makeSoftener(World world, Pointcut entry, TypePattern exceptionType,ResolvedTypeX inAspect,IHasSourceLocation loc) {
  62. Advice ret = world.concreteAdvice(AdviceKind.Softener, entry, null, 0, loc);
  63. ret.exceptionType = exceptionType;
  64. ret.concreteAspect = inAspect;
  65. // System.out.println("made ret: " + ret + " with " + exceptionType);
  66. return ret;
  67. }
  68. public Advice(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature)
  69. {
  70. super(pointcut, attribute.getStart(), attribute.getEnd(), attribute.getSourceContext());
  71. this.attribute = attribute;
  72. this.kind = attribute.getKind(); // alias
  73. this.signature = signature;
  74. }
  75. public boolean match(Shadow shadow, World world) {
  76. if (super.match(shadow, world)) {
  77. if (shadow.getKind() == Shadow.ExceptionHandler) {
  78. if (kind.isAfter() || kind == AdviceKind.Around) {
  79. world.showMessage(IMessage.WARNING,
  80. WeaverMessages.format(WeaverMessages.ONLY_BEFORE_ON_HANDLER),
  81. getSourceLocation(), shadow.getSourceLocation());
  82. return false;
  83. }
  84. }
  85. if (hasExtraParameter() && kind == AdviceKind.AfterReturning) {
  86. return getExtraParameterType().isConvertableFrom(shadow.getReturnType(), world);
  87. } else if (kind == AdviceKind.PerTargetEntry) {
  88. return shadow.hasTarget();
  89. } else if (kind == AdviceKind.PerThisEntry) {
  90. return shadow.hasThis();
  91. } else if (kind == AdviceKind.Around) {
  92. if (shadow.getKind() == Shadow.PreInitialization) {
  93. world.showMessage(IMessage.ERROR,
  94. WeaverMessages.format(WeaverMessages.AROUND_ON_PREINIT),
  95. getSourceLocation(), shadow.getSourceLocation());
  96. return false;
  97. } else if (shadow.getKind() == Shadow.Initialization) {
  98. world.showMessage(IMessage.ERROR,
  99. WeaverMessages.format(WeaverMessages.AROUND_ON_INIT),
  100. getSourceLocation(), shadow.getSourceLocation());
  101. return false;
  102. } else if (shadow.getKind() == Shadow.StaticInitialization &&
  103. shadow.getEnclosingType().isInterface(world))
  104. {
  105. world.showMessage(IMessage.ERROR,
  106. WeaverMessages.format(WeaverMessages.AROUND_ON_INTERFACE_STATICINIT,shadow.getEnclosingType().getName()),
  107. getSourceLocation(), shadow.getSourceLocation());
  108. return false;
  109. } else {
  110. //System.err.println(getSignature().getReturnType() + " from " + shadow.getReturnType());
  111. if (getSignature().getReturnType() == ResolvedTypeX.VOID) {
  112. if (shadow.getReturnType() != ResolvedTypeX.VOID) {
  113. world.showMessage(IMessage.ERROR,
  114. WeaverMessages.format(WeaverMessages.NON_VOID_RETURN,shadow),
  115. getSourceLocation(), shadow.getSourceLocation());
  116. return false;
  117. }
  118. } else if (getSignature().getReturnType().equals(TypeX.OBJECT)) {
  119. return true;
  120. } else if(!shadow.getReturnType().isAssignableFrom(getSignature().getReturnType(), world)) {
  121. //System.err.println(this + ", " + sourceContext + ", " + start);
  122. world.showMessage(IMessage.ERROR,
  123. WeaverMessages.format(WeaverMessages.INCOMPATIBLE_RETURN_TYPE,shadow),
  124. getSourceLocation(), shadow.getSourceLocation());
  125. return false;
  126. }
  127. }
  128. }
  129. return true;
  130. } else {
  131. return false;
  132. }
  133. }
  134. // ----
  135. public AdviceKind getKind() {
  136. return kind;
  137. }
  138. public Member getSignature() {
  139. return signature;
  140. }
  141. public boolean hasExtraParameter() {
  142. return (getExtraParameterFlags() & ExtraArgument) != 0;
  143. }
  144. protected int getExtraParameterFlags() {
  145. return attribute.getExtraParameterFlags();
  146. }
  147. protected int getExtraParameterCount() {
  148. return countOnes(getExtraParameterFlags() & ParameterMask);
  149. }
  150. public static int countOnes(int bits) {
  151. int ret = 0;
  152. while (bits != 0) {
  153. if ((bits & 1) != 0) ret += 1;
  154. bits = bits >> 1;
  155. }
  156. return ret;
  157. }
  158. public int getBaseParameterCount() {
  159. return getSignature().getParameterTypes().length - getExtraParameterCount();
  160. }
  161. public String[] getBaseParameterNames(World world) {
  162. String[] allNames = getSignature().getParameterNames(world);
  163. int extras = getExtraParameterCount();
  164. if (extras == 0) return allNames;
  165. String[] result = new String[getBaseParameterCount()];
  166. for (int i = 0; i < result.length; i++) {
  167. result[i] = allNames[i];
  168. }
  169. return result;
  170. }
  171. public TypeX getExtraParameterType() {
  172. if (!hasExtraParameter()) return ResolvedTypeX.MISSING;
  173. return signature.getParameterTypes()[getBaseParameterCount()];
  174. }
  175. public TypeX getDeclaringAspect() {
  176. return signature.getDeclaringType();
  177. }
  178. protected String extraParametersToString() {
  179. if (getExtraParameterFlags() == 0) {
  180. return "";
  181. } else {
  182. return "(extraFlags: " + getExtraParameterFlags() + ")";
  183. }
  184. }
  185. public Pointcut getPointcut() {
  186. return pointcut;
  187. }
  188. // ----
  189. /** @param fromType is guaranteed to be a non-abstract aspect
  190. * @param clause has been concretized at a higher level
  191. */
  192. public ShadowMunger concretize(ResolvedTypeX fromType, World world, PerClause clause) {
  193. // assert !fromType.isAbstract();
  194. Pointcut p = pointcut.concretize(fromType, signature.getArity(), this);
  195. if (clause != null) {
  196. Pointcut oldP = p;
  197. p = new AndPointcut(clause, p);
  198. p.copyLocationFrom(oldP);
  199. p.state = Pointcut.CONCRETE;
  200. //FIXME ? ATAJ copy unbound bindings to ignore
  201. p.m_ignoreUnboundBindingForNames =oldP.m_ignoreUnboundBindingForNames;
  202. }
  203. Advice munger = world.concreteAdvice(attribute, p, signature);
  204. munger.concreteAspect = fromType;
  205. //System.err.println("concretizing here " + p + " with clause " + clause);
  206. return munger;
  207. }
  208. // ---- from object
  209. public String toString() {
  210. StringBuffer sb = new StringBuffer();
  211. sb.append("(").append(getKind()).append(extraParametersToString());
  212. sb.append(": ").append(pointcut).append("->").append(signature).append(")");
  213. return sb.toString();
  214. // return "("
  215. // + getKind()
  216. // + extraParametersToString()
  217. // + ": "
  218. // + pointcut
  219. // + "->"
  220. // + signature
  221. // + ")";
  222. }
  223. public boolean equals(Object other) {
  224. if (! (other instanceof Advice)) return false;
  225. Advice o = (Advice) other;
  226. return o.attribute.equals(attribute)
  227. && o.pointcut.equals(pointcut)
  228. && o.signature.equals(signature);
  229. }
  230. private volatile int hashCode = 0;
  231. public int hashCode() {
  232. if (hashCode == 0) {
  233. int result = 17;
  234. result = 37*result + kind.hashCode();
  235. result = 37*result + pointcut.hashCode();
  236. if (signature != null) result = 37*result + signature.hashCode();
  237. hashCode = result;
  238. }
  239. return hashCode;
  240. }
  241. // ---- fields
  242. public static final int ExtraArgument = 1;
  243. public static final int ThisJoinPoint = 2;
  244. public static final int ThisJoinPointStaticPart = 4;
  245. public static final int ThisEnclosingJoinPointStaticPart = 8;
  246. public static final int ParameterMask = 0xf;
  247. public static final int CanInline = 0x40;
  248. // for testing only
  249. public void setLexicalPosition(int lexicalPosition) {
  250. start = lexicalPosition;
  251. }
  252. public ResolvedTypeX getConcreteAspect() {
  253. return concreteAspect;
  254. }
  255. }