• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2003,2004 The Apache Software Foundation
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.mockito.cglib.core;
17 
18 import java.util.*;
19 
20 import org.mockito.asm.Type;
21 
22 public class TypeUtils {
23     private static final Map transforms = new HashMap();
24     private static final Map rtransforms = new HashMap();
25 
TypeUtils()26     private TypeUtils() {
27     }
28 
29     static {
30         transforms.put("void", "V");
31         transforms.put("byte", "B");
32         transforms.put("char", "C");
33         transforms.put("double", "D");
34         transforms.put("float", "F");
35         transforms.put("int", "I");
36         transforms.put("long", "J");
37         transforms.put("short", "S");
38         transforms.put("boolean", "Z");
39 
CollectionUtils.reverse(transforms, rtransforms)40         CollectionUtils.reverse(transforms, rtransforms);
41     }
42 
getType(String className)43     public static Type getType(String className) {
44         return Type.getType("L" + className.replace('.', '/') + ";");
45     }
46 
isFinal(int access)47     public static boolean isFinal(int access) {
48         return (Constants.ACC_FINAL & access) != 0;
49     }
50 
isStatic(int access)51     public static boolean isStatic(int access) {
52         return (Constants.ACC_STATIC & access) != 0;
53     }
54 
isProtected(int access)55     public static boolean isProtected(int access) {
56         return (Constants.ACC_PROTECTED & access) != 0;
57     }
58 
isPublic(int access)59     public static boolean isPublic(int access) {
60         return (Constants.ACC_PUBLIC & access) != 0;
61     }
62 
isAbstract(int access)63     public static boolean isAbstract(int access) {
64         return (Constants.ACC_ABSTRACT & access) != 0;
65     }
66 
isInterface(int access)67     public static boolean isInterface(int access) {
68         return (Constants.ACC_INTERFACE & access) != 0;
69     }
70 
isPrivate(int access)71     public static boolean isPrivate(int access) {
72         return (Constants.ACC_PRIVATE & access) != 0;
73     }
74 
isSynthetic(int access)75     public static boolean isSynthetic(int access) {
76         return (Constants.ACC_SYNTHETIC & access) != 0;
77     }
78 
79     // getPackage returns null on JDK 1.2
getPackageName(Type type)80     public static String getPackageName(Type type) {
81         return getPackageName(getClassName(type));
82     }
83 
getPackageName(String className)84     public static String getPackageName(String className) {
85         int idx = className.lastIndexOf('.');
86         return (idx < 0) ? "" : className.substring(0, idx);
87     }
88 
upperFirst(String s)89     public static String upperFirst(String s) {
90         if (s == null || s.length() == 0) {
91             return s;
92         }
93         return Character.toUpperCase(s.charAt(0)) + s.substring(1);
94     }
95 
getClassName(Type type)96     public static String getClassName(Type type) {
97         if (isPrimitive(type)) {
98             return (String)rtransforms.get(type.getDescriptor());
99         } else if (isArray(type)) {
100             return getClassName(getComponentType(type)) + "[]";
101         } else {
102             return type.getClassName();
103         }
104     }
105 
add(Type[] types, Type extra)106     public static Type[] add(Type[] types, Type extra) {
107         if (types == null) {
108             return new Type[]{ extra };
109         } else {
110             List list = Arrays.asList(types);
111             if (list.contains(extra)) {
112                 return types;
113             }
114             Type[] copy = new Type[types.length + 1];
115             System.arraycopy(types, 0, copy, 0, types.length);
116             copy[types.length] = extra;
117             return copy;
118         }
119     }
120 
add(Type[] t1, Type[] t2)121     public static Type[] add(Type[] t1, Type[] t2) {
122         // TODO: set semantics?
123         Type[] all = new Type[t1.length + t2.length];
124         System.arraycopy(t1, 0, all, 0, t1.length);
125         System.arraycopy(t2, 0, all, t1.length, t2.length);
126         return all;
127     }
128 
fromInternalName(String name)129     public static Type fromInternalName(String name) {
130         // TODO; primitives?
131         return Type.getType("L" + name + ";");
132     }
133 
fromInternalNames(String[] names)134     public static Type[] fromInternalNames(String[] names) {
135         if (names == null) {
136             return null;
137         }
138         Type[] types = new Type[names.length];
139         for (int i = 0; i < names.length; i++) {
140             types[i] = fromInternalName(names[i]);
141         }
142         return types;
143     }
144 
getStackSize(Type[] types)145     public static int getStackSize(Type[] types) {
146         int size = 0;
147         for (int i = 0; i < types.length; i++) {
148             size += types[i].getSize();
149         }
150         return size;
151     }
152 
toInternalNames(Type[] types)153     public static String[] toInternalNames(Type[] types) {
154         if (types == null) {
155             return null;
156         }
157         String[] names = new String[types.length];
158         for (int i = 0; i < types.length; i++) {
159             names[i] = types[i].getInternalName();
160         }
161         return names;
162     }
163 
parseSignature(String s)164     public static Signature parseSignature(String s) {
165         int space = s.indexOf(' ');
166         int lparen = s.indexOf('(', space);
167         int rparen = s.indexOf(')', lparen);
168         String returnType = s.substring(0, space);
169         String methodName = s.substring(space + 1, lparen);
170         StringBuffer sb = new StringBuffer();
171         sb.append('(');
172         for (Iterator it = parseTypes(s, lparen + 1, rparen).iterator(); it.hasNext();) {
173             sb.append(it.next());
174         }
175         sb.append(')');
176         sb.append(map(returnType));
177         return new Signature(methodName, sb.toString());
178     }
179 
parseType(String s)180     public static Type parseType(String s) {
181         return Type.getType(map(s));
182     }
183 
parseTypes(String s)184     public static Type[] parseTypes(String s) {
185         List names = parseTypes(s, 0, s.length());
186         Type[] types = new Type[names.size()];
187         for (int i = 0; i < types.length; i++) {
188             types[i] = Type.getType((String)names.get(i));
189         }
190         return types;
191     }
192 
parseConstructor(Type[] types)193     public static Signature parseConstructor(Type[] types) {
194         StringBuffer sb = new StringBuffer();
195         sb.append("(");
196         for (int i = 0; i < types.length; i++) {
197             sb.append(types[i].getDescriptor());
198         }
199         sb.append(")");
200         sb.append("V");
201         return new Signature(Constants.CONSTRUCTOR_NAME, sb.toString());
202     }
203 
parseConstructor(String sig)204     public static Signature parseConstructor(String sig) {
205         return parseSignature("void <init>(" + sig + ")"); // TODO
206     }
207 
parseTypes(String s, int mark, int end)208     private static List parseTypes(String s, int mark, int end) {
209         List types = new ArrayList(5);
210         for (;;) {
211             int next = s.indexOf(',', mark);
212             if (next < 0) {
213                 break;
214             }
215             types.add(map(s.substring(mark, next).trim()));
216             mark = next + 1;
217         }
218         types.add(map(s.substring(mark, end).trim()));
219         return types;
220     }
221 
map(String type)222     private static String map(String type) {
223         if (type.equals("")) {
224             return type;
225         }
226         String t = (String)transforms.get(type);
227         if (t != null) {
228             return t;
229         } else if (type.indexOf('.') < 0) {
230             return map("java.lang." + type);
231         } else {
232             StringBuffer sb = new StringBuffer();
233             int index = 0;
234             while ((index = type.indexOf("[]", index) + 1) > 0) {
235                 sb.append('[');
236             }
237             type = type.substring(0, type.length() - sb.length() * 2);
238             sb.append('L').append(type.replace('.', '/')).append(';');
239             return sb.toString();
240         }
241     }
242 
getBoxedType(Type type)243     public static Type getBoxedType(Type type) {
244         switch (type.getSort()) {
245         case Type.CHAR:
246             return Constants.TYPE_CHARACTER;
247         case Type.BOOLEAN:
248             return Constants.TYPE_BOOLEAN;
249         case Type.DOUBLE:
250             return Constants.TYPE_DOUBLE;
251         case Type.FLOAT:
252             return Constants.TYPE_FLOAT;
253         case Type.LONG:
254             return Constants.TYPE_LONG;
255         case Type.INT:
256             return Constants.TYPE_INTEGER;
257         case Type.SHORT:
258             return Constants.TYPE_SHORT;
259         case Type.BYTE:
260             return Constants.TYPE_BYTE;
261         default:
262             return type;
263         }
264     }
265 
getUnboxedType(Type type)266     public static Type getUnboxedType(Type type) {
267         if (Constants.TYPE_INTEGER.equals(type)) {
268             return Type.INT_TYPE;
269         } else if (Constants.TYPE_BOOLEAN.equals(type)) {
270             return Type.BOOLEAN_TYPE;
271         } else if (Constants.TYPE_DOUBLE.equals(type)) {
272             return Type.DOUBLE_TYPE;
273         } else if (Constants.TYPE_LONG.equals(type)) {
274             return Type.LONG_TYPE;
275         } else if (Constants.TYPE_CHARACTER.equals(type)) {
276             return Type.CHAR_TYPE;
277         } else if (Constants.TYPE_BYTE.equals(type)) {
278             return Type.BYTE_TYPE;
279         } else if (Constants.TYPE_FLOAT.equals(type)) {
280             return Type.FLOAT_TYPE;
281         } else if (Constants.TYPE_SHORT.equals(type)) {
282             return Type.SHORT_TYPE;
283         } else {
284             return type;
285         }
286     }
287 
isArray(Type type)288     public static boolean isArray(Type type) {
289         return type.getSort() == Type.ARRAY;
290     }
291 
getComponentType(Type type)292     public static Type getComponentType(Type type) {
293         if (!isArray(type)) {
294             throw new IllegalArgumentException("Type " + type + " is not an array");
295         }
296         return Type.getType(type.getDescriptor().substring(1));
297     }
298 
isPrimitive(Type type)299     public static boolean isPrimitive(Type type) {
300         switch (type.getSort()) {
301         case Type.ARRAY:
302         case Type.OBJECT:
303             return false;
304         default:
305             return true;
306         }
307     }
308 
emulateClassGetName(Type type)309     public static String emulateClassGetName(Type type) {
310         if (isArray(type)) {
311             return type.getDescriptor().replace('/', '.');
312         } else {
313             return getClassName(type);
314         }
315     }
316 
isConstructor(MethodInfo method)317     public static boolean isConstructor(MethodInfo method) {
318         return method.getSignature().getName().equals(Constants.CONSTRUCTOR_NAME);
319     }
320 
getTypes(Class[] classes)321     public static Type[] getTypes(Class[] classes) {
322         if (classes == null) {
323             return null;
324         }
325         Type[] types = new Type[classes.length];
326         for (int i = 0; i < classes.length; i++) {
327             types[i] = Type.getType(classes[i]);
328         }
329         return types;
330     }
331 
ICONST(int value)332     public static int ICONST(int value) {
333         switch (value) {
334         case -1: return Constants.ICONST_M1;
335         case 0: return Constants.ICONST_0;
336         case 1: return Constants.ICONST_1;
337         case 2: return Constants.ICONST_2;
338         case 3: return Constants.ICONST_3;
339         case 4: return Constants.ICONST_4;
340         case 5: return Constants.ICONST_5;
341         }
342         return -1; // error
343     }
344 
LCONST(long value)345     public static int LCONST(long value) {
346         if (value == 0L) {
347             return Constants.LCONST_0;
348         } else if (value == 1L) {
349             return Constants.LCONST_1;
350         } else {
351             return -1; // error
352         }
353     }
354 
FCONST(float value)355     public static int FCONST(float value) {
356         if (value == 0f) {
357             return Constants.FCONST_0;
358         } else if (value == 1f) {
359             return Constants.FCONST_1;
360         } else if (value == 2f) {
361             return Constants.FCONST_2;
362         } else {
363             return -1; // error
364         }
365     }
366 
DCONST(double value)367     public static int DCONST(double value) {
368         if (value == 0d) {
369             return Constants.DCONST_0;
370         } else if (value == 1d) {
371             return Constants.DCONST_1;
372         } else {
373             return -1; // error
374         }
375     }
376 
NEWARRAY(Type type)377     public static int NEWARRAY(Type type) {
378         switch (type.getSort()) {
379         case Type.BYTE:
380             return Constants.T_BYTE;
381         case Type.CHAR:
382             return Constants.T_CHAR;
383         case Type.DOUBLE:
384             return Constants.T_DOUBLE;
385         case Type.FLOAT:
386             return Constants.T_FLOAT;
387         case Type.INT:
388             return Constants.T_INT;
389         case Type.LONG:
390             return Constants.T_LONG;
391         case Type.SHORT:
392             return Constants.T_SHORT;
393         case Type.BOOLEAN:
394             return Constants.T_BOOLEAN;
395         default:
396             return -1; // error
397         }
398     }
399 
escapeType(String s)400     public static String escapeType(String s) {
401         StringBuffer sb = new StringBuffer();
402         for (int i = 0, len = s.length(); i < len; i++) {
403             char c = s.charAt(i);
404             switch (c) {
405             case '$': sb.append("$24"); break;
406             case '.': sb.append("$2E"); break;
407             case '[': sb.append("$5B"); break;
408             case ';': sb.append("$3B"); break;
409             case '(': sb.append("$28"); break;
410             case ')': sb.append("$29"); break;
411             case '/': sb.append("$2F"); break;
412             default:
413                 sb.append(c);
414             }
415         }
416         return sb.toString();
417     }
418 }
419