169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.DataInputStream; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.io.IOException; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.Map; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.ArrayList; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtClass; 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>Signature_attribute</code>. 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class SignatureAttribute extends AttributeInfo { 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The name of this attribute <code>"Signature"</code>. 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final String tag = "Signature"; 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal SignatureAttribute(ConstPool cp, int n, DataInputStream in) 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws IOException 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(cp, n, in); 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs a Signature attribute. 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param cp a constant pool table. 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param signature the signature represented by this attribute. 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public SignatureAttribute(ConstPool cp, String signature) { 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(cp, tag); 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = cp.addUtf8Info(signature); 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] bvalue = new byte[2]; 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bvalue[0] = (byte)(index >>> 8); 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bvalue[1] = (byte)index; 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal set(bvalue); 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the signature indicated by <code>signature_index</code>. 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see #toClassSignature(String) 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see #toMethodSignature(String) 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getSignature() { 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return getConstPool().getUtf8Info(ByteArray.readU16bit(get(), 0)); 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets <code>signature_index</code> to the index of the given signature, 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * which is added to a constant pool. 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param sig new signature. 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @since 3.11 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setSignature(String sig) { 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = getConstPool().addUtf8Info(sig); 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ByteArray.write16bit(index, info, 0); 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Makes a copy. Class names are replaced according to the 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * given <code>Map</code> object. 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param newCp the constant pool table used by the new copy. 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param classnames pairs of replaced and substituted 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class names. 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public AttributeInfo copy(ConstPool newCp, Map classnames) { 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new SignatureAttribute(newCp, getSignature()); 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void renameClass(String oldname, String newname) { 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String sig = renameClass(getSignature(), oldname, newname); 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal setSignature(sig); 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void renameClass(Map classnames) { 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String sig = renameClass(getSignature(), classnames); 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal setSignature(sig); 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static String renameClass(String desc, String oldname, String newname) { 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Map map = new java.util.HashMap(); 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal map.put(oldname, newname); 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return renameClass(desc, map); 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static String renameClass(String desc, Map map) { 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (map == null) 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return desc; 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuilder newdesc = new StringBuilder(); 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int head = 0; 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = 0; 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (;;) { 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int j = desc.indexOf('L', i); 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (j < 0) 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuilder nameBuf = new StringBuilder(); 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int k = j; 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal char c; 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while ((c = desc.charAt(++k)) != ';') { 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal nameBuf.append(c); 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (c == '<') { 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while ((c = desc.charAt(++k)) != '>') 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal nameBuf.append(c); 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal nameBuf.append(c); 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (IndexOutOfBoundsException e) { break; } 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal i = k + 1; 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String name = nameBuf.toString(); 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String name2 = (String)map.get(name); 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (name2 != null) { 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newdesc.append(desc.substring(head, j)); 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newdesc.append('L'); 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newdesc.append(name2); 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newdesc.append(c); 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal head = i; 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (head == 0) 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return desc; 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int len = desc.length(); 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (head < len) 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal newdesc.append(desc.substring(head, len)); 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return newdesc.toString(); 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static boolean isNamePart(int c) { 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return c != ';' && c != '<'; 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static private class Cursor { 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int position = 0; 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int indexOf(String s, int ch) throws BadBytecode { 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i = s.indexOf(ch, position); 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i < 0) 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw error(s); 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal position = i + 1; 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return i; 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Class signature. 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class ClassSignature { 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeParameter[] params; 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassType superClass; 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassType[] interfaces; 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassSignature(TypeParameter[] p, ClassType s, ClassType[] i) { 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal params = p; 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal superClass = s; 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal interfaces = i; 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the type parameters. 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return a zero-length array if the type parameters are not specified. 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public TypeParameter[] getParameters() { 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return params; 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the super class. 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ClassType getSuperClass() { return superClass; } 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the super interfaces. 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return a zero-length array if the super interfaces are not specified. 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ClassType[] getInterfaces() { return interfaces; } 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the string representation. 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuffer sbuf = new StringBuffer(); 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeParameter.toString(sbuf, params); 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(" extends ").append(superClass); 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (interfaces.length > 0) { 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(" implements "); 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type.toString(sbuf, interfaces); 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return sbuf.toString(); 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Method type signature. 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class MethodSignature { 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeParameter[] typeParams; 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type[] params; 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type retType; 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectType[] exceptions; 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal MethodSignature(TypeParameter[] tp, Type[] p, Type ret, ObjectType[] ex) { 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal typeParams = tp; 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal params = p; 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal retType = ret; 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exceptions = ex; 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the formal type parameters. 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return a zero-length array if the type parameters are not specified. 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public TypeParameter[] getTypeParameters() { return typeParams; } 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the types of the formal parameters. 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return a zero-length array if no formal parameter is taken. 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Type[] getParameterTypes() { return params; } 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the type of the returned value. 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Type getReturnType() { return retType; } 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the types of the exceptions that may be thrown. 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return a zero-length array if exceptions are never thrown or 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the exception types are not parameterized types or type variables. 26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ObjectType[] getExceptionTypes() { return exceptions; } 26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the string representation. 26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuffer sbuf = new StringBuffer(); 27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeParameter.toString(sbuf, typeParams); 27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(" ("); 27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type.toString(sbuf, params); 27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(") "); 27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(retType); 27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (exceptions.length > 0) { 27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(" throws "); 27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type.toString(sbuf, exceptions); 28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return sbuf.toString(); 28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Formal type parameters. 28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class TypeParameter { 29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String name; 29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectType superClass; 29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectType[] superInterfaces; 29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeParameter(String sig, int nb, int ne, ObjectType sc, ObjectType[] si) { 29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal name = sig.substring(nb, ne); 29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal superClass = sc; 29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal superInterfaces = si; 29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the name of the type parameter. 30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getName() { 30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return name; 30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the class bound of this parameter. 30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return null if the class bound is not specified. 31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ObjectType getClassBound() { return superClass; } 31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the interface bound of this parameter. 31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return a zero-length array if the interface bound is not specified. 31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ObjectType[] getInterfaceBound() { return superInterfaces; } 32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the string representation. 32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuffer sbuf = new StringBuffer(getName()); 32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (superClass != null) 32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(" extends ").append(superClass.toString()); 32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int len = superInterfaces.length; 33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (len > 0) { 33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < len; i++) { 33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i > 0 || superClass != null) 33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(" & "); 33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(" extends "); 33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(superInterfaces[i].toString()); 33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return sbuf.toString(); 34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static void toString(StringBuffer sbuf, TypeParameter[] tp) { 34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append('<'); 34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < tp.length; i++) { 34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i > 0) 34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(", "); 34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(tp[i]); 35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append('>'); 35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Type argument. 35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class TypeArgument { 36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectType arg; 36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal char wildcard; 36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeArgument(ObjectType a, char w) { 36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arg = a; 36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal wildcard = w; 36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the kind of this type argument. 37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return <code>' '</code> (not-wildcard), <code>'*'</code> (wildcard), <code>'+'</code> (wildcard with 37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * upper bound), or <code>'-'</code> (wildcard with lower bound). 37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public char getKind() { return wildcard; } 37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns true if this type argument is a wildcard type 37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * such as <code>?</code>, <code>? extends String</code>, or <code>? super Integer</code>. 38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean isWildcard() { return wildcard != ' '; } 38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the type represented by this argument 38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * if the argument is not a wildcard type. Otherwise, this method 38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * returns the upper bound (if the kind is '+'), 38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the lower bound (if the kind is '-'), or null (if the upper or lower 38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * bound is not specified). 38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ObjectType getType() { return arg; } 39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the string representation. 39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (wildcard == '*') 39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return "?"; 39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String type = arg.toString(); 40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (wildcard == ' ') 40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return type; 40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (wildcard == '+') 40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return "? extends " + type; 40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return "? super " + type; 40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Primitive types and object types. 41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static abstract class Type { 41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static void toString(StringBuffer sbuf, Type[] ts) { 41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < ts.length; i++) { 41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i > 0) 41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(", "); 41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(ts[i]); 41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Primitive types. 42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class BaseType extends Type { 42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal char descriptor; 42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal BaseType(char c) { descriptor = c; } 42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the descriptor representing this primitive type. 43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see javassist.bytecode.Descriptor 43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public char getDescriptor() { return descriptor; } 43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the <code>CtClass</code> representing this 43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * primitive type. 44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public CtClass getCtlass() { 44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return Descriptor.toPrimitiveClass(descriptor); 44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the string representation. 44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return Descriptor.toClassName(Character.toString(descriptor)); 45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Class types, array types, and type variables. 45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static abstract class ObjectType extends Type {} 45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Class types. 46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class ClassType extends ObjectType { 46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String name; 46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeArgument[] arguments; 46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static ClassType make(String s, int b, int e, 46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeArgument[] targs, ClassType parent) { 46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (parent == null) 46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new ClassType(s, b, e, targs); 46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new NestedClassType(s, b, e, targs, parent); 47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassType(String signature, int begin, int end, TypeArgument[] targs) { 47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal name = signature.substring(begin, end).replace('/', '.'); 47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal arguments = targs; 47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the class name. 48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getName() { 48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return name; 48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the type arguments. 48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return null if no type arguments are given to this class. 48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public TypeArgument[] getTypeArguments() { return arguments; } 49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If this class is a member of another class, returns the 49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * class in which this class is declared. 49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return null if this class is not a member of another class. 49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ClassType getDeclaringClass() { return null; } 49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the string representation. 50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuffer sbuf = new StringBuffer(); 50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassType parent = getDeclaringClass(); 50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (parent != null) 50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(parent.toString()).append('.'); 50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(name); 51069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (arguments != null) { 51169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append('<'); 51269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = arguments.length; 51369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; i++) { 51469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i > 0) 51569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(", "); 51669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 51769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append(arguments[i].toString()); 51869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 51969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 52069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append('>'); 52169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 52269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 52369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return sbuf.toString(); 52469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 52569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 52669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 52769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 52869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Nested class types. 52969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 53069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class NestedClassType extends ClassType { 53169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassType parent; 53269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal NestedClassType(String s, int b, int e, 53369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeArgument[] targs, ClassType p) { 53469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(s, b, e, targs); 53569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal parent = p; 53669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 53769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 53869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 53969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the class that declares this nested class. 54069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This nested class is a member of that declaring class. 54169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 54269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ClassType getDeclaringClass() { return parent; } 54369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 54469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 54569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 54669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Array types. 54769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 54869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class ArrayType extends ObjectType { 54969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dim; 55069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type componentType; 55169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 55269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public ArrayType(int d, Type comp) { 55369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal dim = d; 55469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal componentType = comp; 55569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 55669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 55769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 55869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the dimension of the array. 55969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 56069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int getDimension() { return dim; } 56169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 56269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 56369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the component type. 56469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 56569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Type getComponentType() { 56669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return componentType; 56769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 56869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 56969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 57069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the string representation. 57169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 57269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 57369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuffer sbuf = new StringBuffer(componentType.toString()); 57469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < dim; i++) 57569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal sbuf.append("[]"); 57669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 57769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return sbuf.toString(); 57869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 57969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 58069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 58169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 58269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Type variables. 58369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 58469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class TypeVariable extends ObjectType { 58569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String name; 58669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 58769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeVariable(String sig, int begin, int end) { 58869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal name = sig.substring(begin, end); 58969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 59069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 59169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 59269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the variable name. 59369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 59469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String getName() { 59569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return name; 59669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 59769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 59869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 59969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the string representation. 60069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 60169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 60269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return name; 60369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 60469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 60569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 60669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 60769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Parses the given signature string as a class signature. 60869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 60969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param sig the signature. 61069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws BadBytecode thrown when a syntactical error is found. 61169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @since 3.5 61269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 61369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static ClassSignature toClassSignature(String sig) throws BadBytecode { 61469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 61569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return parseSig(sig); 61669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 61769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (IndexOutOfBoundsException e) { 61869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw error(sig); 61969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 62069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 62169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 62269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 62369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Parses the given signature string as a method type signature. 62469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 62569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param sig the signature. 62669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws BadBytecode thrown when a syntactical error is found. 62769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @since 3.5 62869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 62969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static MethodSignature toMethodSignature(String sig) throws BadBytecode { 63069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 63169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return parseMethodSig(sig); 63269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 63369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (IndexOutOfBoundsException e) { 63469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw error(sig); 63569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 63669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 63769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 63869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 63969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Parses the given signature string as a field type signature. 64069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 64169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param sig the signature string. 64269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the field type signature. 64369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @throws BadBytecode thrown when a syntactical error is found. 64469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @since 3.5 64569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 64669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static ObjectType toFieldSignature(String sig) throws BadBytecode { 64769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 64869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return parseObjectType(sig, new Cursor(), false); 64969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 65069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (IndexOutOfBoundsException e) { 65169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw error(sig); 65269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 65369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 65469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 65569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static ClassSignature parseSig(String sig) 65669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode, IndexOutOfBoundsException 65769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 65869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Cursor cur = new Cursor(); 65969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeParameter[] tp = parseTypeParams(sig, cur); 66069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassType superClass = parseClassType(sig, cur); 66169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int sigLen = sig.length(); 66269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ArrayList ifArray = new ArrayList(); 66369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (cur.position < sigLen && sig.charAt(cur.position) == 'L') 66469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ifArray.add(parseClassType(sig, cur)); 66569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 66669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassType[] ifs 66769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = (ClassType[])ifArray.toArray(new ClassType[ifArray.size()]); 66869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new ClassSignature(tp, superClass, ifs); 66969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 67069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 67169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static MethodSignature parseMethodSig(String sig) 67269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 67369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 67469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Cursor cur = new Cursor(); 67569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeParameter[] tp = parseTypeParams(sig, cur); 67669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (sig.charAt(cur.position++) != '(') 67769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw error(sig); 67869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 67969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ArrayList params = new ArrayList(); 68069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (sig.charAt(cur.position) != ')') { 68169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type t = parseType(sig, cur); 68269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal params.add(t); 68369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 68469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 68569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cur.position++; 68669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type ret = parseType(sig, cur); 68769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int sigLen = sig.length(); 68869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ArrayList exceptions = new ArrayList(); 68969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (cur.position < sigLen && sig.charAt(cur.position) == '^') { 69069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cur.position++; 69169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectType t = parseObjectType(sig, cur, false); 69269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (t instanceof ArrayType) 69369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw error(sig); 69469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 69569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal exceptions.add(t); 69669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 69769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 69869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type[] p = (Type[])params.toArray(new Type[params.size()]); 69969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectType[] ex = (ObjectType[])exceptions.toArray(new ObjectType[exceptions.size()]); 70069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new MethodSignature(tp, p, ret, ex); 70169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 70269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 70369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static TypeParameter[] parseTypeParams(String sig, Cursor cur) 70469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 70569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 70669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ArrayList typeParam = new ArrayList(); 70769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (sig.charAt(cur.position) == '<') { 70869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cur.position++; 70969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (sig.charAt(cur.position) != '>') { 71069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int nameBegin = cur.position; 71169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int nameEnd = cur.indexOf(sig, ':'); 71269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectType classBound = parseObjectType(sig, cur, true); 71369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ArrayList ifBound = new ArrayList(); 71469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (sig.charAt(cur.position) == ':') { 71569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cur.position++; 71669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ObjectType t = parseObjectType(sig, cur, false); 71769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ifBound.add(t); 71869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 71969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 72069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeParameter p = new TypeParameter(sig, nameBegin, nameEnd, 72169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal classBound, (ObjectType[])ifBound.toArray(new ObjectType[ifBound.size()])); 72269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal typeParam.add(p); 72369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 72469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 72569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cur.position++; 72669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 72769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 72869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return (TypeParameter[])typeParam.toArray(new TypeParameter[typeParam.size()]); 72969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 73069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 73169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static ObjectType parseObjectType(String sig, Cursor c, boolean dontThrow) 73269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 73369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 73469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int i; 73569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int begin = c.position; 73669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal switch (sig.charAt(begin)) { 73769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'L' : 73869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return parseClassType2(sig, c, null); 73969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case 'T' : 74069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal i = c.indexOf(sig, ';'); 74169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new TypeVariable(sig, begin + 1, i); 74269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case '[' : 74369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return parseArray(sig, c); 74469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal default : 74569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (dontThrow) 74669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return null; 74769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 74869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw error(sig); 74969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 75069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 75169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 75269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static ClassType parseClassType(String sig, Cursor c) 75369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 75469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 75569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (sig.charAt(c.position) == 'L') 75669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return parseClassType2(sig, c, null); 75769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 75869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw error(sig); 75969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 76069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 76169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static ClassType parseClassType2(String sig, Cursor c, ClassType parent) 76269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 76369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 76469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int start = ++c.position; 76569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal char t; 76669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal do { 76769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal t = sig.charAt(c.position++); 76869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } while (t != '$' && t != '<' && t != ';'); 76969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int end = c.position - 1; 77069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeArgument[] targs; 77169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (t == '<') { 77269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targs = parseTypeArgs(sig, c); 77369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal t = sig.charAt(c.position++); 77469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 77569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 77669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal targs = null; 77769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 77869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ClassType thisClass = ClassType.make(sig, start, end, targs, parent); 77969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (t == '$') { 78069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.position--; 78169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return parseClassType2(sig, c, thisClass); 78269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 78369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 78469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return thisClass; 78569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 78669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 78769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static TypeArgument[] parseTypeArgs(String sig, Cursor c) throws BadBytecode { 78869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ArrayList args = new ArrayList(); 78969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal char t; 79069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while ((t = sig.charAt(c.position++)) != '>') { 79169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeArgument ta; 79269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (t == '*' ) 79369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ta = new TypeArgument(null, '*'); 79469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 79569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (t != '+' && t != '-') { 79669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal t = ' '; 79769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.position--; 79869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 79969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 80069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ta = new TypeArgument(parseObjectType(sig, c, false), t); 80169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 80269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 80369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal args.add(ta); 80469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 80569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 80669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return (TypeArgument[])args.toArray(new TypeArgument[args.size()]); 80769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 80869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 80969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static ObjectType parseArray(String sig, Cursor c) throws BadBytecode { 81069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int dim = 1; 81169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (sig.charAt(++c.position) == '[') 81269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal dim++; 81369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 81469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new ArrayType(dim, parseType(sig, c)); 81569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 81669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 81769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static Type parseType(String sig, Cursor c) throws BadBytecode { 81869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type t = parseObjectType(sig, c, true); 81969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (t == null) 82069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal t = new BaseType(sig.charAt(c.position++)); 82169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 82269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return t; 82369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 82469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 82569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static BadBytecode error(String sig) { 82669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return new BadBytecode("bad signature: " + sig); 82769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 82869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 829