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.

Shadow.java 7.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  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. * Xerox/PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import java.io.*;
  14. import java.lang.reflect.Modifier;
  15. import java.util.*;
  16. import org.apache.bcel.Constants;
  17. import org.apache.bcel.classfile.Field;
  18. import org.aspectj.weaver.ast.Var;
  19. import org.aspectj.weaver.patterns.IScope;
  20. import org.aspectj.bridge.*;
  21. import org.aspectj.bridge.SourceLocation;
  22. import org.aspectj.lang.JoinPoint;
  23. import org.aspectj.util.*;
  24. /*
  25. * The superclass of anything representing a the shadow of a join point. A shadow represents
  26. * some bit of code, and encompasses both entry and exit from that code. All shadows have a kind
  27. * and a signature.
  28. */
  29. public abstract class Shadow {
  30. private final Kind kind;
  31. private final Member signature;
  32. protected List mungers = new ArrayList(1);
  33. // ----
  34. protected Shadow(Kind kind, Member signature) {
  35. this.kind = kind;
  36. this.signature = signature;
  37. }
  38. // ----
  39. public abstract World getIWorld();
  40. public final boolean hasTarget() {
  41. return !(getSignature().isStatic() || (getKind() == ConstructorCall)
  42. || (getKind() == PreInitialization));
  43. }
  44. public final TypeX getTargetType() {
  45. if (!hasTarget()) return ResolvedTypeX.MISSING;
  46. return getSignature().getDeclaringType();
  47. }
  48. public TypeX[] getArgTypes() {
  49. if (getKind() == FieldSet) return new TypeX[] { getSignature().getReturnType() };
  50. return getSignature().getParameterTypes();
  51. }
  52. public TypeX getArgType(int arg) {
  53. if (getKind() == FieldSet) return getSignature().getReturnType();
  54. return getSignature().getParameterTypes()[arg];
  55. }
  56. public int getArgCount() {
  57. if (getKind() == FieldSet) return 1;
  58. return getSignature()
  59. .getParameterTypes().length;
  60. }
  61. public abstract boolean hasThis();
  62. public abstract TypeX getThisType();
  63. public abstract TypeX getEnclosingType();
  64. public abstract Var getThisVar();
  65. public abstract Var getTargetVar();
  66. public abstract Var getArgVar(int i);
  67. public abstract Var getThisJoinPointVar();
  68. public abstract Var getThisJoinPointStaticPartVar();
  69. public abstract Var getThisEnclosingJoinPointStaticPartVar();
  70. public abstract Member getEnclosingCodeSignature();
  71. /** returns the kind of shadow this is, representing what happens under this shadow
  72. */
  73. public Kind getKind() {
  74. return kind;
  75. }
  76. /** returns the signature of the thing under this shadow
  77. */
  78. public Member getSignature() {
  79. return signature;
  80. }
  81. public TypeX getReturnType() {
  82. if (kind == ConstructorCall) return getSignature().getDeclaringType();
  83. else if (kind == FieldSet) return ResolvedTypeX.VOID;
  84. return getSignature().getReturnType();
  85. }
  86. /**
  87. * These names are the ones that will be returned by thisJoinPoint.getKind()
  88. * Those need to be documented somewhere
  89. */
  90. public static final Kind MethodCall = new Kind(JoinPoint.METHOD_CALL, 1, true);
  91. public static final Kind ConstructorCall = new Kind(JoinPoint.CONSTRUCTOR_CALL, 2, true);
  92. public static final Kind MethodExecution = new Kind(JoinPoint.METHOD_EXECUTION, 3, false);
  93. public static final Kind ConstructorExecution = new Kind(JoinPoint.CONSTRUCTOR_EXECUTION, 4, false);
  94. public static final Kind FieldGet = new Kind(JoinPoint.FIELD_GET, 5, true);
  95. public static final Kind FieldSet = new Kind(JoinPoint.FIELD_SET, 6, true);
  96. public static final Kind StaticInitialization = new Kind(JoinPoint.STATICINITIALIZATION, 7, false);
  97. public static final Kind PreInitialization = new Kind(JoinPoint.PREINTIALIZATION, 8, false);
  98. public static final Kind AdviceExecution = new Kind(JoinPoint.ADVICE_EXECUTION, 9, false);
  99. public static final Kind Initialization = new Kind(JoinPoint.INITIALIZATION, 10, false);
  100. public static final Kind ExceptionHandler = new Kind(JoinPoint.EXCEPTION_HANDLER, 11, true);
  101. /** A type-safe enum representing the kind of shadows
  102. */
  103. public static final class Kind extends TypeSafeEnum {
  104. private boolean argsOnStack;
  105. public Kind(String name, int key, boolean argsOnStack) {
  106. super(name, key);
  107. this.argsOnStack = argsOnStack;
  108. }
  109. public String toLegalJavaIdentifier() {
  110. return getName().replace('-', '_');
  111. }
  112. public boolean argsOnStack() {
  113. return argsOnStack;
  114. }
  115. // !!! this is false for handlers!
  116. public boolean allowsExtraction() {
  117. return true;
  118. }
  119. public String getSimpleName() {
  120. int dash = getName().lastIndexOf('-');
  121. if (dash == -1) return getName();
  122. else return getName().substring(dash+1);
  123. }
  124. public static Kind read(DataInputStream s) throws IOException {
  125. int key = s.readByte();
  126. switch(key) {
  127. case 1: return MethodCall;
  128. case 2: return ConstructorCall;
  129. case 3: return MethodExecution;
  130. case 4: return ConstructorExecution;
  131. case 5: return FieldGet;
  132. case 6: return FieldSet;
  133. case 7: return StaticInitialization;
  134. case 8: return PreInitialization;
  135. case 9: return AdviceExecution;
  136. case 10: return Initialization;
  137. case 11: return ExceptionHandler;
  138. }
  139. throw new BCException("unknown kind: " + key);
  140. }
  141. }
  142. public void addMunger(ShadowMunger munger) {
  143. this.mungers.add(munger);
  144. }
  145. public final void implement() {
  146. sortMungers();
  147. if (mungers == null) return;
  148. prepareForMungers();
  149. implementMungers();
  150. }
  151. private void sortMungers() {
  152. List sorted = PartialOrder.sort(mungers);
  153. if (sorted == null) {
  154. // this means that we have circular dependencies
  155. for (Iterator i = mungers.iterator(); i.hasNext(); ) {
  156. ShadowMunger m = (ShadowMunger)i.next();
  157. getIWorld().getMessageHandler().handleMessage(
  158. MessageUtil.error("circular dependency at " + this, m.getSourceLocation()));
  159. }
  160. }
  161. mungers = sorted;
  162. }
  163. /** Prepare the shadow for implementation. After this is done, the shadow
  164. * should be in such a position that each munger simply needs to be implemented.
  165. */
  166. protected void prepareForMungers() {
  167. throw new RuntimeException("Generic shadows cannot be prepared");
  168. }
  169. /** Actually implement the (non-empty) mungers associated with this shadow */
  170. private void implementMungers() {
  171. World world = getIWorld();
  172. for (Iterator iter = mungers.iterator(); iter.hasNext();) {
  173. ShadowMunger munger = (ShadowMunger) iter.next();
  174. munger.implementOn(this);
  175. if (world.getModel() != null) {
  176. System.err.println("munger: " + munger + " on " + this);
  177. AsmAdaptor.noteMunger(world.getModel(), this, munger);
  178. }
  179. }
  180. }
  181. public String makeReflectiveFactoryString() {
  182. return null; //XXX
  183. }
  184. public abstract SourceLocation getSourceLocation();
  185. // ---- utility
  186. public String toString() {
  187. return getKind() + "(" + getSignature() + ")"; // + getSourceLines();
  188. }
  189. // ---- type access methods
  190. }