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.

GenericSignatureParsingTest.java 8.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  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://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Andy Clement (IBM) initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.apache.bcel.classfile.tests;
  13. import org.aspectj.apache.bcel.classfile.Attribute;
  14. import org.aspectj.apache.bcel.classfile.JavaClass;
  15. import org.aspectj.apache.bcel.classfile.Method;
  16. import org.aspectj.apache.bcel.classfile.Signature;
  17. import org.aspectj.apache.bcel.classfile.Utility;
  18. /**
  19. * Generics introduces more complex signature possibilities, they are no longer just
  20. * made up of primitives or big 'L' types. The addition of 'anglies' due to
  21. * parameterization and the ability to specify wildcards (possibly bounded)
  22. * when talking about parameterized types means we need to be much more sophisticated.
  23. *
  24. *
  25. * Notes:
  26. * Signatures are used to encode Java programming language type informaiton
  27. * that is not part of the JVM type system, such as generic type and method
  28. * declarations and parameterized types. This kind of information is
  29. * needed to support reflection and debugging, and by the Java compiler.
  30. *
  31. * =============================================
  32. *
  33. * ClassTypeSignature = LPackageSpecifier* SimpleClassTypeSignature ClassTypeSignatureSuffix*;
  34. *
  35. * PackageSpecifier = Identifier/PackageSpecifier*
  36. * SimpleClassTypeSignature= Identifier TypeArguments(opt)
  37. * ClassTypeSignatureSuffix= .SimpleClassTypeSignature
  38. * TypeVariableSignature = TIdentifier;
  39. * TypeArguments = <TypeArgument+>
  40. * TypeArgument = WildcardIndiciator(opt) FieldTypeSignature
  41. * *
  42. * WildcardIndicator = +
  43. * -
  44. * ArrayTypeSignature = [TypeSignature
  45. * TypeSignature = [FieldTypeSignature
  46. * [BaseType
  47. *
  48. * <not sure those [ should be prefixing fts and bt>
  49. * Examples:
  50. * Ljava/util/List; == java.util.List
  51. * Ljava/util/List<Ljava/lang/String;>; == java.util.List<java.lang.String>
  52. * Ljava/util/List<Ljava/lang/Double;>; == java.util.List<java.lang.Double>
  53. * Ljava/util/List<+Ljava/lang/Number;>; == java.util.List<? extends java.lang.Number>
  54. * Ljava/util/List<-Ljava/lang/Number;>; == java.util.List<? super java.lang.Number>
  55. * Ljava/util/List<*>; == java.util.List<?>
  56. * Ljava/util/Map<*-Ljava/lang/Number;>; == java.util.Map<?,? super java.lang.Number>
  57. *
  58. * =============================================
  59. *
  60. * ClassSignature = FormalTypeParameters(opt) SuperclassSignature SuperinterfaceSignatures*
  61. *
  62. * optional formal type parameters then a superclass signature then a superinterface signature
  63. *
  64. * FormalTypeParameters = <FormalTypeParameter+>
  65. * FormalTypeParameter = Identifier ClassBound InterfaceBound*
  66. * ClassBound = :FieldTypeSignature(opt)
  67. * InterfaceBound = :FieldTypeSignature
  68. *
  69. * If it exists, a set of formal type parameters are contained in anglies and consist of an identifier a classbound (assumed to be
  70. * object if not specified) and then an optional list of InterfaceBounds
  71. *
  72. * SuperclassSignature = ClassTypeSignature
  73. * SuperinterfaceSignature = ClassTypeSignature
  74. * FieldTypeSignature = ClassTypeSignature
  75. * ArrayTypeSignature
  76. * TypeVariableSignature
  77. *
  78. *
  79. * MethodTypeSignature = FormalTypeParameters(opt) ( TypeSignature* ) ReturnType ThrowsSignature*
  80. * ReturnType = TypeSignature
  81. * VoidDescriptor
  82. * ThrowsSignature = ^ClassTypeSignature
  83. * ^TypeVariableSignature
  84. *
  85. * Examples:
  86. *
  87. * <T::Ljava/lang/Comparable<-Ljava/lang/Number;>;>
  88. *
  89. * ClassBound not supplied, Object assumed. Interface bound is Comparable<? super Number>
  90. *
  91. * "T:Ljava/lang/Object;:Ljava/lang/Comparable<-TT;>;","T extends java.lang.Object & java.lang.Comparable<? super T>"
  92. *
  93. */
  94. public class GenericSignatureParsingTest extends BcelTestCase {
  95. /**
  96. * Throw some generic format signatures at the BCEL signature
  97. * parsing code and see what it does.
  98. */
  99. public void testParsingGenericSignatures_ClassTypeSignature() {
  100. // trivial
  101. checkClassTypeSignature("Ljava/util/List;","java.util.List");
  102. // basics
  103. checkClassTypeSignature("Ljava/util/List<Ljava/lang/String;>;","java.util.List<java.lang.String>");
  104. checkClassTypeSignature("Ljava/util/List<Ljava/lang/Double;>;","java.util.List<java.lang.Double>");
  105. // madness
  106. checkClassTypeSignature("Ljava/util/List<+Ljava/lang/Number;>;","java.util.List<? extends java.lang.Number>");
  107. checkClassTypeSignature("Ljava/util/List<-Ljava/lang/Number;>;","java.util.List<? super java.lang.Number>");
  108. checkClassTypeSignature("Ljava/util/List<*>;", "java.util.List<?>");
  109. checkClassTypeSignature("Ljava/util/Map<*-Ljava/lang/Number;>;","java.util.Map<?,? super java.lang.Number>");
  110. // with type params
  111. checkClassTypeSignature("Ljava/util/Collection<TT;>;","java.util.Collection<T>");
  112. // arrays
  113. checkClassTypeSignature("Ljava/util/List<[Ljava/lang/String;>;","java.util.List<java.lang.String[]>");
  114. checkClassTypeSignature("[Ljava/util/List<Ljava/lang/String;>;","java.util.List<java.lang.String>[]");
  115. }
  116. public void testMethodTypeToSignature() {
  117. checkMethodTypeToSignature("void",new String[]{"java.lang.String[]","boolean"},"([Ljava/lang/String;Z)V");
  118. checkMethodTypeToSignature("void",new String[]{"java.util.List<java/lang/String>"},"(Ljava/util/List<java/lang/String>;)V");
  119. }
  120. public void testMethodSignatureToArgumentTypes() {
  121. checkMethodSignatureArgumentTypes("([Ljava/lang/String;Z)V",new String[]{"java.lang.String[]","boolean"});
  122. // checkMethodSignatureArgumentTypes("(Ljava/util/List<java/lang/String>;)V",new String[]{"java.util.List<java/lang/String>"});
  123. }
  124. public void testMethodSignatureReturnType() {
  125. checkMethodSignatureReturnType("([Ljava/lang/String;)Z","boolean");
  126. }
  127. public void testLoadingGenerics() throws ClassNotFoundException {
  128. JavaClass clazz = getClassFromJar("PossibleGenericsSigs");
  129. // J5TODO asc fill this bit in...
  130. }
  131. // helper methods below
  132. // These routines call BCEL to determine if it can correctly translate from one form to the other.
  133. private void checkClassTypeSignature(String sig, String expected) {
  134. StringBuffer result = new StringBuffer();
  135. int p = Utility.readClassTypeSignatureFrom(sig,0,result,false);
  136. assertTrue("Only swallowed "+p+" chars of this sig "+sig+" (len="+sig.length()+")",p==sig.length());
  137. assertTrue("Expected '"+expected+"' but got '"+result.toString()+"'",result.toString().equals(expected));
  138. }
  139. private void checkMethodTypeToSignature(String ret,String[] args,String expected) {
  140. String res = Utility.methodTypeToSignature(ret,args);
  141. if (!res.equals(expected)) {
  142. fail("Should match. Got: "+res+" Expected:"+expected);
  143. }
  144. }
  145. private void checkMethodSignatureReturnType(String sig,String expected) {
  146. String result = Utility.methodSignatureReturnType(sig,false);
  147. if (!result.equals(expected)) {
  148. fail("Should match. Got: "+result+" Expected:"+expected);
  149. }
  150. }
  151. private void checkMethodSignatureArgumentTypes(String in,String[] expected) {
  152. String[] result = Utility.methodSignatureArgumentTypes(in,false);
  153. if (result.length!=expected.length) {
  154. fail("Expected "+expected.length+" entries to be returned but only got "+result.length);
  155. }
  156. for (int i = 0; i < expected.length; i++) {
  157. String string = result[i];
  158. if (!string.equals(expected[i]))
  159. fail("Argument: "+i+" should have been "+expected[i]+" but was "+string);
  160. }
  161. }
  162. public Signature getSignatureAttribute(JavaClass clazz,String name) {
  163. Method m = getMethod(clazz,name);
  164. Attribute[] as = m.getAttributes();
  165. for (int i = 0; i < as.length; i++) {
  166. Attribute attribute = as[i];
  167. if (attribute.getName().equals("Signature")) {
  168. return (Signature)attribute;
  169. }
  170. }
  171. return null;
  172. }
  173. }