@ -146,10 +146,6 @@ public class Type {
@@ -146,10 +146,6 @@ public class Type {
* /
private final int valueEnd ;
// -----------------------------------------------------------------------------------------------
// Constructors
// -----------------------------------------------------------------------------------------------
/ * *
* Constructs a reference type .
*
@ -167,6 +163,10 @@ public class Type {
@@ -167,6 +163,10 @@ public class Type {
this . valueEnd = valueEnd ;
}
// -----------------------------------------------------------------------------------------------
// Methods to get Type(s) from a descriptor, a reflected Method or Constructor, other types, etc.
// -----------------------------------------------------------------------------------------------
/ * *
* Returns the { @link Type } corresponding to the given type descriptor .
*
@ -174,40 +174,7 @@ public class Type {
@@ -174,40 +174,7 @@ public class Type {
* @return the { @link Type } corresponding to the given type descriptor .
* /
public static Type getType ( final String typeDescriptor ) {
return getType ( typeDescriptor , 0 , typeDescriptor . length ( ) ) ;
}
/ * *
* Returns the { @link Type } corresponding to the given internal name .
*
* @param internalName an internal name .
* @return the { @link Type } corresponding to the given internal name .
* /
public static Type getObjectType ( final String internalName ) {
return new Type (
internalName . charAt ( 0 ) = = '[' ? ARRAY : INTERNAL , internalName , 0 , internalName . length ( ) ) ;
}
/ * *
* Returns the { @link Type } corresponding to the given method descriptor . Equivalent to < code >
* Type . getType ( methodDescriptor ) < / code > .
*
* @param methodDescriptor a method descriptor .
* @return the { @link Type } corresponding to the given method descriptor .
* /
public static Type getMethodType ( final String methodDescriptor ) {
return new Type ( METHOD , methodDescriptor , 0 , methodDescriptor . length ( ) ) ;
}
/ * *
* Returns the method { @link Type } corresponding to the given argument and return types .
*
* @param returnType the return type of the method .
* @param argumentTypes the argument types of the method .
* @return the method { @link Type } corresponding to the given argument and return types .
* /
public static Type getMethodType ( final Type returnType , final Type . . . argumentTypes ) {
return getType ( getMethodDescriptor ( returnType , argumentTypes ) ) ;
return getTypeInternal ( typeDescriptor , 0 , typeDescriptor . length ( ) ) ;
}
/ * *
@ -264,6 +231,60 @@ public class Type {
@@ -264,6 +231,60 @@ public class Type {
return getType ( getMethodDescriptor ( method ) ) ;
}
/ * *
* Returns the type of the elements of this array type . This method should only be used for an
* array type .
*
* @return Returns the type of the elements of this array type .
* /
public Type getElementType ( ) {
final int numDimensions = getDimensions ( ) ;
return getTypeInternal ( valueBuffer , valueBegin + numDimensions , valueEnd ) ;
}
/ * *
* Returns the { @link Type } corresponding to the given internal name .
*
* @param internalName an internal name .
* @return the { @link Type } corresponding to the given internal name .
* /
public static Type getObjectType ( final String internalName ) {
return new Type (
internalName . charAt ( 0 ) = = '[' ? ARRAY : INTERNAL , internalName , 0 , internalName . length ( ) ) ;
}
/ * *
* Returns the { @link Type } corresponding to the given method descriptor . Equivalent to < code >
* Type . getType ( methodDescriptor ) < / code > .
*
* @param methodDescriptor a method descriptor .
* @return the { @link Type } corresponding to the given method descriptor .
* /
public static Type getMethodType ( final String methodDescriptor ) {
return new Type ( METHOD , methodDescriptor , 0 , methodDescriptor . length ( ) ) ;
}
/ * *
* Returns the method { @link Type } corresponding to the given argument and return types .
*
* @param returnType the return type of the method .
* @param argumentTypes the argument types of the method .
* @return the method { @link Type } corresponding to the given argument and return types .
* /
public static Type getMethodType ( final Type returnType , final Type . . . argumentTypes ) {
return getType ( getMethodDescriptor ( returnType , argumentTypes ) ) ;
}
/ * *
* Returns the argument types of methods of this type . This method should only be used for method
* types .
*
* @return the argument types of methods of this type .
* /
public Type [ ] getArgumentTypes ( ) {
return getArgumentTypes ( getDescriptor ( ) ) ;
}
/ * *
* Returns the { @link Type } values corresponding to the argument types of the given method
* descriptor .
@ -307,7 +328,7 @@ public class Type {
@@ -307,7 +328,7 @@ public class Type {
}
}
argumentTypes [ currentArgumentTypeIndex + + ] =
getType ( methodDescriptor , currentArgumentTypeOffset , currentOffset ) ;
getTypeInternal ( methodDescriptor , currentArgumentTypeOffset , currentOffset ) ;
}
return argumentTypes ;
}
@ -327,6 +348,16 @@ public class Type {
@@ -327,6 +348,16 @@ public class Type {
return types ;
}
/ * *
* Returns the return type of methods of this type . This method should only be used for method
* types .
*
* @return the return type of methods of this type .
* /
public Type getReturnType ( ) {
return getReturnType ( getDescriptor ( ) ) ;
}
/ * *
* Returns the { @link Type } corresponding to the return type of the given method descriptor .
*
@ -347,7 +378,7 @@ public class Type {
@@ -347,7 +378,7 @@ public class Type {
}
}
}
return getType ( methodDescriptor , currentOffset + 1 , methodDescriptor . length ( ) ) ;
return getTypeInternal ( methodDescriptor , currentOffset + 1 , methodDescriptor . length ( ) ) ;
}
/ * *
@ -360,47 +391,6 @@ public class Type {
@@ -360,47 +391,6 @@ public class Type {
return getType ( method . getReturnType ( ) ) ;
}
/ * *
* Computes the size of the arguments and of the return value of a method .
*
* @param methodDescriptor a method descriptor .
* @return the size of the arguments of the method ( plus one for the implicit this argument ) ,
* argumentsSize , and the size of its return value , returnSize , packed into a single int i =
* { @code ( argumentsSize & lt ; & lt ; 2 ) | returnSize } ( argumentsSize is therefore equal to { @code
* i & gt ; & gt ; 2 } , and returnSize to { @code i & amp ; 0x03 } ) .
* /
public static int getArgumentsAndReturnSizes ( final String methodDescriptor ) {
int argumentsSize = 1 ;
// Skip the first character, which is always a '('.
int currentOffset = 1 ;
int currentChar = methodDescriptor . charAt ( currentOffset ) ;
// Parse the argument types and compute their size, one at a each loop iteration.
while ( currentChar ! = ')' ) {
if ( currentChar = = 'J' | | currentChar = = 'D' ) {
currentOffset + + ;
argumentsSize + = 2 ;
} else {
while ( methodDescriptor . charAt ( currentOffset ) = = '[' ) {
currentOffset + + ;
}
if ( methodDescriptor . charAt ( currentOffset + + ) = = 'L' ) {
while ( methodDescriptor . charAt ( currentOffset + + ) ! = ';' ) {
// Skip the argument descriptor content.
}
}
argumentsSize + = 1 ;
}
currentChar = methodDescriptor . charAt ( currentOffset ) ;
}
currentChar = methodDescriptor . charAt ( currentOffset + 1 ) ;
if ( currentChar = = 'V' ) {
return argumentsSize < < 2 ;
} else {
int returnSize = ( currentChar = = 'J' | | currentChar = = 'D' ) ? 2 : 1 ;
return argumentsSize < < 2 | returnSize ;
}
}
/ * *
* Returns the { @link Type } corresponding to the given field or method descriptor .
*
@ -411,7 +401,7 @@ public class Type {
@@ -411,7 +401,7 @@ public class Type {
* descriptorBuffer .
* @return the { @link Type } corresponding to the given type descriptor .
* /
private static Type getType (
private static Type getTypeInternal (
final String descriptorBuffer , final int descriptorBegin , final int descriptorEnd ) {
switch ( descriptorBuffer . charAt ( descriptorBegin ) ) {
case 'V' :
@ -444,45 +434,9 @@ public class Type {
@@ -444,45 +434,9 @@ public class Type {
}
// -----------------------------------------------------------------------------------------------
// Accessors
// Methods to get class names, internal names or descriptors.
// -----------------------------------------------------------------------------------------------
/ * *
* Returns the sort of this type .
*
* @return { @link # VOID } , { @link # BOOLEAN } , { @link # CHAR } , { @link # BYTE } , { @link # SHORT } , { @link
* # INT } , { @link # FLOAT } , { @link # LONG } , { @link # DOUBLE } , { @link # ARRAY } , { @link # OBJECT } or
* { @link # METHOD } .
* /
public int getSort ( ) {
return sort = = INTERNAL ? OBJECT : sort ;
}
/ * *
* Returns the number of dimensions of this array type . This method should only be used for an
* array type .
*
* @return the number of dimensions of this array type .
* /
public int getDimensions ( ) {
int numDimensions = 1 ;
while ( valueBuffer . charAt ( valueBegin + numDimensions ) = = '[' ) {
numDimensions + + ;
}
return numDimensions ;
}
/ * *
* Returns the type of the elements of this array type . This method should only be used for an
* array type .
*
* @return Returns the type of the elements of this array type .
* /
public Type getElementType ( ) {
final int numDimensions = getDimensions ( ) ;
return getType ( valueBuffer , valueBegin + numDimensions , valueEnd ) ;
}
/ * *
* Returns the binary name of the class corresponding to this type . This method must not be used
* on method types .
@ -535,42 +489,16 @@ public class Type {
@@ -535,42 +489,16 @@ public class Type {
}
/ * *
* Returns the argument types of methods of this type . This method should only be used for method
* types .
*
* @return the argument types of methods of this type .
* /
public Type [ ] getArgumentTypes ( ) {
return getArgumentTypes ( getDescriptor ( ) ) ;
}
/ * *
* Returns the return type of methods of this type . This method should only be used for method
* types .
*
* @return the return type of methods of this type .
* /
public Type getReturnType ( ) {
return getReturnType ( getDescriptor ( ) ) ;
}
/ * *
* Returns the size of the arguments and of the return value of methods of this type . This method
* should only be used for method types .
* Returns the internal name of the given class . The internal name of a class is its fully
* qualified name , as returned by Class . getName ( ) , where '.' are replaced by '/' .
*
* @return the size of the arguments of the method ( plus one for the implicit this argument ) ,
* argumentsSize , and the size of its return value , returnSize , packed into a single int i =
* { @code ( argumentsSize & lt ; & lt ; 2 ) | returnSize } ( argumentsSize is therefore equal to { @code
* i & gt ; & gt ; 2 } , and returnSize to { @code i & amp ; 0x03 } ) .
* @param clazz an object or array class .
* @return the internal name of the given class .
* /
public int getArgumentsAndReturnSizes ( ) {
return getArgumentsAndReturnSizes ( getDescriptor ( ) ) ;
public static String getInternalName ( final Class < ? > clazz ) {
return clazz . getName ( ) . replace ( '.' , '/' ) ;
}
// -----------------------------------------------------------------------------------------------
// Conversion to type descriptors
// -----------------------------------------------------------------------------------------------
/ * *
* Returns the descriptor corresponding to this type .
*
@ -590,57 +518,6 @@ public class Type {
@@ -590,57 +518,6 @@ public class Type {
}
}
/ * *
* Returns the descriptor corresponding to the given argument and return types .
*
* @param returnType the return type of the method .
* @param argumentTypes the argument types of the method .
* @return the descriptor corresponding to the given argument and return types .
* /
public static String getMethodDescriptor ( final Type returnType , final Type . . . argumentTypes ) {
StringBuilder stringBuilder = new StringBuilder ( ) ;
stringBuilder . append ( '(' ) ;
for ( int i = 0 ; i < argumentTypes . length ; + + i ) {
argumentTypes [ i ] . appendDescriptor ( stringBuilder ) ;
}
stringBuilder . append ( ')' ) ;
returnType . appendDescriptor ( stringBuilder ) ;
return stringBuilder . toString ( ) ;
}
/ * *
* Appends the descriptor corresponding to this type to the given string buffer .
*
* @param stringBuilder the string builder to which the descriptor must be appended .
* /
private void appendDescriptor ( final StringBuilder stringBuilder ) {
if ( sort = = OBJECT ) {
stringBuilder . append ( valueBuffer , valueBegin - 1 , valueEnd + 1 ) ;
} else if ( sort = = INTERNAL ) {
stringBuilder . append ( 'L' ) ;
stringBuilder . append ( valueBuffer , valueBegin , valueEnd ) ;
stringBuilder . append ( ';' ) ;
} else {
stringBuilder . append ( valueBuffer , valueBegin , valueEnd ) ;
}
}
// -----------------------------------------------------------------------------------------------
// Direct conversion from classes to type descriptors,
// without intermediate Type objects
// -----------------------------------------------------------------------------------------------
/ * *
* Returns the internal name of the given class . The internal name of a class is its fully
* qualified name , as returned by Class . getName ( ) , where '.' are replaced by '/' .
*
* @param clazz an object or array class .
* @return the internal name of the given class .
* /
public static String getInternalName ( final Class < ? > clazz ) {
return clazz . getName ( ) . replace ( '.' , '/' ) ;
}
/ * *
* Returns the descriptor corresponding to the given class .
*
@ -649,7 +526,7 @@ public class Type {
@@ -649,7 +526,7 @@ public class Type {
* /
public static String getDescriptor ( final Class < ? > clazz ) {
StringBuilder stringBuilder = new StringBuilder ( ) ;
appendDescriptor ( stringBuilder , clazz ) ;
appendDescriptor ( clazz , stringBuilder ) ;
return stringBuilder . toString ( ) ;
}
@ -664,11 +541,29 @@ public class Type {
@@ -664,11 +541,29 @@ public class Type {
stringBuilder . append ( '(' ) ;
Class < ? > [ ] parameters = constructor . getParameterTypes ( ) ;
for ( int i = 0 ; i < parameters . length ; + + i ) {
appendDescriptor ( stringBuilder , parameters [ i ] ) ;
appendDescriptor ( parameters [ i ] , stringBuilder ) ;
}
return stringBuilder . append ( ")V" ) . toString ( ) ;
}
/ * *
* Returns the descriptor corresponding to the given argument and return types .
*
* @param returnType the return type of the method .
* @param argumentTypes the argument types of the method .
* @return the descriptor corresponding to the given argument and return types .
* /
public static String getMethodDescriptor ( final Type returnType , final Type . . . argumentTypes ) {
StringBuilder stringBuilder = new StringBuilder ( ) ;
stringBuilder . append ( '(' ) ;
for ( int i = 0 ; i < argumentTypes . length ; + + i ) {
argumentTypes [ i ] . appendDescriptor ( stringBuilder ) ;
}
stringBuilder . append ( ')' ) ;
returnType . appendDescriptor ( stringBuilder ) ;
return stringBuilder . toString ( ) ;
}
/ * *
* Returns the descriptor corresponding to the given method .
*
@ -680,20 +575,37 @@ public class Type {
@@ -680,20 +575,37 @@ public class Type {
stringBuilder . append ( '(' ) ;
Class < ? > [ ] parameters = method . getParameterTypes ( ) ;
for ( int i = 0 ; i < parameters . length ; + + i ) {
appendDescriptor ( stringBuilder , parameters [ i ] ) ;
appendDescriptor ( parameters [ i ] , stringBuilder ) ;
}
stringBuilder . append ( ')' ) ;
appendDescriptor ( stringBuilder , method . getReturnType ( ) ) ;
appendDescriptor ( method . getReturnType ( ) , stringBuilder ) ;
return stringBuilder . toString ( ) ;
}
/ * *
* Appends the descriptor of the given class to the given string build er .
* Appends the descriptor corresponding to this type to the given string buff er .
*
* @param stringBuilder the string builder to which the descriptor must be appended .
* /
private void appendDescriptor ( final StringBuilder stringBuilder ) {
if ( sort = = OBJECT ) {
stringBuilder . append ( valueBuffer , valueBegin - 1 , valueEnd + 1 ) ;
} else if ( sort = = INTERNAL ) {
stringBuilder . append ( 'L' ) ;
stringBuilder . append ( valueBuffer , valueBegin , valueEnd ) ;
stringBuilder . append ( ';' ) ;
} else {
stringBuilder . append ( valueBuffer , valueBegin , valueEnd ) ;
}
}
/ * *
* Appends the descriptor of the given class to the given string builder .
*
* @param clazz the class whose descriptor must be computed .
* @param stringBuilder the string builder to which the descriptor must be appended .
* /
private static void appendDescriptor ( final StringBuilder stringBuilder , final Class < ? > clazz ) {
private static void appendDescriptor ( final Class < ? > clazz , final StringBuilder stringBuilder ) {
Class < ? > currentClass = clazz ;
while ( currentClass . isArray ( ) ) {
stringBuilder . append ( '[' ) ;
@ -736,9 +648,34 @@ public class Type {
@@ -736,9 +648,34 @@ public class Type {
}
// -----------------------------------------------------------------------------------------------
// Corresponding size and opcodes
// Methods to get the sort, dimension, size, and opcodes corresponding to a Type or descriptor.
// -----------------------------------------------------------------------------------------------
/ * *
* Returns the sort of this type .
*
* @return { @link # VOID } , { @link # BOOLEAN } , { @link # CHAR } , { @link # BYTE } , { @link # SHORT } , { @link
* # INT } , { @link # FLOAT } , { @link # LONG } , { @link # DOUBLE } , { @link # ARRAY } , { @link # OBJECT } or
* { @link # METHOD } .
* /
public int getSort ( ) {
return sort = = INTERNAL ? OBJECT : sort ;
}
/ * *
* Returns the number of dimensions of this array type . This method should only be used for an
* array type .
*
* @return the number of dimensions of this array type .
* /
public int getDimensions ( ) {
int numDimensions = 1 ;
while ( valueBuffer . charAt ( valueBegin + numDimensions ) = = '[' ) {
numDimensions + + ;
}
return numDimensions ;
}
/ * *
* Returns the size of values of this type . This method must not be used for method types .
*
@ -767,6 +704,60 @@ public class Type {
@@ -767,6 +704,60 @@ public class Type {
}
}
/ * *
* Returns the size of the arguments and of the return value of methods of this type . This method
* should only be used for method types .
*
* @return the size of the arguments of the method ( plus one for the implicit this argument ) ,
* argumentsSize , and the size of its return value , returnSize , packed into a single int i =
* { @code ( argumentsSize & lt ; & lt ; 2 ) | returnSize } ( argumentsSize is therefore equal to { @code
* i & gt ; & gt ; 2 } , and returnSize to { @code i & amp ; 0x03 } ) .
* /
public int getArgumentsAndReturnSizes ( ) {
return getArgumentsAndReturnSizes ( getDescriptor ( ) ) ;
}
/ * *
* Computes the size of the arguments and of the return value of a method .
*
* @param methodDescriptor a method descriptor .
* @return the size of the arguments of the method ( plus one for the implicit this argument ) ,
* argumentsSize , and the size of its return value , returnSize , packed into a single int i =
* { @code ( argumentsSize & lt ; & lt ; 2 ) | returnSize } ( argumentsSize is therefore equal to { @code
* i & gt ; & gt ; 2 } , and returnSize to { @code i & amp ; 0x03 } ) .
* /
public static int getArgumentsAndReturnSizes ( final String methodDescriptor ) {
int argumentsSize = 1 ;
// Skip the first character, which is always a '('.
int currentOffset = 1 ;
int currentChar = methodDescriptor . charAt ( currentOffset ) ;
// Parse the argument types and compute their size, one at a each loop iteration.
while ( currentChar ! = ')' ) {
if ( currentChar = = 'J' | | currentChar = = 'D' ) {
currentOffset + + ;
argumentsSize + = 2 ;
} else {
while ( methodDescriptor . charAt ( currentOffset ) = = '[' ) {
currentOffset + + ;
}
if ( methodDescriptor . charAt ( currentOffset + + ) = = 'L' ) {
while ( methodDescriptor . charAt ( currentOffset + + ) ! = ';' ) {
// Skip the argument descriptor content.
}
}
argumentsSize + = 1 ;
}
currentChar = methodDescriptor . charAt ( currentOffset ) ;
}
currentChar = methodDescriptor . charAt ( currentOffset + 1 ) ;
if ( currentChar = = 'V' ) {
return argumentsSize < < 2 ;
} else {
int returnSize = ( currentChar = = 'J' | | currentChar = = 'D' ) ? 2 : 1 ;
return argumentsSize < < 2 | returnSize ;
}
}
/ * *
* Returns a JVM instruction opcode adapted to this { @link Type } . This method must not be used for
* method types .
@ -841,7 +832,7 @@ public class Type {
@@ -841,7 +832,7 @@ public class Type {
}
// -----------------------------------------------------------------------------------------------
// Equals, hashCode and toString
// Equals, hashCode and toString.
// -----------------------------------------------------------------------------------------------
/ * *