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.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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 v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  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 (ResolvedMember rm : methods) {
  101. if (rm.getName().equals(factoryMethodName) && rm.getSignature().equals(factoryMethodSignature)) {
  102. return rm;
  103. }
  104. }
  105. return null;
  106. }
  107. public String getImplClassName() {
  108. return implClassName;
  109. }
  110. public void write(CompressingDataOutputStream s) throws IOException {
  111. kind.write(s);
  112. signature.write(s);
  113. aspect.write(s);
  114. s.writeUTF(implClassName==null?"":implClassName);
  115. typePattern.write(s);
  116. fieldType.write(s);
  117. s.writeUTF(factoryMethodName);
  118. s.writeUTF(factoryMethodSignature);
  119. s.writeInt(bitflags);
  120. }
  121. public static ResolvedTypeMunger readMethod(VersionedDataInputStream s, ISourceContext context, boolean isEnhanced)
  122. throws IOException {
  123. ResolvedMemberImpl signature = ResolvedMemberImpl.readResolvedMember(s, context);
  124. UnresolvedType aspect = UnresolvedType.read(s);
  125. String implClassName = s.readUTF();
  126. if (implClassName.equals("")) {
  127. implClassName = null;
  128. }
  129. TypePattern tp = TypePattern.read(s, context);
  130. MethodDelegateTypeMunger typeMunger = new MethodDelegateTypeMunger(signature, aspect, implClassName, tp);
  131. UnresolvedType fieldType = null;
  132. if (isEnhanced) {
  133. fieldType = UnresolvedType.read(s);
  134. } else {
  135. // a guess... that will work in a lot of cases
  136. fieldType = signature.getDeclaringType();
  137. }
  138. typeMunger.setFieldType(fieldType);
  139. if (isEnhanced) {
  140. typeMunger.factoryMethodName = s.readUTF();
  141. typeMunger.factoryMethodSignature = s.readUTF();
  142. typeMunger.bitflags = s.readInt();
  143. }
  144. return typeMunger;
  145. }
  146. /**
  147. * Match based on given type pattern, only classes can be matched
  148. *
  149. * @param matchType
  150. * @param aspectType
  151. * @return true if match
  152. */
  153. public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
  154. // match only on class
  155. if (matchType.isEnum() || matchType.isInterface() || matchType.isAnnotation()) {
  156. return false;
  157. }
  158. return typePattern.matchesStatically(matchType);
  159. }
  160. /**
  161. * Needed for reweavable
  162. *
  163. * @return true
  164. */
  165. public boolean changesPublicSignature() {
  166. return true;
  167. }
  168. public static class FieldHostTypeMunger extends ResolvedTypeMunger {
  169. private final UnresolvedType aspect;
  170. /**
  171. * Type pattern this munger applies to
  172. */
  173. private final TypePattern typePattern;
  174. /**
  175. * Construct a new type munger for @AspectJ ITD
  176. *
  177. * @param field
  178. * @param aspect
  179. * @param typePattern
  180. */
  181. public FieldHostTypeMunger(ResolvedMember field, UnresolvedType aspect, TypePattern typePattern) {
  182. super(FieldHost, field);
  183. this.aspect = aspect;
  184. this.typePattern = typePattern;
  185. }
  186. public boolean equals(Object other) {
  187. if (!(other instanceof FieldHostTypeMunger)) {
  188. return false;
  189. }
  190. FieldHostTypeMunger o = (FieldHostTypeMunger) other;
  191. return ((o.aspect == null) ? (aspect == null) : aspect.equals(o.aspect))
  192. && ((o.typePattern == null) ? (typePattern == null) : typePattern.equals(o.typePattern));
  193. }
  194. public int hashCode() {
  195. int result = 17;
  196. result = 37 * result + ((aspect == null) ? 0 : aspect.hashCode());
  197. result = 37 * result + ((typePattern == null) ? 0 : typePattern.hashCode());
  198. return result;
  199. }
  200. public void write(CompressingDataOutputStream s) throws IOException {
  201. kind.write(s);
  202. signature.write(s);
  203. aspect.write(s);
  204. typePattern.write(s);
  205. }
  206. public static ResolvedTypeMunger readFieldHost(VersionedDataInputStream s, ISourceContext context) throws IOException {
  207. ResolvedMemberImpl signature = ResolvedMemberImpl.readResolvedMember(s, context);
  208. UnresolvedType aspect = UnresolvedType.read(s);
  209. TypePattern tp = TypePattern.read(s, context);
  210. return new FieldHostTypeMunger(signature, aspect, tp);
  211. }
  212. /**
  213. * Match based on given type pattern, only classes can be matched
  214. *
  215. * @param matchType
  216. * @param aspectType
  217. * @return true if match
  218. */
  219. public boolean matches(ResolvedType matchType, ResolvedType aspectType) {
  220. // match only on class
  221. if (matchType.isEnum() || matchType.isInterface() || matchType.isAnnotation()) {
  222. return false;
  223. }
  224. return typePattern.matchesStatically(matchType);
  225. }
  226. public boolean changesPublicSignature() {
  227. return false;
  228. }
  229. public boolean existsToSupportShadowMunging() {
  230. return true;
  231. }
  232. }
  233. public void setFieldType(UnresolvedType fieldType) {
  234. this.fieldType = fieldType;
  235. }
  236. public boolean specifiesDelegateFactoryMethod() {
  237. return factoryMethodName != null && factoryMethodName.length() != 0;
  238. }
  239. public String getFactoryMethodName() {
  240. return factoryMethodName;
  241. }
  242. public String getFactoryMethodSignature() {
  243. return factoryMethodSignature;
  244. }
  245. public UnresolvedType getAspect() {
  246. return aspect;
  247. }
  248. public boolean existsToSupportShadowMunging() {
  249. return true;
  250. }
  251. public void tagAsReplacingExistingMethod() {
  252. bitflags |= REPLACING_EXISTING_METHOD;
  253. }
  254. public boolean isReplacingExistingMethod() {
  255. return (bitflags & REPLACING_EXISTING_METHOD) != 0;
  256. }
  257. }