diff options
Diffstat (limited to 'src/proguard/classfile/util/ClassUtil.java')
-rw-r--r-- | src/proguard/classfile/util/ClassUtil.java | 1311 |
1 files changed, 0 insertions, 1311 deletions
diff --git a/src/proguard/classfile/util/ClassUtil.java b/src/proguard/classfile/util/ClassUtil.java deleted file mode 100644 index 037d31a..0000000 --- a/src/proguard/classfile/util/ClassUtil.java +++ /dev/null @@ -1,1311 +0,0 @@ -/* - * ProGuard -- shrinking, optimization, obfuscation, and preverification - * of Java bytecode. - * - * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ -package proguard.classfile.util; - -import proguard.classfile.*; - -import java.util.List; - -/** - * Utility methods for converting between internal and external representations - * of names and descriptions. - * - * @author Eric Lafortune - */ -public class ClassUtil -{ - private static final String EMPTY_STRING = ""; - - - /** - * Checks whether the given class magic number is correct. - * @param magicNumber the magic number. - * @throws UnsupportedOperationException when the magic number is incorrect. - */ - public static void checkMagicNumber(int magicNumber) throws UnsupportedOperationException - { - if (magicNumber != ClassConstants.MAGIC) - { - throw new UnsupportedOperationException("Invalid magic number ["+Integer.toHexString(magicNumber)+"] in class"); - } - } - - - /** - * Returns the combined class version number. - * @param majorVersion the major part of the class version number. - * @param minorVersion the minor part of the class version number. - * @return the combined class version number. - */ - public static int internalClassVersion(int majorVersion, int minorVersion) - { - return (majorVersion << 16) | minorVersion; - } - - - /** - * Returns the major part of the given class version number. - * @param classVersion the combined class version number. - * @return the major part of the class version number. - */ - public static int internalMajorClassVersion(int classVersion) - { - return classVersion >>> 16; - } - - - /** - * Returns the internal class version number. - * @param classVersion the external class version number. - * @return the internal class version number. - */ - public static int internalMinorClassVersion(int classVersion) - { - return classVersion & 0xffff; - } - - - /** - * Returns the internal class version number. - * @param classVersion the external class version number. - * @return the internal class version number. - */ - public static int internalClassVersion(String classVersion) - { - return - classVersion.equals(JavaConstants.CLASS_VERSION_1_0) || - classVersion.equals(JavaConstants.CLASS_VERSION_1_1) ? ClassConstants.CLASS_VERSION_1_0 : - classVersion.equals(JavaConstants.CLASS_VERSION_1_2) ? ClassConstants.CLASS_VERSION_1_2 : - classVersion.equals(JavaConstants.CLASS_VERSION_1_3) ? ClassConstants.CLASS_VERSION_1_3 : - classVersion.equals(JavaConstants.CLASS_VERSION_1_4) ? ClassConstants.CLASS_VERSION_1_4 : - classVersion.equals(JavaConstants.CLASS_VERSION_1_5_ALIAS) || - classVersion.equals(JavaConstants.CLASS_VERSION_1_5) ? ClassConstants.CLASS_VERSION_1_5 : - classVersion.equals(JavaConstants.CLASS_VERSION_1_6_ALIAS) || - classVersion.equals(JavaConstants.CLASS_VERSION_1_6) ? ClassConstants.CLASS_VERSION_1_6 : - classVersion.equals(JavaConstants.CLASS_VERSION_1_7_ALIAS) || - classVersion.equals(JavaConstants.CLASS_VERSION_1_7) ? ClassConstants.CLASS_VERSION_1_7 : - classVersion.equals(JavaConstants.CLASS_VERSION_1_8_ALIAS) || - classVersion.equals(JavaConstants.CLASS_VERSION_1_8) ? ClassConstants.CLASS_VERSION_1_8 : - 0; - } - - - /** - * Returns the minor part of the given class version number. - * @param classVersion the combined class version number. - * @return the minor part of the class version number. - */ - public static String externalClassVersion(int classVersion) - { - switch (classVersion) - { - case ClassConstants.CLASS_VERSION_1_0: return JavaConstants.CLASS_VERSION_1_0; - case ClassConstants.CLASS_VERSION_1_2: return JavaConstants.CLASS_VERSION_1_2; - case ClassConstants.CLASS_VERSION_1_3: return JavaConstants.CLASS_VERSION_1_3; - case ClassConstants.CLASS_VERSION_1_4: return JavaConstants.CLASS_VERSION_1_4; - case ClassConstants.CLASS_VERSION_1_5: return JavaConstants.CLASS_VERSION_1_5; - case ClassConstants.CLASS_VERSION_1_6: return JavaConstants.CLASS_VERSION_1_6; - case ClassConstants.CLASS_VERSION_1_7: return JavaConstants.CLASS_VERSION_1_7; - case ClassConstants.CLASS_VERSION_1_8: return JavaConstants.CLASS_VERSION_1_8; - default: return null; - } - } - - - /** - * Checks whether the given class version number is supported. - * @param classVersion the combined class version number. - * @throws UnsupportedOperationException when the version is not supported. - */ - public static void checkVersionNumbers(int classVersion) throws UnsupportedOperationException - { - if (classVersion < ClassConstants.CLASS_VERSION_1_0 || - classVersion > ClassConstants.CLASS_VERSION_1_8) - { - throw new UnsupportedOperationException("Unsupported class version number ["+ - internalMajorClassVersion(classVersion)+"."+ - internalMinorClassVersion(classVersion)+"] (maximum "+ - ClassConstants.CLASS_VERSION_1_8_MAJOR+"."+ - ClassConstants.CLASS_VERSION_1_8_MINOR+", Java "+ - JavaConstants.CLASS_VERSION_1_8+")"); - } - } - - - /** - * Converts an external class name into an internal class name. - * @param externalClassName the external class name, - * e.g. "<code>java.lang.Object</code>" - * @return the internal class name, - * e.g. "<code>java/lang/Object</code>". - */ - public static String internalClassName(String externalClassName) - { - return externalClassName.replace(JavaConstants.PACKAGE_SEPARATOR, - ClassConstants.PACKAGE_SEPARATOR); - } - - - /** - * Converts an internal class description into an external class description. - * @param accessFlags the access flags of the class. - * @param internalClassName the internal class name, - * e.g. "<code>java/lang/Object</code>". - * @return the external class description, - * e.g. "<code>public java.lang.Object</code>". - */ - public static String externalFullClassDescription(int accessFlags, - String internalClassName) - { - return externalClassAccessFlags(accessFlags) + - externalClassName(internalClassName); - } - - - /** - * Converts an internal class name into an external class name. - * @param internalClassName the internal class name, - * e.g. "<code>java/lang/Object</code>". - * @return the external class name, - * e.g. "<code>java.lang.Object</code>". - */ - public static String externalClassName(String internalClassName) - { - return //internalClassName.startsWith(ClassConstants.PACKAGE_JAVA_LANG) && - //internalClassName.indexOf(ClassConstants.PACKAGE_SEPARATOR, ClassConstants.PACKAGE_JAVA_LANG.length() + 1) < 0 ? - //internalClassName.substring(ClassConstants.PACKAGE_JAVA_LANG.length()) : - internalClassName.replace(ClassConstants.PACKAGE_SEPARATOR, - JavaConstants.PACKAGE_SEPARATOR); - } - - - /** - * Returns the external base type of an external array type, dropping any - * array brackets. - * @param externalArrayType the external array type, - * e.g. "<code>java.lang.Object[][]</code>" - * @return the external base type, - * e.g. "<code>java.lang.Object</code>". - */ - public static String externalBaseType(String externalArrayType) - { - int index = externalArrayType.indexOf(JavaConstants.TYPE_ARRAY); - return index >= 0 ? - externalArrayType.substring(0, index) : - externalArrayType; - } - - - /** - * Returns the external short class name of an external class name, dropping - * the package specification. - * @param externalClassName the external class name, - * e.g. "<code>java.lang.Object</code>" - * @return the external short class name, - * e.g. "<code>Object</code>". - */ - public static String externalShortClassName(String externalClassName) - { - int index = externalClassName.lastIndexOf(JavaConstants.PACKAGE_SEPARATOR); - return externalClassName.substring(index+1); - } - - - /** - * Returns whether the given internal type is an array type. - * @param internalType the internal type, - * e.g. "<code>[[Ljava/lang/Object;</code>". - * @return <code>true</code> if the given type is an array type, - * <code>false</code> otherwise. - */ - public static boolean isInternalArrayType(String internalType) - { - return internalType.length() > 1 && - internalType.charAt(0) == ClassConstants.TYPE_ARRAY; - } - - - /** - * Returns the number of dimensions of the given internal type. - * @param internalType the internal type, - * e.g. "<code>[[Ljava/lang/Object;</code>". - * @return the number of dimensions, e.g. 2. - */ - public static int internalArrayTypeDimensionCount(String internalType) - { - int dimensions = 0; - while (internalType.charAt(dimensions) == ClassConstants.TYPE_ARRAY) - { - dimensions++; - } - - return dimensions; - } - - - /** - * Returns whether the given internal class name is one of the interfaces - * that is implemented by all array types. These class names are - * "<code>java/lang/Object</code>", "<code>java/lang/Cloneable</code>", and - * "<code>java/io/Serializable</code>" - * @param internalClassName the internal class name, - * e.g. "<code>java/lang/Object</code>". - * @return <code>true</code> if the given type is an array interface name, - * <code>false</code> otherwise. - */ - public static boolean isInternalArrayInterfaceName(String internalClassName) - { - return ClassConstants.NAME_JAVA_LANG_OBJECT.equals(internalClassName) || - ClassConstants.NAME_JAVA_LANG_CLONEABLE.equals(internalClassName) || - ClassConstants.NAME_JAVA_IO_SERIALIZABLE.equals(internalClassName); - } - - - /** - * Returns whether the given internal type is a plain primitive type - * (not void). - * @param internalType the internal type, - * e.g. "<code>I</code>". - * @return <code>true</code> if the given type is a class type, - * <code>false</code> otherwise. - */ - public static boolean isInternalPrimitiveType(char internalType) - { - return internalType == ClassConstants.TYPE_BOOLEAN || - internalType == ClassConstants.TYPE_BYTE || - internalType == ClassConstants.TYPE_CHAR || - internalType == ClassConstants.TYPE_SHORT || - internalType == ClassConstants.TYPE_INT || - internalType == ClassConstants.TYPE_FLOAT || - internalType == ClassConstants.TYPE_LONG || - internalType == ClassConstants.TYPE_DOUBLE; - } - - - /** - * Returns whether the given internal type is a primitive Category 2 type. - * @param internalType the internal type, - * e.g. "<code>L</code>". - * @return <code>true</code> if the given type is a Category 2 type, - * <code>false</code> otherwise. - */ - public static boolean isInternalCategory2Type(String internalType) - { - return internalType.length() == 1 && - (internalType.charAt(0) == ClassConstants.TYPE_LONG || - internalType.charAt(0) == ClassConstants.TYPE_DOUBLE); - } - - - /** - * Returns whether the given internal type is a plain class type - * (including an array type of a plain class type). - * @param internalType the internal type, - * e.g. "<code>Ljava/lang/Object;</code>". - * @return <code>true</code> if the given type is a class type, - * <code>false</code> otherwise. - */ - public static boolean isInternalClassType(String internalType) - { - int length = internalType.length(); - return length > 1 && -// internalType.charAt(0) == ClassConstants.TYPE_CLASS_START && - internalType.charAt(length-1) == ClassConstants.TYPE_CLASS_END; - } - - - /** - * Returns the internal type of a given class name. - * @param internalClassName the internal class name, - * e.g. "<code>java/lang/Object</code>". - * @return the internal type, - * e.g. "<code>Ljava/lang/Object;</code>". - */ - public static String internalTypeFromClassName(String internalClassName) - { - return internalArrayTypeFromClassName(internalClassName, 0); - } - - - /** - * Returns the internal array type of a given class name with a given number - * of dimensions. If the number of dimensions is 0, the class name itself is - * returned. - * @param internalClassName the internal class name, - * e.g. "<code>java/lang/Object</code>". - * @param dimensionCount the number of array dimensions. - * @return the internal array type of the array elements, - * e.g. "<code>Ljava/lang/Object;</code>". - */ - public static String internalArrayTypeFromClassName(String internalClassName, - int dimensionCount) - { - StringBuffer buffer = new StringBuffer(internalClassName.length() + dimensionCount + 2); - - for (int dimension = 0; dimension < dimensionCount; dimension++) - { - buffer.append(ClassConstants.TYPE_ARRAY); - } - - return buffer.append(ClassConstants.TYPE_CLASS_START) - .append(internalClassName) - .append(ClassConstants.TYPE_CLASS_END) - .toString(); - } - - - /** - * Returns the internal element type of a given internal array type. - * @param internalArrayType the internal array type, - * e.g. "<code>[[Ljava/lang/Object;</code>" or - * "<code>[I</code>". - * @return the internal type of the array elements, - * e.g. "<code>Ljava/lang/Object;</code>" or - * "<code>I</code>". - */ - public static String internalTypeFromArrayType(String internalArrayType) - { - int index = internalArrayType.lastIndexOf(ClassConstants.TYPE_ARRAY); - return internalArrayType.substring(index+1); - } - - - /** - * Returns the internal class name of a given internal class type - * (including an array type). Types involving primitive types are returned - * unchanged. - * @param internalClassType the internal class type, - * e.g. "<code>[Ljava/lang/Object;</code>", - * "<code>Ljava/lang/Object;</code>", or - * "<code>java/lang/Object</code>". - * @return the internal class name, - * e.g. "<code>java/lang/Object</code>". - */ - public static String internalClassNameFromClassType(String internalClassType) - { - return isInternalClassType(internalClassType) ? - internalClassType.substring(internalClassType.indexOf(ClassConstants.TYPE_CLASS_START)+1, - internalClassType.length()-1) : - internalClassType; - } - - - /** - * Returns the internal class name of any given internal descriptor type, - * disregarding array prefixes. - * @param internalClassType the internal class type, - * e.g. "<code>Ljava/lang/Object;</code>" or - * "<code>[[I</code>". - * @return the internal class name, - * e.g. "<code>java/lang/Object</code>" or - * <code>null</code>. - */ - public static String internalClassNameFromType(String internalClassType) - { - if (!isInternalClassType(internalClassType)) - { - return null; - } - - // Is it an array type? - if (isInternalArrayType(internalClassType)) - { - internalClassType = internalTypeFromArrayType(internalClassType); - } - - return internalClassNameFromClassType(internalClassType); - } - - - /** - * Returns whether the given method name refers to a class initializer or - * an instance initializer. - * @param internalMethodName the internal method name, - * e.g. "<code><clinit></code>". - * @return whether the method name refers to an initializer, - * e.g. <code>true</code>. - */ - public static boolean isInitializer(String internalMethodName) - { - return internalMethodName.equals(ClassConstants.METHOD_NAME_CLINIT) || - internalMethodName.equals(ClassConstants.METHOD_NAME_INIT); - } - - - /** - * Returns the internal type of the given internal method descriptor. - * @param internalMethodDescriptor the internal method descriptor, - * e.g. "<code>(II)Z</code>". - * @return the internal return type, - * e.g. "<code>Z</code>". - */ - public static String internalMethodReturnType(String internalMethodDescriptor) - { - int index = internalMethodDescriptor.indexOf(ClassConstants.METHOD_ARGUMENTS_CLOSE); - return internalMethodDescriptor.substring(index + 1); - } - - - /** - * Returns the number of parameters of the given internal method descriptor. - * @param internalMethodDescriptor the internal method descriptor, - * e.g. "<code>(ID)Z</code>". - * @return the number of parameters, - * e.g. 2. - */ - public static int internalMethodParameterCount(String internalMethodDescriptor) - { - int counter = 0; - int index = 1; - - while (true) - { - char c = internalMethodDescriptor.charAt(index++); - switch (c) - { - case ClassConstants.TYPE_ARRAY: - { - // Just ignore all array characters. - break; - } - case ClassConstants.TYPE_CLASS_START: - { - counter++; - - // Skip the class name. - index = internalMethodDescriptor.indexOf(ClassConstants.TYPE_CLASS_END, index) + 1; - break; - } - default: - { - counter++; - break; - } - case ClassConstants.METHOD_ARGUMENTS_CLOSE: - { - return counter; - } - } - } - } - - - /** - * Returns the size taken up on the stack by the parameters of the given - * internal method descriptor. This accounts for long and double parameters - * taking up two entries. - * @param internalMethodDescriptor the internal method descriptor, - * e.g. "<code>(ID)Z</code>". - * @return the size taken up on the stack, - * e.g. 3. - */ - public static int internalMethodParameterSize(String internalMethodDescriptor) - { - return internalMethodParameterSize(internalMethodDescriptor, true); - } - - - /** - * Returns the size taken up on the stack by the parameters of the given - * internal method descriptor. This accounts for long and double parameters - * taking up two entries, and a non-static method taking up an additional - * entry. - * @param internalMethodDescriptor the internal method descriptor, - * e.g. "<code>(ID)Z</code>". - * @param accessFlags the access flags of the method, - * e.g. 0. - * @return the size taken up on the stack, - * e.g. 4. - */ - public static int internalMethodParameterSize(String internalMethodDescriptor, - int accessFlags) - { - return internalMethodParameterSize(internalMethodDescriptor, - (accessFlags & ClassConstants.ACC_STATIC) != 0); - } - - - /** - * Returns the size taken up on the stack by the parameters of the given - * internal method descriptor. This accounts for long and double parameters - * taking up two spaces, and a non-static method taking up an additional - * entry. - * @param internalMethodDescriptor the internal method descriptor, - * e.g. "<code>(ID)Z</code>". - * @param isStatic specifies whether the method is static, - * e.g. false. - * @return the size taken up on the stack, - * e.g. 4. - */ - public static int internalMethodParameterSize(String internalMethodDescriptor, - boolean isStatic) - { - int size = isStatic ? 0 : 1; - int index = 1; - - while (true) - { - char c = internalMethodDescriptor.charAt(index++); - switch (c) - { - case ClassConstants.TYPE_LONG: - case ClassConstants.TYPE_DOUBLE: - { - size += 2; - break; - } - case ClassConstants.TYPE_CLASS_START: - { - size++; - - // Skip the class name. - index = internalMethodDescriptor.indexOf(ClassConstants.TYPE_CLASS_END, index) + 1; - break; - } - case ClassConstants.TYPE_ARRAY: - { - size++; - - // Skip all array characters. - while ((c = internalMethodDescriptor.charAt(index++)) == ClassConstants.TYPE_ARRAY) {} - - if (c == ClassConstants.TYPE_CLASS_START) - { - // Skip the class type. - index = internalMethodDescriptor.indexOf(ClassConstants.TYPE_CLASS_END, index) + 1; - } - break; - } - default: - { - size++; - break; - } - case ClassConstants.METHOD_ARGUMENTS_CLOSE: - { - return size; - } - } - } - } - - - /** - * Returns the size taken up on the stack by the given internal type. - * The size is 1, except for long and double types, for which it is 2, - * and for the void type, for which 0 is returned. - * @param internalType the internal type, - * e.g. "<code>I</code>". - * @return the size taken up on the stack, - * e.g. 1. - */ - public static int internalTypeSize(String internalType) - { - if (internalType.length() == 1) - { - char internalPrimitiveType = internalType.charAt(0); - if (internalPrimitiveType == ClassConstants.TYPE_LONG || - internalPrimitiveType == ClassConstants.TYPE_DOUBLE) - { - return 2; - } - else if (internalPrimitiveType == ClassConstants.TYPE_VOID) - { - return 0; - } - } - - return 1; - } - - - /** - * Converts an external type into an internal type. - * @param externalType the external type, - * e.g. "<code>java.lang.Object[][]</code>" or - * "<code>int[]</code>". - * @return the internal type, - * e.g. "<code>[[Ljava/lang/Object;</code>" or - * "<code>[I</code>". - */ - public static String internalType(String externalType) - { - // Strip the array part, if any. - int dimensionCount = externalArrayTypeDimensionCount(externalType); - if (dimensionCount > 0) - { - externalType = externalType.substring(0, externalType.length() - dimensionCount * JavaConstants.TYPE_ARRAY.length()); - } - - // Analyze the actual type part. - char internalTypeChar = - externalType.equals(JavaConstants.TYPE_VOID ) ? ClassConstants.TYPE_VOID : - externalType.equals(JavaConstants.TYPE_BOOLEAN) ? ClassConstants.TYPE_BOOLEAN : - externalType.equals(JavaConstants.TYPE_BYTE ) ? ClassConstants.TYPE_BYTE : - externalType.equals(JavaConstants.TYPE_CHAR ) ? ClassConstants.TYPE_CHAR : - externalType.equals(JavaConstants.TYPE_SHORT ) ? ClassConstants.TYPE_SHORT : - externalType.equals(JavaConstants.TYPE_INT ) ? ClassConstants.TYPE_INT : - externalType.equals(JavaConstants.TYPE_FLOAT ) ? ClassConstants.TYPE_FLOAT : - externalType.equals(JavaConstants.TYPE_LONG ) ? ClassConstants.TYPE_LONG : - externalType.equals(JavaConstants.TYPE_DOUBLE ) ? ClassConstants.TYPE_DOUBLE : - externalType.equals("%" ) ? '%' : - (char)0; - - String internalType = - internalTypeChar != 0 ? String.valueOf(internalTypeChar) : - ClassConstants.TYPE_CLASS_START + - internalClassName(externalType) + - ClassConstants.TYPE_CLASS_END; - - // Prepend the array part, if any. - for (int count = 0; count < dimensionCount; count++) - { - internalType = ClassConstants.TYPE_ARRAY + internalType; - } - - return internalType; - } - - - /** - * Returns the number of dimensions of the given external type. - * @param externalType the external type, - * e.g. "<code>[[Ljava/lang/Object;</code>". - * @return the number of dimensions, e.g. 2. - */ - public static int externalArrayTypeDimensionCount(String externalType) - { - int dimensions = 0; - int length = JavaConstants.TYPE_ARRAY.length(); - int offset = externalType.length() - length; - while (externalType.regionMatches(offset, - JavaConstants.TYPE_ARRAY, - 0, - length)) - { - dimensions++; - offset -= length; - } - - return dimensions; - } - - - /** - * Converts an internal type into an external type. - * @param internalType the internal type, - * e.g. "<code>[[Ljava/lang/Object;</code>" or - * "<code>[I</code>". - * @return the external type, - * e.g. "<code>java.lang.Object[][]</code>" or - * "<code>int[]</code>". - */ - public static String externalType(String internalType) - { - // Strip the array part, if any. - int dimensionCount = internalArrayTypeDimensionCount(internalType); - if (dimensionCount > 0) - { - internalType = internalType.substring(dimensionCount); - } - - // Analyze the actual type part. - char internalTypeChar = internalType.charAt(0); - - String externalType = - internalTypeChar == ClassConstants.TYPE_VOID ? JavaConstants.TYPE_VOID : - internalTypeChar == ClassConstants.TYPE_BOOLEAN ? JavaConstants.TYPE_BOOLEAN : - internalTypeChar == ClassConstants.TYPE_BYTE ? JavaConstants.TYPE_BYTE : - internalTypeChar == ClassConstants.TYPE_CHAR ? JavaConstants.TYPE_CHAR : - internalTypeChar == ClassConstants.TYPE_SHORT ? JavaConstants.TYPE_SHORT : - internalTypeChar == ClassConstants.TYPE_INT ? JavaConstants.TYPE_INT : - internalTypeChar == ClassConstants.TYPE_FLOAT ? JavaConstants.TYPE_FLOAT : - internalTypeChar == ClassConstants.TYPE_LONG ? JavaConstants.TYPE_LONG : - internalTypeChar == ClassConstants.TYPE_DOUBLE ? JavaConstants.TYPE_DOUBLE : - internalTypeChar == '%' ? "%" : - internalTypeChar == ClassConstants.TYPE_CLASS_START ? externalClassName(internalType.substring(1, internalType.indexOf(ClassConstants.TYPE_CLASS_END))) : - null; - - if (externalType == null) - { - throw new IllegalArgumentException("Unknown type ["+internalType+"]"); - } - - // Append the array part, if any. - for (int count = 0; count < dimensionCount; count++) - { - externalType += JavaConstants.TYPE_ARRAY; - } - - return externalType; - } - - - /** - * Returns whether the given internal descriptor String represents a method - * descriptor. - * @param internalDescriptor the internal descriptor String, - * e.g. "<code>(II)Z</code>". - * @return <code>true</code> if the given String is a method descriptor, - * <code>false</code> otherwise. - */ - public static boolean isInternalMethodDescriptor(String internalDescriptor) - { - return internalDescriptor.charAt(0) == ClassConstants.METHOD_ARGUMENTS_OPEN; - } - - - /** - * Returns whether the given member String represents an external method - * name with arguments. - * @param externalMemberNameAndArguments the external member String, - * e.g. "<code>myField</code>" or - * e.g. "<code>myMethod(int,int)</code>". - * @return <code>true</code> if the given String refers to a method, - * <code>false</code> otherwise. - */ - public static boolean isExternalMethodNameAndArguments(String externalMemberNameAndArguments) - { - return externalMemberNameAndArguments.indexOf(JavaConstants.METHOD_ARGUMENTS_OPEN) > 0; - } - - - /** - * Returns the name part of the given external method name and arguments. - * @param externalMethodNameAndArguments the external method name and arguments, - * e.g. "<code>myMethod(int,int)</code>". - * @return the name part of the String, e.g. "<code>myMethod</code>". - */ - public static String externalMethodName(String externalMethodNameAndArguments) - { - ExternalTypeEnumeration externalTypeEnumeration = - new ExternalTypeEnumeration(externalMethodNameAndArguments); - - return externalTypeEnumeration.methodName(); - } - - - /** - * Converts the given external method return type and name and arguments to - * an internal method descriptor. - * @param externalReturnType the external method return type, - * e.g. "<code>boolean</code>". - * @param externalMethodNameAndArguments the external method name and arguments, - * e.g. "<code>myMethod(int,int)</code>". - * @return the internal method descriptor, - * e.g. "<code>(II)Z</code>". - */ - public static String internalMethodDescriptor(String externalReturnType, - String externalMethodNameAndArguments) - { - StringBuffer internalMethodDescriptor = new StringBuffer(); - internalMethodDescriptor.append(ClassConstants.METHOD_ARGUMENTS_OPEN); - - ExternalTypeEnumeration externalTypeEnumeration = - new ExternalTypeEnumeration(externalMethodNameAndArguments); - - while (externalTypeEnumeration.hasMoreTypes()) - { - internalMethodDescriptor.append(internalType(externalTypeEnumeration.nextType())); - } - - internalMethodDescriptor.append(ClassConstants.METHOD_ARGUMENTS_CLOSE); - internalMethodDescriptor.append(internalType(externalReturnType)); - - return internalMethodDescriptor.toString(); - } - - - /** - * Converts the given external method return type and List of arguments to - * an internal method descriptor. - * @param externalReturnType the external method return type, - * e.g. "<code>boolean</code>". - * @param externalArguments the external method arguments, - * e.g. <code>{ "int", "int" }</code>. - * @return the internal method descriptor, - * e.g. "<code>(II)Z</code>". - */ - public static String internalMethodDescriptor(String externalReturnType, - List externalArguments) - { - StringBuffer internalMethodDescriptor = new StringBuffer(); - internalMethodDescriptor.append(ClassConstants.METHOD_ARGUMENTS_OPEN); - - for (int index = 0; index < externalArguments.size(); index++) - { - internalMethodDescriptor.append(internalType((String)externalArguments.get(index))); - } - - internalMethodDescriptor.append(ClassConstants.METHOD_ARGUMENTS_CLOSE); - internalMethodDescriptor.append(internalType(externalReturnType)); - - return internalMethodDescriptor.toString(); - } - - - /** - * Converts an internal field description into an external full field description. - * @param accessFlags the access flags of the field. - * @param fieldName the field name, - * e.g. "<code>myField</code>". - * @param internalFieldDescriptor the internal field descriptor, - * e.g. "<code>Z</code>". - * @return the external full field description, - * e.g. "<code>public boolean myField</code>". - */ - public static String externalFullFieldDescription(int accessFlags, - String fieldName, - String internalFieldDescriptor) - { - return externalFieldAccessFlags(accessFlags) + - externalType(internalFieldDescriptor) + - ' ' + - fieldName; - } - - - /** - * Converts an internal method description into an external full method description. - * @param internalClassName the internal name of the class of the method, - * e.g. "<code>mypackage/MyClass</code>". - * @param accessFlags the access flags of the method. - * @param internalMethodName the internal method name, - * e.g. "<code>myMethod</code>" or - * "<code><init></code>". - * @param internalMethodDescriptor the internal method descriptor, - * e.g. "<code>(II)Z</code>". - * @return the external full method description, - * e.g. "<code>public boolean myMethod(int,int)</code>" or - * "<code>public MyClass(int,int)</code>". - */ - public static String externalFullMethodDescription(String internalClassName, - int accessFlags, - String internalMethodName, - String internalMethodDescriptor) - { - return externalMethodAccessFlags(accessFlags) + - externalMethodReturnTypeAndName(internalClassName, - internalMethodName, - internalMethodDescriptor) + - JavaConstants.METHOD_ARGUMENTS_OPEN + - externalMethodArguments(internalMethodDescriptor) + - JavaConstants.METHOD_ARGUMENTS_CLOSE; - } - - - /** - * Converts internal class access flags into an external access description. - * @param accessFlags the class access flags. - * @return the external class access description, - * e.g. "<code>public final </code>". - */ - public static String externalClassAccessFlags(int accessFlags) - { - return externalClassAccessFlags(accessFlags, ""); - } - - - /** - * Converts internal class access flags into an external access description. - * @param accessFlags the class access flags. - * @param prefix a prefix that is added to each access modifier. - * @return the external class access description, - * e.g. "<code>public final </code>". - */ - public static String externalClassAccessFlags(int accessFlags, String prefix) - { - if (accessFlags == 0) - { - return EMPTY_STRING; - } - - StringBuffer string = new StringBuffer(50); - - if ((accessFlags & ClassConstants.ACC_PUBLIC) != 0) - { - string.append(prefix).append(JavaConstants.ACC_PUBLIC).append(' '); - } - if ((accessFlags & ClassConstants.ACC_PRIVATE) != 0) - { - // Only in InnerClasses attributes. - string.append(prefix).append(JavaConstants.ACC_PRIVATE).append(' '); - } - if ((accessFlags & ClassConstants.ACC_PROTECTED) != 0) - { - // Only in InnerClasses attributes. - string.append(prefix).append(JavaConstants.ACC_PROTECTED).append(' '); - } - if ((accessFlags & ClassConstants.ACC_STATIC) != 0) - { - // Only in InnerClasses attributes. - string.append(prefix).append(JavaConstants.ACC_STATIC).append(' '); - } - if ((accessFlags & ClassConstants.ACC_FINAL) != 0) - { - string.append(prefix).append(JavaConstants.ACC_FINAL).append(' '); - } - if ((accessFlags & ClassConstants.ACC_ANNOTATTION) != 0) - { - string.append(prefix).append(JavaConstants.ACC_ANNOTATION); - } - if ((accessFlags & ClassConstants.ACC_INTERFACE) != 0) - { - string.append(prefix).append(JavaConstants.ACC_INTERFACE).append(' '); - } - else if ((accessFlags & ClassConstants.ACC_ENUM) != 0) - { - string.append(prefix).append(JavaConstants.ACC_ENUM).append(' '); - } - else if ((accessFlags & ClassConstants.ACC_ABSTRACT) != 0) - { - string.append(prefix).append(JavaConstants.ACC_ABSTRACT).append(' '); - } - else if ((accessFlags & ClassConstants.ACC_SYNTHETIC) != 0) - { - string.append(prefix).append(JavaConstants.ACC_SYNTHETIC).append(' '); - } - - return string.toString(); - } - - - /** - * Converts internal field access flags into an external access description. - * @param accessFlags the field access flags. - * @return the external field access description, - * e.g. "<code>public volatile </code>". - */ - public static String externalFieldAccessFlags(int accessFlags) - { - return externalFieldAccessFlags(accessFlags, ""); - } - - - /** - * Converts internal field access flags into an external access description. - * @param accessFlags the field access flags. - * @param prefix a prefix that is added to each access modifier. - * @return the external field access description, - * e.g. "<code>public volatile </code>". - */ - public static String externalFieldAccessFlags(int accessFlags, String prefix) - { - if (accessFlags == 0) - { - return EMPTY_STRING; - } - - StringBuffer string = new StringBuffer(50); - - if ((accessFlags & ClassConstants.ACC_PUBLIC) != 0) - { - string.append(prefix).append(JavaConstants.ACC_PUBLIC).append(' '); - } - if ((accessFlags & ClassConstants.ACC_PRIVATE) != 0) - { - string.append(prefix).append(JavaConstants.ACC_PRIVATE).append(' '); - } - if ((accessFlags & ClassConstants.ACC_PROTECTED) != 0) - { - string.append(prefix).append(JavaConstants.ACC_PROTECTED).append(' '); - } - if ((accessFlags & ClassConstants.ACC_STATIC) != 0) - { - string.append(prefix).append(JavaConstants.ACC_STATIC).append(' '); - } - if ((accessFlags & ClassConstants.ACC_FINAL) != 0) - { - string.append(prefix).append(JavaConstants.ACC_FINAL).append(' '); - } - if ((accessFlags & ClassConstants.ACC_VOLATILE) != 0) - { - string.append(prefix).append(JavaConstants.ACC_VOLATILE).append(' '); - } - if ((accessFlags & ClassConstants.ACC_TRANSIENT) != 0) - { - string.append(prefix).append(JavaConstants.ACC_TRANSIENT).append(' '); - } - if ((accessFlags & ClassConstants.ACC_SYNTHETIC) != 0) - { - string.append(prefix).append(JavaConstants.ACC_SYNTHETIC).append(' '); - } - - return string.toString(); - } - - - /** - * Converts internal method access flags into an external access description. - * @param accessFlags the method access flags. - * @return the external method access description, - * e.g. "<code>public synchronized </code>". - */ - public static String externalMethodAccessFlags(int accessFlags) - { - return externalMethodAccessFlags(accessFlags, ""); - } - - - /** - * Converts internal method access flags into an external access description. - * @param accessFlags the method access flags. - * @param prefix a prefix that is added to each access modifier. - * @return the external method access description, - * e.g. "public synchronized ". - */ - public static String externalMethodAccessFlags(int accessFlags, String prefix) - { - if (accessFlags == 0) - { - return EMPTY_STRING; - } - - StringBuffer string = new StringBuffer(50); - - if ((accessFlags & ClassConstants.ACC_PUBLIC) != 0) - { - string.append(prefix).append(JavaConstants.ACC_PUBLIC).append(' '); - } - if ((accessFlags & ClassConstants.ACC_PRIVATE) != 0) - { - string.append(prefix).append(JavaConstants.ACC_PRIVATE).append(' '); - } - if ((accessFlags & ClassConstants.ACC_PROTECTED) != 0) - { - string.append(prefix).append(JavaConstants.ACC_PROTECTED).append(' '); - } - if ((accessFlags & ClassConstants.ACC_STATIC) != 0) - { - string.append(prefix).append(JavaConstants.ACC_STATIC).append(' '); - } - if ((accessFlags & ClassConstants.ACC_FINAL) != 0) - { - string.append(prefix).append(JavaConstants.ACC_FINAL).append(' '); - } - if ((accessFlags & ClassConstants.ACC_SYNCHRONIZED) != 0) - { - string.append(prefix).append(JavaConstants.ACC_SYNCHRONIZED).append(' '); - } - if ((accessFlags & ClassConstants.ACC_BRIDGE) != 0) - { - string.append(prefix).append(JavaConstants.ACC_BRIDGE).append(' '); - } - if ((accessFlags & ClassConstants.ACC_VARARGS) != 0) - { - string.append(prefix).append(JavaConstants.ACC_VARARGS).append(' '); - } - if ((accessFlags & ClassConstants.ACC_NATIVE) != 0) - { - string.append(prefix).append(JavaConstants.ACC_NATIVE).append(' '); - } - if ((accessFlags & ClassConstants.ACC_ABSTRACT) != 0) - { - string.append(prefix).append(JavaConstants.ACC_ABSTRACT).append(' '); - } - if ((accessFlags & ClassConstants.ACC_STRICT) != 0) - { - string.append(prefix).append(JavaConstants.ACC_STRICT).append(' '); - } - if ((accessFlags & ClassConstants.ACC_SYNTHETIC) != 0) - { - string.append(prefix).append(JavaConstants.ACC_SYNTHETIC).append(' '); - } - - return string.toString(); - } - - - /** - * Converts internal method parameter access flags into an external access - * description. - * @param accessFlags the method parameter access flags. - * @return the external method parameter access description, - * e.g. "<code>final mandated </code>". - */ - public static String externalParameterAccessFlags(int accessFlags) - { - return externalParameterAccessFlags(accessFlags, ""); - } - - - /** - * Converts internal method parameter access flags into an external access - * description. - * @param accessFlags the method parameter access flags. - * @param prefix a prefix that is added to each access modifier. - * @return the external method parameter access description, - * e.g. "final mandated ". - */ - public static String externalParameterAccessFlags(int accessFlags, String prefix) - { - if (accessFlags == 0) - { - return EMPTY_STRING; - } - - StringBuffer string = new StringBuffer(50); - - if ((accessFlags & ClassConstants.ACC_FINAL) != 0) - { - string.append(prefix).append(JavaConstants.ACC_FINAL).append(' '); - } - if ((accessFlags & ClassConstants.ACC_SYNTHETIC) != 0) - { - string.append(prefix).append(JavaConstants.ACC_SYNTHETIC).append(' '); - } - if ((accessFlags & ClassConstants.ACC_MANDATED) != 0) - { - string.append(prefix).append(JavaConstants.ACC_MANDATED).append(' '); - } - - return string.toString(); - } - - - /** - * Converts an internal method descriptor into an external method return type. - * @param internalMethodDescriptor the internal method descriptor, - * e.g. "<code>(II)Z</code>". - * @return the external method return type, - * e.g. "<code>boolean</code>". - */ - public static String externalMethodReturnType(String internalMethodDescriptor) - { - return externalType(internalMethodReturnType(internalMethodDescriptor)); - } - - - /** - * Converts an internal class name, method name, and method descriptor to - * an external method return type and name. - * @param internalClassName the internal name of the class of the method, - * e.g. "<code>mypackage/MyClass</code>". - * @param internalMethodName the internal method name, - * e.g. "<code>myMethod</code>" or - * "<code><init></code>". - * @param internalMethodDescriptor the internal method descriptor, - * e.g. "<code>(II)Z</code>". - * @return the external method return type and name, - * e.g. "<code>boolean myMethod</code>" or - * "<code>MyClass</code>". - */ - private static String externalMethodReturnTypeAndName(String internalClassName, - String internalMethodName, - String internalMethodDescriptor) - { - return internalMethodName.equals(ClassConstants.METHOD_NAME_INIT) ? - externalShortClassName(externalClassName(internalClassName)) : - (externalMethodReturnType(internalMethodDescriptor) + - ' ' + - internalMethodName); - } - - - /** - * Converts an internal method descriptor into an external method argument - * description. - * @param internalMethodDescriptor the internal method descriptor, - * e.g. "<code>(II)Z</code>". - * @return the external method argument description, - * e.g. "<code>int,int</code>". - */ - public static String externalMethodArguments(String internalMethodDescriptor) - { - StringBuffer externalMethodNameAndArguments = new StringBuffer(); - - InternalTypeEnumeration internalTypeEnumeration = - new InternalTypeEnumeration(internalMethodDescriptor); - - while (internalTypeEnumeration.hasMoreTypes()) - { - externalMethodNameAndArguments.append(externalType(internalTypeEnumeration.nextType())); - if (internalTypeEnumeration.hasMoreTypes()) - { - externalMethodNameAndArguments.append(JavaConstants.METHOD_ARGUMENTS_SEPARATOR); - } - } - - return externalMethodNameAndArguments.toString(); - } - - - /** - * Returns the internal package name of the given internal class name. - * @param internalClassName the internal class name, - * e.g. "<code>java/lang/Object</code>". - * @return the internal package name, - * e.g. "<code>java/lang</code>". - */ - public static String internalPackageName(String internalClassName) - { - String internalPackagePrefix = internalPackagePrefix(internalClassName); - int length = internalPackagePrefix.length(); - return length > 0 ? - internalPackagePrefix.substring(0, length - 1) : - ""; - } - - - /** - * Returns the internal package prefix of the given internal class name. - * @param internalClassName the internal class name, - * e.g. "<code>java/lang/Object</code>". - * @return the internal package prefix, - * e.g. "<code>java/lang/</code>". - */ - public static String internalPackagePrefix(String internalClassName) - { - return internalClassName.substring(0, internalClassName.lastIndexOf(ClassConstants.PACKAGE_SEPARATOR, - internalClassName.length() - 2) + 1); - } - - - /** - * Returns the external package name of the given external class name. - * @param externalClassName the external class name, - * e.g. "<code>java.lang.Object</code>". - * @return the external package name, - * e.g. "<code>java.lang</code>". - */ - public static String externalPackageName(String externalClassName) - { - String externalPackagePrefix = externalPackagePrefix(externalClassName); - int length = externalPackagePrefix.length(); - return length > 0 ? - externalPackagePrefix.substring(0, length - 1) : - ""; - } - - - /** - * Returns the external package prefix of the given external class name. - * @param externalClassName the external class name, - * e.g. "<code>java.lang.Object</code>". - * @return the external package prefix, - * e.g. "<code>java.lang.</code>". - */ - public static String externalPackagePrefix(String externalClassName) - { - return externalClassName.substring(0, externalClassName.lastIndexOf(JavaConstants.PACKAGE_SEPARATOR, - externalClassName.length() - 2) + 1); - } -} |