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.

MethodDelegateTypeMunger.java 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. /* *******************************************************************
  2. * Copyright (c) 2005 Contributors.
  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://eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Alexandre Vasseur initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver;
  13. import java.io.IOException;
  14. import org.aspectj.weaver.patterns.TypePattern;
  15. /**
  16. * Type munger for annotation style ITD declare parents. with an interface AND an implementation. Given the aspect that has a field
  17. * public static Interface fieldI = ... // impl. we will weave in the Interface' methods and delegate to the aspect public static
  18. * field fieldI
  19. *
  20. * Note: this munger DOES NOT handles the interface addition to the target classes - a regular Parent kinded munger must be added in
  21. * coordination.
  22. */
  23. public class MethodDelegateTypeMunger extends ResolvedTypeMunger {
  24. private final UnresolvedType aspect;
  25. private UnresolvedType fieldType;
  26. /**
  27. * The mixin implementation (which should have a no-argument constructor)
  28. */
  29. private final String implClassName;
  30. /**
  31. * Type pattern this munger applies to
  32. */
  33. private final TypePattern typePattern;
  34. /**
  35. * When created to represent a mixed in method for @DeclareMixin, these hold the signature of the factory method
  36. */
  37. private String factoryMethodName;
  38. private String factoryMethodSignature;
  39. private int bitflags;
  40. private static final int REPLACING_EXISTING_METHOD = 0x001;
  41. /**
  42. * Construct a new type munger for @AspectJ ITD
  43. *
  44. * @param signature
  45. * @param aspect
  46. * @param implClassName
  47. * @param typePattern
  48. */
  49. public MethodDelegateTypeMunger(ResolvedMember signature, UnresolvedType aspect, String implClassName, TypePattern typePattern) {
  50. super(MethodDelegate2, signature);
  51. this.aspect = aspect;
  52. this.typePattern = typePattern;
  53. this.implClassName = implClassName;
  54. factoryMethodName = "";
  55. factoryMethodSignature = "";
  56. }
  57. public MethodDelegateTypeMunger(ResolvedMember signature, UnresolvedType aspect, String implClassName, TypePattern typePattern,
  58. String factoryMethodName, String factoryMethodSignature) {
  59. super(MethodDelegate2, signature);
  60. this.aspect = aspect;
  61. this.typePattern = typePattern;
  62. this.implClassName = implClassName;
  63. this.factoryMethodName = factoryMethodName;
  64. this.factoryMethodSignature = factoryMethodSignature;
  65. }
  66. public boolean equals(Object other) {
  67. if (!(other instanceof MethodDelegateTypeMunger)) {
  68. return false;
  69. }
  70. MethodDelegateTypeMunger o = (MethodDelegateTypeMunger) other;
  71. return ((o.aspect == null) ? (aspect == null) : aspect.equals(o.aspect))
  72. && ((o.typePattern == null) ? (typePattern == null) : typePattern.equals(o.typePattern))
  73. && ((o.implClassName == null) ? (implClassName == null) : implClassName.equals(o.implClassName))
  74. && ((o.fieldType == null ? (fieldType == null) : fieldType.equals(o.fieldType)))
  75. && ((o.factoryMethodName == null) ? (factoryMethodName == null) : factoryMethodName.equals(o.factoryMethodName))
  76. && ((o.factoryMethodSignature == null) ? (factoryMethodSignature == null) : factoryMethodSignature
  77. .equals(o.factoryMethodSignature)) && o.bitflags == bitflags;
  78. }
  79. private volatile int hashCode = 0;
  80. public int hashCode() {
  81. if (hashCode == 0) {
  82. int result = 17;
  83. result = 37 * result + ((aspect == null) ? 0 : aspect.hashCode());
  84. result = 37 * result + ((typePattern == null) ? 0 : typePattern.hashCode());
  85. result = 37 * result + ((implClassName == null) ? 0 : implClassName.hashCode());
  86. result = 37 * result + ((fieldType == null) ? 0 : fieldType.hashCode());
  87. result = 37 * result + ((factoryMethodName == null) ? 0 : factoryMethodName.hashCode());
  88. result = 37 * result + ((factoryMethodSignature == null) ? 0 : factoryMethodSignature.hashCode());
  89. result = 37 * result + bitflags;
  90. hashCode = result;
  91. }
  92. return hashCode;
  93. }
  94. public ResolvedMember getDelegate(ResolvedType targetType) {
  95. return AjcMemberMaker.itdAtDeclareParentsField(targetType, fieldType, aspect);
  96. }
  97. public ResolvedMember getDelegateFactoryMethod(World w) {
  98. ResolvedType aspectType = w.resolve(aspect);
  99. ResolvedMember[] methods = aspectType.getDeclaredMethods();
  100. for (int i = 0; i < methods.length; i++) {
  101. ResolvedMember rm = methods[i];
  102. if (rm.getName().equals(factoryMethodName) && rm.getSignature().equals(factoryMethodSignature)) {
  103. return rm;
  104. }
  105. }
  106. return null;
  107. }
  108. public String getImplClassName() {
  109. return implClassName;
  110. }
  111. public void write(CompressingDataOutputStream s) throws IOException {
  112. kind.write(s);
  113. signature.write(s);
  114. aspect.write(s);
  115. s.writeUTF(implClassName);
  116. typePattern.write(s);
  117. fieldType.write(s);
  118. s.writeUTF(factoryMethodName);
  119. s.writeUTF(factoryMethodSignature);
  120. s.writeInt(bitflags);
  121. }
  122. public static ResolvedTypeMunger readMethod(VersionedDataInputStream s, ISourceContext context, boolean isEnhanced)
  123. throws IOException {
  124. ResolvedMemberImpl signature = ResolvedMemberImpl.readResolvedMember(s, context);
  125. UnresolvedType aspect = UnresolvedType.read(s);
  126. String implClassName = s.readUTF();
  127. TypePattern tp = TypePattern.read(s, context);
  128. MethodDelegateTypeMunger typeMunger = new MethodDelegateTypeMunger(signature, aspect, implClassName, tp);
  129. UnresolvedType fieldType = null;
  130. if (isEnhanced) {
  131. fieldType = UnresolvedType.read(s);
  132. } else {
  133. // a guess... that will work in a lot of cases
  134. fieldType = signature.getDeclaringType();
  135. }
  136. typeMunger.setFieldType(fieldType);
  137. if (isEnhanced) {
  138. typeMunger.factoryMethodName = s.readUTF();
  139. typeMunger.factoryMethodSignature = s.readUTF();
  140. typeMunger.bitflags = s.readInt();
  141. }
  142. return typeMunger;
  143. }
  144. /**
  145. * Match based on given type pattern, only classes can be matched
  146. *
  147. * @param matchType
  148. * @param aspectType
  149. * @return true if match
  150. */
  151. public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
  152. // match only on class
  153. if (matchType.isEnum() || matchType.isInterface() || matchType.isAnnotation()) {
  154. return false;
  155. }
  156. return typePattern.matchesStatically(matchType);
  157. }
  158. /**
  159. * Needed for reweavable
  160. *
  161. * @return true
  162. */
  163. public boolean changesPublicSignature() {
  164. return true;
  165. }
  166. public static class FieldHostTypeMunger extends ResolvedTypeMunger {
  167. private final UnresolvedType aspect;
  168. /**
  169. * Type pattern this munger applies to
  170. */
  171. private final TypePattern typePattern;
  172. /**
  173. * Construct a new type munger for @AspectJ ITD
  174. *
  175. * @param field
  176. * @param aspect
  177. * @param typePattern
  178. */
  179. public FieldHostTypeMunger(ResolvedMember field, UnresolvedType aspect, TypePattern typePattern) {
  180. super(FieldHost, field);
  181. this.aspect = aspect;
  182. this.typePattern = typePattern;
  183. }
  184. public boolean equals(Object other) {
  185. if (!(other instanceof FieldHostTypeMunger)) {
  186. return false;
  187. }
  188. FieldHostTypeMunger o = (FieldHostTypeMunger) other;
  189. return ((o.aspect == null) ? (aspect == null) : aspect.equals(o.aspect))
  190. && ((o.typePattern == null) ? (typePattern == null) : typePattern.equals(o.typePattern));
  191. }
  192. public int hashCode() {
  193. int result = 17;
  194. result = 37 * result + ((aspect == null) ? 0 : aspect.hashCode());
  195. result = 37 * result + ((typePattern == null) ? 0 : typePattern.hashCode());
  196. return result;
  197. }
  198. public void write(CompressingDataOutputStream s) throws IOException {
  199. kind.write(s);
  200. signature.write(s);
  201. aspect.write(s);
  202. typePattern.write(s);
  203. }
  204. public static ResolvedTypeMunger readFieldHost(VersionedDataInputStream s, ISourceContext context) throws IOException {
  205. ResolvedMemberImpl signature = ResolvedMemberImpl.readResolvedMember(s, context);
  206. UnresolvedType aspect = UnresolvedType.read(s);
  207. TypePattern tp = TypePattern.read(s, context);
  208. return new FieldHostTypeMunger(signature, aspect, tp);
  209. }
  210. /**
  211. * Match based on given type pattern, only classes can be matched
  212. *
  213. * @param matchType
  214. * @param aspectType
  215. * @return true if match
  216. */
  217. public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
  218. // match only on class
  219. if (matchType.isEnum() || matchType.isInterface() || matchType.isAnnotation()) {
  220. return false;
  221. }
  222. return typePattern.matchesStatically(matchType);
  223. }
  224. public boolean changesPublicSignature() {
  225. return false;
  226. }
  227. public boolean existsToSupportShadowMunging() {
  228. return true;
  229. }
  230. }
  231. public void setFieldType(UnresolvedType fieldType) {
  232. this.fieldType = fieldType;
  233. }
  234. public boolean specifiesDelegateFactoryMethod() {
  235. return factoryMethodName != null && factoryMethodName.length() != 0;
  236. }
  237. public String getFactoryMethodName() {
  238. return factoryMethodName;
  239. }
  240. public String getFactoryMethodSignature() {
  241. return factoryMethodSignature;
  242. }
  243. public UnresolvedType getAspect() {
  244. return aspect;
  245. }
  246. public boolean existsToSupportShadowMunging() {
  247. return true;
  248. }
  249. public void tagAsReplacingExistingMethod() {
  250. bitflags |= REPLACING_EXISTING_METHOD;
  251. }
  252. public boolean isReplacingExistingMethod() {
  253. return (bitflags & REPLACING_EXISTING_METHOD) != 0;
  254. }
  255. }