From 12955162326c89f1c6cf44e130efa80c9145f934 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 21 Mar 2023 12:27:27 +0100 Subject: [PATCH] feat: initial proxy rework, replaced getters with public constants, rely more on ow2 Types instead of homebrew solutions --- .../java/ftbsc/lll/proxies/AbstractProxy.java | 104 ++++++++------- .../java/ftbsc/lll/proxies/FieldProxy.java | 65 +--------- .../java/ftbsc/lll/proxies/MethodProxy.java | 119 +++--------------- 3 files changed, 81 insertions(+), 207 deletions(-) diff --git a/src/main/java/ftbsc/lll/proxies/AbstractProxy.java b/src/main/java/ftbsc/lll/proxies/AbstractProxy.java index 1ee19a8..4dd2a72 100644 --- a/src/main/java/ftbsc/lll/proxies/AbstractProxy.java +++ b/src/main/java/ftbsc/lll/proxies/AbstractProxy.java @@ -1,5 +1,7 @@ package ftbsc.lll.proxies; +import org.objectweb.asm.Type; + /** * Abstract proxy class, implementing common aspects * of {@link MethodProxy} and {@link FieldProxy}. @@ -8,57 +10,38 @@ package ftbsc.lll.proxies; public abstract class AbstractProxy { /** - * The name of the corresponding class member. + * The name of the corresponding element. */ - private final String name; + public final String name; + + + /** + * The {@link Type} corresponding to this element. + */ + public final Type type; /** * The fully qualified name (i.e. java.lang.String) of * the parent class. */ - private final String parent; + public final String parent; /** - * The modifiers of the member, as a packed int. + * The modifiers of the element, as a packed int. * @see java.lang.reflect.Modifier */ - private final int modifiers; - - /** - * @return the name of the item - */ - public String getName() { - return this.name; - } - - /** - * @return the modifiers of the member, as a packed int - * @see java.lang.reflect.Modifier - */ - public int getModifiers() { - return this.modifiers; - } - - /** - * @return the fully qualified name of the parent class - */ - public String getParent() { - return this.parent; - } - - /** - * @return the descriptor of the member - */ - public abstract String getDescriptor(); + public final int modifiers; /** * The private constructor, should be called by all classes extending this in theirs. - * @param name the name of the member + * @param name the name of the element + * @param type the {@link Type} for the element * @param modifiers the modifiers, as a packed int * @param parent the FQN of the parent class */ - protected AbstractProxy(String name, int modifiers, String parent) { + protected AbstractProxy(String name, Type type, int modifiers, String parent) { this.name = name; + this.type = type; this.modifiers = modifiers; this.parent = parent; } @@ -70,12 +53,12 @@ public abstract class AbstractProxy { public abstract static class Builder { /** - * The name of the member. + * The name of the element. */ - protected final String name; + protected String name; /** - * The modifiers of the member, as a packed int. + * The modifiers of the element, as a packed int. */ protected int modifiers; @@ -84,23 +67,20 @@ public abstract class AbstractProxy { */ protected String parent; + /** + * The {@link Type} corresponding to the element. + */ + protected Type type; + /** * The constructor. - * @param name the name of the member + * @param name the name of the element */ protected Builder(String name) { this.name = name; this.modifiers = 0; } - /** - * @param parentFQN the fully qualified name of the parent - * @return the current state of the builder - */ - public Builder setParent(String parentFQN) { - this.parent = parentFQN; - return this; - } /** * @param newModifier the modifier to add @@ -115,11 +95,41 @@ public abstract class AbstractProxy { * @param newModifier the new modifier value * @return the current state of the builder */ - public Builder setModifier(int newModifier) { + public Builder setModifiers(int newModifier) { this.modifiers = newModifier; return this; } + /** + * @param parentFQN the fully qualified name of the parent + * @return the current state of the builder + */ + public Builder setParent(String parentFQN) { + this.parent = parentFQN; + return this; + } + + /** + * @param type the {@link Type} corresponding to the element + * @return the current state of the builder + */ + public Builder setType(Type type) { + this.type = type; + return this; + } + + + /** + * Sets {@link Type} for this element from the descriptor, passed as a {@link String}. + * @param descriptor the descriptor passed as a {@link String} + * @return the builder's state after the change + */ + public Builder setDescriptor(String descriptor) { + return this.setType(Type.getType(descriptor)); + } + + + /** * @return the built proxy object */ diff --git a/src/main/java/ftbsc/lll/proxies/FieldProxy.java b/src/main/java/ftbsc/lll/proxies/FieldProxy.java index 0edd735..72a4e40 100644 --- a/src/main/java/ftbsc/lll/proxies/FieldProxy.java +++ b/src/main/java/ftbsc/lll/proxies/FieldProxy.java @@ -1,6 +1,5 @@ package ftbsc.lll.proxies; -import ftbsc.lll.tools.DescriptorBuilder; import org.objectweb.asm.Type; import java.lang.reflect.Field; @@ -11,40 +10,24 @@ import java.lang.reflect.Field; * @since 0.3.0 */ public class FieldProxy extends AbstractProxy { - - /** - * The descriptor of the field's type. - */ - private final String typeDescriptor; - /** * A public constructor, builds a proxy from a {@link Field} * obtained from reflection. * @param f the {@link Field} object corresponding to this. */ public FieldProxy(Field f) { - super(f.getName(), f.getModifiers(), Type.getInternalName(f.getDeclaringClass())); - this.typeDescriptor = Type.getDescriptor(f.getType()); + super(f.getName(), Type.getType(f.getType()), f.getModifiers(), Type.getInternalName(f.getDeclaringClass())); } /** - * A protected constructor, called only from the builder. + * Protected constructor, called only from the builder. * @param name the name of the field + * @param type the {@link Type} of the field * @param modifiers the modifiers of the field * @param parent the FQN of the parent class of the field - * @param typeDescriptor the type descriptor of the field */ - FieldProxy(String name, int modifiers, String parent, String typeDescriptor) { - super(name, modifiers, parent); - this.typeDescriptor = typeDescriptor; - } - - /** - * @return the field's type descriptor - */ - @Override - public String getDescriptor() { - return typeDescriptor; + protected FieldProxy(String name, Type type, int modifiers, String parent) { + super(name, type, modifiers, parent); } /** @@ -60,11 +43,6 @@ public class FieldProxy extends AbstractProxy { * A builder object for {@link FieldProxy}. */ public static class Builder extends AbstractProxy.Builder { - /** - * The descriptor of the field's type. - */ - private String typeDescriptor; - /** * The constructor of the builder, used only internally. * @param name the name of the field @@ -73,44 +51,13 @@ public class FieldProxy extends AbstractProxy { super(name); } - /** - * Sets the descriptor of the field type to the given {@link String}. - * @param typeDescriptor the descriptor of the field type - * @return the builder's state after the change - */ - public Builder setDescriptor(String typeDescriptor) { - this.typeDescriptor = typeDescriptor; - return this; - } - - /** - * Sets the descriptor of the field type to match the give {@link Class}. - * @param fqn the fully qualified name of the field type - * @param arrayLevel the array level of the field type - * @return the builder's state after the change - */ - public Builder setType(String fqn, int arrayLevel) { - this.typeDescriptor = DescriptorBuilder.nameToDescriptor(fqn, arrayLevel); - return this; - } - - /** - * Sets the descriptor of the field type to match the give {@link Class}. - * @param type a {@link Class} object representing the field type - * @return the builder's state after the change - */ - public Builder setType(Class type) { - this.typeDescriptor = Type.getDescriptor(type); - return this; - } - /** * Builds a {@link FieldProxy} of the given kind. * @return the built {@link FieldProxy} */ @Override public FieldProxy build() { - return new FieldProxy(this.name, this.modifiers, this.parent, this.typeDescriptor); + return new FieldProxy(this.name, this.type, this.modifiers, this.parent); } } } diff --git a/src/main/java/ftbsc/lll/proxies/MethodProxy.java b/src/main/java/ftbsc/lll/proxies/MethodProxy.java index ff5e1f0..5f80c08 100644 --- a/src/main/java/ftbsc/lll/proxies/MethodProxy.java +++ b/src/main/java/ftbsc/lll/proxies/MethodProxy.java @@ -1,12 +1,13 @@ package ftbsc.lll.proxies; -import ftbsc.lll.tools.DescriptorBuilder; import org.objectweb.asm.Type; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; +import static ftbsc.lll.tools.DescriptorBuilder.nameToDescriptor; + /** * A container for information about class methods to be used * in ASM patching. @@ -16,23 +17,13 @@ public class MethodProxy extends AbstractProxy { /** * The parameters of the method. - * It holds fully qualified names for objects, and {@link Class} - * objects for primitives. */ - private final Object[] parameters; + public final Type[] parameters; /** * The return type of the method. - * It contains if it's an object, or a {@link Class} - * object for primitives. */ - private final Object returnType; - - /** - * Caches the the descriptor after generating it once for - * performance. - */ - private String descriptorCache; + public final Type returnType; /** * A public constructor, builds a proxy from a {@link Method} @@ -40,13 +31,10 @@ public class MethodProxy extends AbstractProxy { * @param m the {@link Method} object corresponding to this. */ public MethodProxy(Method m) { - super(m.getName(), m.getModifiers(), Type.getInternalName(m.getDeclaringClass())); - List parameters = new ArrayList<>(); - for(Class p : m.getParameterTypes()) - parameters.add(p.isPrimitive() ? p : new TypeContainer(p)); - this.parameters = parameters.toArray(); - Class returnType = m.getReturnType(); - this.returnType = returnType.isPrimitive() ? returnType : new TypeContainer(returnType); + super(m.getName(), Type.getType(m), m.getModifiers(), Type.getInternalName(m.getDeclaringClass())); + Type mt = Type.getType(m); + this.parameters = mt.getArgumentTypes(); + this.returnType = mt.getReturnType(); } /** @@ -57,41 +45,10 @@ public class MethodProxy extends AbstractProxy { * @param parameters the parameters of the method * @param returnType the return type of the method */ - protected MethodProxy(String name, int modifiers, String parent, Object[] parameters, Object returnType) { - super(name, modifiers, parent); + protected MethodProxy(String name, int modifiers, String parent, Type[] parameters, Type returnType) { + super(name, Type.getMethodType(returnType, parameters), modifiers, parent); this.parameters = parameters; this.returnType = returnType; - this.descriptorCache = null; - } - - /** - * Builds (or returns from cache if present) - * the method's descriptor. - * @return the method's descriptor - */ - @Override - public String getDescriptor() { - if(this.descriptorCache != null) - return this.descriptorCache; - DescriptorBuilder b = new DescriptorBuilder(); - for(Object p : this.parameters) - addParameterToBuilder(b, p); - addParameterToBuilder(b, this.returnType); - this.descriptorCache = b.build(); - return this.descriptorCache; - } - - /** - * A static method used internally to correctly insert a - * {@link TypeContainer} into a {@link DescriptorBuilder}. - * @param b the {@link DescriptorBuilder} - * @param p the {@link TypeContainer} - */ - private static void addParameterToBuilder(DescriptorBuilder b, Object p) { - if(p instanceof TypeContainer) { - TypeContainer param = (TypeContainer) p; - b.addParameter(param.fqn, param.arrayLevel); - } else b.addParameter((Class) p); } /** @@ -110,12 +67,12 @@ public class MethodProxy extends AbstractProxy { /** * The parameters of the method. */ - private final List parameters; + private final List parameters; /** * The return type of the method. Defaults to void. */ - private Object returnType; + private Type returnType; /** * The constructor of the builder, used only internally. @@ -124,7 +81,7 @@ public class MethodProxy extends AbstractProxy { Builder(String name) { super(name); this.parameters = new ArrayList<>(); - this.returnType = void.class; + this.returnType = Type.getType(void.class); } /** @@ -134,7 +91,7 @@ public class MethodProxy extends AbstractProxy { * @return the builder's state after the change */ public Builder addParameter(String fqn, int arrayLevel) { - this.parameters.add(new TypeContainer(fqn, arrayLevel)); + this.parameters.add(Type.getType(nameToDescriptor(fqn, arrayLevel))); return this; } @@ -145,7 +102,7 @@ public class MethodProxy extends AbstractProxy { * @return the builder's state after the change */ public Builder addParameter(Class paramType) { - this.parameters.add(paramType); + this.parameters.add(Type.getType(paramType)); return this; } @@ -156,7 +113,7 @@ public class MethodProxy extends AbstractProxy { * @return the builder's state after the change */ public Builder setReturnType(String fqn, int arrayLevel) { - this.returnType = new TypeContainer(fqn, arrayLevel); + this.returnType = Type.getType(nameToDescriptor(fqn, arrayLevel)); return this; } @@ -167,7 +124,7 @@ public class MethodProxy extends AbstractProxy { * @return the builder's state after the change */ public Builder setReturnType(Class returnType) { - this.returnType = returnType; + this.returnType = Type.getType(returnType); return this; } @@ -177,47 +134,7 @@ public class MethodProxy extends AbstractProxy { */ @Override public MethodProxy build() { - return new MethodProxy(name, modifiers, parent, parameters.toArray(), returnType); - } - } - - /** - * A container class, holding information about a given type. - */ - protected static class TypeContainer { - /** - * The fully qualified name of the type. - */ - public final String fqn; - - /** - * The array level of the type. - */ - public final int arrayLevel; - - /** - * Public constructor for the class. - * @param fqn the fully qualified name of the type - * @param arrayLevel the array level of the type - */ - public TypeContainer(String fqn, int arrayLevel) { - this.fqn = fqn; - this.arrayLevel = arrayLevel; - } - - /** - * Public constructor for the class, extracting the - * necessary information from a {@link Class} object. - * @param clazz the class object - */ - public TypeContainer(Class clazz) { - int arrayLevel = 0; - while(clazz.isArray()) { - arrayLevel++; - clazz = clazz.getComponentType(); - } - this.arrayLevel = arrayLevel; - this.fqn = clazz.getCanonicalName(); + return new MethodProxy(name, modifiers, parent, parameters.toArray(new Type[0]), returnType); } } }