PageRenderTime 46ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/aspectj-1.6.9/aspectjweaver1.6.9/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXConverter.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 259 lines | 197 code | 27 blank | 35 comment | 33 complexity | d9e8cc444e7084fdbca10c5c43456ed1 MD5 | raw file
  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 v1.0
  6. * which accompanies this distribution and is available at
  7. * http://eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Adrian Colyer Initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.bcel;
  13. import java.util.HashMap;
  14. import java.util.Map;
  15. import org.aspectj.util.GenericSignature;
  16. import org.aspectj.util.GenericSignature.SimpleClassTypeSignature;
  17. import org.aspectj.weaver.BoundedReferenceType;
  18. import org.aspectj.weaver.ReferenceType;
  19. import org.aspectj.weaver.ResolvedType;
  20. import org.aspectj.weaver.TypeFactory;
  21. import org.aspectj.weaver.TypeVariable;
  22. import org.aspectj.weaver.TypeVariableReferenceType;
  23. import org.aspectj.weaver.UnresolvedType;
  24. import org.aspectj.weaver.World;
  25. import org.aspectj.weaver.tools.Trace;
  26. import org.aspectj.weaver.tools.TraceFactory;
  27. /**
  28. * A utility class that assists in unpacking constituent parts of generic signature attributes and returning their equivalents in
  29. * UnresolvedType world.
  30. */
  31. public class BcelGenericSignatureToTypeXConverter {
  32. private static Trace trace = TraceFactory.getTraceFactory().getTrace(BcelGenericSignatureToTypeXConverter.class);
  33. public static ResolvedType classTypeSignature2TypeX(GenericSignature.ClassTypeSignature aClassTypeSignature,
  34. GenericSignature.FormalTypeParameter[] typeParams, World world) throws GenericSignatureFormatException {
  35. Map typeMap = new HashMap();
  36. ResolvedType ret = classTypeSignature2TypeX(aClassTypeSignature, typeParams, world, typeMap);
  37. fixUpCircularDependencies(ret, typeMap);
  38. return ret;
  39. }
  40. private static ResolvedType classTypeSignature2TypeX(GenericSignature.ClassTypeSignature aClassTypeSignature,
  41. GenericSignature.FormalTypeParameter[] typeParams, World world, Map inProgressTypeVariableResolutions)
  42. throws GenericSignatureFormatException {
  43. // class type sig consists of an outer type, and zero or more nested types
  44. // the fully qualified name is outer-type.nested-type1.nested-type2....
  45. // each type in the hierarchy may have type arguments
  46. // first build the 'raw type' signature
  47. StringBuffer sig = new StringBuffer();
  48. sig.append(aClassTypeSignature.outerType.identifier.replace(';', ' ').trim());
  49. for (int i = 0; i < aClassTypeSignature.nestedTypes.length; i++) {
  50. sig.append("$");
  51. sig.append(aClassTypeSignature.nestedTypes[i].identifier.replace(';', ' ').trim());
  52. }
  53. sig.append(";");
  54. // now look for any type parameters.
  55. // I *think* we only need to worry about the 'right-most' type...
  56. SimpleClassTypeSignature innerType = aClassTypeSignature.outerType;
  57. if (aClassTypeSignature.nestedTypes.length > 0) {
  58. innerType = aClassTypeSignature.nestedTypes[aClassTypeSignature.nestedTypes.length - 1];
  59. }
  60. if (innerType.typeArguments.length > 0) {
  61. // we have to create a parameterized type
  62. // type arguments may be array types, class types, or typevariable types
  63. ResolvedType theBaseType = UnresolvedType.forSignature(sig.toString()).resolve(world);
  64. // Sometimes we may find that when the code is being load-time woven that the types have changed.
  65. // Perhaps an old form of a library jar is being used - this can mean we discover right here
  66. // that a type is not parameterizable (is that a word?). I think in these cases it is ok to
  67. // just return with what we know (the base type). (see pr152848)
  68. if (!(theBaseType.isGenericType() || theBaseType.isRawType())) {
  69. if (trace.isTraceEnabled())
  70. trace.event("classTypeSignature2TypeX: this type is not a generic type:", null, new Object[] { theBaseType });
  71. return theBaseType;
  72. }
  73. ResolvedType[] typeArgumentTypes = new ResolvedType[innerType.typeArguments.length];
  74. for (int i = 0; i < typeArgumentTypes.length; i++) {
  75. typeArgumentTypes[i] = typeArgument2TypeX(innerType.typeArguments[i], typeParams, world,
  76. inProgressTypeVariableResolutions);
  77. }
  78. return TypeFactory.createParameterizedType(theBaseType, typeArgumentTypes, world);
  79. // world.resolve(UnresolvedType.forParameterizedTypes(
  80. // UnresolvedType.forSignature(sig.toString()).resolve(world),
  81. // typeArgumentTypes));
  82. } else {
  83. // we have a non-parameterized type
  84. return world.resolve(UnresolvedType.forSignature(sig.toString()));
  85. }
  86. }
  87. public static ResolvedType fieldTypeSignature2TypeX(GenericSignature.FieldTypeSignature aFieldTypeSignature,
  88. GenericSignature.FormalTypeParameter[] typeParams, World world) throws GenericSignatureFormatException {
  89. Map typeMap = new HashMap();
  90. ResolvedType ret = fieldTypeSignature2TypeX(aFieldTypeSignature, typeParams, world, typeMap);
  91. fixUpCircularDependencies(ret, typeMap);
  92. return ret;
  93. }
  94. private static ResolvedType fieldTypeSignature2TypeX(GenericSignature.FieldTypeSignature aFieldTypeSignature,
  95. GenericSignature.FormalTypeParameter[] typeParams, World world, Map inProgressTypeVariableResolutions)
  96. throws GenericSignatureFormatException {
  97. if (aFieldTypeSignature.isClassTypeSignature()) {
  98. return classTypeSignature2TypeX((GenericSignature.ClassTypeSignature) aFieldTypeSignature, typeParams, world,
  99. inProgressTypeVariableResolutions);
  100. } else if (aFieldTypeSignature.isArrayTypeSignature()) {
  101. int dims = 0;
  102. GenericSignature.TypeSignature ats = aFieldTypeSignature;
  103. while (ats instanceof GenericSignature.ArrayTypeSignature) {
  104. dims++;
  105. ats = ((GenericSignature.ArrayTypeSignature) ats).typeSig;
  106. }
  107. return world.resolve(UnresolvedType.makeArray(typeSignature2TypeX(ats, typeParams, world,
  108. inProgressTypeVariableResolutions), dims));
  109. } else if (aFieldTypeSignature.isTypeVariableSignature()) {
  110. ResolvedType rtx = typeVariableSignature2TypeX((GenericSignature.TypeVariableSignature) aFieldTypeSignature,
  111. typeParams, world, inProgressTypeVariableResolutions);
  112. return rtx;
  113. } else {
  114. throw new GenericSignatureFormatException("Cant understand field type signature: " + aFieldTypeSignature);
  115. }
  116. }
  117. public static TypeVariable formalTypeParameter2TypeVariable(GenericSignature.FormalTypeParameter aFormalTypeParameter,
  118. GenericSignature.FormalTypeParameter[] typeParams, World world) throws GenericSignatureFormatException {
  119. Map typeMap = new HashMap();
  120. return formalTypeParameter2TypeVariable(aFormalTypeParameter, typeParams, world, typeMap);
  121. }
  122. private static TypeVariable formalTypeParameter2TypeVariable(GenericSignature.FormalTypeParameter aFormalTypeParameter,
  123. GenericSignature.FormalTypeParameter[] typeParams, World world, Map inProgressTypeVariableResolutions)
  124. throws GenericSignatureFormatException {
  125. UnresolvedType upperBound = fieldTypeSignature2TypeX(aFormalTypeParameter.classBound, typeParams, world,
  126. inProgressTypeVariableResolutions);
  127. UnresolvedType[] ifBounds = new UnresolvedType[aFormalTypeParameter.interfaceBounds.length];
  128. for (int i = 0; i < ifBounds.length; i++) {
  129. ifBounds[i] = fieldTypeSignature2TypeX(aFormalTypeParameter.interfaceBounds[i], typeParams, world,
  130. inProgressTypeVariableResolutions);
  131. }
  132. return new TypeVariable(aFormalTypeParameter.identifier, upperBound, ifBounds);
  133. }
  134. private static ResolvedType typeArgument2TypeX(GenericSignature.TypeArgument aTypeArgument,
  135. GenericSignature.FormalTypeParameter[] typeParams, World world, Map inProgressTypeVariableResolutions)
  136. throws GenericSignatureFormatException {
  137. if (aTypeArgument.isWildcard)
  138. return UnresolvedType.SOMETHING.resolve(world);
  139. if (aTypeArgument.isMinus) {
  140. UnresolvedType bound = fieldTypeSignature2TypeX(aTypeArgument.signature, typeParams, world,
  141. inProgressTypeVariableResolutions);
  142. ReferenceType rBound = (ReferenceType) world.resolve(bound);
  143. return new BoundedReferenceType(rBound, false, world);
  144. } else if (aTypeArgument.isPlus) {
  145. UnresolvedType bound = fieldTypeSignature2TypeX(aTypeArgument.signature, typeParams, world,
  146. inProgressTypeVariableResolutions);
  147. ReferenceType rBound = (ReferenceType) world.resolve(bound);
  148. return new BoundedReferenceType(rBound, true, world);
  149. } else {
  150. return fieldTypeSignature2TypeX(aTypeArgument.signature, typeParams, world, inProgressTypeVariableResolutions);
  151. }
  152. }
  153. public static ResolvedType typeSignature2TypeX(GenericSignature.TypeSignature aTypeSig,
  154. GenericSignature.FormalTypeParameter[] typeParams, World world) throws GenericSignatureFormatException {
  155. Map typeMap = new HashMap();
  156. ResolvedType ret = typeSignature2TypeX(aTypeSig, typeParams, world, typeMap);
  157. fixUpCircularDependencies(ret, typeMap);
  158. return ret;
  159. }
  160. private static ResolvedType typeSignature2TypeX(GenericSignature.TypeSignature aTypeSig,
  161. GenericSignature.FormalTypeParameter[] typeParams, World world, Map inProgressTypeVariableResolutions)
  162. throws GenericSignatureFormatException {
  163. if (aTypeSig.isBaseType()) {
  164. return world.resolve(UnresolvedType.forSignature(((GenericSignature.BaseTypeSignature) aTypeSig).toString()));
  165. } else {
  166. return fieldTypeSignature2TypeX((GenericSignature.FieldTypeSignature) aTypeSig, typeParams, world,
  167. inProgressTypeVariableResolutions);
  168. }
  169. }
  170. private static ResolvedType typeVariableSignature2TypeX(GenericSignature.TypeVariableSignature aTypeVarSig,
  171. GenericSignature.FormalTypeParameter[] typeParams, World world, Map inProgressTypeVariableResolutions)
  172. throws GenericSignatureFormatException {
  173. GenericSignature.FormalTypeParameter typeVarBounds = null;
  174. for (int i = 0; i < typeParams.length; i++) {
  175. if (typeParams[i].identifier.equals(aTypeVarSig.typeVariableName)) {
  176. typeVarBounds = typeParams[i];
  177. break;
  178. }
  179. }
  180. if (typeVarBounds == null) {
  181. // blowing up here breaks the situation with ITDs where the type variable is mentioned in the
  182. // declaring type and used somewhere in the signature. Temporary change to allow it to return just a
  183. // 'dumb' typevariablereference.
  184. return new TypeVariableReferenceType(new TypeVariable(aTypeVarSig.typeVariableName), world);
  185. // throw new GenericSignatureFormatException("Undeclared type variable in signature: " + aTypeVarSig.typeVariableName);
  186. }
  187. if (inProgressTypeVariableResolutions.containsKey(typeVarBounds)) {
  188. return (ResolvedType) inProgressTypeVariableResolutions.get(typeVarBounds);
  189. }
  190. inProgressTypeVariableResolutions.put(typeVarBounds, new FTPHolder(typeVarBounds, world));
  191. ResolvedType ret = new TypeVariableReferenceType(formalTypeParameter2TypeVariable(typeVarBounds, typeParams, world,
  192. inProgressTypeVariableResolutions), world);
  193. inProgressTypeVariableResolutions.put(typeVarBounds, ret);
  194. return ret;
  195. }
  196. private static void fixUpCircularDependencies(ResolvedType aTypeX, Map typeVariableResolutions) {
  197. if (!(aTypeX instanceof ReferenceType)) {
  198. return;
  199. }
  200. ReferenceType rt = (ReferenceType) aTypeX;
  201. TypeVariable[] typeVars = rt.getTypeVariables();
  202. if (typeVars != null) {
  203. for (int i = 0; i < typeVars.length; i++) {
  204. if (typeVars[i].getUpperBound() instanceof FTPHolder) {
  205. GenericSignature.FormalTypeParameter key = ((FTPHolder) typeVars[i].getUpperBound()).ftpToBeSubstituted;
  206. typeVars[i].setUpperBound((UnresolvedType) typeVariableResolutions.get(key));
  207. }
  208. }
  209. }
  210. }
  211. private static class FTPHolder extends ReferenceType {
  212. public GenericSignature.FormalTypeParameter ftpToBeSubstituted;
  213. public FTPHolder(GenericSignature.FormalTypeParameter ftp, World world) {
  214. super("Ljava/lang/Object;", world);
  215. this.ftpToBeSubstituted = ftp;
  216. }
  217. public String toString() {
  218. return "placeholder for TypeVariable of " + ftpToBeSubstituted.toString();
  219. }
  220. public ResolvedType resolve(World world) {
  221. return this;
  222. }
  223. public boolean isCacheable() {
  224. return false;
  225. }
  226. }
  227. public static class GenericSignatureFormatException extends Exception {
  228. public GenericSignatureFormatException(String explanation) {
  229. super(explanation);
  230. }
  231. }
  232. }