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.

UnresolvedType.java 30KB

15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
12 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
12 年之前
12 年之前
12 年之前
12 年之前
14 年之前
12 年之前
14 年之前
15 年之前
14 年之前
12 年之前
12 年之前
15 年之前
15 年之前
14 年之前
15 年之前
15 年之前
15 年之前
15 年之前
14 年之前
15 年之前
15 年之前
14 年之前
15 年之前
14 年之前
15 年之前
15 年之前
14 年之前
15 年之前
15 年之前
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967
  1. /* *******************************************************************
  2. * Copyright (c) 2002,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://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * Andy Clement start of generics upgrade...
  12. * Adrian Colyer - overhaul
  13. * ******************************************************************/
  14. package org.aspectj.weaver;
  15. import java.io.DataInputStream;
  16. import java.io.IOException;
  17. import java.util.Map;
  18. import org.aspectj.util.GenericSignature;
  19. import org.aspectj.util.GenericSignature.ClassSignature;
  20. import org.aspectj.util.GenericSignatureParser;
  21. import org.aspectj.weaver.tools.Traceable;
  22. /**
  23. * A UnresolvedType represents a type to the weaver. UnresolvedTypes are resolved in some World (a type repository). When a
  24. * UnresolvedType is resolved it turns into a ResolvedType which may be a primitive type, or a ReferenceType. ReferenceTypes may
  25. * refer to simple, generic, parameterized or type-variable based reference types. A ReferenceType is backed by a delegate that
  26. * provides information about the type based on some repository (for example an Eclipse based delegate, a bytecode based delegate or
  27. * a reflection based delegate).
  28. * <p>
  29. * Every UnresolvedType has a signature, the unique key for the type in the world.
  30. */
  31. public class UnresolvedType implements Traceable, TypeVariableDeclaringElement {
  32. // common type structures
  33. public static final UnresolvedType[] NONE = new UnresolvedType[0];
  34. public static final UnresolvedType OBJECT = forSignature("Ljava/lang/Object;");
  35. public static final UnresolvedType OBJECTARRAY = forSignature("[Ljava/lang/Object;");
  36. public static final UnresolvedType CLONEABLE = forSignature("Ljava/lang/Cloneable;");
  37. public static final UnresolvedType SERIALIZABLE = forSignature("Ljava/io/Serializable;");
  38. public static final UnresolvedType THROWABLE = forSignature("Ljava/lang/Throwable;");
  39. public static final UnresolvedType RUNTIME_EXCEPTION = forSignature("Ljava/lang/RuntimeException;");
  40. public static final UnresolvedType ERROR = forSignature("Ljava/lang/Error;");
  41. public static final UnresolvedType AT_INHERITED = forSignature("Ljava/lang/annotation/Inherited;");
  42. public static final UnresolvedType AT_RETENTION = forSignature("Ljava/lang/annotation/Retention;");
  43. public static final UnresolvedType ENUM = forSignature("Ljava/lang/Enum;");
  44. public static final UnresolvedType ANNOTATION = forSignature("Ljava/lang/annotation/Annotation;");
  45. public static final UnresolvedType JL_CLASS = forSignature("Ljava/lang/Class;");
  46. public static final UnresolvedType JAVA_LANG_CLASS_ARRAY = forSignature("[Ljava/lang/Class;");
  47. public static final UnresolvedType JL_STRING = forSignature("Ljava/lang/String;");
  48. public static final UnresolvedType JL_EXCEPTION = forSignature("Ljava/lang/Exception;");
  49. public static final UnresolvedType JAVA_LANG_REFLECT_METHOD = forSignature("Ljava/lang/reflect/Method;");
  50. public static final UnresolvedType JAVA_LANG_REFLECT_FIELD = forSignature("Ljava/lang/reflect/Field;");
  51. public static final UnresolvedType JAVA_LANG_REFLECT_CONSTRUCTOR = forSignature("Ljava/lang/reflect/Constructor;");
  52. public static final UnresolvedType JAVA_LANG_ANNOTATION = forSignature("Ljava/lang/annotation/Annotation;");
  53. public static final UnresolvedType SUPPRESS_AJ_WARNINGS = forSignature("Lorg/aspectj/lang/annotation/SuppressAjWarnings;");
  54. public static final UnresolvedType AT_TARGET = forSignature("Ljava/lang/annotation/Target;");
  55. public static final UnresolvedType SOMETHING = new UnresolvedType("?");
  56. public static final UnresolvedType[] ARRAY_WITH_JUST_OBJECT = new UnresolvedType[] { OBJECT };
  57. public static final UnresolvedType JOINPOINT_STATICPART = forSignature("Lorg/aspectj/lang/JoinPoint$StaticPart;");
  58. public static final UnresolvedType JOINPOINT_ENCLOSINGSTATICPART = forSignature("Lorg/aspectj/lang/JoinPoint$EnclosingStaticPart;");
  59. public static final UnresolvedType AJC_PRIVILEGED = forSignature("Lorg/aspectj/internal/lang/annotation/ajcPrivileged;");
  60. public static final UnresolvedType PROCEEDING_JOINPOINT = forSignature("Lorg/aspectj/lang/ProceedingJoinPoint;");
  61. public static final UnresolvedType BOOLEAN = forPrimitiveType("Z");
  62. public static final UnresolvedType BYTE = forPrimitiveType("B");
  63. public static final UnresolvedType CHAR = forPrimitiveType("C");
  64. public static final UnresolvedType DOUBLE = forPrimitiveType("D");
  65. public static final UnresolvedType FLOAT = forPrimitiveType("F");
  66. public static final UnresolvedType INT = forPrimitiveType("I");
  67. public static final UnresolvedType LONG = forPrimitiveType("J");
  68. public static final UnresolvedType SHORT = forPrimitiveType("S");
  69. public static final UnresolvedType VOID = forPrimitiveType("V");
  70. // A type is considered missing if we have a signature for it but cannot find the delegate
  71. public static final String MISSING_NAME = "@missing@";
  72. // OPTIMIZE I dont think you can ask something unresolved what kind of type it is, how can it always know? Push down into
  73. // resolvedtype that will force references to resolvedtypes to be correct rather than relying on unresolvedtypes to answer
  74. // questions
  75. protected TypeKind typeKind = TypeKind.SIMPLE; // what kind of type am I?
  76. protected String signature;
  77. /**
  78. * The erasure of the signature. Contains only the Java signature of the type with all supertype, superinterface, type variable,
  79. * and parameter information removed.
  80. */
  81. protected String signatureErasure;
  82. /**
  83. * Calculated on first request - the package name (java.lang for type java.lang.String)
  84. */
  85. private String packageName;
  86. /**
  87. * Calculated on first request - the class name (String for type java.lang.String)
  88. */
  89. private String className;
  90. /**
  91. * Iff isParameterized(), then these are the type parameters
  92. */
  93. protected UnresolvedType[] typeParameters;
  94. /**
  95. * Iff isGeneric(), then these are the type variables declared on the type Iff isParameterized(), then these are the type
  96. * variables bound as parameters in the type
  97. */
  98. // OPTIMIZE should be no state in here that will damage whether equals() is correct...
  99. protected TypeVariable[] typeVariables;
  100. public boolean isPrimitiveType() {
  101. return typeKind == TypeKind.PRIMITIVE;
  102. }
  103. public boolean isVoid() {
  104. // OPTIMIZE promote to bitflag?
  105. return signature.equals("V");
  106. }
  107. public boolean isSimpleType() {
  108. return typeKind == TypeKind.SIMPLE;
  109. }
  110. public boolean isRawType() {
  111. return typeKind == TypeKind.RAW;
  112. }
  113. public boolean isGenericType() {
  114. return typeKind == TypeKind.GENERIC;
  115. }
  116. public boolean isParameterizedType() {
  117. return typeKind == TypeKind.PARAMETERIZED;
  118. }
  119. public boolean isParameterizedOrGenericType() {
  120. return typeKind == TypeKind.GENERIC || typeKind == TypeKind.PARAMETERIZED;
  121. }
  122. public boolean isParameterizedOrRawType() {
  123. return typeKind == TypeKind.PARAMETERIZED || typeKind == TypeKind.RAW;
  124. }
  125. public boolean isTypeVariableReference() {
  126. return typeKind == TypeKind.TYPE_VARIABLE;
  127. }
  128. public boolean isGenericWildcard() {
  129. return typeKind == TypeKind.WILDCARD;
  130. }
  131. public TypeKind getTypekind() {
  132. return typeKind;
  133. }
  134. // for any reference type, we can get some extra information...
  135. public final boolean isArray() {
  136. return signature.length() > 0 && signature.charAt(0) == '[';
  137. }
  138. /**
  139. * Equality is checked based on the underlying signature.
  140. */
  141. @Override
  142. public boolean equals(Object other) {
  143. if (!(other instanceof UnresolvedType)) {
  144. return false;
  145. }
  146. return signature.equals(((UnresolvedType) other).signature);
  147. }
  148. /**
  149. * Equality is checked based on the underlying signature, so the hash code of a particular type is the hash code of its
  150. * signature string.
  151. */
  152. @Override
  153. public int hashCode() {
  154. return signature.hashCode();
  155. }
  156. protected UnresolvedType(String signature) {
  157. this.signature = signature;
  158. this.signatureErasure = signature;
  159. }
  160. protected UnresolvedType(String signature, String signatureErasure) {
  161. this.signature = signature;
  162. this.signatureErasure = signatureErasure;
  163. }
  164. // called from TypeFactory
  165. public UnresolvedType(String signature, String signatureErasure, UnresolvedType[] typeParams) {
  166. this.signature = signature;
  167. this.signatureErasure = signatureErasure;
  168. this.typeParameters = typeParams;
  169. if (typeParams != null) {
  170. this.typeKind = TypeKind.PARAMETERIZED;
  171. }
  172. }
  173. // The operations supported by an UnresolvedType are those that do not require a world
  174. /**
  175. * This is the size of this type as used in JVM.
  176. */
  177. public int getSize() {
  178. return size;
  179. }
  180. private int size = 1;
  181. /**
  182. * NOTE: Use forSignature() if you can, it'll be cheaper ! Constructs a UnresolvedType for a java language type name. For
  183. * example:
  184. *
  185. * <blockquote>
  186. *
  187. * <pre>
  188. * UnresolvedType.forName(&quot;java.lang.Thread[]&quot;)
  189. * UnresolvedType.forName(&quot;int&quot;)
  190. * </pre>
  191. *
  192. * </blockquote>
  193. *
  194. * Types may equivalently be produced by this or by {@link #forSignature(String)}.
  195. *
  196. * <blockquote>
  197. *
  198. * <pre>
  199. * UnresolvedType.forName(&quot;java.lang.Thread[]&quot;).equals(Type.forSignature(&quot;[Ljava/lang/Thread;&quot;)
  200. * UnresolvedType.forName(&quot;int&quot;).equals(Type.forSignature(&quot;I&quot;))
  201. * </pre>
  202. *
  203. * </blockquote>
  204. *
  205. * @param name the java language type name in question.
  206. * @return a type object representing that java language type.
  207. */
  208. // OPTIMIZE change users of this to use forSignature, especially for simple cases
  209. public static UnresolvedType forName(String name) {
  210. return forSignature(nameToSignature(name));
  211. }
  212. /**
  213. * Constructs a UnresolvedType for each java language type name in an incoming array.
  214. *
  215. * @param names an array of java language type names.
  216. * @return an array of UnresolvedType objects.
  217. * @see #forName(String)
  218. */
  219. public static UnresolvedType[] forNames(String[] names) {
  220. UnresolvedType[] ret = new UnresolvedType[names.length];
  221. for (int i = 0, len = names.length; i < len; i++) {
  222. ret[i] = UnresolvedType.forName(names[i]);
  223. }
  224. return ret;
  225. }
  226. public static UnresolvedType forGenericType(String name, TypeVariable[] tvbs, String genericSig) {
  227. String sig = nameToSignature(name);
  228. UnresolvedType ret = UnresolvedType.forSignature(sig);
  229. ret.typeKind = TypeKind.GENERIC;
  230. ret.typeVariables = tvbs;
  231. ret.signatureErasure = sig;
  232. return ret;
  233. }
  234. public static UnresolvedType forGenericTypeSignature(String sig, String declaredGenericSig) {
  235. UnresolvedType ret = UnresolvedType.forSignature(sig);
  236. ret.typeKind = TypeKind.GENERIC;
  237. ClassSignature csig = new GenericSignatureParser().parseAsClassSignature(declaredGenericSig);
  238. GenericSignature.FormalTypeParameter[] ftps = csig.formalTypeParameters;
  239. ret.typeVariables = new TypeVariable[ftps.length];
  240. for (int i = 0; i < ftps.length; i++) {
  241. GenericSignature.FormalTypeParameter parameter = ftps[i];
  242. if (parameter.classBound instanceof GenericSignature.ClassTypeSignature) {
  243. GenericSignature.ClassTypeSignature cts = (GenericSignature.ClassTypeSignature) parameter.classBound;
  244. ret.typeVariables[i] = new TypeVariable(ftps[i].identifier, UnresolvedType.forSignature(cts.outerType.identifier
  245. + ";"));
  246. } else if (parameter.classBound instanceof GenericSignature.TypeVariableSignature) {
  247. GenericSignature.TypeVariableSignature tvs = (GenericSignature.TypeVariableSignature) parameter.classBound;
  248. UnresolvedTypeVariableReferenceType utvrt = new UnresolvedTypeVariableReferenceType(new TypeVariable(
  249. tvs.typeVariableName));
  250. ret.typeVariables[i] = new TypeVariable(ftps[i].identifier, utvrt);
  251. } else {
  252. throw new BCException(
  253. "UnresolvedType.forGenericTypeSignature(): Do not know how to process type variable bound of type '"
  254. + parameter.classBound.getClass() + "'. Full signature is '" + sig + "'");
  255. }
  256. }
  257. ret.signatureErasure = sig;
  258. ret.signature = ret.signatureErasure;
  259. return ret;
  260. }
  261. public static UnresolvedType forGenericTypeVariables(String sig, TypeVariable[] tVars) {
  262. UnresolvedType ret = UnresolvedType.forSignature(sig);
  263. ret.typeKind = TypeKind.GENERIC;
  264. ret.typeVariables = tVars;
  265. ret.signatureErasure = sig;
  266. ret.signature = ret.signatureErasure;
  267. return ret;
  268. }
  269. public static UnresolvedType forRawTypeName(String name) {
  270. UnresolvedType ret = UnresolvedType.forName(name);
  271. ret.typeKind = TypeKind.RAW;
  272. return ret;
  273. }
  274. public static UnresolvedType forPrimitiveType(String signature) {
  275. UnresolvedType ret = new UnresolvedType(signature);
  276. ret.typeKind = TypeKind.PRIMITIVE;
  277. if (signature.equals("J") || signature.equals("D")) {
  278. ret.size = 2;
  279. } else if (signature.equals("V")) {
  280. ret.size = 0;
  281. }
  282. return ret;
  283. }
  284. /**
  285. * Creates a new type array with a fresh type appended to the end.
  286. *
  287. * @param types the left hand side of the new array
  288. * @param end the right hand side of the new array
  289. */
  290. public static UnresolvedType[] add(UnresolvedType[] types, UnresolvedType end) {
  291. int len = types.length;
  292. UnresolvedType[] ret = new UnresolvedType[len + 1];
  293. System.arraycopy(types, 0, ret, 0, len);
  294. ret[len] = end;
  295. return ret;
  296. }
  297. /**
  298. * Creates a new type array with a fresh type inserted at the beginning.
  299. *
  300. *
  301. * @param start the left hand side of the new array
  302. * @param types the right hand side of the new array
  303. */
  304. public static UnresolvedType[] insert(UnresolvedType start, UnresolvedType[] types) {
  305. int len = types.length;
  306. UnresolvedType[] ret = new UnresolvedType[len + 1];
  307. ret[0] = start;
  308. System.arraycopy(types, 0, ret, 1, len);
  309. return ret;
  310. }
  311. /**
  312. * Constructs a Type for a JVM bytecode signature string. For example:
  313. *
  314. * <blockquote>
  315. *
  316. * <pre>
  317. * UnresolvedType.forSignature(&quot;[Ljava/lang/Thread;&quot;)
  318. * UnresolvedType.forSignature(&quot;I&quot;);
  319. * </pre>
  320. *
  321. * </blockquote>
  322. *
  323. * Types may equivalently be produced by this or by {@link #forName(String)}. This method should not be passed P signatures.
  324. *
  325. * <blockquote>
  326. *
  327. * <pre>
  328. * UnresolvedType.forName(&quot;java.lang.Thread[]&quot;).equals(Type.forSignature(&quot;[Ljava/lang/Thread;&quot;)
  329. * UnresolvedType.forName(&quot;int&quot;).equals(Type.forSignature(&quot;I&quot;))
  330. * </pre>
  331. *
  332. * </blockquote>
  333. *
  334. * @param signature the JVM bytecode signature string for the desired type.
  335. * @return a type object represnting that JVM bytecode signature.
  336. */
  337. public static UnresolvedType forSignature(String signature) {
  338. assert !(signature.startsWith("L") && signature.contains("<"));
  339. switch (signature.charAt(0)) {
  340. case 'B':
  341. return UnresolvedType.BYTE;
  342. case 'C':
  343. return UnresolvedType.CHAR;
  344. case 'D':
  345. return UnresolvedType.DOUBLE;
  346. case 'F':
  347. return UnresolvedType.FLOAT;
  348. case 'I':
  349. return UnresolvedType.INT;
  350. case 'J':
  351. return UnresolvedType.LONG;
  352. case 'L':
  353. return TypeFactory.createTypeFromSignature(signature);
  354. case 'P':
  355. return TypeFactory.createTypeFromSignature(signature);
  356. case 'S':
  357. return UnresolvedType.SHORT;
  358. case 'V':
  359. return UnresolvedType.VOID;
  360. case 'Z':
  361. return UnresolvedType.BOOLEAN;
  362. case '[':
  363. return TypeFactory.createTypeFromSignature(signature);
  364. case '+':
  365. return TypeFactory.createTypeFromSignature(signature);
  366. case '-':
  367. return TypeFactory.createTypeFromSignature(signature);
  368. case '?':
  369. return TypeFactory.createTypeFromSignature(signature);
  370. case 'T':
  371. return TypeFactory.createTypeFromSignature(signature);
  372. default:
  373. throw new BCException("Bad type signature " + signature);
  374. }
  375. }
  376. /**
  377. * Constructs a UnresolvedType for each JVM bytecode type signature in an incoming array.
  378. *
  379. * @param sigs an array of JVM bytecode type signatures
  380. * @return an array of UnresolvedType objects.
  381. * @see #forSignature(String)
  382. */
  383. public static UnresolvedType[] forSignatures(String[] sigs) {
  384. UnresolvedType[] ret = new UnresolvedType[sigs.length];
  385. for (int i = 0, len = sigs.length; i < len; i++) {
  386. ret[i] = UnresolvedType.forSignature(sigs[i]);
  387. }
  388. return ret;
  389. }
  390. /**
  391. * Returns the name of this type in java language form (e.g. java.lang.Thread or boolean[]). This produces a more aesthetically
  392. * pleasing string than {@link java.lang.Class#getName()}.
  393. *
  394. * @return the java language name of this type.
  395. */
  396. public String getName() {
  397. return signatureToName(signature);
  398. }
  399. public String getSimpleName() {
  400. String name = getRawName();
  401. int lastDot = name.lastIndexOf('.');
  402. if (lastDot != -1) {
  403. name = name.substring(lastDot + 1);
  404. }
  405. if (isParameterizedType()) {
  406. StringBuffer sb = new StringBuffer(name);
  407. sb.append("<");
  408. for (int i = 0; i < (typeParameters.length - 1); i++) {
  409. sb.append(typeParameters[i].getSimpleName());
  410. sb.append(",");
  411. }
  412. sb.append(typeParameters[typeParameters.length - 1].getSimpleName());
  413. sb.append(">");
  414. name = sb.toString();
  415. }
  416. return name;
  417. }
  418. public String getRawName() {
  419. return signatureToName((signatureErasure == null ? signature : signatureErasure));
  420. }
  421. public String getBaseName() {
  422. String name = getName();
  423. if (isParameterizedType() || isGenericType()) {
  424. if (typeParameters == null) {
  425. return name;
  426. } else {
  427. return name.substring(0, name.indexOf("<"));
  428. }
  429. } else {
  430. return name;
  431. }
  432. }
  433. public String getSimpleBaseName() {
  434. String name = getBaseName();
  435. int lastDot = name.lastIndexOf('.');
  436. if (lastDot != -1) {
  437. name = name.substring(lastDot + 1);
  438. }
  439. return name;
  440. }
  441. /**
  442. * Returns an array of strings representing the java langauge names of an array of types.
  443. *
  444. * @param types an array of UnresolvedType objects
  445. * @return an array of Strings fo the java language names of types.
  446. * @see #getName()
  447. */
  448. public static String[] getNames(UnresolvedType[] types) {
  449. String[] ret = new String[types.length];
  450. for (int i = 0, len = types.length; i < len; i++) {
  451. ret[i] = types[i].getName();
  452. }
  453. return ret;
  454. }
  455. /**
  456. * Returns the name of this type in JVM signature form. For all UnresolvedType t:
  457. *
  458. * <blockquote>
  459. *
  460. * <pre>
  461. * UnresolvedType.forSignature(t.getSignature()).equals(t)
  462. * </pre>
  463. *
  464. * </blockquote>
  465. *
  466. * and for all String s where s is a lexically valid JVM type signature string:
  467. *
  468. * <blockquote>
  469. *
  470. * <pre>
  471. * UnresolvedType.forSignature(s).getSignature().equals(s)
  472. * </pre>
  473. *
  474. * </blockquote>
  475. *
  476. * @return the java JVM signature string for this type.
  477. */
  478. public String getSignature() {
  479. return signature;
  480. }
  481. /**
  482. * For parameterized types, return the signature for the raw type
  483. */
  484. public String getErasureSignature() {
  485. if (signatureErasure == null) {
  486. return signature;
  487. }
  488. return signatureErasure;
  489. }
  490. private boolean needsModifiableDelegate = false;
  491. public boolean needsModifiableDelegate() {
  492. return needsModifiableDelegate;
  493. }
  494. public void setNeedsModifiableDelegate(boolean b) {
  495. this.needsModifiableDelegate = b;
  496. }
  497. public UnresolvedType getRawType() {
  498. return UnresolvedType.forSignature(getErasureSignature());
  499. }
  500. /**
  501. * Returns a UnresolvedType object representing the effective outermost enclosing type for a name type. For all other types,
  502. * this will return the type itself.
  503. *
  504. * The only guarantee is given in JLS 13.1 where code generated according to those rules will have type names that can be split
  505. * apart in this way.
  506. *
  507. * @return the outermost enclosing UnresolvedType object or this.
  508. */
  509. public UnresolvedType getOutermostType() {
  510. if (isArray() || isPrimitiveType()) {
  511. return this;
  512. }
  513. String sig = getErasureSignature();
  514. int dollar = sig.indexOf('$');
  515. if (dollar != -1) {
  516. return UnresolvedType.forSignature(sig.substring(0, dollar) + ';');
  517. } else {
  518. return this;
  519. }
  520. }
  521. /**
  522. * Returns a UnresolvedType object representing the component type of this array, or null if this type does not represent an
  523. * array type.
  524. *
  525. * @return the component UnresolvedType object, or null.
  526. */
  527. public UnresolvedType getComponentType() {
  528. if (isArray()) {
  529. return forSignature(signature.substring(1));
  530. } else {
  531. return null;
  532. }
  533. }
  534. /**
  535. * Returns a java language string representation of this type.
  536. */
  537. @Override
  538. public String toString() {
  539. return getName(); // + " - " + getKind();
  540. }
  541. public String toDebugString() {
  542. return getName();
  543. }
  544. // ---- requires worlds
  545. /**
  546. * Returns a resolved version of this type according to a particular world.
  547. *
  548. * @param world the {@link World} within which to resolve.
  549. * @return a resolved type representing this type in the appropriate world.
  550. */
  551. public ResolvedType resolve(World world) {
  552. return world.resolve(this);
  553. }
  554. // ---- helpers
  555. private static String signatureToName(String signature) {
  556. switch (signature.charAt(0)) {
  557. case 'B':
  558. return "byte";
  559. case 'C':
  560. return "char";
  561. case 'D':
  562. return "double";
  563. case 'F':
  564. return "float";
  565. case 'I':
  566. return "int";
  567. case 'J':
  568. return "long";
  569. case 'L':
  570. String name = signature.substring(1, signature.length() - 1).replace('/', '.');
  571. return name;
  572. case 'T':
  573. StringBuffer nameBuff2 = new StringBuffer();
  574. int colon = signature.indexOf(";");
  575. String tvarName = signature.substring(1, colon);
  576. nameBuff2.append(tvarName);
  577. return nameBuff2.toString();
  578. case 'P': // it's one of our parameterized type sigs
  579. StringBuffer nameBuff = new StringBuffer();
  580. // signature for parameterized types is e.g.
  581. // List<String> -> Ljava/util/List<Ljava/lang/String;>;
  582. // Map<String,List<Integer>> -> Ljava/util/Map<java/lang/String;Ljava/util/List<Ljava/lang/Integer;>;>;
  583. int paramNestLevel = 0;
  584. for (int i = 1; i < signature.length(); i++) {
  585. char c = signature.charAt(i);
  586. switch (c) {
  587. case '/':
  588. nameBuff.append('.');
  589. break;
  590. case '<':
  591. nameBuff.append("<");
  592. paramNestLevel++;
  593. StringBuffer innerBuff = new StringBuffer();
  594. while (paramNestLevel > 0) {
  595. c = signature.charAt(++i);
  596. if (c == '<') {
  597. paramNestLevel++;
  598. }
  599. if (c == '>') {
  600. paramNestLevel--;
  601. }
  602. if (paramNestLevel > 0) {
  603. innerBuff.append(c);
  604. }
  605. if (c == ';' && paramNestLevel == 1) {
  606. nameBuff.append(signatureToName(innerBuff.toString()));
  607. if (signature.charAt(i + 1) != '>') {
  608. nameBuff.append(',');
  609. }
  610. innerBuff = new StringBuffer();
  611. }
  612. }
  613. nameBuff.append(">");
  614. break;
  615. case ';':
  616. break;
  617. default:
  618. nameBuff.append(c);
  619. }
  620. }
  621. return nameBuff.toString();
  622. case 'S':
  623. return "short";
  624. case 'V':
  625. return "void";
  626. case 'Z':
  627. return "boolean";
  628. case '[':
  629. return signatureToName(signature.substring(1, signature.length())) + "[]";
  630. // case '<':
  631. // // its a generic!
  632. // if (signature.charAt(1)=='>') return signatureToName(signature.substring(2));
  633. case '+':
  634. return "? extends " + signatureToName(signature.substring(1, signature.length()));
  635. case '-':
  636. return "? super " + signatureToName(signature.substring(1, signature.length()));
  637. case '*':
  638. return "?";
  639. default:
  640. throw new BCException("Bad type signature: " + signature);
  641. }
  642. }
  643. private static String nameToSignature(String name) {
  644. int len = name.length();
  645. if (len < 8) {
  646. if (name.equals("int")) {
  647. return "I";
  648. }
  649. if (name.equals("void")) {
  650. return "V";
  651. }
  652. if (name.equals("long")) {
  653. return "J";
  654. }
  655. if (name.equals("boolean")) {
  656. return "Z";
  657. }
  658. if (name.equals("double")) {
  659. return "D";
  660. }
  661. if (name.equals("float")) {
  662. return "F";
  663. }
  664. if (name.equals("byte")) {
  665. return "B";
  666. }
  667. if (name.equals("short")) {
  668. return "S";
  669. }
  670. if (name.equals("char")) {
  671. return "C";
  672. }
  673. if (name.equals("?")) {
  674. return name;
  675. }
  676. }
  677. if (len == 0) {
  678. throw new BCException("Bad type name: " + name);
  679. }
  680. if (name.endsWith("[]")) {
  681. return "[" + nameToSignature(name.substring(0, name.length() - 2));
  682. }
  683. // Sometimes the 'name' for an array is of the form: [Ljava.lang.String;
  684. if (name.charAt(0)=='[') {
  685. return name.replace('.','/');
  686. }
  687. if (!name.contains("<")) {
  688. // not parameterized
  689. return new StringBuilder("L").append(name.replace('.', '/')).append(';').toString();
  690. } else {
  691. StringBuffer nameBuff = new StringBuffer();
  692. int nestLevel = 0;
  693. nameBuff.append("P");
  694. for (int i = 0; i < len; i++) {
  695. char c = name.charAt(i);
  696. switch (c) {
  697. case '.':
  698. nameBuff.append('/');
  699. break;
  700. case '<':
  701. nameBuff.append("<");
  702. nestLevel++;
  703. StringBuffer innerBuff = new StringBuffer();
  704. while (nestLevel > 0) {
  705. c = name.charAt(++i);
  706. if (c == '<') {
  707. nestLevel++;
  708. } else if (c == '>') {
  709. nestLevel--;
  710. }
  711. if (c == ',' && nestLevel == 1) {
  712. nameBuff.append(nameToSignature(innerBuff.toString()));
  713. innerBuff = new StringBuffer();
  714. } else {
  715. if (nestLevel > 0) {
  716. innerBuff.append(c);
  717. }
  718. }
  719. }
  720. nameBuff.append(nameToSignature(innerBuff.toString()));
  721. nameBuff.append('>');
  722. break;
  723. // case '>':
  724. // throw new IllegalStateException("Should by matched by <");
  725. // case ',':
  726. // throw new IllegalStateException("Should only happen inside <...>");
  727. default:
  728. nameBuff.append(c);
  729. }
  730. }
  731. nameBuff.append(";");
  732. return nameBuff.toString();
  733. }
  734. }
  735. /**
  736. * Write out an UnresolvedType - the signature should be enough.
  737. */
  738. public final void write(CompressingDataOutputStream s) throws IOException {
  739. s.writeUTF(getSignature());
  740. }
  741. /**
  742. * Read in an UnresolvedType - just read the signature and rebuild the UnresolvedType.
  743. */
  744. public static UnresolvedType read(DataInputStream s) throws IOException {
  745. String sig = s.readUTF();
  746. if (sig.equals(MISSING_NAME)) {
  747. return ResolvedType.MISSING;
  748. } else {
  749. // TODO isn't it a shame to build these (this method is expensive) and then chuck them away on resolution?
  750. // TODO review callers and see if they are immediately resolving it, maybe we can do something more optimal if they are
  751. return UnresolvedType.forSignature(sig);
  752. }
  753. }
  754. public String getNameAsIdentifier() {
  755. return getName().replace('.', '_');
  756. }
  757. public String getPackageNameAsIdentifier() {
  758. String name = getName();
  759. int index = name.lastIndexOf('.');
  760. if (index == -1) {
  761. return "";
  762. } else {
  763. return name.substring(0, index).replace('.', '_');
  764. }
  765. }
  766. public UnresolvedType[] getTypeParameters() {
  767. return typeParameters == null ? UnresolvedType.NONE : typeParameters;
  768. }
  769. public TypeVariable[] getTypeVariables() {
  770. return typeVariables;
  771. }
  772. public static class TypeKind {
  773. // Note: It is not sufficient to say that a parameterized type with no type parameters in fact
  774. // represents a raw type - a parameterized type with no type parameters can represent
  775. // an inner type of a parameterized type that specifies no type parameters of its own.
  776. public final static TypeKind PRIMITIVE = new TypeKind("primitive");
  777. public final static TypeKind SIMPLE = new TypeKind("simple"); // a type with NO type parameters/vars
  778. public final static TypeKind RAW = new TypeKind("raw"); // the erasure of a generic type
  779. public final static TypeKind GENERIC = new TypeKind("generic"); // a generic type
  780. public final static TypeKind PARAMETERIZED = new TypeKind("parameterized"); // a parameterized type
  781. public final static TypeKind TYPE_VARIABLE = new TypeKind("type_variable"); // a type variable
  782. public final static TypeKind WILDCARD = new TypeKind("wildcard"); // a generic wildcard type
  783. @Override
  784. public String toString() {
  785. return type;
  786. }
  787. private TypeKind(String type) {
  788. this.type = type;
  789. }
  790. private final String type;
  791. }
  792. @Override
  793. public TypeVariable getTypeVariableNamed(String name) {
  794. TypeVariable[] vars = getTypeVariables();
  795. if (vars == null || vars.length == 0) {
  796. return null;
  797. }
  798. for (TypeVariable aVar : vars) {
  799. if (aVar.getName().equals(name)) {
  800. return aVar;
  801. }
  802. }
  803. return null;
  804. }
  805. @Override
  806. public String toTraceString() {
  807. return getClass().getName() + "[" + getName() + "]";
  808. }
  809. /**
  810. * Return a version of this parameterized type in which any type parameters that are type variable references are replaced by
  811. * their matching type variable binding.
  812. */
  813. // OPTIMIZE methods like this just allow callers to be lazy and not ensure they are working with the right (resolved) subtype
  814. public UnresolvedType parameterize(Map<String, UnresolvedType> typeBindings) {
  815. throw new UnsupportedOperationException("unable to parameterize unresolved type: " + signature);
  816. }
  817. /**
  818. * @return the class name (does not include the package name)
  819. */
  820. public String getClassName() {
  821. if (className == null) {
  822. String name = getName();
  823. if (name.contains("<")) {
  824. name = name.substring(0, name.indexOf("<"));
  825. }
  826. int index = name.lastIndexOf('.');
  827. if (index == -1) {
  828. className = name;
  829. } else {
  830. className = name.substring(index + 1);
  831. }
  832. }
  833. return className;
  834. }
  835. /**
  836. * @return the package name (no class name included)
  837. */
  838. public String getPackageName() {
  839. if (packageName == null) {
  840. String name = getName();
  841. int angly = name.indexOf('<');
  842. if (angly != -1) {
  843. name = name.substring(0, angly);
  844. }
  845. int index = name.lastIndexOf('.');
  846. if (index == -1) {
  847. packageName = "";
  848. } else {
  849. packageName = name.substring(0, index);
  850. }
  851. }
  852. return packageName;
  853. }
  854. public static void writeArray(UnresolvedType[] types, CompressingDataOutputStream stream) throws IOException {
  855. int len = types.length;
  856. stream.writeShort(len);
  857. for (UnresolvedType type : types) {
  858. type.write(stream);
  859. }
  860. }
  861. public static UnresolvedType[] readArray(DataInputStream s) throws IOException {
  862. int len = s.readShort();
  863. if (len == 0) {
  864. return UnresolvedType.NONE;
  865. }
  866. UnresolvedType[] types = new UnresolvedType[len];
  867. for (int i = 0; i < len; i++) {
  868. types[i] = UnresolvedType.read(s);
  869. }
  870. return types;
  871. }
  872. public static UnresolvedType makeArray(UnresolvedType base, int dims) {
  873. StringBuffer sig = new StringBuffer();
  874. for (int i = 0; i < dims; i++) {
  875. sig.append("[");
  876. }
  877. sig.append(base.getSignature());
  878. return UnresolvedType.forSignature(sig.toString());
  879. }
  880. }