I'm trying to extract method parameters information from Java class bytecode using asm MethodVisitor
. visitParameter
method of MethodVisitor
is not called (because no parameter names are present in compiled class file). How can i get count of method parameters and their types?
The only thing I've found so far is desc
parameter of visitMethod
from MethodVisitor
. I can copy-paste TraceSignatureVisitor
class from asm-util, rewrite about 50 lines of code to store parameters declarations into List/array instead of single StringBuffer
.
Another option is suggested by in answer "https://stackoverflow.com/questions/18061588/get-function-arguments-values-using-java-asm-for-bytecode-instrimentation":
The number of arguments to the method can be computed from the method description using the code in the following gist: https://gist.github.com/VijayKrishna/6160036. Using the
parseMethodArguments(String desc)
method you can easily compute the number of arguments to the method.
From my point of view copy-pasting and rewriting TraceSignatureVisitor
is still better.
But i suppose there should be more simple way to work with method signatures in asm-util. Is there?
ASM has an abstract for that purpose, Type
.
Instances of Type
may represent a primitive type, a reference type, or a method type. So you can first get a type to represent the method type from the descriptor string, followed by querying it for the parameter types and return type.
String desc = "(Ljava/lang/String;I[[ZJ)D";
Type methodType = Type.getMethodType(desc);
int sizes = methodType.getArgumentsAndReturnSizes();
System.out.println("return type: "
+ methodType.getReturnType().getClassName() + " (" +(sizes & 3) + ')');
Type[] argTypes = methodType.getArgumentTypes();
System.out.println(argTypes.length + " arguments (" + (sizes >> 2) + ')');
for (int ix = 0; ix < argTypes.length; ix++) {
System.out.println("arg" + ix + ": " + argTypes[ix].getClassName());
}
The sizes returned by getArgumentsAndReturnSizes()
refer to local variables and operand stack entries, where long
and double
count as two. It also accounts for the implied this
parameter, which is convenient for an instance method but requires the caller to subtract one for static
methods.
The example prints
return type: double (2)
4 arguments (6)
arg0: java.lang.String
arg1: int
arg2: boolean[][]
arg3: long
If you are interested in one of the features only, you can get it directly using one of the static methods of the Type
class.
int sizes = Type.getArgumentsAndReturnSizes(desc);
Type ret = Type.getReturnType(desc);
Type[] argTypes = Type.getArgumentTypes(desc);