aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2016-07-14 15:03:53 +0100
committerMichael Williamson <mike@zwobble.org>2016-07-14 15:03:53 +0100
commit334f2173712a4a4c0d434c5f01187a1fc7a4f440 (patch)
tree52417de806c88707e08706cb3398b025a7a1157b /src/main
parente4d1a3c446825a0fcfa00df4a29e66f81c56b7da (diff)
Extract common code for type descriptions
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/zwobble/couscous/ast/visitors/DynamicNodeVisitor.java27
-rw-r--r--src/main/java/org/zwobble/couscous/util/asm/TypeDescriptions.java45
2 files changed, 51 insertions, 21 deletions
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<T> {
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<T> {
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<T> {
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<T> {
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();
+ }
+}