• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: Descriptors.java,v 1.1.1.1 2004/05/09 16:57:52 vlad_r Exp $
8  */
9 package com.vladium.util;
10 
11 import com.vladium.jcd.cls.IClassDefConstants;
12 
13 // ----------------------------------------------------------------------------
14 /**
15  * @author Vlad Roubtsov, (C) 2003
16  */
17 public
18 abstract class Descriptors
19 {
20     // public: ................................................................
21 
22     // TODO: some overlap with Types in c.v.jcp.lib
23 
24     public static final char JAVA_NAME_SEPARATOR = '.';
25     public static final char VM_NAME_SEPARATOR = '/';
26 
combine(final String packageName, final String name, final char separator)27     public static String combine (final String packageName, final String name, final char separator)
28     {
29         if ((name == null) || (name.length () == 0))
30             throw new IllegalArgumentException ("null or empty input: name");
31 
32         if ((packageName == null) || (packageName.length () == 0))
33             return name;
34         else
35             return new StringBuffer (packageName).append (separator).append (name).toString ();
36     }
37 
combineJavaName(final String packageName, final String name)38     public static String combineJavaName (final String packageName, final String name)
39     {
40         return combine (packageName, name, JAVA_NAME_SEPARATOR);
41     }
42 
combineVMName(final String packageName, final String name)43     public static String combineVMName (final String packageName, final String name)
44     {
45         return combine (packageName, name, VM_NAME_SEPARATOR);
46     }
47 
48     /**
49      * Converts a Java package/class name to how it would be
50      * represented in the VM.<P>
51      *
52      * Example:
53      * <PRE><CODE>
54      * javaNameToVMName("java.lang.Object") = "java/lang/Object"
55      * </CODE></PRE>
56      *
57      * @see #vmNameToJavaName
58      */
javaNameToVMName(final String javaName)59     public static String javaNameToVMName (final String javaName)
60     {
61         if (javaName == null) return null;
62 
63         return javaName.replace ('.', '/');
64     }
65 
66     /**
67      * Converts a JVM package/class name to how it would be
68      * represented in Java.<P>
69      *
70      * Example:
71      * <PRE><CODE>
72      * vmNameToJavaName("java/lang/Object") = "java.lang.Object"
73      * </CODE></PRE>
74      *
75      * @see #javaNameToVMName
76      */
vmNameToJavaName(final String vmName)77     public static String vmNameToJavaName (final String vmName)
78     {
79         if (vmName == null) return null;
80 
81         return vmName.replace ('/', '.');
82     }
83 
84     /**
85      * NOTE: With 'shortTypeNames'=true the output is potentially lossy (truncates
86      * package name) and can result in method signature collisions in very rare
87      * circumstances (e.g., java.awt.List = java.util.List).<P>
88      *
89      * Return type info is also lost.
90      *
91      * @return method name (signature), no package prefix, no return type
92      */
methodVMNameToJavaName(final String className, final String methodVMName, final String descriptor, final boolean renameInits, final boolean shortTypeNames, final boolean appendReturnType)93     public static String methodVMNameToJavaName (final String className,
94                                                  final String methodVMName,
95                                                  final String descriptor,
96                                                  final boolean renameInits,
97                                                  final boolean shortTypeNames,
98                                                  final boolean appendReturnType)
99     {
100         final StringBuffer out = new StringBuffer ();
101 
102         if (renameInits)
103         {
104             if (IClassDefConstants.CLINIT_NAME.equals (methodVMName))
105                 return "<static initializer>";
106             else if (IClassDefConstants.INIT_NAME.equals (methodVMName))
107                 out.append (className);
108             else
109                 out.append (methodVMName);
110         }
111         else
112         {
113             if (IClassDefConstants.CLINIT_NAME.equals (methodVMName))
114                 return IClassDefConstants.CLINIT_NAME;
115             else
116                 out.append (methodVMName);
117         }
118 
119         final char [] chars = descriptor.toCharArray ();
120         int end;
121 
122         out.append (" (");
123         {
124             for (end = chars.length; chars [-- end] != ')'; );
125 
126             for (int start = 1; start < end; )
127             {
128                 if (start > 1) out.append (", ");
129                 start = typeDescriptorToJavaName (chars, start, shortTypeNames, out);
130             }
131         }
132 
133         if (appendReturnType)
134         {
135             out.append ("): ");
136 
137             typeDescriptorToJavaName (chars, end + 1, shortTypeNames, out);
138         }
139         else
140         {
141             out.append (')');
142         }
143 
144         return out.toString ();
145     }
146 
147 
148 
149     // protected: .............................................................
150 
151     // package: ...............................................................
152 
153     // private: ...............................................................
154 
155 //    private static int typeSignatureToJavaName (final char [] signature, int start,
156 //                                                final boolean shortTypeNames,
157 //                                                final StringBuffer out)
158 //    {
159 //
160 //    }
161 
162 
typeDescriptorToJavaName(final char [] descriptor, int start, final boolean shortTypeNames, final StringBuffer out)163     private static int typeDescriptorToJavaName (final char [] descriptor, int start,
164                                                  final boolean shortTypeNames,
165                                                  final StringBuffer out)
166     {
167         int dims;
168         for (dims = 0; descriptor [start] == '['; ++ dims, ++ start);
169 
170         char c = descriptor [start ++];
171         switch (c)
172         {
173             case 'L':
174             {
175                 if (shortTypeNames)
176                 {
177                     int lastSlash = -1;
178                     for (int s = start; descriptor [s] != ';'; ++ s)
179                     {
180                         if (descriptor [s] == '/') lastSlash = s;
181                     }
182 
183                     for (start = lastSlash > 0 ? lastSlash + 1 : start; descriptor [start] != ';'; ++ start)
184                     {
185                         c = descriptor [start];
186                         if (RENAME_INNER_CLASSES)
187                             out.append (c != '$' ? c : '.');
188                         else
189                             out.append (c);
190                     }
191                 }
192                 else
193                 {
194                     for (; descriptor [start] != ';'; ++ start)
195                     {
196                         c = descriptor [start];
197                         out.append (c != '/' ? c : '.');
198                     }
199                 }
200 
201                 ++ start;
202             }
203             break;
204 
205             case 'B': out.append ("byte"); break;
206             case 'C': out.append ("char"); break;
207             case 'D': out.append ("double"); break;
208             case 'F': out.append ("float"); break;
209             case 'I': out.append ("int"); break;
210             case 'J': out.append ("long"); break;
211             case 'S': out.append ("short"); break;
212             case 'Z': out.append ("boolean"); break;
213 
214             case 'V': out.append ("void"); break;
215 
216             default:
217                 throw new IllegalStateException ("unknown type descriptor element: " + c);
218 
219         } // end of switch
220 
221         if (dims > 0)
222         {
223             out.append (' ');
224             for (int d = 0; d < dims; ++ d) out.append ("[]");
225         }
226 
227         return start;
228     }
229 
230 
Descriptors()231     private Descriptors () {} // prevent subclassing
232 
233 
234     // note: setting this to 'true' is not 100% reliable because it is legal
235     // to have $'s in regular class names as well:
236     private static final boolean RENAME_INNER_CLASSES = false;
237 
238 } // end of class
239 // ----------------------------------------------------------------------------