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.

ExactTypePattern.java 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  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.patterns;
  13. import java.io.DataInputStream;
  14. import java.io.DataOutputStream;
  15. import java.io.IOException;
  16. import java.util.HashMap;
  17. import java.util.Map;
  18. import org.aspectj.util.FuzzyBoolean;
  19. import org.aspectj.weaver.AjAttribute;
  20. import org.aspectj.weaver.BCException;
  21. import org.aspectj.weaver.ISourceContext;
  22. import org.aspectj.weaver.ResolvedTypeX;
  23. import org.aspectj.weaver.TypeX;
  24. import org.aspectj.weaver.VersionedDataInputStream;
  25. public class ExactTypePattern extends TypePattern {
  26. protected TypeX type;
  27. public static final Map primitiveTypesMap;
  28. public static final Map boxedPrimitivesMap;
  29. private static final Map boxedTypesMap;
  30. static {
  31. primitiveTypesMap = new HashMap();
  32. primitiveTypesMap.put("int",int.class);
  33. primitiveTypesMap.put("short",short.class);
  34. primitiveTypesMap.put("long",long.class);
  35. primitiveTypesMap.put("byte",byte.class);
  36. primitiveTypesMap.put("char",char.class);
  37. primitiveTypesMap.put("float",float.class);
  38. primitiveTypesMap.put("double",double.class);
  39. boxedPrimitivesMap = new HashMap();
  40. boxedPrimitivesMap.put("java.lang.Integer",Integer.class);
  41. boxedPrimitivesMap.put("java.lang.Short",Short.class);
  42. boxedPrimitivesMap.put("java.lang.Long",Long.class);
  43. boxedPrimitivesMap.put("java.lang.Byte",Byte.class);
  44. boxedPrimitivesMap.put("java.lang.Character",Character.class);
  45. boxedPrimitivesMap.put("java.lang.Float",Float.class);
  46. boxedPrimitivesMap.put("java.lang.Double",Double.class);
  47. boxedTypesMap = new HashMap();
  48. boxedTypesMap.put("int",Integer.class);
  49. boxedTypesMap.put("short",Short.class);
  50. boxedTypesMap.put("long",Long.class);
  51. boxedTypesMap.put("byte",Byte.class);
  52. boxedTypesMap.put("char",Character.class);
  53. boxedTypesMap.put("float",Float.class);
  54. boxedTypesMap.put("double",Double.class);
  55. }
  56. public ExactTypePattern(TypeX type, boolean includeSubtypes,boolean isVarArgs) {
  57. super(includeSubtypes,isVarArgs);
  58. this.type = type;
  59. }
  60. /* (non-Javadoc)
  61. * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
  62. */
  63. protected boolean couldEverMatchSameTypesAs(TypePattern other) {
  64. if (super.couldEverMatchSameTypesAs(other)) return true;
  65. // false is necessary but not sufficient
  66. TypeX otherType = other.getExactType();
  67. if (otherType != ResolvedTypeX.MISSING) {
  68. return type.equals(otherType);
  69. }
  70. if (other instanceof WildTypePattern) {
  71. WildTypePattern owtp = (WildTypePattern) other;
  72. String yourSimpleNamePrefix = owtp.namePatterns[0].maybeGetSimpleName();
  73. if (yourSimpleNamePrefix != null) {
  74. return (type.getName().startsWith(yourSimpleNamePrefix));
  75. }
  76. }
  77. return true;
  78. }
  79. protected boolean matchesExactly(ResolvedTypeX matchType) {
  80. boolean typeMatch = this.type.equals(matchType);
  81. boolean annMatch = this.annotationPattern.matches(matchType).alwaysTrue();
  82. return (typeMatch && annMatch);
  83. }
  84. public TypeX getType() { return type; }
  85. public FuzzyBoolean matchesInstanceof(ResolvedTypeX matchType) {
  86. // in our world, Object is assignable from anything
  87. if (type.equals(ResolvedTypeX.OBJECT))
  88. return FuzzyBoolean.YES.and(annotationPattern.matches(matchType));
  89. if (type.isAssignableFrom(matchType, matchType.getWorld())) {
  90. return FuzzyBoolean.YES.and(annotationPattern.matches(matchType));
  91. }
  92. // fix for PR 64262 - shouldn't try to coerce primitives
  93. if (type.isPrimitive()) {
  94. return FuzzyBoolean.NO;
  95. } else {
  96. return matchType.isCoerceableFrom(type) ? FuzzyBoolean.MAYBE : FuzzyBoolean.NO;
  97. }
  98. }
  99. public boolean matchesExactly(Class matchType) {
  100. try {
  101. Class toMatchAgainst = getClassFor(type.getName());
  102. return matchType == toMatchAgainst;
  103. } catch (ClassNotFoundException cnfEx) {
  104. return false;
  105. }
  106. }
  107. public FuzzyBoolean matchesInstanceof(Class matchType) {
  108. if (matchType.equals(Object.class)) return FuzzyBoolean.YES;
  109. try {
  110. String typeName = type.getName();
  111. Class toMatchAgainst = getClassFor(typeName);
  112. FuzzyBoolean ret = FuzzyBoolean.fromBoolean(toMatchAgainst.isAssignableFrom(matchType));
  113. if (ret == FuzzyBoolean.NO) {
  114. if (boxedTypesMap.containsKey(typeName)) {
  115. // try again with 'boxed' alternative
  116. toMatchAgainst = (Class) boxedTypesMap.get(typeName);
  117. ret = FuzzyBoolean.fromBoolean(toMatchAgainst.isAssignableFrom(matchType));
  118. }
  119. }
  120. return ret;
  121. } catch (ClassNotFoundException cnfEx) {
  122. return FuzzyBoolean.NO;
  123. }
  124. }
  125. /**
  126. * Return YES if any subtype of the static type would match,
  127. * MAYBE if some subtypes could match
  128. * NO if there could never be a match
  129. * @param staticType
  130. * @return
  131. */
  132. public FuzzyBoolean willMatchDynamically(Class staticType) {
  133. if (matchesExactly(staticType)) return FuzzyBoolean.YES;
  134. if (matchesInstanceof(staticType) == FuzzyBoolean.YES) return FuzzyBoolean.YES;
  135. try {
  136. String typeName = type.getName();
  137. Class toMatchAgainst = getClassFor(typeName);
  138. if (toMatchAgainst.isInterface()) return FuzzyBoolean.MAYBE;
  139. if (staticType.isAssignableFrom(toMatchAgainst)) return FuzzyBoolean.MAYBE;
  140. return FuzzyBoolean.NO;
  141. } catch (ClassNotFoundException cnfEx) {
  142. return FuzzyBoolean.NO;
  143. }
  144. }
  145. private Class getClassFor(String typeName) throws ClassNotFoundException {
  146. Class ret = null;
  147. ret = (Class) primitiveTypesMap.get(typeName);
  148. if (ret == null) ret = Class.forName(typeName);
  149. return ret;
  150. }
  151. public boolean equals(Object other) {
  152. if (!(other instanceof ExactTypePattern)) return false;
  153. ExactTypePattern o = (ExactTypePattern)other;
  154. if (includeSubtypes != o.includeSubtypes) return false;
  155. if (isVarArgs != o.isVarArgs) return false;
  156. return (o.type.equals(this.type) && o.annotationPattern.equals(this.annotationPattern));
  157. }
  158. public int hashCode() {
  159. int result = 17;
  160. result = 37*result + type.hashCode();
  161. result = 37*result + annotationPattern.hashCode();
  162. return result;
  163. }
  164. private static final byte EXACT_VERSION = 1; // rev if changed
  165. public void write(DataOutputStream out) throws IOException {
  166. out.writeByte(TypePattern.EXACT);
  167. out.writeByte(EXACT_VERSION);
  168. type.write(out);
  169. out.writeBoolean(includeSubtypes);
  170. out.writeBoolean(isVarArgs);
  171. annotationPattern.write(out);
  172. writeLocation(out);
  173. }
  174. public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  175. if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
  176. return readTypePattern150(s,context);
  177. } else {
  178. return readTypePatternOldStyle(s,context);
  179. }
  180. }
  181. public static TypePattern readTypePattern150(VersionedDataInputStream s, ISourceContext context) throws IOException {
  182. byte version = s.readByte();
  183. if (version > EXACT_VERSION) throw new BCException("ExactTypePattern was written by a more recent version of AspectJ");
  184. TypePattern ret = new ExactTypePattern(TypeX.read(s), s.readBoolean(), s.readBoolean());
  185. ret.setAnnotationTypePattern(AnnotationTypePattern.read(s,context));
  186. ret.readLocation(context, s);
  187. return ret;
  188. }
  189. public static TypePattern readTypePatternOldStyle(DataInputStream s, ISourceContext context) throws IOException {
  190. TypePattern ret = new ExactTypePattern(TypeX.read(s), s.readBoolean(),false);
  191. ret.readLocation(context, s);
  192. return ret;
  193. }
  194. public String toString() {
  195. StringBuffer buff = new StringBuffer();
  196. if (annotationPattern != AnnotationTypePattern.ANY) {
  197. buff.append('(');
  198. buff.append(annotationPattern.toString());
  199. buff.append(' ');
  200. }
  201. buff.append(type.toString());
  202. if (includeSubtypes) buff.append('+');
  203. // Note, there will be a rogue [] in the pattern here in the case of varargs ...
  204. if (isVarArgs) buff.append("...");
  205. if (annotationPattern != AnnotationTypePattern.ANY) {
  206. buff.append(')');
  207. }
  208. return buff.toString();
  209. }
  210. public TypePattern resolveBindings(IScope scope, Bindings bindings,
  211. boolean allowBinding, boolean requireExactType)
  212. {
  213. throw new BCException("trying to re-resolve");
  214. }
  215. public TypePattern resolveBindingsFromRTTI(boolean allowBinding, boolean requireExactType) {
  216. throw new IllegalStateException("trying to re-resolve");
  217. }
  218. }