]> source.dussan.org Git - aspectj.git/commitdiff
GenericsWork: testcode for verifying signature parsing is behaving. work in progress.
authoraclement <aclement>
Wed, 1 Jun 2005 14:58:14 +0000 (14:58 +0000)
committeraclement <aclement>
Wed, 1 Jun 2005 14:58:14 +0000 (14:58 +0000)
bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/AllTests.java
bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java [new file with mode: 0644]

index cba6096cf7ccb334ac4768e6facb9487a3ef9a9f..ff170ab07239d14dcd8934ac1602cd770a00ce09 100644 (file)
@@ -33,8 +33,7 @@ public class AllTests {
        public static Test suite() {
                TestSuite suite = new TestSuite("Tests for BCEL Java5 support");
                //$JUnit-BEGIN$
-               suite
-                       .addTestSuite(RuntimeVisibleParameterAnnotationAttributeTest.class);
+               suite.addTestSuite(RuntimeVisibleParameterAnnotationAttributeTest.class);
                suite.addTestSuite(AnnotationDefaultAttributeTest.class);
                suite.addTestSuite(EnclosingMethodAttributeTest.class);
                suite.addTestSuite(MethodAnnotationsTest.class);
@@ -50,6 +49,7 @@ public class AllTests {
                suite.addTestSuite(GeneratingAnnotatedClassesTest.class);
                suite.addTestSuite(TypeAnnotationsTest.class);
                suite.addTestSuite(UtilTests.class);
+               suite.addTestSuite(GenericSignatureParsingTest.class);
                //$JUnit-END$
                return suite;
        }
diff --git a/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java b/bcel-builder/testsrc/org/aspectj/apache/bcel/classfile/tests/GenericSignatureParsingTest.java
new file mode 100644 (file)
index 0000000..11a200f
--- /dev/null
@@ -0,0 +1,195 @@
+/* *******************************************************************
+ * Copyright (c) 2005 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Common Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/cpl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement (IBM)     initial implementation 
+ * ******************************************************************/
+package org.aspectj.apache.bcel.classfile.tests;
+
+import org.aspectj.apache.bcel.classfile.Attribute;
+import org.aspectj.apache.bcel.classfile.JavaClass;
+import org.aspectj.apache.bcel.classfile.Method;
+import org.aspectj.apache.bcel.classfile.Signature;
+import org.aspectj.apache.bcel.classfile.Utility;
+
+/**
+ * Generics introduces more complex signature possibilities, they are no longer just
+ * made up of primitives or big 'L' types. The addition of 'anglies' due to
+ * parameterization and the ability to specify wildcards (possibly bounded)
+ * when talking about parameterized types means we need to be much more sophisticated.
+ *
+ *
+ * Notes:
+ * Signatures are used to encode Java programming language type informaiton
+ * that is not part of the JVM type system, such as generic type and method
+ * declarations and parameterized types.  This kind of information is
+ * needed to support reflection and debugging, and by the Java compiler.
+ * 
+ * ============================================= 
+ * 
+ * ClassTypeSignature =      LPackageSpecifier* SimpleClassTypeSignature ClassTypeSignatureSuffix*;
+ * 
+ * PackageSpecifier =        Identifier/PackageSpecifier*
+ * SimpleClassTypeSignature= Identifier TypeArguments(opt)
+ * ClassTypeSignatureSuffix= .SimpleClassTypeSignature
+ * TypeVariableSignature =   TIdentifier;
+ * TypeArguments =           <TypeArgument+>
+ * TypeArgument =            WildcardIndiciator(opt) FieldTypeSignature
+ *                           *
+ * WildcardIndicator =       +
+ *                           -
+ * ArrayTypeSignature =      [TypeSignature
+ * TypeSignature =           [FieldTypeSignature
+ *                           [BaseType
+ *                           
+ *                           <not sure those [ should be prefixing fts and bt>
+ * Examples:
+ *     Ljava/util/List;                      ==   java.util.List
+ *  Ljava/util/List<Ljava/lang/String;>;  ==   java.util.List<java.lang.String>
+ *  Ljava/util/List<Ljava/lang/Double;>;  ==   java.util.List<java.lang.Double>
+ *  Ljava/util/List<+Ljava/lang/Number;>; ==   java.util.List<? extends java.lang.Number>
+ *  Ljava/util/List<-Ljava/lang/Number;>; ==   java.util.List<? super java.lang.Number>
+ *  Ljava/util/List<*>;                   ==   java.util.List<?>
+ *  Ljava/util/Map<*-Ljava/lang/Number;>; ==   java.util.Map<?,? super java.lang.Number>
+ *                           
+ * ============================================= 
+ * 
+ * ClassSignature =          FormalTypeParameters(opt) SuperclassSignature SuperinterfaceSignatures*
+ *   
+ *   optional formal type parameters then a superclass signature then a superinterface signature
+ * 
+ * FormalTypeParameters =    <FormalTypeParameter+>
+ * FormalTypeParameter  =    Identifier ClassBound InterfaceBound*  
+ * ClassBound =              :FieldTypeSignature(opt)
+ * InterfaceBound =          :FieldTypeSignature
+ *    
+ *   If it exists, a set of formal type parameters are contained in anglies and consist of an identifier a classbound (assumed to be
+ *   object if not specified) and then an optional list of InterfaceBounds
+ *   
+ * SuperclassSignature =     ClassTypeSignature
+ * SuperinterfaceSignature = ClassTypeSignature
+ * FieldTypeSignature =      ClassTypeSignature
+ *                           ArrayTypeSignature
+ *                           TypeVariableSignature
+ *                           
+ *                           
+ * MethodTypeSignature =     FormalTypeParameters(opt) ( TypeSignature* ) ReturnType ThrowsSignature*
+ * ReturnType =              TypeSignature
+ *                           VoidDescriptor
+ * ThrowsSignature =         ^ClassTypeSignature
+ *                           ^TypeVariableSignature
+ *                           
+ *  Examples: 
+ * 
+ * <T::Ljava/lang/Comparable<-Ljava/lang/Number;>;>
+ * 
+ * ClassBound not supplied, Object assumed.  Interface bound is Comparable<? super Number>
+ * 
+ * "T:Ljava/lang/Object;:Ljava/lang/Comparable<-TT;>;","T extends java.lang.Object & java.lang.Comparable<? super T>"
+ *
+ */
+public class GenericSignatureParsingTest extends BcelTestCase {
+       
+       
+       /** 
+        * Throw some generic format signatures at the BCEL signature 
+        * parsing code and see what it does.
+        */
+       public void testParsingGenericSignatures_ClassTypeSignature() {
+               // trivial
+               checkClassTypeSignature("Ljava/util/List;","java.util.List");
+               
+               // basics
+               checkClassTypeSignature("Ljava/util/List<Ljava/lang/String;>;","java.util.List<java.lang.String>");
+               checkClassTypeSignature("Ljava/util/List<Ljava/lang/Double;>;","java.util.List<java.lang.Double>");
+
+               // madness
+               checkClassTypeSignature("Ljava/util/List<+Ljava/lang/Number;>;","java.util.List<? extends java.lang.Number>");
+               checkClassTypeSignature("Ljava/util/List<-Ljava/lang/Number;>;","java.util.List<? super java.lang.Number>");
+               checkClassTypeSignature("Ljava/util/List<*>;",                  "java.util.List<?>");
+               checkClassTypeSignature("Ljava/util/Map<*-Ljava/lang/Number;>;","java.util.Map<?,? super java.lang.Number>");
+               
+               // with type params
+               checkClassTypeSignature("Ljava/util/Collection<TT;>;","java.util.Collection<T>");
+               
+               // arrays
+               checkClassTypeSignature("Ljava/util/List<[Ljava/lang/String;>;","java.util.List<java.lang.String[]>");
+               checkClassTypeSignature("[Ljava/util/List<Ljava/lang/String;>;","java.util.List<java.lang.String>[]");
+
+       }
+       
+       
+       public void testMethodTypeToSignature() {
+         checkMethodTypeToSignature("void",new String[]{"java.lang.String[]","boolean"},"([Ljava/lang/String;Z)V");
+         checkMethodTypeToSignature("void",new String[]{"java.util.List<java/lang/String>"},"(Ljava/util/List<java/lang/String>;)V");
+       }
+       
+       public void testMethodSignatureToArgumentTypes() {
+         checkMethodSignatureArgumentTypes("([Ljava/lang/String;Z)V",new String[]{"java.lang.String[]","boolean"});
+         checkMethodSignatureArgumentTypes("(Ljava/util/List<java/lang/String>;)V",new String[]{"java.util.List<java/lang/String>"});
+       }
+       
+       public void testMethodSignatureReturnType() {
+         checkMethodSignatureReturnType("([Ljava/lang/String;)Z","boolean");
+       }
+       
+       public void testLoadingGenerics() throws ClassNotFoundException {
+               JavaClass clazz = getClassFromJar("PossibleGenericsSigs");
+               // J5TODO asc fill this bit in...
+       }
+       
+       
+       // helper methods below
+
+       // These routines call BCEL to determine if it can correctly translate from one form to the other.
+       private void checkClassTypeSignature(String sig, String expected) {
+               StringBuffer result = new StringBuffer();
+               int p = Utility.readClassTypeSignatureFrom(sig,0,result,false);
+               assertTrue("Only swallowed "+p+" chars of this sig "+sig+" (len="+sig.length()+")",p==sig.length());
+               assertTrue("Expected '"+expected+"' but got '"+result.toString()+"'",result.toString().equals(expected));
+       }
+       
+       private void checkMethodTypeToSignature(String ret,String[] args,String expected) {
+               String res = Utility.methodTypeToSignature(ret,args);
+               if (!res.equals(expected)) {
+                       fail("Should match.  Got: "+res+"  Expected:"+expected);
+               }
+       }
+       
+       private void checkMethodSignatureReturnType(String sig,String expected) {
+               String result = Utility.methodSignatureReturnType(sig,false);
+               if (!result.equals(expected)) {
+                       fail("Should match.  Got: "+result+"  Expected:"+expected);
+               }
+       }
+       
+       private void checkMethodSignatureArgumentTypes(String in,String[] expected) {
+               String[] result = Utility.methodSignatureArgumentTypes(in,false);
+               if (result.length!=expected.length) {
+                       fail("Expected "+expected.length+" entries to be returned but only got "+result.length);
+               }
+               for (int i = 0; i < expected.length; i++) {
+                       String string = result[i];
+                       if (!string.equals(expected[i]))
+                               fail("Argument: "+i+" should have been "+expected[i]+" but was "+string);
+               }
+       }
+       
+       public Signature getSignatureAttribute(JavaClass clazz,String name) {
+               Method m = getMethod(clazz,name);
+               Attribute[] as = m.getAttributes();
+               for (int i = 0; i < as.length; i++) {
+                       Attribute attribute = as[i];
+                       if (attribute.getName().equals("Signature")) {
+                               return (Signature)attribute;
+                       }
+               }
+               return null;
+       }
+       
+}