1674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/*
2674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Copyright 2003,2004 The Apache Software Foundation
3674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
4674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *  Licensed under the Apache License, Version 2.0 (the "License");
5674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * you may not use this file except in compliance with the License.
6674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * You may obtain a copy of the License at
7674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
8674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *      http://www.apache.org/licenses/LICENSE-2.0
9674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
10674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *  Unless required by applicable law or agreed to in writing, software
11674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * distributed under the License is distributed on an "AS IS" BASIS,
12674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * See the License for the specific language governing permissions and
14674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * limitations under the License.
15674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */
16674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpackage org.mockito.cglib.core;
17674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
18674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.util.*;
19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.Type;
21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic class TypeUtils {
23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Map transforms = new HashMap();
24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Map rtransforms = new HashMap();
25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private TypeUtils() {
27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    static {
30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        transforms.put("void", "V");
31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        transforms.put("byte", "B");
32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        transforms.put("char", "C");
33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        transforms.put("double", "D");
34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        transforms.put("float", "F");
35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        transforms.put("int", "I");
36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        transforms.put("long", "J");
37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        transforms.put("short", "S");
38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        transforms.put("boolean", "Z");
39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        CollectionUtils.reverse(transforms, rtransforms);
41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type getType(String className) {
44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return Type.getType("L" + className.replace('.', '/') + ";");
45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isFinal(int access) {
48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return (Constants.ACC_FINAL & access) != 0;
49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isStatic(int access) {
52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return (Constants.ACC_STATIC & access) != 0;
53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isProtected(int access) {
56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return (Constants.ACC_PROTECTED & access) != 0;
57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isPublic(int access) {
60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return (Constants.ACC_PUBLIC & access) != 0;
61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
62674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isAbstract(int access) {
64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return (Constants.ACC_ABSTRACT & access) != 0;
65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isInterface(int access) {
68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return (Constants.ACC_INTERFACE & access) != 0;
69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isPrivate(int access) {
72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return (Constants.ACC_PRIVATE & access) != 0;
73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isSynthetic(int access) {
76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return (Constants.ACC_SYNTHETIC & access) != 0;
77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    // getPackage returns null on JDK 1.2
80674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static String getPackageName(Type type) {
81674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return getPackageName(getClassName(type));
82674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
83674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
84674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static String getPackageName(String className) {
85674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int idx = className.lastIndexOf('.');
86674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return (idx < 0) ? "" : className.substring(0, idx);
87674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
88674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
89674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static String upperFirst(String s) {
90674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (s == null || s.length() == 0) {
91674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return s;
92674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
93674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return Character.toUpperCase(s.charAt(0)) + s.substring(1);
94674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
95674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
96674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static String getClassName(Type type) {
97674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (isPrimitive(type)) {
98674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return (String)rtransforms.get(type.getDescriptor());
99674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (isArray(type)) {
100674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return getClassName(getComponentType(type)) + "[]";
101674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else {
102674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return type.getClassName();
103674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
104674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
105674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
106674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type[] add(Type[] types, Type extra) {
107674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (types == null) {
108674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return new Type[]{ extra };
109674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else {
110674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            List list = Arrays.asList(types);
111674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            if (list.contains(extra)) {
112674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                return types;
113674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
114674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            Type[] copy = new Type[types.length + 1];
115674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            System.arraycopy(types, 0, copy, 0, types.length);
116674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            copy[types.length] = extra;
117674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return copy;
118674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
119674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
120674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
121674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type[] add(Type[] t1, Type[] t2) {
122674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        // TODO: set semantics?
123674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        Type[] all = new Type[t1.length + t2.length];
124674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        System.arraycopy(t1, 0, all, 0, t1.length);
125674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        System.arraycopy(t2, 0, all, t1.length, t2.length);
126674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return all;
127674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
128674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
129674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type fromInternalName(String name) {
130674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        // TODO; primitives?
131674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return Type.getType("L" + name + ";");
132674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
133674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
134674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type[] fromInternalNames(String[] names) {
135674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (names == null) {
136674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return null;
137674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
138674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        Type[] types = new Type[names.length];
139674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (int i = 0; i < names.length; i++) {
140674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            types[i] = fromInternalName(names[i]);
141674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
142674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return types;
143674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
144674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
145674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static int getStackSize(Type[] types) {
146674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int size = 0;
147674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (int i = 0; i < types.length; i++) {
148674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            size += types[i].getSize();
149674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
150674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return size;
151674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
152674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
153674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static String[] toInternalNames(Type[] types) {
154674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (types == null) {
155674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return null;
156674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
157674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        String[] names = new String[types.length];
158674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (int i = 0; i < types.length; i++) {
159674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            names[i] = types[i].getInternalName();
160674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
161674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return names;
162674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
163674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
164674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Signature parseSignature(String s) {
165674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int space = s.indexOf(' ');
166674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int lparen = s.indexOf('(', space);
167674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int rparen = s.indexOf(')', lparen);
168674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        String returnType = s.substring(0, space);
169674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        String methodName = s.substring(space + 1, lparen);
170674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        StringBuffer sb = new StringBuffer();
171674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        sb.append('(');
172674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (Iterator it = parseTypes(s, lparen + 1, rparen).iterator(); it.hasNext();) {
173674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            sb.append(it.next());
174674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
175674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        sb.append(')');
176674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        sb.append(map(returnType));
177674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return new Signature(methodName, sb.toString());
178674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
179674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
180674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type parseType(String s) {
181674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return Type.getType(map(s));
182674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
183674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
184674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type[] parseTypes(String s) {
185674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        List names = parseTypes(s, 0, s.length());
186674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        Type[] types = new Type[names.size()];
187674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (int i = 0; i < types.length; i++) {
188674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            types[i] = Type.getType((String)names.get(i));
189674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
190674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return types;
191674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
192674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
193674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Signature parseConstructor(Type[] types) {
194674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        StringBuffer sb = new StringBuffer();
195674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        sb.append("(");
196674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (int i = 0; i < types.length; i++) {
197674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            sb.append(types[i].getDescriptor());
198674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
199674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        sb.append(")");
200674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        sb.append("V");
201674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return new Signature(Constants.CONSTRUCTOR_NAME, sb.toString());
202674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
203674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
204674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Signature parseConstructor(String sig) {
205674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return parseSignature("void <init>(" + sig + ")"); // TODO
206674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
207674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
208674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static List parseTypes(String s, int mark, int end) {
209674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        List types = new ArrayList(5);
210674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (;;) {
211674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            int next = s.indexOf(',', mark);
212674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            if (next < 0) {
213674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                break;
214674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
215674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            types.add(map(s.substring(mark, next).trim()));
216674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            mark = next + 1;
217674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
218674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        types.add(map(s.substring(mark, end).trim()));
219674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return types;
220674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
221674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
222674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static String map(String type) {
223674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (type.equals("")) {
224674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return type;
225674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
226674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        String t = (String)transforms.get(type);
227674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (t != null) {
228674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return t;
229674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (type.indexOf('.') < 0) {
230674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return map("java.lang." + type);
231674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else {
232674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            StringBuffer sb = new StringBuffer();
233674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            int index = 0;
234674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            while ((index = type.indexOf("[]", index) + 1) > 0) {
235674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                sb.append('[');
236674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
237674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            type = type.substring(0, type.length() - sb.length() * 2);
238674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            sb.append('L').append(type.replace('.', '/')).append(';');
239674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return sb.toString();
240674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
241674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
242674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
243674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type getBoxedType(Type type) {
244674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        switch (type.getSort()) {
245674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.CHAR:
246674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.TYPE_CHARACTER;
247674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.BOOLEAN:
248674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.TYPE_BOOLEAN;
249674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.DOUBLE:
250674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.TYPE_DOUBLE;
251674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.FLOAT:
252674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.TYPE_FLOAT;
253674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.LONG:
254674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.TYPE_LONG;
255674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.INT:
256674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.TYPE_INTEGER;
257674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.SHORT:
258674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.TYPE_SHORT;
259674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.BYTE:
260674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.TYPE_BYTE;
261674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        default:
262674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return type;
263674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
264674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
265674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
266674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type getUnboxedType(Type type) {
267674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (Constants.TYPE_INTEGER.equals(type)) {
268674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Type.INT_TYPE;
269674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (Constants.TYPE_BOOLEAN.equals(type)) {
270674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Type.BOOLEAN_TYPE;
271674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (Constants.TYPE_DOUBLE.equals(type)) {
272674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Type.DOUBLE_TYPE;
273674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (Constants.TYPE_LONG.equals(type)) {
274674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Type.LONG_TYPE;
275674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (Constants.TYPE_CHARACTER.equals(type)) {
276674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Type.CHAR_TYPE;
277674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (Constants.TYPE_BYTE.equals(type)) {
278674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Type.BYTE_TYPE;
279674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (Constants.TYPE_FLOAT.equals(type)) {
280674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Type.FLOAT_TYPE;
281674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (Constants.TYPE_SHORT.equals(type)) {
282674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Type.SHORT_TYPE;
283674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else {
284674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return type;
285674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
286674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
287674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
288674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isArray(Type type) {
289674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return type.getSort() == Type.ARRAY;
290674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
291674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
292674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type getComponentType(Type type) {
293674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (!isArray(type)) {
294674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            throw new IllegalArgumentException("Type " + type + " is not an array");
295674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
296674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return Type.getType(type.getDescriptor().substring(1));
297674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
298674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
299674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isPrimitive(Type type) {
300674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        switch (type.getSort()) {
301674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.ARRAY:
302674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.OBJECT:
303674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return false;
304674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        default:
305674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return true;
306674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
307674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
308674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
309674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static String emulateClassGetName(Type type) {
310674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (isArray(type)) {
311674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return type.getDescriptor().replace('/', '.');
312674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else {
313674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return getClassName(type);
314674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
315674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
316674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
317674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static boolean isConstructor(MethodInfo method) {
318674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return method.getSignature().getName().equals(Constants.CONSTRUCTOR_NAME);
319674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
320674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
321674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static Type[] getTypes(Class[] classes) {
322674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (classes == null) {
323674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return null;
324674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
325674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        Type[] types = new Type[classes.length];
326674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (int i = 0; i < classes.length; i++) {
327674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            types[i] = Type.getType(classes[i]);
328674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
329674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return types;
330674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
331674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
332674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static int ICONST(int value) {
333674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        switch (value) {
334674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case -1: return Constants.ICONST_M1;
335674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case 0: return Constants.ICONST_0;
336674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case 1: return Constants.ICONST_1;
337674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case 2: return Constants.ICONST_2;
338674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case 3: return Constants.ICONST_3;
339674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case 4: return Constants.ICONST_4;
340674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case 5: return Constants.ICONST_5;
341674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
342674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return -1; // error
343674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
344674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
345674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static int LCONST(long value) {
346674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (value == 0L) {
347674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.LCONST_0;
348674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (value == 1L) {
349674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.LCONST_1;
350674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else {
351674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return -1; // error
352674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
353674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
354674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
355674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static int FCONST(float value) {
356674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (value == 0f) {
357674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.FCONST_0;
358674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (value == 1f) {
359674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.FCONST_1;
360674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (value == 2f) {
361674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.FCONST_2;
362674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else {
363674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return -1; // error
364674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
365674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
366674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
367674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static int DCONST(double value) {
368674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (value == 0d) {
369674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.DCONST_0;
370674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else if (value == 1d) {
371674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.DCONST_1;
372674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        } else {
373674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return -1; // error
374674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
375674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
376674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
377674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static int NEWARRAY(Type type) {
378674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        switch (type.getSort()) {
379674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.BYTE:
380674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.T_BYTE;
381674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.CHAR:
382674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.T_CHAR;
383674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.DOUBLE:
384674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.T_DOUBLE;
385674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.FLOAT:
386674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.T_FLOAT;
387674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.INT:
388674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.T_INT;
389674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.LONG:
390674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.T_LONG;
391674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.SHORT:
392674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.T_SHORT;
393674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        case Type.BOOLEAN:
394674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return Constants.T_BOOLEAN;
395674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        default:
396674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            return -1; // error
397674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
398674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
399674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
400674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public static String escapeType(String s) {
401674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        StringBuffer sb = new StringBuffer();
402674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (int i = 0, len = s.length(); i < len; i++) {
403674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            char c = s.charAt(i);
404674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            switch (c) {
405674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            case '$': sb.append("$24"); break;
406674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            case '.': sb.append("$2E"); break;
407674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            case '[': sb.append("$5B"); break;
408674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            case ';': sb.append("$3B"); break;
409674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            case '(': sb.append("$28"); break;
410674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            case ')': sb.append("$29"); break;
411674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            case '/': sb.append("$2F"); break;
412674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            default:
413674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                sb.append(c);
414674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
415674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
416674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        return sb.toString();
417674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
418674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen}
419