]> source.dussan.org Git - javassist.git/commitdiff
reformatted.
authorchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Mon, 18 Oct 2004 18:53:57 +0000 (18:53 +0000)
committerchiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3>
Mon, 18 Oct 2004 18:53:57 +0000 (18:53 +0000)
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@143 30ef5769-5b8d-40dd-aea6-55b5d6557bb3

src/main/javassist/CannotCompileException.java
src/main/javassist/bytecode/Descriptor.java
src/main/javassist/compiler/CodeGen.java

index f01a79a0896a73b57c07904fd088102b7b51169e..042662810855c08495de0994f9232dcd2be83ef1 100644 (file)
@@ -33,6 +33,8 @@ public class CannotCompileException extends Exception {
 
     /**
      * Constructs a CannotCompileException with a message.
+     *
+     * @param msg       the message.
      */
     public CannotCompileException(String msg) {
         super(msg);
@@ -41,7 +43,10 @@ public class CannotCompileException extends Exception {
     }
 
     /**
-     * Constructs a CannotCompileException with an <code>Exception</code>.
+     * Constructs a CannotCompileException with an <code>Exception</code>
+     * representing the cause.
+     *
+     * @param e     the cause.
      */
     public CannotCompileException(Throwable e) {
         super("by " + e.toString());
@@ -49,6 +54,13 @@ public class CannotCompileException extends Exception {
         cause = e;
     }
 
+    /**
+     * Constructs a CannotCompileException with a detailed message
+     * and an <code>Exception</code> representing the cause.
+     *
+     * @param msg   the message.
+     * @param e     the cause.
+     */
     public CannotCompileException(String msg, Throwable e) {
         this(msg);
         cause = e;
@@ -66,8 +78,7 @@ public class CannotCompileException extends Exception {
      * Constructs a CannotCompileException with an <code>CompileError</code>.
      */
     public CannotCompileException(CompileError e) {
-        super("[source error] " + e.getMessage(), e);
-        message = null;
+        this("[source error] " + e.getMessage(), e);
     }
 
     /**
index 1128d7e3a1faec220fdb8b51183927e536ad5c71..1b07548cfc8c9165f876252b78d81315396009c0 100644 (file)
@@ -19,660 +19,622 @@ import javassist.ClassPool;
 import javassist.CtClass;
 import javassist.CtPrimitiveType;
 import javassist.NotFoundException;
-
 import java.util.Map;
 
 /**
  * A support class for dealing with descriptors.
- * <p/>
+ *
  * <p>See chapter 4.3 in "The Java Virtual Machine Specification (2nd ed.)"
  */
-public class Descriptor
-{
-   /**
-    * Converts a class name into the internal representation used in
-    * the JVM.
-    * <p/>
-    * <p>Note that <code>toJvmName(toJvmName(s))</code> is equivalent
-    * to <code>toJvmName(s)</code>.
-    */
-   public static String toJvmName(String classname)
-   {
-      return classname.replace('.', '/');
-   }
-
-   /**
-    * Converts a class name from the internal representation used in
-    * the JVM to the normal one used in Java.
-    */
-   public static String toJavaName(String classname)
-   {
-      return classname.replace('/', '.');
-   }
-
-   /**
-    * Returns the internal representation of the class name in the
-    * JVM.
-    */
-   public static String toJvmName(CtClass clazz)
-   {
-      if (clazz.isArray())
-         return of(clazz);
-      else
-         return toJvmName(clazz.getName());
-   }
-
-   /**
-    * Converts to a Java class name from a descriptor
-    */
-   public static String toClassName(String descriptor)
-   {
-      if (descriptor.equals("V")) return "void";
-      if (descriptor.equals("I")) return "int";
-      if (descriptor.equals("B")) return "byte";
-      if (descriptor.equals("J")) return "long";
-      if (descriptor.equals("D")) return "double";
-      if (descriptor.equals("F")) return "float";
-      if (descriptor.equals("C")) return "char";
-      if (descriptor.equals("S")) return "short";
-      if (descriptor.equals("Z")) return "boolean";
-      String newname = toJavaName(descriptor);
-      return newname.substring(1, newname.length() - 1);
-   }
-
-   /**
-    * Converts to a descriptor from a Java class name
-    */
-   public static String of(String classname)
-   {
-      if (classname.equals("void")) return "V";
-      if (classname.equals("int")) return "I";
-      if (classname.equals("byte")) return "B";
-      if (classname.equals("long")) return "J";
-      if (classname.equals("double")) return "D";
-      if (classname.equals("float")) return "F";
-      if (classname.equals("char")) return "C";
-      if (classname.equals("short")) return "S";
-      if (classname.equals("boolean")) return "Z";
-      return "L" + toJvmName(classname) + ";";
-   }
-
-   /**
-    * Substitutes a class name
-    * in the given descriptor string.
-    *
-    * @param desc    descriptor string
-    * @param oldname replaced JVM class name
-    * @param newname substituted JVM class name
-    * @see Descriptor#toJvmName(String)
-    */
-   public static String rename(String desc,
-                               String oldname, String newname)
-   {
-      if (desc.indexOf(oldname) < 0)
-         return desc;
-
-      StringBuffer newdesc = new StringBuffer();
-      int head = 0;
-      int i = 0;
-      for (; ;)
-      {
-         int j = desc.indexOf('L', i);
-         if (j < 0)
-            break;
-         else if (desc.startsWith(oldname, j + 1)
-                 && desc.charAt(j + oldname.length() + 1) == ';')
-         {
-            newdesc.append(desc.substring(head, j));
+public class Descriptor {
+    /**
+     * Converts a class name into the internal representation used in
+     * the JVM.
+     *
+     * <p>Note that <code>toJvmName(toJvmName(s))</code> is equivalent
+     * to <code>toJvmName(s)</code>.
+     */
+    public static String toJvmName(String classname) {
+        return classname.replace('.', '/');
+    }
+
+    /**
+     * Converts a class name from the internal representation used in
+     * the JVM to the normal one used in Java.
+     */
+    public static String toJavaName(String classname) {
+        return classname.replace('/', '.');
+    }
+
+    /**
+     * Returns the internal representation of the class name in the
+     * JVM.
+     */
+    public static String toJvmName(CtClass clazz) {
+        if (clazz.isArray())
+            return of(clazz);
+        else
+            return toJvmName(clazz.getName());
+    }
+
+    /**
+     * Converts to a Java class name from a descriptor
+     */
+    public static String toClassName(String descriptor) {
+        if (descriptor.equals("V"))
+            return "void";
+        else if (descriptor.equals("I"))
+            return "int";
+        else if (descriptor.equals("B"))
+            return "byte";
+        else if (descriptor.equals("J"))
+            return "long";
+        else if (descriptor.equals("D"))
+            return "double";
+        else if (descriptor.equals("F"))
+            return "float";
+        else if (descriptor.equals("C"))
+            return "char";
+        else if (descriptor.equals("S"))
+            return "short";
+        else if (descriptor.equals("Z"))
+            return "boolean";
+        else {
+            String newname = toJavaName(descriptor);
+            return newname.substring(1, newname.length() - 1);
+        }
+    }
+
+    /**
+     * Converts to a descriptor from a Java class name
+     */
+    public static String of(String classname) {
+        if (classname.equals("void"))
+            return "V";
+        else if (classname.equals("int"))
+            return "I";
+        else if (classname.equals("byte"))
+            return "B";
+        else if (classname.equals("long"))
+            return "J";
+        else if (classname.equals("double"))
+            return "D";
+        else if (classname.equals("float"))
+            return "F";
+        else if (classname.equals("char"))
+            return "C";
+        else if (classname.equals("short"))
+            return "S";
+        else if (classname.equals("boolean"))
+            return "Z";
+        else
+            return "L" + toJvmName(classname) + ";";
+    }
+
+    /**
+     * Substitutes a class name
+     * in the given descriptor string.
+     *
+     * @param desc    descriptor string
+     * @param oldname replaced JVM class name
+     * @param newname substituted JVM class name
+     *
+     * @see Descriptor#toJvmName(String)
+     */
+    public static String rename(String desc, String oldname, String newname) {
+        if (desc.indexOf(oldname) < 0)
+            return desc;
+
+        StringBuffer newdesc = new StringBuffer();
+        int head = 0;
+        int i = 0;
+        for (;;) {
+            int j = desc.indexOf('L', i);
+            if (j < 0)
+                break;
+            else if (desc.startsWith(oldname, j + 1)
+                     && desc.charAt(j + oldname.length() + 1) == ';') {
+                newdesc.append(desc.substring(head, j));
+                newdesc.append('L');
+                newdesc.append(newname);
+                newdesc.append(';');
+                head = i = j + oldname.length() + 2;
+            }
+            else {
+                i = desc.indexOf(';', j) + 1;
+                if (i < 1)
+                    break; // ';' was not found.
+            }
+        }
+
+        if (head == 0)
+            return desc;
+        else {
+            int len = desc.length();
+            if (head < len)
+                newdesc.append(desc.substring(head, len));
+
+            return newdesc.toString();
+        }
+    }
+
+    /**
+     * Substitutes class names in the given descriptor string
+     * according to the given <code>map</code>.
+     *
+     * @param map a map between replaced and substituted
+     *            JVM class names.
+     * @see Descriptor#toJvmName(String)
+     */
+    public static String rename(String desc, Map map) {
+        if (map == null)
+            return desc;
+
+        StringBuffer newdesc = new StringBuffer();
+        int head = 0;
+        int i = 0;
+        for (;;) {
+            int j = desc.indexOf('L', i);
+            if (j < 0)
+                break;
+
+            int k = desc.indexOf(';', j);
+            if (k < 0)
+                break;
+
+            i = k + 1;
+            String name = desc.substring(j + 1, k);
+            String name2 = (String)map.get(name);
+            if (name2 != null) {
+                newdesc.append(desc.substring(head, j));
+                newdesc.append('L');
+                newdesc.append(name2);
+                newdesc.append(';');
+                head = i;
+            }
+        }
+
+        if (head == 0)
+            return desc;
+        else {
+            int len = desc.length();
+            if (head < len)
+                newdesc.append(desc.substring(head, len));
+
+            return newdesc.toString();
+        }
+    }
+
+    /**
+     * Returns the descriptor representing the given type.
+     */
+    public static String of(CtClass type) {
+        StringBuffer sbuf = new StringBuffer();
+        toDescriptor(sbuf, type);
+        return sbuf.toString();
+    }
+
+    private static void toDescriptor(StringBuffer desc, CtClass type) {
+        if (type.isArray()) {
+            desc.append('[');
+            try {
+                toDescriptor(desc, type.getComponentType());
+            }
+            catch (NotFoundException e) {
+                desc.append('L');
+                String name = type.getName();
+                desc.append(toJvmName(name.substring(0, name.length() - 2)));
+                desc.append(';');
+            }
+        }
+        else if (type.isPrimitive()) {
+            CtPrimitiveType pt = (CtPrimitiveType)type;
+            desc.append(pt.getDescriptor());
+        }
+        else { // class type
+            desc.append('L');
+            desc.append(type.getName().replace('.', '/'));
+            desc.append(';');
+        }
+    }
+
+    /**
+     * Returns the descriptor representing a constructor receiving
+     * the given parameter types.
+     *
+     * @param paramTypes parameter types
+     */
+    public static String ofConstructor(CtClass[] paramTypes) {
+        return ofMethod(CtClass.voidType, paramTypes);
+    }
+
+    /**
+     * Returns the descriptor representing a method that receives
+     * the given parameter types and returns the given type.
+     *
+     * @param returnType return type
+     * @param paramTypes parameter types
+     */
+    public static String ofMethod(CtClass returnType, CtClass[] paramTypes) {
+        StringBuffer desc = new StringBuffer();
+        desc.append('(');
+        if (paramTypes != null) {
+            int n = paramTypes.length;
+            for (int i = 0; i < n; ++i)
+                toDescriptor(desc, paramTypes[i]);
+        }
+
+        desc.append(')');
+        if (returnType != null)
+            toDescriptor(desc, returnType);
+
+        return desc.toString();
+    }
+
+    /**
+     * Returns the descriptor representing a list of parameter types.
+     * For example, if the given parameter types are two <code>int</code>,
+     * then this method returns <code>"(II)"</code>.
+     *
+     * @param paramTypes parameter types
+     */
+    public static String ofParameters(CtClass[] paramTypes) {
+        return ofMethod(null, paramTypes);
+    }
+
+    /**
+     * Appends a parameter type to the parameter list represented
+     * by the given descriptor.
+     *
+     * <p><code>classname</code> must not be an array type.
+     *
+     * @param classname parameter type (not primitive type)
+     * @param desc      descriptor
+     */
+    public static String appendParameter(String classname, String desc) {
+        int i = desc.indexOf(')');
+        if (i < 0)
+            return desc;
+        else {
+            StringBuffer newdesc = new StringBuffer();
+            newdesc.append(desc.substring(0, i));
             newdesc.append('L');
-            newdesc.append(newname);
+            newdesc.append(classname.replace('.', '/'));
             newdesc.append(';');
-            head = i = j + oldname.length() + 2;
-         }
-         else
-         {
-            i = desc.indexOf(';', j) + 1;
-            if (i < 1)
-               break;      // ';' was not found.
-         }
-      }
-
-      if (head == 0)
-         return desc;
-      else
-      {
-         int len = desc.length();
-         if (head < len)
-            newdesc.append(desc.substring(head, len));
-
-         return newdesc.toString();
-      }
-   }
-
-   /**
-    * Substitutes class names in the given descriptor string
-    * according to the given <code>map</code>.
-    *
-    * @param map a map between replaced and substituted
-    *            JVM class names.
-    * @see Descriptor#toJvmName(String)
-    */
-   public static String rename(String desc, Map map)
-   {
-      if (map == null)
-         return desc;
-
-      StringBuffer newdesc = new StringBuffer();
-      int head = 0;
-      int i = 0;
-      for (; ;)
-      {
-         int j = desc.indexOf('L', i);
-         if (j < 0)
-            break;
-
-         int k = desc.indexOf(';', j);
-         if (k < 0)
-            break;
-
-         i = k + 1;
-         String name = desc.substring(j + 1, k);
-         String name2 = (String) map.get(name);
-         if (name2 != null)
-         {
-            newdesc.append(desc.substring(head, j));
+            newdesc.append(desc.substring(i));
+            return newdesc.toString();
+        }
+    }
+
+    /**
+     * Inserts a parameter type at the beginning of the parameter
+     * list represented
+     * by the given descriptor.
+     *
+     * <p><code>classname</code> must not be an array type.
+     *
+     * @param classname parameter type (not primitive type)
+     * @param desc      descriptor
+     */
+    public static String insertParameter(String classname, String desc) {
+        if (desc.charAt(0) != '(')
+            return desc;
+        else
+            return "(L" + classname.replace('.', '/') + ';'
+                   + desc.substring(1);
+    }
+
+    /**
+     * Changes the return type included in the given descriptor.
+     *
+     * <p><code>classname</code> must not be an array type.
+     *
+     * @param classname return type
+     * @param desc      descriptor
+     */
+    public static String changeReturnType(String classname, String desc) {
+        int i = desc.indexOf(')');
+        if (i < 0)
+            return desc;
+        else {
+            StringBuffer newdesc = new StringBuffer();
+            newdesc.append(desc.substring(0, i + 1));
             newdesc.append('L');
-            newdesc.append(name2);
+            newdesc.append(classname.replace('.', '/'));
             newdesc.append(';');
-            head = i;
-         }
-      }
-
-      if (head == 0)
-         return desc;
-      else
-      {
-         int len = desc.length();
-         if (head < len)
-            newdesc.append(desc.substring(head, len));
-
-         return newdesc.toString();
-      }
-   }
-
-   /**
-    * Returns the descriptor representing the given type.
-    */
-   public static String of(CtClass type)
-   {
-      StringBuffer sbuf = new StringBuffer();
-      toDescriptor(sbuf, type);
-      return sbuf.toString();
-   }
-
-   private static void toDescriptor(StringBuffer desc, CtClass type)
-   {
-      if (type.isArray())
-      {
-         desc.append('[');
-         try
-         {
-            toDescriptor(desc, type.getComponentType());
-         }
-         catch (NotFoundException e)
-         {
-            desc.append('L');
-            String name = type.getName();
-            desc.append(toJvmName(name.substring(0, name.length() - 2)));
-            desc.append(';');
-         }
-      }
-      else if (type.isPrimitive())
-      {
-         CtPrimitiveType pt = (CtPrimitiveType) type;
-         desc.append(pt.getDescriptor());
-      }
-      else
-      {          // class type
-         desc.append('L');
-         desc.append(type.getName().replace('.', '/'));
-         desc.append(';');
-      }
-   }
-
-   /**
-    * Returns the descriptor representing a constructor receiving
-    * the given parameter types.
-    *
-    * @param paramTypes parameter types
-    */
-   public static String ofConstructor(CtClass[] paramTypes)
-   {
-      return ofMethod(CtClass.voidType, paramTypes);
-   }
-
-   /**
-    * Returns the descriptor representing a method that receives
-    * the given parameter types and returns the given type.
-    *
-    * @param returnType return type
-    * @param paramTypes parameter types
-    */
-   public static String ofMethod(CtClass returnType, CtClass[] paramTypes)
-   {
-      StringBuffer desc = new StringBuffer();
-      desc.append('(');
-      if (paramTypes != null)
-      {
-         int n = paramTypes.length;
-         for (int i = 0; i < n; ++i)
-            toDescriptor(desc, paramTypes[i]);
-      }
-
-      desc.append(')');
-      if (returnType != null)
-         toDescriptor(desc, returnType);
-
-      return desc.toString();
-   }
-
-   /**
-    * Returns the descriptor representing a list of parameter types.
-    * For example, if the given parameter types are two <code>int</code>,
-    * then this method returns <code>"(II)"</code>.
-    *
-    * @param paramTypes parameter types
-    */
-   public static String ofParameters(CtClass[] paramTypes)
-   {
-      return ofMethod(null, paramTypes);
-   }
-
-   /**
-    * Appends a parameter type to the parameter list represented
-    * by the given descriptor.
-    * <p/>
-    * <p><code>classname</code> must not be an array type.
-    *
-    * @param classname parameter type (not primitive type)
-    * @param desc      descriptor
-    */
-   public static String appendParameter(String classname,
-                                        String desc)
-   {
-      int i = desc.indexOf(')');
-      if (i < 0)
-         return desc;
-      else
-      {
-         StringBuffer newdesc = new StringBuffer();
-         newdesc.append(desc.substring(0, i));
-         newdesc.append('L');
-         newdesc.append(classname.replace('.', '/'));
-         newdesc.append(';');
-         newdesc.append(desc.substring(i));
-         return newdesc.toString();
-      }
-   }
-
-   /**
-    * Inserts a parameter type at the beginning of the parameter
-    * list represented
-    * by the given descriptor.
-    * <p/>
-    * <p><code>classname</code> must not be an array type.
-    *
-    * @param classname parameter type (not primitive type)
-    * @param desc      descriptor
-    */
-   public static String insertParameter(String classname,
-                                        String desc)
-   {
-      if (desc.charAt(0) != '(')
-         return desc;
-      else
-         return "(L" + classname.replace('.', '/') + ';'
-                 + desc.substring(1);
-   }
-
-   /**
-    * Changes the return type included in the given descriptor.
-    * <p/>
-    * <p><code>classname</code> must not be an array type.
-    *
-    * @param classname return type
-    * @param desc      descriptor
-    */
-   public static String changeReturnType(String classname, String desc)
-   {
-      int i = desc.indexOf(')');
-      if (i < 0)
-         return desc;
-      else
-      {
-         StringBuffer newdesc = new StringBuffer();
-         newdesc.append(desc.substring(0, i + 1));
-         newdesc.append('L');
-         newdesc.append(classname.replace('.', '/'));
-         newdesc.append(';');
-         return newdesc.toString();
-      }
-   }
-
-   /**
-    * Returns the <code>CtClass</code> objects representing the parameter
-    * types specified by the given descriptor.
-    *
-    * @param desc descriptor
-    * @param cp   the class pool used for obtaining
-    *             a <code>CtClass</code> object.
-    */
-   public static CtClass[] getParameterTypes(String desc, ClassPool cp)
-           throws NotFoundException
-   {
-      if (desc.charAt(0) != '(')
-         return null;
-      else
-      {
-         int num = numOfParameters(desc);
-         CtClass[] args = new CtClass[num];
-         int n = 0;
-         int i = 1;
-         do
-         {
-            i = toCtClass(cp, desc, i, args, n++);
-         } while (i > 0);
-         return args;
-      }
-   }
-
-   /**
-    * Returns true if the list of the parameter types of desc1 is equal to
-    * that of desc2.
-    * For example, "(II)V" and "(II)I" are equal.
-    */
-   public static boolean eqParamTypes(String desc1, String desc2)
-   {
-      if (desc1.charAt(0) != '(')
-         return false;
-
-      for (int i = 0; true; ++i)
-      {
-         char c = desc1.charAt(i);
-         if (c != desc2.charAt(i))
+            return newdesc.toString();
+        }
+    }
+
+    /**
+     * Returns the <code>CtClass</code> objects representing the parameter
+     * types specified by the given descriptor.
+     *
+     * @param desc descriptor
+     * @param cp   the class pool used for obtaining
+     *             a <code>CtClass</code> object.
+     */
+    public static CtClass[] getParameterTypes(String desc, ClassPool cp)
+        throws NotFoundException
+    {
+        if (desc.charAt(0) != '(')
+            return null;
+        else {
+            int num = numOfParameters(desc);
+            CtClass[] args = new CtClass[num];
+            int n = 0;
+            int i = 1;
+            do {
+                i = toCtClass(cp, desc, i, args, n++);
+            } while (i > 0);
+            return args;
+        }
+    }
+
+    /**
+     * Returns true if the list of the parameter types of desc1 is equal to
+     * that of desc2.
+     * For example, "(II)V" and "(II)I" are equal.
+     */
+    public static boolean eqParamTypes(String desc1, String desc2) {
+        if (desc1.charAt(0) != '(')
             return false;
 
-         if (c == ')')
-            return true;
-      }
-   }
-
-   /**
-    * Returns the signature of the given descriptor.  The signature does
-    * not include the return type.  For example, the signature of "(I)V"
-    * is "(I)".
-    */
-   public static String getParamDescriptor(String decl)
-   {
-      return decl.substring(0, decl.indexOf(')') + 1);
-   }
-
-   /**
-    * Returns the <code>CtClass</code> object representing the return
-    * type specified by the given descriptor.
-    *
-    * @param desc descriptor
-    * @param cp   the class pool used for obtaining
-    *             a <code>CtClass</code> object.
-    */
-   public static CtClass getReturnType(String desc, ClassPool cp)
-           throws NotFoundException
-   {
-      int i = desc.indexOf(')');
-      if (i < 0)
-         return null;
-      else
-      {
-         CtClass[] type = new CtClass[1];
-         toCtClass(cp, desc, i + 1, type, 0);
-         return type[0];
-      }
-   }
-
-   /**
-    * Returns the number of the prameters included in the given
-    * descriptor.
-    *
-    * @param desc descriptor
-    */
-   public static int numOfParameters(String desc)
-   {
-      int n = 0;
-      int i = 1;
-      for (; ;)
-      {
-         char c = desc.charAt(i);
-         if (c == ')')
-            break;
+        for (int i = 0; true; ++i) {
+            char c = desc1.charAt(i);
+            if (c != desc2.charAt(i))
+                return false;
 
-         while (c == '[')
-            c = desc.charAt(++i);
-
-         if (c == 'L')
-         {
-            i = desc.indexOf(';', i) + 1;
-            if (i <= 0)
-               throw new IndexOutOfBoundsException("bad descriptor");
-         }
-         else
-            ++i;
-
-         ++n;
-      }
-
-      return n;
-   }
-
-   /**
-    * Returns a <code>CtClass</code> object representing the type
-    * specified by the given descriptor.
-    * <p/>
-    * <p>This method works even if the package-class separator is
-    * not <code>/</code> but <code>.</code> (period).  For example,
-    * it accepts <code>Ljava.lang.Object;</code>
-    * as well as <code>Ljava/lang/Object;</code>.
-    *
-    * @param desc descriptor
-    * @param cp   the class pool used for obtaining
-    *             a <code>CtClass</code> object.
-    */
-   public static CtClass toCtClass(String desc, ClassPool cp)
-           throws NotFoundException
-   {
-      CtClass[] clazz = new CtClass[1];
-      int res = toCtClass(cp, desc, 0, clazz, 0);
-      if (res >= 0)
-         return clazz[0];
-      else
-      {
-         // maybe, you forgot to surround the class name with
-         // L and ;.  It violates the protocol, but I'm tolerant...
-         return cp.get(desc.replace('/', '.'));
-      }
-   }
-
-   private static int toCtClass(ClassPool cp, String desc, int i,
-                                CtClass[] args, int n)
-           throws NotFoundException
-   {
-      int i2;
-      String name;
-
-      int arrayDim = 0;
-      char c = desc.charAt(i);
-      while (c == '[')
-      {
-         ++arrayDim;
-         c = desc.charAt(++i);
-      }
-
-      if (c == 'L')
-      {
-         i2 = desc.indexOf(';', ++i);
-         name = desc.substring(i, i2++).replace('/', '.');
-      }
-      else
-      {
-         CtClass type = toPrimitiveClass(c);
-         if (type == null)
-            return -1;      // error
-
-         i2 = i + 1;
-         if (arrayDim == 0)
-         {
-            args[n] = type;
-            return i2;      // neither an array type or a class type
-         }
-         else
-            name = type.getName();
-      }
-
-      if (arrayDim > 0)
-      {
-         StringBuffer sbuf = new StringBuffer(name);
-         while (arrayDim-- > 0)
-            sbuf.append("[]");
-
-         name = sbuf.toString();
-      }
-
-      args[n] = cp.get(name);
-      return i2;
-   }
-
-   private static CtClass toPrimitiveClass(char c)
-   {
-      CtClass type = null;
-      switch (c)
-      {
-      case 'Z':
-         type = CtClass.booleanType;
-         break;
-      case 'C':
-         type = CtClass.charType;
-         break;
-      case 'B':
-         type = CtClass.byteType;
-         break;
-      case 'S':
-         type = CtClass.shortType;
-         break;
-      case 'I':
-         type = CtClass.intType;
-         break;
-      case 'J':
-         type = CtClass.longType;
-         break;
-      case 'F':
-         type = CtClass.floatType;
-         break;
-      case 'D':
-         type = CtClass.doubleType;
-         break;
-      case 'V':
-         type = CtClass.voidType;
-         break;
-      }
-
-      return type;
-   }
-
-   /**
-    * Computes the dimension of the array represented by the given
-    * descriptor.  For example, if the descriptor is <code>"[[I"</code>,
-    * then this method returns 2.
-    *
-    * @param desc the descriptor.
-    * @return 0        if the descriptor does not represent an array type.
-    */
-   public static int arrayDimension(String desc)
-   {
-      int dim = 0;
-      while (desc.charAt(dim) == '[')
-         ++dim;
-
-      return dim;
-   }
-
-   /**
-    * Returns the descriptor of the type of the array component.
-    * For example, if the given descriptor is
-    * <code>"[[Ljava/lang/String;"</code> and the given dimension is 2,
-    * then this method returns <code>"Ljava/lang/String;"</code>.
-    *
-    * @param desc the descriptor.
-    * @param dim  the array dimension.
-    */
-   public static String toArrayComponent(String desc, int dim)
-   {
-      return desc.substring(dim);
-   }
-
-   /**
-    * Computes the data size specified by the given descriptor.
-    * For example, if the descriptor is "D", this method returns 2.
-    * <p/>
-    * <p>If the descriptor represents a method type, this method returns
-    * (the size of the returned value) - (the sum of the data sizes
-    * of all the parameters).  For example, if the descriptor is
-    * "(I)D", then this method returns 1 (= 2 - 1).
-    *
-    * @param desc descriptor
-    */
-   public static int dataSize(String desc)
-   {
-      int n = 0;
-      char c = desc.charAt(0);
-      if (c == '(')
-      {
-         int i = 1;
-         for (; ;)
-         {
-            c = desc.charAt(i);
             if (c == ')')
-            {
-               c = desc.charAt(i + 1);
-               break;
-            }
+                return true;
+        }
+    }
+
+    /**
+     * Returns the signature of the given descriptor.  The signature does
+     * not include the return type.  For example, the signature of "(I)V"
+     * is "(I)".
+     */
+    public static String getParamDescriptor(String decl) {
+        return decl.substring(0, decl.indexOf(')') + 1);
+    }
+
+    /**
+     * Returns the <code>CtClass</code> object representing the return
+     * type specified by the given descriptor.
+     *
+     * @param desc descriptor
+     * @param cp   the class pool used for obtaining
+     *             a <code>CtClass</code> object.
+     */
+    public static CtClass getReturnType(String desc, ClassPool cp)
+        throws NotFoundException
+    {
+        int i = desc.indexOf(')');
+        if (i < 0)
+            return null;
+        else {
+            CtClass[] type = new CtClass[1];
+            toCtClass(cp, desc, i + 1, type, 0);
+            return type[0];
+        }
+    }
+
+    /**
+     * Returns the number of the prameters included in the given
+     * descriptor.
+     *
+     * @param desc descriptor
+     */
+    public static int numOfParameters(String desc) {
+        int n = 0;
+        int i = 1;
+        for (;;) {
+            char c = desc.charAt(i);
+            if (c == ')')
+                break;
 
-            boolean array = false;
             while (c == '[')
-            {
-               array = true;
-               c = desc.charAt(++i);
-            }
+                c = desc.charAt(++i);
 
-            if (c == 'L')
-            {
-               i = desc.indexOf(';', i) + 1;
-               if (i <= 0)
-                  throw new IndexOutOfBoundsException("bad descriptor");
+            if (c == 'L') {
+                i = desc.indexOf(';', i) + 1;
+                if (i <= 0)
+                    throw new IndexOutOfBoundsException("bad descriptor");
             }
             else
-               ++i;
-
-            if (!array && (c == 'J' || c == 'D'))
-               n -= 2;
+                ++i;
+
+            ++n;
+        }
+
+        return n;
+    }
+
+    /**
+     * Returns a <code>CtClass</code> object representing the type
+     * specified by the given descriptor.
+     *
+     * <p>This method works even if the package-class separator is
+     * not <code>/</code> but <code>.</code> (period).  For example,
+     * it accepts <code>Ljava.lang.Object;</code>
+     * as well as <code>Ljava/lang/Object;</code>.
+     *
+     * @param desc descriptor
+     * @param cp   the class pool used for obtaining
+     *             a <code>CtClass</code> object.
+     */
+    public static CtClass toCtClass(String desc, ClassPool cp)
+        throws NotFoundException
+    {
+        CtClass[] clazz = new CtClass[1];
+        int res = toCtClass(cp, desc, 0, clazz, 0);
+        if (res >= 0)
+            return clazz[0];
+        else {
+            // maybe, you forgot to surround the class name with
+            // L and ;.  It violates the protocol, but I'm tolerant...
+            return cp.get(desc.replace('/', '.'));
+        }
+    }
+
+    private static int toCtClass(ClassPool cp, String desc, int i,
+                                 CtClass[] args, int n)
+        throws NotFoundException
+    {
+        int i2;
+        String name;
+
+        int arrayDim = 0;
+        char c = desc.charAt(i);
+        while (c == '[') {
+            ++arrayDim;
+            c = desc.charAt(++i);
+        }
+
+        if (c == 'L') {
+            i2 = desc.indexOf(';', ++i);
+            name = desc.substring(i, i2++).replace('/', '.');
+        }
+        else {
+            CtClass type = toPrimitiveClass(c);
+            if (type == null)
+                return -1; // error
+
+            i2 = i + 1;
+            if (arrayDim == 0) {
+                args[n] = type;
+                return i2; // neither an array type or a class type
+            }
             else
-               --n;
-         }
-      }
+                name = type.getName();
+        }
+
+        if (arrayDim > 0) {
+            StringBuffer sbuf = new StringBuffer(name);
+            while (arrayDim-- > 0)
+                sbuf.append("[]");
+
+            name = sbuf.toString();
+        }
+
+        args[n] = cp.get(name);
+        return i2;
+    }
+
+    private static CtClass toPrimitiveClass(char c) {
+        CtClass type = null;
+        switch (c) {
+        case 'Z' :
+            type = CtClass.booleanType;
+            break;
+        case 'C' :
+            type = CtClass.charType;
+            break;
+        case 'B' :
+            type = CtClass.byteType;
+            break;
+        case 'S' :
+            type = CtClass.shortType;
+            break;
+        case 'I' :
+            type = CtClass.intType;
+            break;
+        case 'J' :
+            type = CtClass.longType;
+            break;
+        case 'F' :
+            type = CtClass.floatType;
+            break;
+        case 'D' :
+            type = CtClass.doubleType;
+            break;
+        case 'V' :
+            type = CtClass.voidType;
+            break;
+        }
+
+        return type;
+    }
+
+    /**
+     * Computes the dimension of the array represented by the given
+     * descriptor.  For example, if the descriptor is <code>"[[I"</code>,
+     * then this method returns 2.
+     *
+     * @param desc the descriptor.
+     * @return 0        if the descriptor does not represent an array type.
+     */
+    public static int arrayDimension(String desc) {
+        int dim = 0;
+        while (desc.charAt(dim) == '[')
+            ++dim;
+
+        return dim;
+    }
+
+    /**
+     * Returns the descriptor of the type of the array component.
+     * For example, if the given descriptor is
+     * <code>"[[Ljava/lang/String;"</code> and the given dimension is 2,
+     * then this method returns <code>"Ljava/lang/String;"</code>.
+     *
+     * @param desc the descriptor.
+     * @param dim  the array dimension.
+     */
+    public static String toArrayComponent(String desc, int dim) {
+        return desc.substring(dim);
+    }
+
+    /**
+     * Computes the data size specified by the given descriptor.
+     * For example, if the descriptor is "D", this method returns 2.
+     *
+     * <p>If the descriptor represents a method type, this method returns
+     * (the size of the returned value) - (the sum of the data sizes
+     * of all the parameters).  For example, if the descriptor is
+     * "(I)D", then this method returns 1 (= 2 - 1).
+     *
+     * @param desc descriptor
+     */
+    public static int dataSize(String desc) {
+        int n = 0;
+        char c = desc.charAt(0);
+        if (c == '(') {
+            int i = 1;
+            for (;;) {
+                c = desc.charAt(i);
+                if (c == ')') {
+                    c = desc.charAt(i + 1);
+                    break;
+                }
+
+                boolean array = false;
+                while (c == '[') {
+                    array = true;
+                    c = desc.charAt(++i);
+                }
+
+                if (c == 'L') {
+                    i = desc.indexOf(';', i) + 1;
+                    if (i <= 0)
+                        throw new IndexOutOfBoundsException("bad descriptor");
+                }
+                else
+                    ++i;
+
+                if (!array && (c == 'J' || c == 'D'))
+                    n -= 2;
+                else
+                    --n;
+            }
+        }
 
-      if (c == 'J' || c == 'D')
-         n += 2;
-      else if (c != 'V')
-         ++n;
+        if (c == 'J' || c == 'D')
+            n += 2;
+        else if (c != 'V')
+            ++n;
 
-      return n;
-   }
+        return n;
+    }
 }
index 221cbfcd496d7c7727b136db2839b8aca13e1a2b..3308a2420691ce84e258e1df589d862dfdf32492 100644 (file)
@@ -1370,7 +1370,7 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId {
             bytecode.addIconst(0);
         }
         else if (token == CALL)         // method call
-            fatal(); 
+            fatal();
         else {
             expr.oprand1().accept(this);
             int type = typePrecedence(exprType);