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.

JavaLangTypeToResolvedTypeConverter.java 5.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. package org.aspectj.weaver.reflect;
  10. import java.lang.reflect.GenericArrayType;
  11. import java.lang.reflect.ParameterizedType;
  12. import java.lang.reflect.Type;
  13. import java.lang.reflect.WildcardType;
  14. import java.util.HashMap;
  15. import java.util.Map;
  16. import org.aspectj.weaver.BoundedReferenceType;
  17. import org.aspectj.weaver.ReferenceType;
  18. import org.aspectj.weaver.ResolvedType;
  19. import org.aspectj.weaver.TypeFactory;
  20. import org.aspectj.weaver.TypeVariable;
  21. import org.aspectj.weaver.TypeVariableReferenceType;
  22. import org.aspectj.weaver.UnresolvedType;
  23. import org.aspectj.weaver.World;
  24. /**
  25. * Handles the translation of java.lang.reflect.Type objects into AspectJ UnresolvedTypes.
  26. *
  27. * @author Adrian Colyer
  28. */
  29. public class JavaLangTypeToResolvedTypeConverter {
  30. // Used to prevent recursion - we record what we are working on and return it if asked again *whilst* working on it
  31. private Map<Type, TypeVariableReferenceType> typeVariablesInProgress = new HashMap<>();
  32. private final World world;
  33. public JavaLangTypeToResolvedTypeConverter(World aWorld) {
  34. this.world = aWorld;
  35. }
  36. private World getWorld() {
  37. return this.world;
  38. }
  39. public ResolvedType fromType(Type type) {
  40. if (type instanceof Class) {
  41. Class clazz = (Class) type;
  42. String name = clazz.getName();
  43. /**
  44. * getName() can return:
  45. *
  46. * 1. If this class object represents a reference type that is not an
  47. * array type then the binary name of the class is returned
  48. * 2. If this class object represents a primitive type or void, then
  49. * the name returned is a String equal to the Java language keyword
  50. * corresponding to the primitive type or void.
  51. * 3. If this class object represents a class of arrays, then the internal
  52. * form of the name consists of the name of the element type preceded by
  53. * one or more '[' characters representing the depth of the array nesting.
  54. */
  55. if (clazz.isArray()) {
  56. UnresolvedType ut = UnresolvedType.forSignature(name.replace('.', '/'));
  57. return getWorld().resolve(ut);
  58. } else {
  59. return getWorld().resolve(name);
  60. }
  61. } else if (type instanceof ParameterizedType) {
  62. // https://bugs.eclipse.org/bugs/show_bug.cgi?id=509327
  63. // TODO should deal with the ownerType if it set, indicating this is possibly an inner type of a parameterized type
  64. Type ownerType = ((ParameterizedType) type).getOwnerType();
  65. ParameterizedType parameterizedType = (ParameterizedType) type;
  66. ResolvedType baseType = fromType(parameterizedType.getRawType());
  67. Type[] typeArguments = parameterizedType.getActualTypeArguments();
  68. if (baseType.isSimpleType() && typeArguments.length == 0 && ownerType != null) {
  69. // 'type' is an inner type of some outer parameterized type
  70. // For now just return the base type - in future create the parameterized form of the outer
  71. // and use it with the inner. We return the base type to be compatible with what the
  72. // code does that accesses the info from the bytecode (unlike this code which accesses it
  73. // reflectively).
  74. return baseType;
  75. }
  76. ResolvedType[] resolvedTypeArguments = fromTypes(typeArguments);
  77. return TypeFactory.createParameterizedType(baseType, resolvedTypeArguments, getWorld());
  78. } else if (type instanceof java.lang.reflect.TypeVariable) {
  79. TypeVariableReferenceType inprogressVar = typeVariablesInProgress.get(type);
  80. if (inprogressVar != null) {
  81. return inprogressVar;
  82. }
  83. java.lang.reflect.TypeVariable tv = (java.lang.reflect.TypeVariable) type;
  84. TypeVariable rt_tv = new TypeVariable(tv.getName());
  85. TypeVariableReferenceType tvrt = new TypeVariableReferenceType(rt_tv, getWorld());
  86. typeVariablesInProgress.put(type, tvrt); // record what we are working on, for recursion case
  87. Type[] bounds = tv.getBounds();
  88. ResolvedType[] resBounds = fromTypes(bounds);
  89. ResolvedType upperBound = resBounds[0];
  90. ResolvedType[] additionalBounds = ResolvedType.EMPTY_RESOLVED_TYPE_ARRAY;
  91. if (resBounds.length > 1) {
  92. additionalBounds = new ResolvedType[resBounds.length - 1];
  93. System.arraycopy(resBounds, 1, additionalBounds, 0, additionalBounds.length);
  94. }
  95. rt_tv.setUpperBound(upperBound);
  96. rt_tv.setAdditionalInterfaceBounds(additionalBounds);
  97. typeVariablesInProgress.remove(type); // we have finished working on it
  98. return tvrt;
  99. } else if (type instanceof WildcardType) {
  100. WildcardType wildType = (WildcardType) type;
  101. Type[] lowerBounds = wildType.getLowerBounds();
  102. Type[] upperBounds = wildType.getUpperBounds();
  103. ResolvedType bound = null;
  104. boolean isExtends = lowerBounds.length == 0;
  105. if (isExtends) {
  106. bound = fromType(upperBounds[0]);
  107. } else {
  108. bound = fromType(lowerBounds[0]);
  109. }
  110. return new BoundedReferenceType((ReferenceType) bound, isExtends, getWorld());
  111. } else if (type instanceof GenericArrayType) {
  112. GenericArrayType genericArrayType = (GenericArrayType) type;
  113. Type componentType = genericArrayType.getGenericComponentType();
  114. return UnresolvedType.makeArray(fromType(componentType), 1).resolve(getWorld());
  115. }
  116. return ResolvedType.MISSING;
  117. }
  118. public ResolvedType[] fromTypes(Type[] types) {
  119. ResolvedType[] ret = new ResolvedType[types.length];
  120. for (int i = 0; i < ret.length; i++) {
  121. ret[i] = fromType(types[i]);
  122. }
  123. return ret;
  124. }
  125. }