📄 descriptor.java
字号:
/* * Javassist, a Java-bytecode translator toolkit. * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved. * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. Alternatively, the contents of this file may be used under * the terms of the GNU Lesser General Public License Version 2.1 or later. * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. */package javassist.bytecode;import javassist.ClassPool;import javassist.CtClass;import javassist.CtPrimitiveType;import javassist.NotFoundException;import java.util.Map;/** * A support class for dealing with descriptors. * * <p>See chapter 4.3 in "The Java Virtual Machine Specification (2nd ed.)" */public class Descriptor { /** * Converts a class name into the internal representation used in * the JVM. * * <p>Note that <code>toJvmName(toJvmName(s))</code> is equivalent * to <code>toJvmName(s)</code>. */ public static String toJvmName(String classname) { return classname.replace('.', '/'); } /** * Converts a class name from the internal representation used in * the JVM to the normal one used in Java. */ public static String toJavaName(String classname) { return classname.replace('/', '.'); } /** * Returns the internal representation of the class name in the * JVM. */ public static String toJvmName(CtClass clazz) { if (clazz.isArray()) return of(clazz); else return toJvmName(clazz.getName()); } /** * Converts to a Java class name from a descriptor. * * @param descriptor type descriptor. */ public static String toClassName(String descriptor) { int arrayDim = 0; int i = 0; char c = descriptor.charAt(0); while (c == '[') { ++arrayDim; c = descriptor.charAt(++i); } String name; if (c == 'L') { int i2 = descriptor.indexOf(';', i++); name = descriptor.substring(i, i2).replace('/', '.'); i = i2; } else if (c == 'V') name = "void"; else if (c == 'I') name = "int"; else if (c == 'B') name = "byte"; else if (c == 'J') name = "long"; else if (c == 'D') name = "double"; else if (c == 'F') name = "float"; else if (c == 'C') name = "char"; else if (c == 'S') name = "short"; else if (c == 'Z') name = "boolean"; else throw new RuntimeException("bad descriptor: " + descriptor); if (i + 1 != descriptor.length()) throw new RuntimeException("multiple descriptors?: " + descriptor); if (arrayDim == 0) return name; else { StringBuffer sbuf = new StringBuffer(name); do { sbuf.append("[]"); } while (--arrayDim > 0); return sbuf.toString(); } } /** * Converts to a descriptor from a Java class name */ public static String of(String classname) { if (classname.equals("void")) return "V"; else if (classname.equals("int")) return "I"; else if (classname.equals("byte")) return "B"; else if (classname.equals("long")) return "J"; else if (classname.equals("double")) return "D"; else if (classname.equals("float")) return "F"; else if (classname.equals("char")) return "C"; else if (classname.equals("short")) return "S"; else if (classname.equals("boolean")) return "Z"; else return "L" + toJvmName(classname) + ";"; } /** * Substitutes a class name * in the given descriptor string. * * @param desc descriptor string * @param oldname replaced JVM class name * @param newname substituted JVM class name * * @see Descriptor#toJvmName(String) */ public static String rename(String desc, String oldname, String newname) { if (desc.indexOf(oldname) < 0) return desc; StringBuffer newdesc = new StringBuffer(); int head = 0; int i = 0; for (;;) { int j = desc.indexOf('L', i); if (j < 0) break; else if (desc.startsWith(oldname, j + 1) && desc.charAt(j + oldname.length() + 1) == ';') { newdesc.append(desc.substring(head, j)); newdesc.append('L'); newdesc.append(newname); newdesc.append(';'); head = i = j + oldname.length() + 2; } else { i = desc.indexOf(';', j) + 1; if (i < 1) break; // ';' was not found. } } if (head == 0) return desc; else { int len = desc.length(); if (head < len) newdesc.append(desc.substring(head, len)); return newdesc.toString(); } } /** * Substitutes class names in the given descriptor string * according to the given <code>map</code>. * * @param map a map between replaced and substituted * JVM class names. * @see Descriptor#toJvmName(String) */ public static String rename(String desc, Map map) { if (map == null) return desc; StringBuffer newdesc = new StringBuffer(); int head = 0; int i = 0; for (;;) { int j = desc.indexOf('L', i); if (j < 0) break; int k = desc.indexOf(';', j); if (k < 0) break; i = k + 1; String name = desc.substring(j + 1, k); String name2 = (String)map.get(name); if (name2 != null) { newdesc.append(desc.substring(head, j)); newdesc.append('L'); newdesc.append(name2); newdesc.append(';'); head = i; } } if (head == 0) return desc; else { int len = desc.length(); if (head < len) newdesc.append(desc.substring(head, len)); return newdesc.toString(); } } /** * Returns the descriptor representing the given type. */ public static String of(CtClass type) { StringBuffer sbuf = new StringBuffer(); toDescriptor(sbuf, type); return sbuf.toString(); } private static void toDescriptor(StringBuffer desc, CtClass type) { if (type.isArray()) { desc.append('['); try { toDescriptor(desc, type.getComponentType()); } catch (NotFoundException e) { desc.append('L'); String name = type.getName(); desc.append(toJvmName(name.substring(0, name.length() - 2))); desc.append(';'); } } else if (type.isPrimitive()) { CtPrimitiveType pt = (CtPrimitiveType)type; desc.append(pt.getDescriptor()); } else { // class type desc.append('L'); desc.append(type.getName().replace('.', '/')); desc.append(';'); } } /** * Returns the descriptor representing a constructor receiving * the given parameter types. * * @param paramTypes parameter types */ public static String ofConstructor(CtClass[] paramTypes) { return ofMethod(CtClass.voidType, paramTypes); } /** * Returns the descriptor representing a method that receives * the given parameter types and returns the given type. * * @param returnType return type * @param paramTypes parameter types */ public static String ofMethod(CtClass returnType, CtClass[] paramTypes) { StringBuffer desc = new StringBuffer(); desc.append('('); if (paramTypes != null) { int n = paramTypes.length; for (int i = 0; i < n; ++i) toDescriptor(desc, paramTypes[i]); } desc.append(')'); if (returnType != null) toDescriptor(desc, returnType); return desc.toString(); } /** * Returns the descriptor representing a list of parameter types. * For example, if the given parameter types are two <code>int</code>, * then this method returns <code>"(II)"</code>. * * @param paramTypes parameter types */ public static String ofParameters(CtClass[] paramTypes) { return ofMethod(null, paramTypes); } /** * Appends a parameter type to the parameter list represented * by the given descriptor. * * <p><code>classname</code> must not be an array type. * * @param classname parameter type (not primitive type) * @param desc descriptor */ public static String appendParameter(String classname, String desc) { int i = desc.indexOf(')'); if (i < 0) return desc; else { StringBuffer newdesc = new StringBuffer(); newdesc.append(desc.substring(0, i)); newdesc.append('L'); newdesc.append(classname.replace('.', '/')); newdesc.append(';'); newdesc.append(desc.substring(i)); return newdesc.toString(); } } /** * Inserts a parameter type at the beginning of the parameter * list represented * by the given descriptor. * * <p><code>classname</code> must not be an array type. * * @param classname parameter type (not primitive type) * @param desc descriptor */ public static String insertParameter(String classname, String desc) { if (desc.charAt(0) != '(') return desc; else return "(L" + classname.replace('.', '/') + ';' + desc.substring(1); } /** * Changes the return type included in the given descriptor. * * <p><code>classname</code> must not be an array type. * * @param classname return type * @param desc descriptor */ public static String changeReturnType(String classname, String desc) { int i = desc.indexOf(')'); if (i < 0) return desc; else { StringBuffer newdesc = new StringBuffer(); newdesc.append(desc.substring(0, i + 1)); newdesc.append('L'); newdesc.append(classname.replace('.', '/')); newdesc.append(';'); return newdesc.toString(); } } /** * Returns the <code>CtClass</code> objects representing the parameter * types specified by the given descriptor. * * @param desc descriptor * @param cp the class pool used for obtaining * a <code>CtClass</code> object. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -