選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

Advice.java 9.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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. public static Advice makeSoftener(World world, Pointcut entry, TypePattern exceptionType,ResolvedTypeX inAspect) {
  56. Advice ret = world.concreteAdvice(AdviceKind.Softener,
  57. entry, null, 0, entry);
  58. ret.exceptionType = exceptionType;
  59. ret.concreteAspect = inAspect;
  60. // System.out.println("made ret: " + ret + " with " + exceptionType);
  61. return ret;
  62. }
  63. public Advice(AjAttribute.AdviceAttribute attribute, Pointcut pointcut, Member signature)
  64. {
  65. super(pointcut, attribute.getStart(), attribute.getEnd(), attribute.getSourceContext());
  66. this.attribute = attribute;
  67. this.kind = attribute.getKind(); // alias
  68. this.signature = signature;
  69. }
  70. public boolean match(Shadow shadow, World world) {
  71. if (super.match(shadow, world)) {
  72. if (shadow.getKind() == Shadow.ExceptionHandler) {
  73. if (kind.isAfter() || kind == AdviceKind.Around) {
  74. world.showMessage(IMessage.WARNING,
  75. WeaverMessages.format(WeaverMessages.ONLY_BEFORE_ON_HANDLER),
  76. getSourceLocation(), shadow.getSourceLocation());
  77. return false;
  78. }
  79. }
  80. if (hasExtraParameter() && kind == AdviceKind.AfterReturning) {
  81. return getExtraParameterType().isConvertableFrom(shadow.getReturnType(), world);
  82. } else if (kind == AdviceKind.PerTargetEntry) {
  83. return shadow.hasTarget();
  84. } else if (kind == AdviceKind.PerThisEntry) {
  85. return shadow.hasThis();
  86. } else if (kind == AdviceKind.Around) {
  87. if (shadow.getKind() == Shadow.PreInitialization) {
  88. world.showMessage(IMessage.ERROR,
  89. WeaverMessages.format(WeaverMessages.AROUND_ON_PREINIT),
  90. getSourceLocation(), shadow.getSourceLocation());
  91. return false;
  92. } else if (shadow.getKind() == Shadow.Initialization) {
  93. world.showMessage(IMessage.ERROR,
  94. WeaverMessages.format(WeaverMessages.AROUND_ON_INIT),
  95. getSourceLocation(), shadow.getSourceLocation());
  96. return false;
  97. } else if (shadow.getKind() == Shadow.StaticInitialization &&
  98. shadow.getEnclosingType().isInterface(world))
  99. {
  100. world.showMessage(IMessage.ERROR,
  101. WeaverMessages.format(WeaverMessages.AROUND_ON_INTERFACE_STATICINIT,shadow.getEnclosingType().getName()),
  102. getSourceLocation(), shadow.getSourceLocation());
  103. return false;
  104. } else {
  105. //System.err.println(getSignature().getReturnType() + " from " + shadow.getReturnType());
  106. if (getSignature().getReturnType() == ResolvedTypeX.VOID) {
  107. if (shadow.getReturnType() != ResolvedTypeX.VOID) {
  108. world.showMessage(IMessage.ERROR,
  109. WeaverMessages.format(WeaverMessages.NON_VOID_RETURN,shadow),
  110. getSourceLocation(), shadow.getSourceLocation());
  111. return false;
  112. }
  113. } else if (getSignature().getReturnType().equals(TypeX.OBJECT)) {
  114. return true;
  115. } else if(!shadow.getReturnType().isAssignableFrom(getSignature().getReturnType(), world)) {
  116. //System.err.println(this + ", " + sourceContext + ", " + start);
  117. world.showMessage(IMessage.ERROR,
  118. WeaverMessages.format(WeaverMessages.INCOMPATIBLE_RETURN_TYPE,shadow),
  119. getSourceLocation(), shadow.getSourceLocation());
  120. return false;
  121. }
  122. }
  123. }
  124. return true;
  125. } else {
  126. return false;
  127. }
  128. }
  129. // ----
  130. public AdviceKind getKind() {
  131. return kind;
  132. }
  133. public Member getSignature() {
  134. return signature;
  135. }
  136. public boolean hasExtraParameter() {
  137. return (getExtraParameterFlags() & ExtraArgument) != 0;
  138. }
  139. protected int getExtraParameterFlags() {
  140. return attribute.getExtraParameterFlags();
  141. }
  142. protected int getExtraParameterCount() {
  143. return countOnes(getExtraParameterFlags() & ParameterMask);
  144. }
  145. public static int countOnes(int bits) {
  146. int ret = 0;
  147. while (bits != 0) {
  148. if ((bits & 1) != 0) ret += 1;
  149. bits = bits >> 1;
  150. }
  151. return ret;
  152. }
  153. public int getBaseParameterCount() {
  154. return getSignature().getParameterTypes().length - getExtraParameterCount();
  155. }
  156. public String[] getBaseParameterNames(World world) {
  157. String[] allNames = getSignature().getParameterNames(world);
  158. int extras = getExtraParameterCount();
  159. if (extras == 0) return allNames;
  160. String[] result = new String[getBaseParameterCount()];
  161. for (int i = 0; i < result.length; i++) {
  162. result[i] = allNames[i];
  163. }
  164. return result;
  165. }
  166. public TypeX getExtraParameterType() {
  167. if (!hasExtraParameter()) return ResolvedTypeX.MISSING;
  168. return signature.getParameterTypes()[getBaseParameterCount()];
  169. }
  170. public TypeX getDeclaringAspect() {
  171. return signature.getDeclaringType();
  172. }
  173. protected String extraParametersToString() {
  174. if (getExtraParameterFlags() == 0) {
  175. return "";
  176. } else {
  177. return "(extraFlags: " + getExtraParameterFlags() + ")";
  178. }
  179. }
  180. public Pointcut getPointcut() {
  181. return pointcut;
  182. }
  183. // ----
  184. /** @param fromType is guaranteed to be a non-abstract aspect
  185. * @param perClause has been concretized at a higher level
  186. */
  187. public ShadowMunger concretize(ResolvedTypeX fromType, World world, PerClause clause) {
  188. // assert !fromType.isAbstract();
  189. Pointcut p = pointcut.concretize(fromType, signature.getArity(), this);
  190. if (clause != null) {
  191. Pointcut oldP = p;
  192. p = new AndPointcut(clause, p);
  193. p.copyLocationFrom(oldP);
  194. p.state = Pointcut.CONCRETE;
  195. }
  196. Advice munger = world.concreteAdvice(attribute, p, signature);
  197. munger.concreteAspect = fromType;
  198. //System.err.println("concretizing here " + p + " with clause " + clause);
  199. return munger;
  200. }
  201. // ---- from object
  202. public String toString() {
  203. return "("
  204. + getKind()
  205. + extraParametersToString()
  206. + ": "
  207. + pointcut
  208. + "->"
  209. + signature
  210. + ")";
  211. }
  212. public boolean equals(Object other) {
  213. if (! (other instanceof Advice)) return false;
  214. Advice o = (Advice) other;
  215. return o.attribute.equals(attribute)
  216. && o.pointcut.equals(pointcut)
  217. && o.signature.equals(signature);
  218. }
  219. private volatile int hashCode = 0;
  220. public int hashCode() {
  221. if (hashCode == 0) {
  222. int result = 17;
  223. result = 37*result + kind.hashCode();
  224. result = 37*result + pointcut.hashCode();
  225. if (signature != null) result = 37*result + signature.hashCode();
  226. hashCode = result;
  227. }
  228. return hashCode;
  229. }
  230. // ---- fields
  231. public static final int ExtraArgument = 1;
  232. public static final int ThisJoinPoint = 2;
  233. public static final int ThisJoinPointStaticPart = 4;
  234. public static final int ThisEnclosingJoinPointStaticPart = 8;
  235. public static final int ParameterMask = 0xf;
  236. public static final int CanInline = 0x40;
  237. // for testing only
  238. public void setLexicalPosition(int lexicalPosition) {
  239. start = lexicalPosition;
  240. }
  241. public ResolvedTypeX getConcreteAspect() {
  242. return concreteAspect;
  243. }
  244. }