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 7.0KB

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