view src/clojure/asm/commons/Method.java @ 10:ef7dbbd6452c

added clojure source goodness
author Robert McIntyre <rlm@mit.edu>
date Sat, 21 Aug 2010 06:25:44 -0400
parents
children
line wrap: on
line source
1 /***
2 * ASM: a very small and fast Java bytecode manipulation framework
3 * Copyright (c) 2000-2005 INRIA, France Telecom
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGE.
29 */
30 package clojure.asm.commons;
32 import java.util.HashMap;
33 import java.util.Map;
35 import clojure.asm.Type;
37 /**
38 * A named method descriptor.
39 *
40 * @author Juozas Baliuka
41 * @author Chris Nokleberg
42 * @author Eric Bruneton
43 */
44 public class Method{
46 /**
47 * The method name.
48 */
49 private final String name;
51 /**
52 * The method descriptor.
53 */
54 private final String desc;
56 /**
57 * Maps primitive Java type names to their descriptors.
58 */
59 private final static Map DESCRIPTORS;
61 static
62 {
63 DESCRIPTORS = new HashMap();
64 DESCRIPTORS.put("void", "V");
65 DESCRIPTORS.put("byte", "B");
66 DESCRIPTORS.put("char", "C");
67 DESCRIPTORS.put("double", "D");
68 DESCRIPTORS.put("float", "F");
69 DESCRIPTORS.put("int", "I");
70 DESCRIPTORS.put("long", "J");
71 DESCRIPTORS.put("short", "S");
72 DESCRIPTORS.put("boolean", "Z");
73 }
75 /**
76 * Creates a new {@link Method}.
77 *
78 * @param name the method's name.
79 * @param desc the method's descriptor.
80 */
81 public Method(final String name, final String desc){
82 this.name = name;
83 this.desc = desc;
84 }
86 /**
87 * Creates a new {@link Method}.
88 *
89 * @param name the method's name.
90 * @param returnType the method's return type.
91 * @param argumentTypes the method's argument types.
92 */
93 public Method(
94 final String name,
95 final Type returnType,
96 final Type[] argumentTypes){
97 this(name, Type.getMethodDescriptor(returnType, argumentTypes));
98 }
100 /**
101 * Returns a {@link Method} corresponding to the given Java method
102 * declaration.
103 *
104 * @param method a Java method declaration, without argument names, of the
105 * form "returnType name (argumentType1, ... argumentTypeN)", where
106 * the types are in plain Java (e.g. "int", "float",
107 * "java.util.List", ...). Classes of the java.lang package can be
108 * specified by their unqualified name; all other classes names must
109 * be fully qualified.
110 * @return a {@link Method} corresponding to the given Java method
111 * declaration.
112 * @throws IllegalArgumentException if <code>method</code> could not get
113 * parsed.
114 */
115 public static Method getMethod(final String method)
116 throws IllegalArgumentException{
117 return getMethod(method, false);
118 }
120 /**
121 * Returns a {@link Method} corresponding to the given Java method
122 * declaration.
123 *
124 * @param method a Java method declaration, without argument names, of the
125 * form "returnType name (argumentType1, ... argumentTypeN)", where
126 * the types are in plain Java (e.g. "int", "float",
127 * "java.util.List", ...). Classes of the java.lang package may be
128 * specified by their unqualified name, depending on the
129 * defaultPackage argument; all other classes names must be fully
130 * qualified.
131 * @param defaultPackage true if unqualified class names belong to the
132 * default package, or false if they correspond to java.lang classes.
133 * For instance "Object" means "Object" if this option is true, or
134 * "java.lang.Object" otherwise.
135 * @return a {@link Method} corresponding to the given Java method
136 * declaration.
137 * @throws IllegalArgumentException if <code>method</code> could not get
138 * parsed.
139 */
140 public static Method getMethod(
141 final String method,
142 final boolean defaultPackage) throws IllegalArgumentException{
143 int space = method.indexOf(' ');
144 int start = method.indexOf('(', space) + 1;
145 int end = method.indexOf(')', start);
146 if(space == -1 || start == -1 || end == -1)
147 {
148 throw new IllegalArgumentException();
149 }
150 // TODO: Check validity of returnType, methodName and arguments.
151 String returnType = method.substring(0, space);
152 String methodName = method.substring(space + 1, start - 1).trim();
153 StringBuffer sb = new StringBuffer();
154 sb.append('(');
155 int p;
156 do
157 {
158 String s;
159 p = method.indexOf(',', start);
160 if(p == -1)
161 {
162 s = map(method.substring(start, end).trim(), defaultPackage);
163 }
164 else
165 {
166 s = map(method.substring(start, p).trim(), defaultPackage);
167 start = p + 1;
168 }
169 sb.append(s);
170 } while(p != -1);
171 sb.append(')');
172 sb.append(map(returnType, defaultPackage));
173 return new Method(methodName, sb.toString());
174 }
176 private static String map(final String type, final boolean defaultPackage){
177 if(type.equals(""))
178 {
179 return type;
180 }
182 StringBuffer sb = new StringBuffer();
183 int index = 0;
184 while((index = type.indexOf("[]", index) + 1) > 0)
185 {
186 sb.append('[');
187 }
189 String t = type.substring(0, type.length() - sb.length() * 2);
190 String desc = (String) DESCRIPTORS.get(t);
191 if(desc != null)
192 {
193 sb.append(desc);
194 }
195 else
196 {
197 sb.append('L');
198 if(t.indexOf('.') < 0)
199 {
200 if(!defaultPackage)
201 {
202 sb.append("java/lang/");
203 }
204 sb.append(t);
205 }
206 else
207 {
208 sb.append(t.replace('.', '/'));
209 }
210 sb.append(';');
211 }
212 return sb.toString();
213 }
215 /**
216 * Returns the name of the method described by this object.
217 *
218 * @return the name of the method described by this object.
219 */
220 public String getName(){
221 return name;
222 }
224 /**
225 * Returns the descriptor of the method described by this object.
226 *
227 * @return the descriptor of the method described by this object.
228 */
229 public String getDescriptor(){
230 return desc;
231 }
233 /**
234 * Returns the return type of the method described by this object.
235 *
236 * @return the return type of the method described by this object.
237 */
238 public Type getReturnType(){
239 return Type.getReturnType(desc);
240 }
242 /**
243 * Returns the argument types of the method described by this object.
244 *
245 * @return the argument types of the method described by this object.
246 */
247 public Type[] getArgumentTypes(){
248 return Type.getArgumentTypes(desc);
249 }
251 public String toString(){
252 return name + desc;
253 }
255 public boolean equals(final Object o){
256 if(!(o instanceof Method))
257 {
258 return false;
259 }
260 Method other = (Method) o;
261 return name.equals(other.name) && desc.equals(other.desc);
262 }
264 public int hashCode(){
265 return name.hashCode() ^ desc.hashCode();
266 }