private static String print(Method method) { StringBuilder sb = new StringBuilder(); sb.append(print(method.getReturnType())).append(" ").append(method.getName()).append("("); for (Type t : method.getArgumentTypes()) { sb.append(print(t)).append(" "); } sb.append(")"); return sb.toString(); }
private @Nullable Method hack(@Nullable Method method) { if (method == null) { return null; } Type[] argumentTypes = method.getArgumentTypes(); Type[] hackedArgumentTypes = new Type[argumentTypes.length]; for (int i = 0; i < argumentTypes.length; i++) { hackedArgumentTypes[i] = hack(argumentTypes[i]); } return new Method(method.getName(), hack(method.getReturnType()), hackedArgumentTypes); }
@RequiresNonNull("type") private void addShim(ShimType shimType) { for (java.lang.reflect.Method reflectMethod : shimType.shimMethods()) { Method method = Method.getMethod(reflectMethod); Shim shim = reflectMethod.getAnnotation(Shim.class); checkNotNull(shim); if (shim.value().length != 1) { throw new IllegalStateException( "@Shim annotation must have exactly one value when used on methods"); } Method targetMethod = Method.getMethod(shim.value()[0]); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, method.getName(), method.getDescriptor(), null, null); mv.visitCode(); int i = 0; mv.visitVarInsn(ALOAD, i++); for (Type argumentType : method.getArgumentTypes()) { mv.visitVarInsn(argumentType.getOpcode(ILOAD), i++); } mv.visitMethodInsn(INVOKEVIRTUAL, type.getInternalName(), targetMethod.getName(), targetMethod.getDescriptor(), false); mv.visitInsn(method.getReturnType().getOpcode(IRETURN)); mv.visitMaxs(0, 0); mv.visitEnd(); } }
/** * Produce a rebased method declaration, also visiting referenced types. */ private Method processMethod(String sourceType, String name, String desc) { Method method = new Method(name, desc); Type[] argumentTypes = method.getArgumentTypes(); for (int i = 0, j = argumentTypes.length; i < j; i++) { argumentTypes[i] = processType(sourceType, argumentTypes[i]); } method = new Method(name, processType(sourceType, method.getReturnType()), argumentTypes); return method; }
private void initOnReturnAdvice(PointcutClass adviceClass, PointcutMethod adviceMethod) throws AdviceConstructionException { checkState(!hasOnReturnAdvice, "@Pointcut '" + adviceClass.type().getClassName() + "' has more than one @OnReturn method"); Method asmMethod = adviceMethod.toAsmMethod(); List<AdviceParameter> parameters = getAdviceParameters(adviceMethod.parameterAnnotationTypes(), asmMethod.getArgumentTypes(), onReturnBindAnnotationTypes, OnReturnType); for (int i = 1; i < parameters.size(); i++) { checkState(parameters.get(i).kind() != ParameterKind.RETURN, "@BindReturn must be the first argument to @OnReturn"); checkState(parameters.get(i).kind() != ParameterKind.OPTIONAL_RETURN, "@BindOptionalReturn must be the first argument to @OnReturn"); } builder.onReturnAdvice(asmMethod); builder.addAllOnReturnParameters(parameters); checkForBindThreadContext(parameters); checkForBindOptionalThreadContext(parameters); hasOnReturnAdvice = true; }
private void initIsEnabledAdvice(PointcutClass adviceClass, PointcutMethod adviceMethod) throws AdviceConstructionException { checkState(!hasIsEnabledAdvice, "@Pointcut '" + adviceClass.type().getClassName() + "' has more than one @IsEnabled method"); Method asmMethod = adviceMethod.toAsmMethod(); checkState(asmMethod.getReturnType().getSort() == Type.BOOLEAN, "@IsEnabled method must return boolean"); builder.isEnabledAdvice(asmMethod); List<AdviceParameter> parameters = getAdviceParameters(adviceMethod.parameterAnnotationTypes(), asmMethod.getArgumentTypes(), isEnabledBindAnnotationTypes, IsEnabledType); builder.addAllIsEnabledParameters(parameters); hasIsEnabledAdvice = true; }
private void initOnThrowAdvice(PointcutClass adviceClass, PointcutMethod adviceMethod) throws AdviceConstructionException { checkState(!hasOnThrowAdvice, "@Pointcut '" + adviceClass.type().getClassName() + "' has more than one @OnThrow method"); Method asmMethod = adviceMethod.toAsmMethod(); List<AdviceParameter> parameters = getAdviceParameters(adviceMethod.parameterAnnotationTypes(), asmMethod.getArgumentTypes(), onThrowBindAnnotationTypes, OnThrowType); for (int i = 1; i < parameters.size(); i++) { checkState(parameters.get(i).kind() != ParameterKind.THROWABLE, "@BindThrowable must be the first argument to @OnThrow"); } checkState(asmMethod.getReturnType().getSort() == Type.VOID, "@OnThrow method must return void (for now)"); builder.onThrowAdvice(asmMethod); builder.addAllOnThrowParameters(parameters); checkForBindThreadContext(parameters); checkForBindOptionalThreadContext(parameters); hasOnThrowAdvice = true; }
private void initOnAfterAdvice(PointcutClass adviceClass, PointcutMethod adviceMethod) throws AdviceConstructionException { checkState(!hasOnAfterAdvice, "@Pointcut '" + adviceClass.type().getClassName() + "' has more than one @OnAfter method"); Method asmMethod = adviceMethod.toAsmMethod(); checkState(asmMethod.getReturnType().getSort() == Type.VOID, "@OnAfter method must return void"); builder.onAfterAdvice(asmMethod); List<AdviceParameter> parameters = getAdviceParameters(adviceMethod.parameterAnnotationTypes(), asmMethod.getArgumentTypes(), onAfterBindAnnotationTypes, OnAfterType); builder.addAllOnAfterParameters(parameters); checkForBindThreadContext(parameters); checkForBindOptionalThreadContext(parameters); hasOnAfterAdvice = true; }
visitJumpInsn(IFEQ, onThrowBlockEnd); if (onThrowAdvice.getArgumentTypes().length > 0) { int startIndex; Object[] stack;
private void initOnBeforeAdvice(PointcutClass adviceClass, PointcutMethod adviceMethod) throws AdviceConstructionException { checkState(!hasOnBeforeAdvice, "@Pointcut '" + adviceClass.type().getClassName() + "' has more than one @OnBefore method"); Method asmMethod = adviceMethod.toAsmMethod(); builder.onBeforeAdvice(asmMethod); List<AdviceParameter> parameters = getAdviceParameters(adviceMethod.parameterAnnotationTypes(), asmMethod.getArgumentTypes(), onBeforeBindAnnotationTypes, OnBeforeType); builder.addAllOnBeforeParameters(parameters); if (asmMethod.getReturnType().getSort() != Type.VOID) { builder.travelerType(asmMethod.getReturnType()); } checkForBindThreadContext(parameters); checkForBindOptionalThreadContext(parameters); hasOnBeforeAdvice = true; }
private static String print(Method method) { StringBuilder sb = new StringBuilder(); sb.append(print(method.getReturnType())).append(" ").append(method.getName()).append("("); for (Type t : method.getArgumentTypes()) { sb.append(print(t)).append(" "); } sb.append(")"); return sb.toString(); }
private static String print(Method method) { StringBuilder sb = new StringBuilder(); sb.append(print(method.getReturnType())).append(" ").append(method.getName()).append("("); for (Type t : method.getArgumentTypes()) { sb.append(print(t)).append(" "); } sb.append(")"); return sb.toString(); }
private void weaveOnReturnAdvice(int opcode, Advice advice, Method onReturnAdvice) { if (onReturnAdvice.getArgumentTypes().length > 0) {
public static MethodRef createStaticMethod(TypeInfo owner, Method method) { return new AutoValue_MethodRef( Opcodes.INVOKESTATIC, owner, method, method.getReturnType(), ImmutableList.<Type>builder().add(method.getArgumentTypes()).build(), Features.of()); }
public static MethodRef createStaticMethod(TypeInfo owner, Method method) { return new AutoValue_MethodRef( Opcodes.INVOKESTATIC, owner, method, method.getReturnType(), ImmutableList.<Type>builder().add(method.getArgumentTypes()).build(), Features.of()); }
public static MethodRef createInstanceMethod(TypeInfo owner, Method method) { return new AutoValue_MethodRef( Opcodes.INVOKEVIRTUAL, owner, method, method.getReturnType(), ImmutableList.<Type>builder().add(owner.type()).add(method.getArgumentTypes()).build(), Features.of()); }
public static MethodRef createInstanceMethod(TypeInfo owner, Method method) { return new AutoValue_MethodRef( Opcodes.INVOKEVIRTUAL, owner, method, method.getReturnType(), ImmutableList.<Type>builder().add(owner.type()).add(method.getArgumentTypes()).build(), Features.of()); }
/** * Returns a new {@link ConstructorRef} that refers to a constructor on the given type with the * given parameter types. */ public static ConstructorRef create(TypeInfo type, Method init) { checkArgument( init.getName().equals("<init>") && init.getReturnType().equals(Type.VOID_TYPE), "'%s' is not a valid constructor", init); return new AutoValue_ConstructorRef(type, init, ImmutableList.copyOf(init.getArgumentTypes())); }
/** * Returns a new {@link ConstructorRef} that refers to a constructor on the given type with the * given parameter types. */ public static ConstructorRef create(TypeInfo type, Method init) { checkArgument( init.getName().equals("<init>") && init.getReturnType().equals(Type.VOID_TYPE), "'%s' is not a valid constructor", init); return new AutoValue_ConstructorRef(type, init, ImmutableList.copyOf(init.getArgumentTypes())); }
/** * Produce a rebased method declaration, also visiting referenced types. */ private Method processMethod(String sourceType, String name, String desc) { Method method = new Method(name, desc); Type[] argumentTypes = method.getArgumentTypes(); for (int i = 0, j = argumentTypes.length; i < j; i++) { argumentTypes[i] = processType(sourceType, argumentTypes[i]); } method = new Method(name, processType(sourceType, method.getReturnType()), argumentTypes); return method; }