From 334f2173712a4a4c0d434c5f01187a1fc7a4f440 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 14 Jul 2016 15:03:53 +0100 Subject: Extract common code for type descriptions --- .../couscous/ast/visitors/DynamicNodeVisitor.java | 27 +++---------- .../couscous/util/asm/TypeDescriptions.java | 45 ++++++++++++++++++++++ 2 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 src/main/java/org/zwobble/couscous/util/asm/TypeDescriptions.java diff --git a/src/main/java/org/zwobble/couscous/ast/visitors/DynamicNodeVisitor.java b/src/main/java/org/zwobble/couscous/ast/visitors/DynamicNodeVisitor.java index b233d39..55419f7 100644 --- a/src/main/java/org/zwobble/couscous/ast/visitors/DynamicNodeVisitor.java +++ b/src/main/java/org/zwobble/couscous/ast/visitors/DynamicNodeVisitor.java @@ -18,6 +18,7 @@ import net.bytebuddy.matcher.ElementMatchers; import org.zwobble.couscous.ast.Node; import org.zwobble.couscous.ast.NodeTypes; import org.zwobble.couscous.util.asm.StackManipulationSwitch; +import org.zwobble.couscous.util.asm.TypeDescriptions; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -25,8 +26,6 @@ import java.util.List; import java.util.function.Consumer; import static java.util.Arrays.asList; -import static net.bytebuddy.matcher.ElementMatchers.isConstructor; -import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static org.zwobble.couscous.util.ExtraLists.eagerFilter; import static org.zwobble.couscous.util.ExtraLists.eagerMap; @@ -103,17 +102,12 @@ public class DynamicNodeVisitor { StackManipulation.Size size = new StackManipulation.Compound( // this() MethodVariableAccess.REFERENCE.loadOffset(0), - MethodInvocation.invoke(new TypeDescription.ForLoadedType(Object.class) - .getDeclaredMethods() - .filter(isConstructor().and(takesArguments(0))).getOnly()), + MethodInvocation.invoke(TypeDescriptions.findConstructor(Object.class)), // this.visitor = visitor MethodVariableAccess.REFERENCE.loadOffset(0), MethodVariableAccess.REFERENCE.loadOffset(1), - FieldAccess.forField(implementationTarget.getInstrumentedType() - .getDeclaredFields() - .filter(ElementMatchers.named("visitor")) - .getOnly()).putter(), + FieldAccess.forField(TypeDescriptions.findField(implementationTarget, "visitor")).putter(), // return MethodReturn.VOID @@ -136,10 +130,7 @@ public class DynamicNodeVisitor { return new ByteCodeAppender() { @Override public Size apply(MethodVisitor methodVisitor, Context context, MethodDescription instrumentedMethod) { - MethodDescription typeMethod = new TypeDescription.ForLoadedType(Node.class) - .getDeclaredMethods() - .filter(ElementMatchers.named("type").and(ElementMatchers.takesArguments(0))) - .getOnly(); + MethodDescription typeMethod = TypeDescriptions.findMethod(Node.class, "type"); StackManipulation.Size size = new StackManipulation.Compound( MethodVariableAccess.REFERENCE.loadOffset(1), MethodInvocation.invoke(typeMethod), @@ -147,10 +138,7 @@ public class DynamicNodeVisitor { new StackManipulation.Compound( TypeCreation.of(new TypeDescription.ForLoadedType(UnsupportedOperationException.class)), Duplication.SINGLE, - MethodInvocation.invoke(new TypeDescription.ForLoadedType(UnsupportedOperationException.class) - .getDeclaredMethods() - .filter(ElementMatchers.isDefaultConstructor()) - .getOnly()), + MethodInvocation.invoke(TypeDescriptions.findConstructor(UnsupportedOperationException.class)), Throw.INSTANCE ), eagerMap(visitMethods, method -> { @@ -159,10 +147,7 @@ public class DynamicNodeVisitor { NodeTypes.forClass(nodeClass), new StackManipulation.Compound( MethodVariableAccess.REFERENCE.loadOffset(0), - FieldAccess.forField(target.getInstrumentedType() - .getDeclaredFields() - .filter(ElementMatchers.named("visitor")) - .getOnly()).getter(), + FieldAccess.forField(TypeDescriptions.findField(target, "visitor")).getter(), MethodVariableAccess.REFERENCE.loadOffset(1), TypeCasting.to(new TypeDescription.ForLoadedType(nodeClass)), MethodInvocation.invoke(new MethodDescription.ForLoadedMethod(method)), diff --git a/src/main/java/org/zwobble/couscous/util/asm/TypeDescriptions.java b/src/main/java/org/zwobble/couscous/util/asm/TypeDescriptions.java new file mode 100644 index 0000000..e702b97 --- /dev/null +++ b/src/main/java/org/zwobble/couscous/util/asm/TypeDescriptions.java @@ -0,0 +1,45 @@ +package org.zwobble.couscous.util.asm; + +import net.bytebuddy.description.field.FieldDescription; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.implementation.Implementation; +import net.bytebuddy.matcher.ElementMatchers; + +public class TypeDescriptions { + private TypeDescriptions() { + } + + public static FieldDescription findField(Implementation.Target target, String fieldName) { + return findField(target.getInstrumentedType(), fieldName); + } + + public static FieldDescription findField(TypeDescription typeDescription, String fieldName) { + return typeDescription + .getDeclaredFields() + .filter(ElementMatchers.named(fieldName)) + .getOnly(); + } + + public static MethodDescription findMethod(Class clazz, String name, Class... arguments) { + return findMethod(new TypeDescription.ForLoadedType(clazz), name, arguments); + } + + public static MethodDescription findMethod(TypeDescription typeDescription, String name, Class... arguments) { + return typeDescription + .getDeclaredMethods() + .filter(ElementMatchers.named(name).and(ElementMatchers.takesArguments(arguments))) + .getOnly(); + } + + public static MethodDescription findConstructor(Class clazz, Class... arguments) { + return findConstructor(new TypeDescription.ForLoadedType(clazz), arguments); + } + + public static MethodDescription findConstructor(TypeDescription typeDescription, Class... arguments) { + return typeDescription + .getDeclaredMethods() + .filter(ElementMatchers.isConstructor().and(ElementMatchers.takesArguments(arguments))) + .getOnly(); + } +} -- cgit v1.2.3