/** * {@inheritDoc} */ public boolean matches(T target) { return target.isAssignableTo(typeDescription); }
/** * {@inheritDoc} */ public TypeDescription resolve(TypeDescription instrumentedType, TypeDescription.Generic parameterType) { if (!typeDescription.isAssignableTo(parameterType.asErasure())) { throw new IllegalStateException("Impossible to assign " + typeDescription + " to parameter of type " + parameterType); } return typeDescription; } }
/** {@inheritDoc} */ public Boolean onNonGenericType(Generic typeDescription) { return typeDescription.asErasure().isAssignableTo(Throwable.class); } },
/** * {@inheritDoc} */ public TypeDescription resolve(TypeDescription.Generic parameterType) { if (!typeDescription.isAssignableTo(parameterType.asErasure())) { throw new IllegalStateException("Impossible to assign " + typeDescription + " to parameter of type " + parameterType); } return typeDescription; } }
/** * {@inheritDoc} */ public Resolved resolve(TypeDescription instrumentedType, MethodDescription instrumentedMethod, Assigner assigner, Assigner.Typing typing) { if (instrumentedMethod.isStatic()) { throw new IllegalStateException("Cannot get this instance from static method: " + instrumentedMethod); } else if (!instrumentedType.isAssignableTo(typeDescription)) { throw new IllegalStateException(instrumentedType + " is not assignable to " + instrumentedType); } return new Resolved.Simple(MethodVariableAccess.loadThis(), typeDescription); }
/** * {@inheritDoc} */ public FieldDescription resolve(TypeDescription instrumentedType) { if (!fieldDescription.isStatic() && !instrumentedType.isAssignableTo(fieldDescription.getType().asErasure())) { throw new IllegalStateException("Cannot access " + fieldDescription + " from " + instrumentedType); } return fieldDescription; } }
@Override protected FieldLocator fieldLocator(TypeDescription instrumentedType) { if (!declaringType.represents(TargetType.class) && !instrumentedType.isAssignableTo(declaringType)) { throw new IllegalStateException(declaringType + " is no super type of " + instrumentedType); } return new FieldLocator.ForExactType(TargetType.resolve(declaringType, instrumentedType)); } }
private boolean alreadyEnhanced(TypeDescription managedCtClass) { for ( TypeDescription.Generic declaredInterface : managedCtClass.getInterfaces() ) { if ( declaredInterface.asErasure().isAssignableTo( Managed.class ) ) { return true; } } return false; }
/** * {@inheritDoc} */ public Prepared prepare(TypeDescription instrumentedType) { if (!fieldDescription.isStatic() && !instrumentedType.isAssignableTo(fieldDescription.getDeclaringType().asErasure())) { throw new IllegalStateException(fieldDescription + " is not declared by " + instrumentedType); } else if (!fieldDescription.isAccessibleTo(instrumentedType)) { throw new IllegalStateException("Cannot access " + fieldDescription + " from " + instrumentedType); } return this; }
/** * Creates an implementation that creates a new instance of the given {@link Throwable} type on each method invocation * which is then thrown immediately. For this to be possible, the given type must define a default constructor * which is visible from the instrumented type. * * @param throwableType The type of the {@link Throwable}. * @return An implementation that will throw an instance of the {@link Throwable} on each method invocation of the * instrumented methods. */ public static Implementation throwing(TypeDescription throwableType) { if (!throwableType.isAssignableTo(Throwable.class)) { throw new IllegalArgumentException(throwableType + " does not extend throwable"); } return new ExceptionMethod(new ConstructionDelegate.ForDefaultConstructor(throwableType)); }
/** * Matches a {@link MethodDescription} by its capability to throw a given * checked exception. For specifying a non-checked exception, any method is matched. * * @param exceptionType The type of the exception that should be declared by the method to be matched. * @param <T> The type of the matched object. * @return A matcher that matches a method description by its declaration of throwing a checked exception. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> canThrow(TypeDescription exceptionType) { return exceptionType.isAssignableTo(RuntimeException.class) || exceptionType.isAssignableTo(Error.class) ? new BooleanMatcher<T>(true) : ElementMatchers.<T>declaresGenericException(new CollectionItemMatcher<TypeDescription.Generic>(erasure(isSuperTypeOf(exceptionType)))); }
/** * Creates an implementation that creates a new instance of the given {@link Throwable} type on each method * invocation which is then thrown immediately. For this to be possible, the given type must define a * constructor that takes a single {@link java.lang.String} as its argument. * * @param throwableType The type of the {@link Throwable}. * @param message The string that is handed to the constructor. Usually an exception message. * @return An implementation that will throw an instance of the {@link Throwable} on each method invocation * of the instrumented methods. */ public static Implementation throwing(TypeDescription throwableType, String message) { if (!throwableType.isAssignableTo(Throwable.class)) { throw new IllegalArgumentException(throwableType + " does not extend throwable"); } return new ExceptionMethod(new ConstructionDelegate.ForStringConstructor(throwableType, message)); }
/** * {@inheritDoc} */ public TerminationHandler make(TypeDescription instrumentedType) { if (!fieldDescription.isStatic() && !instrumentedType.isAssignableTo(fieldDescription.getDeclaringType().asErasure())) { throw new IllegalStateException("Cannot set " + fieldDescription + " from " + instrumentedType); } else if (!fieldDescription.isAccessibleTo(instrumentedType)) { throw new IllegalStateException("Cannot access " + fieldDescription + " from " + instrumentedType); } return new FieldSetting(fieldDescription); } }
/** * Matches a method that declares the given generic exception type as a (erased) exception type. * * @param exceptionType The exception type that is matched. * @param <T> The type of the matched object. * @return A matcher that matches any method that exactly matches the provided exception. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> declaresException(TypeDescription exceptionType) { return exceptionType.isAssignableTo(Throwable.class) ? ElementMatchers.<T>declaresGenericException(new CollectionItemMatcher<TypeDescription.Generic>(erasure(exceptionType))) : new BooleanMatcher<T>(false); }
/** * {@inheritDoc} */ public Size apply(MethodVisitor methodVisitor, Context implementationContext, MethodDescription instrumentedMethod) { if (instrumentedMethod.isStatic() || !instrumentedType.isAssignableTo(instrumentedMethod.getReturnType().asErasure())) { throw new IllegalStateException("Cannot return 'this' from " + instrumentedMethod); } return new ByteCodeAppender.Simple( MethodVariableAccess.loadThis(), MethodReturn.REFERENCE ).apply(methodVisitor, implementationContext, instrumentedMethod); } }
/** * {@inheritDoc} */ public StackManipulation assign(TypeDescription.Generic source, TypeDescription.Generic target, Typing typing) { if (source.isPrimitive() || target.isPrimitive()) { return source.equals(target) ? StackManipulation.Trivial.INSTANCE : StackManipulation.Illegal.INSTANCE; } else if (source.asErasure().isAssignableTo(target.asErasure())) { return StackManipulation.Trivial.INSTANCE; } else if (typing.isDynamic()) { return TypeCasting.to(target); } else { return StackManipulation.Illegal.INSTANCE; } } }
/** * {@inheritDoc} */ public TargetHandler make(Implementation.Target implementationTarget) { FieldDescription fieldDescription = location.resolve(implementationTarget.getInstrumentedType()); if (!fieldDescription.isStatic() && !implementationTarget.getInstrumentedType().isAssignableTo(fieldDescription.getDeclaringType().asErasure())) { throw new IllegalStateException("Cannot access " + fieldDescription + " from " + implementationTarget.getInstrumentedType()); } return new ForField(fieldDescription); } }
/** * {@inheritDoc} */ public ByteCodeAppender appender(Target implementationTarget) { FieldLocator.Resolution resolution = fieldLocatorFactory.make(implementationTarget.getInstrumentedType()).locate(fieldName); if (!resolution.isResolved()) { throw new IllegalStateException("Could not find a field named '" + fieldName + "' for " + implementationTarget.getInstrumentedType()); } else if (!resolution.getField().getType().asErasure().isAssignableTo(InvocationHandler.class)) { throw new IllegalStateException("Field " + resolution.getField() + " does not declare a type that is assignable to invocation handler"); } return new Appender(resolution.getField()); }
/** * Matches a method that declares the given generic exception type. For non-generic type, this matcher behaves identically to * {@link ElementMatchers#declaresException(TypeDescription)}. For exceptions that are expressed as type variables, only exceptions * that are represented as this type variable are matched. * * @param exceptionType The generic exception type that is matched exactly. * @param <T> The type of the matched object. * @return A matcher that matches any method that exactly matches the provided generic exception. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> declaresGenericException(TypeDescription.Generic exceptionType) { return !exceptionType.getSort().isWildcard() && exceptionType.asErasure().isAssignableTo(Throwable.class) ? ElementMatchers.<T>declaresGenericException(new CollectionItemMatcher<TypeDescription.Generic>(is(exceptionType))) : new BooleanMatcher<T>(false); }
/** * {@inheritDoc} */ public boolean isInvokeBootstrap() { TypeDescription returnType = getReturnType().asErasure(); if ((isMethod() && (!isStatic() || !(JavaType.CALL_SITE.getTypeStub().isAssignableFrom(returnType) || JavaType.CALL_SITE.getTypeStub().isAssignableTo(returnType)))) || (isConstructor() && !JavaType.CALL_SITE.getTypeStub().isAssignableFrom(getDeclaringType().asErasure()))) { return false; } return isBootstrap(JavaType.METHOD_TYPE.getTypeStub()); }