Skip to content

Commit

Permalink
Refactored annotation binder to be parameter based.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rafael Winterhalter committed Mar 18, 2015
1 parent 7d6d63e commit 71be1c4
Show file tree
Hide file tree
Showing 33 changed files with 746 additions and 794 deletions.
Expand Up @@ -74,6 +74,11 @@ static interface Engine {
*/ */
static class ForRedefinition implements Engine { static class ForRedefinition implements Engine {


/**
* Instructs the retention of a method in its original form if it is not redefined.
*/
private static final MethodDescription RETAIN_METHOD = null;

/** /**
* Representative of a {@link org.objectweb.asm.MethodVisitor} that is instructed to ignoring a result. * Representative of a {@link org.objectweb.asm.MethodVisitor} that is instructed to ignoring a result.
*/ */
Expand Down Expand Up @@ -358,13 +363,9 @@ public MethodVisitor visitMethod(int modifiers,
injectedCode.getInjectorProxyMethod().getExceptionTypes().toInternalNames()); injectedCode.getInjectorProxyMethod().getExceptionTypes().toInternalNames());
} }
MethodDescription methodDescription = declarableMethods.remove(internalName + descriptor); MethodDescription methodDescription = declarableMethods.remove(internalName + descriptor);
return methodDescription == null return methodDescription == RETAIN_METHOD
// Ignored method or not existent for the instrumented type. ? super.visitMethod(modifiers, internalName, descriptor, genericSignature, exceptionTypeInternalName)
? : redefine(methodDescription, (modifiers & Opcodes.ACC_ABSTRACT) != 0);
super.visitMethod(modifiers, internalName, descriptor, genericSignature,
exceptionTypeInternalName)
:
redefine(methodDescription, (modifiers & Opcodes.ACC_ABSTRACT) != 0);
} }


/** /**
Expand Down Expand Up @@ -393,12 +394,8 @@ private MethodVisitor redefine(MethodDescription methodDescription, boolean abst
methodDescription.getExceptionTypes().toInternalNames()); methodDescription.getExceptionTypes().toInternalNames());
entry.getAttributeAppender().apply(methodVisitor, methodDescription); entry.getAttributeAppender().apply(methodVisitor, methodDescription);
return abstractOrigin return abstractOrigin
? ? new AttributeObtainingMethodVisitor(methodVisitor, entry.getByteCodeAppender(), methodDescription)
new AttributeObtainingMethodVisitor(methodVisitor, entry.getByteCodeAppender(), : new CodePreservingMethodVisitor(methodVisitor, entry.getByteCodeAppender(), methodDescription);
methodDescription)
:
new CodePreservingMethodVisitor(methodVisitor, entry.getByteCodeAppender(),
methodDescription);
} }


@Override @Override
Expand Down
Expand Up @@ -3,6 +3,7 @@
import net.bytebuddy.instrumentation.Instrumentation; import net.bytebuddy.instrumentation.Instrumentation;
import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription; import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription;
import net.bytebuddy.instrumentation.method.MethodDescription; import net.bytebuddy.instrumentation.method.MethodDescription;
import net.bytebuddy.instrumentation.method.ParameterDescription;
import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder; import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder;
import net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation; import net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation;
import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner; import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner;
Expand Down Expand Up @@ -112,20 +113,18 @@ public Class<AllArguments> getHandledType() {


@Override @Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<AllArguments> annotation, public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<AllArguments> annotation,
int targetParameterIndex,
MethodDescription source, MethodDescription source,
MethodDescription target, ParameterDescription target,
Instrumentation.Target instrumentationTarget, Instrumentation.Target instrumentationTarget,
Assigner assigner) { Assigner assigner) {
TypeDescription targetType = target.getParameterTypes().get(targetParameterIndex); if (!target.getTypeDescription().isArray()) {
if (!targetType.isArray()) {
throw new IllegalStateException("Expected an array type for all argument annotation on " + source); throw new IllegalStateException("Expected an array type for all argument annotation on " + source);
} }
ArrayFactory arrayFactory = ArrayFactory.targeting(targetType.getComponentType()); ArrayFactory arrayFactory = ArrayFactory.targeting(target.getTypeDescription().getComponentType());
List<StackManipulation> stackManipulations = new ArrayList<StackManipulation>(source.getParameterTypes().size()); List<StackManipulation> stackManipulations = new ArrayList<StackManipulation>(source.getParameters().size());
int offset = source.isStatic() ? 0 : 1; int offset = source.isStatic() ? 0 : 1;
boolean dynamicallyTyped = RuntimeType.Verifier.check(target, targetParameterIndex); boolean dynamicallyTyped = RuntimeType.Verifier.check(target);
for (TypeDescription sourceParameter : source.getParameterTypes()) { for (TypeDescription sourceParameter : source.getParameters().asTypeList()) {
StackManipulation stackManipulation = new StackManipulation.Compound( StackManipulation stackManipulation = new StackManipulation.Compound(
MethodVariableAccess.forType(sourceParameter).loadFromIndex(offset), MethodVariableAccess.forType(sourceParameter).loadFromIndex(offset),
assigner.assign(sourceParameter, arrayFactory.getComponentType(), dynamicallyTyped)); assigner.assign(sourceParameter, arrayFactory.getComponentType(), dynamicallyTyped));
Expand Down
Expand Up @@ -4,6 +4,7 @@
import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription; import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription;
import net.bytebuddy.instrumentation.attribute.annotation.AnnotationList; import net.bytebuddy.instrumentation.attribute.annotation.AnnotationList;
import net.bytebuddy.instrumentation.method.MethodDescription; import net.bytebuddy.instrumentation.method.MethodDescription;
import net.bytebuddy.instrumentation.method.ParameterDescription;
import net.bytebuddy.instrumentation.method.bytecode.bind.ArgumentTypeResolver; import net.bytebuddy.instrumentation.method.bytecode.bind.ArgumentTypeResolver;
import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder; import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder;
import net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation; import net.bytebuddy.instrumentation.method.bytecode.stack.StackManipulation;
Expand Down Expand Up @@ -146,23 +147,22 @@ public Class<Argument> getHandledType() {


@Override @Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Argument> annotation, public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Argument> annotation,
int targetParameterIndex,
MethodDescription source, MethodDescription source,
MethodDescription target, ParameterDescription target,
Instrumentation.Target instrumentationTarget, Instrumentation.Target instrumentationTarget,
Assigner assigner) { Assigner assigner) {
Argument argument = annotation.loadSilent(); Argument argument = annotation.loadSilent();
if (argument.value() < 0) { if (argument.value() < 0) {
throw new IllegalArgumentException(String.format("Argument annotation on %d's argument virtual " + throw new IllegalArgumentException(String.format("Argument annotation on %d's argument virtual " +
"%s holds negative index", targetParameterIndex, target)); "%s holds negative index", target.getIndex(), target));
} else if (source.getParameterTypes().size() <= argument.value()) { } else if (source.getParameters().size() <= argument.value()) {
return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE; return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE;
} }
return argument.bindingMechanic().makeBinding(source.getParameterTypes().get(argument.value()), return argument.bindingMechanic().makeBinding(source.getParameters().get(argument.value()).getTypeDescription(),
target.getParameterTypes().get(targetParameterIndex), target.getTypeDescription(),
argument.value(), argument.value(),
assigner, assigner,
RuntimeType.Verifier.check(target, targetParameterIndex), RuntimeType.Verifier.check(target),
source.getParameterOffset(argument.value())); source.getParameterOffset(argument.value()));
} }
} }
Expand Down
Expand Up @@ -3,9 +3,9 @@
import net.bytebuddy.instrumentation.Instrumentation; import net.bytebuddy.instrumentation.Instrumentation;
import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription; import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription;
import net.bytebuddy.instrumentation.method.MethodDescription; import net.bytebuddy.instrumentation.method.MethodDescription;
import net.bytebuddy.instrumentation.method.ParameterDescription;
import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder; import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder;
import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner; import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner;
import net.bytebuddy.instrumentation.type.TypeDescription;
import net.bytebuddy.instrumentation.type.auxiliary.TypeProxy; import net.bytebuddy.instrumentation.type.auxiliary.TypeProxy;


import java.lang.annotation.*; import java.lang.annotation.*;
Expand Down Expand Up @@ -47,18 +47,16 @@ public Class<Default> getHandledType() {


@Override @Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Default> annotation, public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Default> annotation,
int targetParameterIndex,
MethodDescription source, MethodDescription source,
MethodDescription target, ParameterDescription target,
Instrumentation.Target instrumentationTarget, Instrumentation.Target instrumentationTarget,
Assigner assigner) { Assigner assigner) {
TypeDescription parameterType = target.getParameterTypes().get(targetParameterIndex); if (!target.getTypeDescription().isInterface()) {
if (!parameterType.isInterface()) {
throw new IllegalStateException(target + " uses the @Default annotation on a non-interface type"); throw new IllegalStateException(target + " uses the @Default annotation on a non-interface type");
} else if (source.isStatic() || !instrumentationTarget.getTypeDescription().getInterfaces().contains(parameterType)) { } else if (source.isStatic() || !instrumentationTarget.getTypeDescription().getInterfaces().contains(target.getTypeDescription())) {
return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE; return MethodDelegationBinder.ParameterBinding.Illegal.INSTANCE;
} else { } else {
return new MethodDelegationBinder.ParameterBinding.Anonymous(new TypeProxy.ForDefaultMethod(parameterType, return new MethodDelegationBinder.ParameterBinding.Anonymous(new TypeProxy.ForDefaultMethod(target.getTypeDescription(),
instrumentationTarget, instrumentationTarget,
annotation.loadSilent().serializableProxy())); annotation.loadSilent().serializableProxy()));
} }
Expand Down
Expand Up @@ -4,6 +4,7 @@
import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription; import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription;
import net.bytebuddy.instrumentation.method.MethodDescription; import net.bytebuddy.instrumentation.method.MethodDescription;
import net.bytebuddy.instrumentation.method.MethodList; import net.bytebuddy.instrumentation.method.MethodList;
import net.bytebuddy.instrumentation.method.ParameterDescription;
import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder; import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder;
import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner; import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner;
import net.bytebuddy.instrumentation.type.TypeDescription; import net.bytebuddy.instrumentation.type.TypeDescription;
Expand Down Expand Up @@ -90,12 +91,11 @@ public Class<DefaultCall> getHandledType() {


@Override @Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<DefaultCall> annotation, public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<DefaultCall> annotation,
int targetParameterIndex,
MethodDescription source, MethodDescription source,
MethodDescription target, ParameterDescription target,
Instrumentation.Target instrumentationTarget, Instrumentation.Target instrumentationTarget,
Assigner assigner) { Assigner assigner) {
TypeDescription targetType = target.getParameterTypes().get(targetParameterIndex); TypeDescription targetType = target.getTypeDescription();
if (!targetType.represents(Runnable.class) && !targetType.represents(Callable.class) && !targetType.represents(Object.class)) { if (!targetType.represents(Runnable.class) && !targetType.represents(Callable.class) && !targetType.represents(Object.class)) {
throw new IllegalStateException("A default method call proxy can only be assigned to Runnable or Callable types: " + target); throw new IllegalStateException("A default method call proxy can only be assigned to Runnable or Callable types: " + target);
} }
Expand Down
Expand Up @@ -3,6 +3,7 @@
import net.bytebuddy.instrumentation.Instrumentation; import net.bytebuddy.instrumentation.Instrumentation;
import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription; import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription;
import net.bytebuddy.instrumentation.method.MethodDescription; import net.bytebuddy.instrumentation.method.MethodDescription;
import net.bytebuddy.instrumentation.method.ParameterDescription;
import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder; import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder;
import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner; import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner;
import net.bytebuddy.instrumentation.method.bytecode.stack.constant.DefaultValue; import net.bytebuddy.instrumentation.method.bytecode.stack.constant.DefaultValue;
Expand Down Expand Up @@ -35,13 +36,11 @@ public Class<Empty> getHandledType() {


@Override @Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Empty> annotation, public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Empty> annotation,
int targetParameterIndex,
MethodDescription source, MethodDescription source,
MethodDescription target, ParameterDescription target,
Instrumentation.Target instrumentationTarget, Instrumentation.Target instrumentationTarget,
Assigner assigner) { Assigner assigner) {
return new MethodDelegationBinder.ParameterBinding.Anonymous(DefaultValue return new MethodDelegationBinder.ParameterBinding.Anonymous(DefaultValue.of(target.getTypeDescription()));
.of(target.getParameterTypes().get(targetParameterIndex)));
} }
} }
} }
Expand Up @@ -11,6 +11,7 @@
import net.bytebuddy.instrumentation.field.FieldList; import net.bytebuddy.instrumentation.field.FieldList;
import net.bytebuddy.instrumentation.method.MethodDescription; import net.bytebuddy.instrumentation.method.MethodDescription;
import net.bytebuddy.instrumentation.method.MethodList; import net.bytebuddy.instrumentation.method.MethodList;
import net.bytebuddy.instrumentation.method.ParameterDescription;
import net.bytebuddy.instrumentation.method.bytecode.ByteCodeAppender; import net.bytebuddy.instrumentation.method.bytecode.ByteCodeAppender;
import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder; import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder;
import net.bytebuddy.instrumentation.method.bytecode.stack.Duplication; import net.bytebuddy.instrumentation.method.bytecode.stack.Duplication;
Expand Down Expand Up @@ -211,16 +212,14 @@ public Class<Field> getHandledType() {


@Override @Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Field> annotation, public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Field> annotation,
int targetParameterIndex,
MethodDescription source, MethodDescription source,
MethodDescription target, ParameterDescription target,
Instrumentation.Target instrumentationTarget, Instrumentation.Target instrumentationTarget,
Assigner assigner) { Assigner assigner) {
TypeDescription parameterType = target.getParameterTypes().get(targetParameterIndex);
AccessType accessType; AccessType accessType;
if (parameterType.equals(getterMethod.getDeclaringType())) { if (target.getTypeDescription().equals(getterMethod.getDeclaringType())) {
accessType = AccessType.GETTER; accessType = AccessType.GETTER;
} else if (parameterType.equals(setterMethod.getDeclaringType())) { } else if (target.getTypeDescription().equals(setterMethod.getDeclaringType())) {
accessType = AccessType.SETTER; accessType = AccessType.SETTER;
} else { } else {
throw new IllegalStateException(target + " uses a @Field annotation on an non-installed type"); throw new IllegalStateException(target + " uses a @Field annotation on an non-installed type");
Expand Down
Expand Up @@ -10,6 +10,7 @@
import net.bytebuddy.instrumentation.method.MethodDescription; import net.bytebuddy.instrumentation.method.MethodDescription;
import net.bytebuddy.instrumentation.method.MethodList; import net.bytebuddy.instrumentation.method.MethodList;
import net.bytebuddy.instrumentation.method.MethodLookupEngine; import net.bytebuddy.instrumentation.method.MethodLookupEngine;
import net.bytebuddy.instrumentation.method.ParameterDescription;
import net.bytebuddy.instrumentation.method.bytecode.ByteCodeAppender; import net.bytebuddy.instrumentation.method.bytecode.ByteCodeAppender;
import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder; import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder;
import net.bytebuddy.instrumentation.method.bytecode.stack.Duplication; import net.bytebuddy.instrumentation.method.bytecode.stack.Duplication;
Expand Down Expand Up @@ -182,15 +183,13 @@ public Class<Morph> getHandledType() {


@Override @Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Morph> annotation, public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Morph> annotation,
int targetParameterIndex,
MethodDescription source, MethodDescription source,
MethodDescription target, ParameterDescription target,
Instrumentation.Target instrumentationTarget, Instrumentation.Target instrumentationTarget,
Assigner assigner) { Assigner assigner) {
TypeDescription parameterType = target.getParameterTypes().get(targetParameterIndex); if (!target.getTypeDescription().equals(forwardingMethod.getDeclaringType())) {
if (!parameterType.equals(forwardingMethod.getDeclaringType())) {
throw new IllegalStateException(String.format("The installed type %s for the @Morph annotation does not " + throw new IllegalStateException(String.format("The installed type %s for the @Morph annotation does not " +
"equal the annotated parameter type on %s", parameterType, target)); "equal the annotated parameter type on %s", target.getTypeDescription(), target));
} }
Instrumentation.SpecialMethodInvocation specialMethodInvocation; Instrumentation.SpecialMethodInvocation specialMethodInvocation;
TypeDescription typeDescription = annotation.getValue(DEFAULT_TARGET, TypeDescription.class); TypeDescription typeDescription = annotation.getValue(DEFAULT_TARGET, TypeDescription.class);
Expand Down
Expand Up @@ -3,6 +3,7 @@
import net.bytebuddy.instrumentation.Instrumentation; import net.bytebuddy.instrumentation.Instrumentation;
import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription; import net.bytebuddy.instrumentation.attribute.annotation.AnnotationDescription;
import net.bytebuddy.instrumentation.method.MethodDescription; import net.bytebuddy.instrumentation.method.MethodDescription;
import net.bytebuddy.instrumentation.method.ParameterDescription;
import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder; import net.bytebuddy.instrumentation.method.bytecode.bind.MethodDelegationBinder;
import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner; import net.bytebuddy.instrumentation.method.bytecode.stack.assign.Assigner;
import net.bytebuddy.instrumentation.method.bytecode.stack.constant.*; import net.bytebuddy.instrumentation.method.bytecode.stack.constant.*;
Expand Down Expand Up @@ -87,12 +88,11 @@ public Class<Origin> getHandledType() {


@Override @Override
public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Origin> annotation, public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loadable<Origin> annotation,
int targetParameterIndex,
MethodDescription source, MethodDescription source,
MethodDescription target, ParameterDescription target,
Instrumentation.Target instrumentationTarget, Instrumentation.Target instrumentationTarget,
Assigner assigner) { Assigner assigner) {
TypeDescription parameterType = target.getParameterTypes().get(targetParameterIndex); TypeDescription parameterType = target.getTypeDescription();
if (parameterType.represents(Class.class)) { if (parameterType.represents(Class.class)) {
return new MethodDelegationBinder.ParameterBinding.Anonymous(ClassConstant.of(instrumentationTarget.getOriginType())); return new MethodDelegationBinder.ParameterBinding.Anonymous(ClassConstant.of(instrumentationTarget.getOriginType()));
} else if (parameterType.represents(Method.class)) { } else if (parameterType.represents(Method.class)) {
Expand All @@ -106,7 +106,7 @@ public MethodDelegationBinder.ParameterBinding<?> bind(AnnotationDescription.Loa
} else if (JavaType.METHOD_TYPE.representedBy(parameterType)) { } else if (JavaType.METHOD_TYPE.representedBy(parameterType)) {
return new MethodDelegationBinder.ParameterBinding.Anonymous(new MethodTypeConstant(source)); return new MethodDelegationBinder.ParameterBinding.Anonymous(new MethodTypeConstant(source));
} else { } else {
throw new IllegalStateException("The " + target + " method's " + targetParameterIndex + throw new IllegalStateException("The " + target + " method's " + target.getIndex() +
" parameter is annotated with a Origin annotation with an argument not representing a Class" + " parameter is annotated with a Origin annotation with an argument not representing a Class" +
" Method, String, MethodType or MethodHandle type"); " Method, String, MethodType or MethodHandle type");
} }
Expand Down

0 comments on commit 71be1c4

Please sign in to comment.