下面列出了org.objectweb.asm.Type#getReturnType ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void visitMethodInsn(final int opcode, final String owner,
final String name, final String desc, final boolean itf) {
if (hasArgumentMatchingTheReturnType(desc)) {
final MutationIdentifier newId = this.context.registerMutation(
this.factory, "replaced call to " + owner + "::" + name
+ " with argument");
if (this.context.shouldMutate(newId)) {
final Type returnType = Type.getReturnType(desc);
replaceMethodCallWithArgumentHavingSameTypeAsReturnValue(
Type.getArgumentTypes(desc), returnType, opcode);
} else {
this.mv.visitMethodInsn(opcode, owner, name, desc, itf);
}
} else {
this.mv.visitMethodInsn(opcode, owner, name, desc, itf);
}
}
private static int doMethodEmulation(String desc) {
int result = 0;
Type[] args = Type.getArgumentTypes(desc);
Type returnType = Type.getReturnType(desc);
for (Type type : args) {
if (type.getSort() == Type.LONG || type.getSort() == Type.DOUBLE)
result--;
result--;
}
if (returnType.getSort() == Type.LONG || returnType.getSort() == Type.DOUBLE)
result++;
if (returnType.getSort() != Type.VOID)
result++;
return result;
}
private void executeInvokeInsn(
final AbstractInsnNode insn, final String methodDescriptor, final Interpreter<V> interpreter)
throws AnalyzerException {
ArrayList<V> valueList = new ArrayList<>();
for (int i = Type.getArgumentTypes(methodDescriptor).length; i > 0; --i) {
valueList.add(0, pop());
}
if (insn.getOpcode() != Opcodes.INVOKESTATIC && insn.getOpcode() != Opcodes.INVOKEDYNAMIC) {
valueList.add(0, pop());
}
if (Type.getReturnType(methodDescriptor) == Type.VOID_TYPE) {
interpreter.naryOperation(insn, valueList);
} else {
push(interpreter.naryOperation(insn, valueList));
}
}
/**
* Returns the given method descriptor, with its argument and return type descriptors remapped
* with {@link #mapDesc(String)}.
*
* @param methodDescriptor a method descriptor.
* @return the given method descriptor, with its argument and return type descriptors remapped
* with {@link #mapDesc(String)}.
*/
public String mapMethodDesc(final String methodDescriptor) {
if ("()V".equals(methodDescriptor)) {
return methodDescriptor;
}
StringBuilder stringBuilder = new StringBuilder("(");
for (Type argumentType : Type.getArgumentTypes(methodDescriptor)) {
stringBuilder.append(mapType(argumentType).getDescriptor());
}
Type returnType = Type.getReturnType(methodDescriptor);
if (returnType == Type.VOID_TYPE) {
stringBuilder.append(")V");
} else {
stringBuilder.append(')').append(mapType(returnType).getDescriptor());
}
return stringBuilder.toString();
}
public static void remapVirtual(AbstractInsnNode insn) {
MethodInsnNode method = (MethodInsnNode) insn;
if (!(("java/lang/Class".equals(method.owner) && ("getField".equals(method.name)
|| "getDeclaredField".equals(method.name)
|| "getMethod".equals(method.name)
|| "getDeclaredMethod".equals(method.name)
|| "getSimpleName".equals(method.name))
)
|| ("getName".equals(method.name) && ("java/lang/reflect/Field".equals(method.owner)
|| "java/lang/reflect/Method".equals(method.owner)))
|| ("java/lang/ClassLoader".equals(method.owner) && "loadClass".equals(method.name)))) {
return;
}
Type returnType = Type.getReturnType(method.desc);
ArrayList<Type> args = new ArrayList<>();
args.add(Type.getObjectType(method.owner));
args.addAll(Arrays.asList(Type.getArgumentTypes(method.desc)));
method.setOpcode(Opcodes.INVOKESTATIC);
method.owner = Type.getInternalName(RemappedMethods.class);
method.desc = Type.getMethodDescriptor(returnType, args.toArray(new Type[args.size()]));
}
@Override
public AnnotationVisitor visitAnnotation(String descriptor, boolean visible) {
boolean isPublic = (this.access & Opcodes.ACC_PUBLIC) != 0;
boolean isStatic = (this.access & Opcodes.ACC_STATIC) != 0;
if(Type.getType(descriptor).getClassName().equals(Callable.class.getName())) {
if (!isPublic) {
throw new ABICompilerException("@Callable methods must be public", methodName);
}
if (!isStatic) {
throw new ABICompilerException("@Callable methods must be static", methodName);
}
checkArgumentsAndReturnType();
isCallable = true;
return null;
} else if (Type.getType(descriptor).getClassName().equals(Fallback.class.getName())) {
if (!isStatic) {
throw new ABICompilerException("Fallback function must be static", methodName);
}
if (Type.getReturnType(methodDescriptor) != Type.VOID_TYPE) {
throw new ABICompilerException(
"Function annotated @Fallback must have void return type", methodName);
}
if (Type.getArgumentTypes(methodDescriptor).length != 0) {
throw new ABICompilerException(
"Function annotated @Fallback cannot take arguments", methodName);
}
isFallback = true;
return null;
} else if (Type.getType(descriptor).getClassName().equals(Initializable.class.getName())) {
throw new ABICompilerException(
"Methods cannot be annotated @Initializable", methodName);
} else {
return super.visitAnnotation(descriptor, visible);
}
}
private void doVisitMethodInsn(final int opcode, final String descriptor) {
if (isConstructor && !superClassConstructorCalled) {
for (Type argumentType : Type.getArgumentTypes(descriptor)) {
popValue();
if (argumentType.getSize() == 2) {
popValue();
}
}
switch (opcode) {
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
popValue();
break;
case INVOKESPECIAL:
Object value = popValue();
if (value == UNINITIALIZED_THIS && !superClassConstructorCalled) {
onMethodEnter();
superClassConstructorCalled = true;
}
break;
default:
break;
}
Type returnType = Type.getReturnType(descriptor);
if (returnType != Type.VOID_TYPE) {
pushValue(OTHER);
if (returnType.getSize() == 2) {
pushValue(OTHER);
}
}
}
}
/** Confirm that this method has the given return and param types or throw */
public void assertType(Type returnType, Type... paramTypes) {
Type actualReturnType = Type.getReturnType(methodSig);
if (!returnType.equals(actualReturnType))
throw new IllegalArgumentException("Invalid return type, expected " + returnType + ", got " + actualReturnType);
Type[] actualParamTypes = Type.getArgumentTypes(methodSig);
if (!Arrays.equals(paramTypes, actualParamTypes))
throw new IllegalArgumentException("Invalid arg types, expected " + Arrays.toString(paramTypes) +
", got " + Arrays.toString(actualParamTypes));
}
@Test
public void asm_Type() throws NoSuchMethodException {
Type toStringType = Type.getReturnType(Object.class.getDeclaredMethod("toString"));
JavaType toStringJavaType = JavaTypeImporter.importAsmType(toStringType);
assertThat(toStringJavaType.getName()).isEqualTo(String.class.getName());
assertThat(toStringJavaType.resolveClass()).isEqualTo(String.class);
}
/**
* Handle method return logic.
*
* @param desc the method signature
*/
private void handleReturnType(String desc) {
Type ret = Type.getReturnType(desc);
if (ret.getSort() == Type.VOID) {
pop();
} else {
ByteCodeUtils.unbox(this, ret);
}
}
private void doVisitMethodInsn(final int opcode, final String descriptor) {
if (isConstructor && !superClassConstructorCalled) {
for (Type argumentType : Type.getArgumentTypes(descriptor)) {
popValue();
if (argumentType.getSize() == 2) {
popValue();
}
}
switch (opcode) {
case INVOKEINTERFACE:
case INVOKEVIRTUAL:
popValue();
break;
case INVOKESPECIAL:
Object value = popValue();
if (value == UNINITIALIZED_THIS && !superClassConstructorCalled) {
superClassConstructorCalled = true;
onMethodEnter();
}
break;
default:
break;
}
Type returnType = Type.getReturnType(descriptor);
if (returnType != Type.VOID_TYPE) {
pushValue(OTHER);
if (returnType.getSize() == 2) {
pushValue(OTHER);
}
}
}
}
/**
* Constructs a new {@link GeneratorAdapter}.
*
* @param api the ASM API version implemented by this visitor. Must be one of {@link
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
* @param methodVisitor the method visitor to which this adapter delegates calls.
* @param access the method's access flags (see {@link Opcodes}).
* @param name the method's name.
* @param descriptor the method's descriptor (see {@link Type}).
*/
protected GeneratorAdapter(
final int api,
final MethodVisitor methodVisitor,
final int access,
final String name,
final String descriptor) {
super(api, access, descriptor, methodVisitor);
this.access = access;
this.name = name;
this.returnType = Type.getReturnType(descriptor);
this.argumentTypes = Type.getArgumentTypes(descriptor);
}
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
final String ownerType = readClassName(owner);
final Type[] argumentTypes = Type.getArgumentTypes(desc);
for (Type argumentType : argumentTypes) {
final String parameterTypeName = readTypeName(argumentType);
}
final Type returnType = Type.getReturnType(desc);
final String returnTypeName = readTypeName(returnType);
}
private static void unwrapResult(final MethodVisitor mv, final String desc) {
Type returnType = Type.getReturnType(desc);
if (returnType == Type.VOID_TYPE) {
mv.visitInsn(POP);
mv.visitInsn(RETURN);
} else {
if (isPrimitive(returnType)) {
BytecodeHelper.unbox(mv, ClassHelper.make(returnType.getClassName()));
} else {
mv.visitTypeInsn(CHECKCAST, returnType.getInternalName());
}
mv.visitInsn(getReturnInsn(returnType));
}
}
public Type getReturnType() {
return Type.getReturnType(desc);
}
private String getReturnTypeClass(String desc) {
Type type = Type.getReturnType(desc);
return type.getClassName();
}
/**
* Get the return type of the annotated method
*/
public Type getMethodReturnType() {
return Type.getReturnType(this.getMethod().desc);
}
protected void detectGoals(Method method, List<OutputCoverageTestFitness> goals) {
String className = method.getDeclaringClass().getName();
String methodName = method.getName()+Type.getMethodDescriptor(method);
Type returnType = Type.getReturnType(method);
LOG.info("Adding output goals for method " + className + "." + methodName);
int typeSort = returnType.getSort();
if(typeSort == Type.OBJECT) {
Class<?> typeClass = method.getReturnType();
if(ClassUtils.isPrimitiveWrapper(typeClass)) {
typeSort = Type.getType(ClassUtils.wrapperToPrimitive(typeClass)).getSort();
goals.add(createGoal(className, methodName, returnType, REF_NULL));
}
}
switch (typeSort) {
case Type.BOOLEAN:
goals.add(createGoal(className, methodName, returnType, BOOL_TRUE));
goals.add(createGoal(className, methodName, returnType, BOOL_FALSE));
break;
case Type.CHAR:
goals.add(createGoal(className, methodName, returnType, CHAR_ALPHA));
goals.add(createGoal(className, methodName, returnType, CHAR_DIGIT));
goals.add(createGoal(className, methodName, returnType, CHAR_OTHER));
break;
case Type.BYTE:
case Type.SHORT:
case Type.INT:
case Type.FLOAT:
case Type.LONG:
case Type.DOUBLE:
goals.add(createGoal(className, methodName, returnType, NUM_NEGATIVE));
goals.add(createGoal(className, methodName, returnType, NUM_ZERO));
goals.add(createGoal(className, methodName, returnType, NUM_POSITIVE));
break;
case Type.ARRAY:
goals.add(createGoal(className, methodName, returnType, REF_NULL));
goals.add(createGoal(className, methodName, returnType, ARRAY_EMPTY));
goals.add(createGoal(className, methodName, returnType, ARRAY_NONEMPTY));
break;
case Type.OBJECT:
goals.add(createGoal(className, methodName, returnType, REF_NULL));
//goals.add(new OutputCoverageTestFitness(new OutputCoverageGoal(className, methodName, returnType.toString(), REF_NONNULL)));
if (returnType.getClassName().equals("java.lang.String")) {
goals.add(createGoal(className, methodName, returnType, STRING_EMPTY));
goals.add(createGoal(className, methodName, returnType, STRING_NONEMPTY));
break;
}
boolean observerGoalsAdded = false;
Class<?> returnClazz = method.getReturnType();
for(Inspector inspector : InspectorManager.getInstance().getInspectors(returnClazz)) {
String insp = inspector.getMethodCall() + Type.getMethodDescriptor(inspector.getMethod());
Type t = Type.getReturnType(inspector.getMethod());
if (t.getSort() == Type.BOOLEAN) {
goals.add(createGoal(className, methodName, returnType, REF_NONNULL + ":" + returnType.getClassName() + ":" + insp + ":" + BOOL_TRUE));
goals.add(createGoal(className, methodName, returnType, REF_NONNULL + ":" + returnType.getClassName() + ":" + insp + ":" + BOOL_FALSE));
observerGoalsAdded = true;
} else if (Arrays.asList(new Integer[]{Type.BYTE, Type.SHORT, Type.INT, Type.FLOAT, Type.LONG, Type.DOUBLE}).contains(t.getSort())) {
goals.add(createGoal(className, methodName, returnType, REF_NONNULL + ":" + returnType.getClassName() + ":" + insp + ":" + NUM_NEGATIVE));
goals.add(createGoal(className, methodName, returnType, REF_NONNULL + ":" + returnType.getClassName() + ":" + insp + ":" + NUM_ZERO));
goals.add(createGoal(className, methodName, returnType, REF_NONNULL + ":" + returnType.getClassName() + ":" + insp + ":" + NUM_POSITIVE));
observerGoalsAdded = true;
}
}
if (!observerGoalsAdded){
goals.add(createGoal(className, methodName, returnType, REF_NONNULL));
}
break;
default:
break;
}
}
/**
* Returns the return type of the method described by this object.
*
* @return the return type of the method described by this object.
*/
public Type getReturnType() {
return Type.getReturnType(descriptor);
}
/**
* Returns the Opcode for the specific return type
*
* @param desc method description
* @return Opcode for the specific return type
*/
public static int getReturnCode(final String desc) {
final Type t = Type.getReturnType(desc);
return t.getOpcode(Opcodes.IRETURN);
}