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.

HasMemberTypePattern.java 6.3KB

15 年之前
15 年之前
15 年之前
15 年之前
12 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
12 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
12 年之前
15 年之前
12 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
12 年之前
15 年之前
14 年之前
15 年之前
14 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
14 年之前
15 年之前
14 年之前
14 年之前
15 年之前
15 年之前
14 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
14 年之前
15 年之前
15 年之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  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. * Adrian Colyer Initial implementation
  11. * Nieraj Singh
  12. * ******************************************************************/
  13. package org.aspectj.weaver.patterns;
  14. import java.io.IOException;
  15. import java.lang.reflect.Modifier;
  16. import java.util.Iterator;
  17. import java.util.List;
  18. import java.util.Map;
  19. import org.aspectj.bridge.IMessage;
  20. import org.aspectj.util.FuzzyBoolean;
  21. import org.aspectj.weaver.CompressingDataOutputStream;
  22. import org.aspectj.weaver.ConcreteTypeMunger;
  23. import org.aspectj.weaver.ISourceContext;
  24. import org.aspectj.weaver.Member;
  25. import org.aspectj.weaver.ResolvedMember;
  26. import org.aspectj.weaver.ResolvedType;
  27. import org.aspectj.weaver.UnresolvedType;
  28. import org.aspectj.weaver.VersionedDataInputStream;
  29. import org.aspectj.weaver.WeaverMessages;
  30. import org.aspectj.weaver.World;
  31. /**
  32. * @author colyer Matches types that have a certain method / constructor / field Currently only allowed within declare parents and
  33. * declare @type
  34. */
  35. public class HasMemberTypePattern extends TypePattern {
  36. private SignaturePattern signaturePattern;
  37. public HasMemberTypePattern(SignaturePattern aSignaturePattern) {
  38. super(false, false);
  39. this.signaturePattern = aSignaturePattern;
  40. }
  41. @Override
  42. protected boolean matchesExactly(ResolvedType type) {
  43. if (signaturePattern.getKind() == Member.FIELD) {
  44. return hasField(type);
  45. } else {
  46. return hasMethod(type);
  47. }
  48. }
  49. public ISignaturePattern getSignaturePattern() {
  50. return signaturePattern;
  51. }
  52. private final static String declareAtPrefix = "ajc$declare_at";
  53. private boolean hasField(ResolvedType type) {
  54. // TODO what about ITDs
  55. World world = type.getWorld();
  56. for (Iterator<ResolvedMember> iter = type.getFields(); iter.hasNext();) {
  57. Member field = iter.next();
  58. if (field.getName().startsWith(declareAtPrefix)) {
  59. continue;
  60. }
  61. if (signaturePattern.matches(field, type.getWorld(), false)) {
  62. if (field.getDeclaringType().resolve(world) != type) {
  63. if (Modifier.isPrivate(field.getModifiers())) {
  64. continue;
  65. }
  66. }
  67. return true;
  68. }
  69. }
  70. return false;
  71. }
  72. protected boolean hasMethod(ResolvedType type) {
  73. // TODO what about ITDs
  74. World world = type.getWorld();
  75. for (Iterator<ResolvedMember> iter = type.getMethods(true, true); iter.hasNext();) {
  76. Member method = iter.next();
  77. if (method.getName().startsWith(declareAtPrefix)) {
  78. continue;
  79. }
  80. if (signaturePattern.matches(method, type.getWorld(), false)) {
  81. ResolvedType declaringType = method.getDeclaringType().resolve(world);
  82. if (declaringType != type) {
  83. if (Modifier.isPrivate(method.getModifiers())) {
  84. continue;
  85. }
  86. }
  87. // J9: Object.finalize() is marked Deprecated it seems... triggers unhelpful messages
  88. if (method.getName().equals("finalize") && declaringType.equals(ResolvedType.OBJECT)
  89. && (signaturePattern.getAnnotationPattern() instanceof ExactAnnotationTypePattern)
  90. && ((ExactAnnotationTypePattern)signaturePattern.getAnnotationPattern()).getAnnotationType().getSignature().equals("Ljava/lang/Deprecated;")) {
  91. continue;
  92. }
  93. return true;
  94. }
  95. }
  96. // try itds before we give up (this doesnt find annotations - the signature returned may not include them)
  97. List<ConcreteTypeMunger> mungers = type.getInterTypeMungersIncludingSupers();
  98. for (ConcreteTypeMunger munger : mungers) {
  99. Member member = munger.getSignature();
  100. if (signaturePattern.matches(member, type.getWorld(), false)) {
  101. if (!Modifier.isPublic(member.getModifiers())) {
  102. continue;
  103. }
  104. return true;
  105. }
  106. }
  107. return false;
  108. }
  109. @Override
  110. protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
  111. return matchesExactly(type);
  112. }
  113. @Override
  114. protected boolean matchesArray(UnresolvedType type) {
  115. return true;
  116. }
  117. @Override
  118. public FuzzyBoolean matchesInstanceof(ResolvedType type) {
  119. throw new UnsupportedOperationException("hasmethod/field do not support instanceof matching");
  120. }
  121. @Override
  122. public TypePattern parameterizeWith(Map typeVariableMap, World w) {
  123. HasMemberTypePattern ret = new HasMemberTypePattern(signaturePattern.parameterizeWith(typeVariableMap, w));
  124. ret.copyLocationFrom(this);
  125. return ret;
  126. }
  127. @Override
  128. public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) {
  129. // check that hasmember type patterns are allowed!
  130. if (!scope.getWorld().isHasMemberSupportEnabled()) {
  131. String msg = WeaverMessages.format(WeaverMessages.HAS_MEMBER_NOT_ENABLED, this.toString());
  132. scope.message(IMessage.ERROR, this, msg);
  133. }
  134. signaturePattern.resolveBindings(scope, bindings);
  135. return this;
  136. }
  137. @Override
  138. public boolean equals(Object obj) {
  139. if (!(obj instanceof HasMemberTypePattern)) {
  140. return false;
  141. }
  142. if (this == obj) {
  143. return true;
  144. }
  145. return signaturePattern.equals(((HasMemberTypePattern) obj).signaturePattern);
  146. }
  147. @Override
  148. public int hashCode() {
  149. return signaturePattern.hashCode();
  150. }
  151. @Override
  152. public String toString() {
  153. StringBuilder buff = new StringBuilder();
  154. if (signaturePattern.getKind() == Member.FIELD) {
  155. buff.append("hasfield(");
  156. } else {
  157. buff.append("hasmethod(");
  158. }
  159. buff.append(signaturePattern.toString());
  160. buff.append(")");
  161. return buff.toString();
  162. }
  163. @Override
  164. public void write(CompressingDataOutputStream s) throws IOException {
  165. s.writeByte(TypePattern.HAS_MEMBER);
  166. signaturePattern.write(s);
  167. writeLocation(s);
  168. }
  169. public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  170. SignaturePattern sp = SignaturePattern.read(s, context);
  171. HasMemberTypePattern ret = new HasMemberTypePattern(sp);
  172. ret.readLocation(context, s);
  173. return ret;
  174. }
  175. @Override
  176. public Object accept(PatternNodeVisitor visitor, Object data) {
  177. return visitor.visit(this, data);
  178. }
  179. public Object traverse(PatternNodeVisitor visitor, Object data) {
  180. Object ret = accept(visitor, data);
  181. if (this.signaturePattern != null)
  182. this.signaturePattern.traverse(visitor, ret);
  183. return ret;
  184. }
  185. }