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 org.objectweb.asm.commons; 31 32 import java.util.HashMap; 33 import java.util.Map; 34 35 import org.objectweb.asm.Type; 36 37 /** 38 * A named method descriptor. 39 * 40 * @author Juozas Baliuka 41 * @author Chris Nokleberg 42 * @author Eric Bruneton 43 */ 44 public class Method { 45 46 /** 47 * The method name. 48 */ 49 private final String name; 50 51 /** 52 * The method descriptor. 53 */ 54 private final String desc; 55 56 /** 57 * Maps primitive Java type names to their descriptors. 58 */ 59 private final static Map DESCRIPTORS; 60 61 static { 62 DESCRIPTORS = new HashMap(); 63 DESCRIPTORS.put("void", "V"); 64 DESCRIPTORS.put("byte", "B"); 65 DESCRIPTORS.put("char", "C"); 66 DESCRIPTORS.put("double", "D"); 67 DESCRIPTORS.put("float", "F"); 68 DESCRIPTORS.put("int", "I"); 69 DESCRIPTORS.put("long", "J"); 70 DESCRIPTORS.put("short", "S"); 71 DESCRIPTORS.put("boolean", "Z"); 72 } 73 74 /** 75 * Creates a new {@link Method}. 76 * 77 * @param name the method's name. 78 * @param desc the method's descriptor. 79 */ Method(final String name, final String desc)80 public Method(final String name, final String desc) { 81 this.name = name; 82 this.desc = desc; 83 } 84 85 /** 86 * Creates a new {@link Method}. 87 * 88 * @param name the method's name. 89 * @param returnType the method's return type. 90 * @param argumentTypes the method's argument types. 91 */ Method( final String name, final Type returnType, final Type[] argumentTypes)92 public Method( 93 final String name, 94 final Type returnType, 95 final Type[] argumentTypes) 96 { 97 this(name, Type.getMethodDescriptor(returnType, argumentTypes)); 98 } 99 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", ...). 108 * @return a {@link Method} corresponding to the given Java method 109 * declaration. 110 * @throws IllegalArgumentException if <code>method</code> could not get 111 * parsed. 112 */ getMethod(final String method)113 public static Method getMethod(final String method) 114 throws IllegalArgumentException 115 { 116 int space = method.indexOf(' '); 117 int start = method.indexOf('(', space) + 1; 118 int end = method.indexOf(')', start); 119 if (space == -1 || start == -1 || end == -1) { 120 throw new IllegalArgumentException(); 121 } 122 // TODO: Check validity of returnType, methodName and arguments. 123 String returnType = method.substring(0, space); 124 String methodName = method.substring(space + 1, start - 1).trim(); 125 StringBuffer sb = new StringBuffer(); 126 sb.append('('); 127 int p; 128 do { 129 p = method.indexOf(',', start); 130 if (p == -1) { 131 sb.append(map(method.substring(start, end).trim())); 132 } else { 133 sb.append(map(method.substring(start, p).trim())); 134 start = p + 1; 135 } 136 } while (p != -1); 137 sb.append(')'); 138 sb.append(map(returnType)); 139 return new Method(methodName, sb.toString()); 140 } 141 map(final String type)142 private static String map(final String type) { 143 if (type.equals("")) { 144 return type; 145 } 146 147 StringBuffer sb = new StringBuffer(); 148 int index = 0; 149 while ((index = type.indexOf("[]", index) + 1) > 0) { 150 sb.append('['); 151 } 152 153 String t = type.substring(0, type.length() - sb.length() * 2); 154 String desc = (String) DESCRIPTORS.get(t); 155 if (desc != null) { 156 sb.append(desc); 157 } else { 158 sb.append('L'); 159 if (t.indexOf('.') < 0) { 160 sb.append("java/lang/" + t); 161 } else { 162 sb.append(t.replace('.', '/')); 163 } 164 sb.append(';'); 165 } 166 return sb.toString(); 167 } 168 169 /** 170 * Returns the name of the method described by this object. 171 * 172 * @return the name of the method described by this object. 173 */ getName()174 public String getName() { 175 return name; 176 } 177 178 /** 179 * Returns the descriptor of the method described by this object. 180 * 181 * @return the descriptor of the method described by this object. 182 */ getDescriptor()183 public String getDescriptor() { 184 return desc; 185 } 186 187 /** 188 * Returns the return type of the method described by this object. 189 * 190 * @return the return type of the method described by this object. 191 */ getReturnType()192 public Type getReturnType() { 193 return Type.getReturnType(desc); 194 } 195 196 /** 197 * Returns the argument types of the method described by this object. 198 * 199 * @return the argument types of the method described by this object. 200 */ getArgumentTypes()201 public Type[] getArgumentTypes() { 202 return Type.getArgumentTypes(desc); 203 } 204 toString()205 public String toString() { 206 return name + desc; 207 } 208 equals(final Object o)209 public boolean equals(final Object o) { 210 if (!(o instanceof Method)) { 211 return false; 212 } 213 Method other = (Method) o; 214 return name.equals(other.name) && desc.equals(other.desc); 215 } 216 hashCode()217 public int hashCode() { 218 return name.hashCode() ^ desc.hashCode(); 219 } 220 }