From 12955162326c89f1c6cf44e130efa80c9145f934 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 21 Mar 2023 12:27:27 +0100 Subject: [PATCH 1/7] 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); } } } From 8c11b0b4d89b1d340bdd620d96e5127c05c2e066 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 21 Mar 2023 12:31:10 +0100 Subject: [PATCH 2/7] chore: updated insnnodes to match --- src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java | 6 +++--- .../java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java index 896dc42..d23686d 100644 --- a/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java +++ b/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java @@ -19,9 +19,9 @@ public class FieldProxyInsnNode extends FieldInsnNode { public FieldProxyInsnNode(int opcode, FieldProxy f) { super( opcode, - f.getParent().replace('.', '/'), - f.getName(), - f.getDescriptor() + f.parent.replace('.', '/'), + f.name, + f.type.getDescriptor() ); } } diff --git a/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java index 63196fd..904615d 100644 --- a/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java +++ b/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java @@ -20,9 +20,9 @@ public class MethodProxyInsnNode extends MethodInsnNode { public MethodProxyInsnNode(int opcode, MethodProxy m) { super( opcode, - m.getParent().replace('.', '/'), - m.getName(), - m.getDescriptor() + m.parent.replace('.', '/'), + m.name, + m.type.getDescriptor() ); } } From 40686b8c929279bd486529fceae1d8dd7fa2735f Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 21 Mar 2023 14:05:14 +0100 Subject: [PATCH 3/7] feat: added ClassProxy --- .../java/ftbsc/lll/proxies/ClassProxy.java | 174 ++++++++++++++++++ .../ftbsc/lll/tools/DescriptorBuilder.java | 15 +- 2 files changed, 182 insertions(+), 7 deletions(-) create mode 100644 src/main/java/ftbsc/lll/proxies/ClassProxy.java diff --git a/src/main/java/ftbsc/lll/proxies/ClassProxy.java b/src/main/java/ftbsc/lll/proxies/ClassProxy.java new file mode 100644 index 0000000..c369231 --- /dev/null +++ b/src/main/java/ftbsc/lll/proxies/ClassProxy.java @@ -0,0 +1,174 @@ +package ftbsc.lll.proxies; + +import org.objectweb.asm.Type; + +/** + * A container for information about classes to be used + * in ASM patching. + * @since 0.4.0 + */ +public class ClassProxy extends AbstractProxy { + + /** + * The fully-qualified name of the class represented by this proxy. + */ + public final String fqn; + + /** + * The {@link ClassProxy} representing the class which contains the + * class represented by this proxy. May be null if the class represented + * by this proxy is not an inner class. + */ + public final ClassProxy containerClass; + + /** + * Protected constructor, called only from the builder. + * @param name the name of the class + * @param type the {@link Type} of the class + * @param modifiers the modifiers of the class + * @param parent the FQN of the parent class of the class + */ + protected ClassProxy(String name, Type type, int modifiers, String parent) { + super(name, type, modifiers, parent); + this.fqn = String.format("%s.%s", name, parent); + this.containerClass = null; + } + + /** + * Protected constructor, called only from the builder. + * @param name the name of the class + * @param type the {@link Type} of the class + * @param modifiers the modifiers of the class + * @param containerClass the FQN of the parent class of the class + */ + protected ClassProxy(String name, Type type, int modifiers, ClassProxy containerClass) { + super(name, type, modifiers, containerClass.fqn); + this.fqn = String.format("%s$%s", name, parent); + this.containerClass = containerClass; + } + + /** + * Builds a {@link ClassProxy} given only the fully-qualified name and modifiers. + * @param fqn the fully qualified name of the desired class + * @param modifiers the access modifiers of the desired class + * @return the built {@link ClassProxy} + */ + protected static ClassProxy from(String fqn, int modifiers) { + Type type = Type.getObjectType(fqn.replace('.', '/')); + if(fqn.contains("$")) { + String[] split = fqn.split("\\$"); + String simpleName = split[split.length - 1]; + ClassProxy parentClass = from(fqn.replace("$" + simpleName, ""), 0); + return new ClassProxy(simpleName, type, modifiers, parentClass); + } else { + String[] split = fqn.split("\\."); + String simpleName = split[split.length - 1]; + String parent = fqn.replace("." + simpleName, ""); + return new ClassProxy(simpleName, type, modifiers, parent); + } + } + + /** + * Builds a {@link ClassProxy} from a {@link Class} object. + * @param clazz the {@link Class} object representing the target class + * @return the built {@link ClassProxy} + */ + protected static ClassProxy from(Class clazz) { + if(clazz.getEnclosingClass() == null) + return new ClassProxy( + clazz.getSimpleName(), + Type.getType(clazz), + clazz.getModifiers(), + clazz.getPackage().getName() + ); + else + return new ClassProxy( + clazz.getSimpleName(), + Type.getType(clazz), + clazz.getModifiers(), + from(clazz.getEnclosingClass()) + ); + } + + /** + * Returns a new instance of {@link ClassProxy.Builder}. + * @param name the name of the class + * @return the builder object for class proxies + */ + public static Builder builder(String name) { + return new Builder(name); + } + + /** + * A builder object for {@link ClassProxy}. + */ + public static class Builder extends AbstractProxy.Builder { + + private ClassProxy containerClass; + + /** + * The constructor of the builder, used only internally. + * @param name the "simple name" of the class + */ + Builder(String name) { + super(name); + this.containerClass = null; + } + + /** + * Sets this class as an inner class and sets the containing + * class to the given class object. + * @param containerClass the {@link Class} representing the + * container class + * @return the builder's state after the change + */ + public Builder setContainerClass(Class containerClass) { + this.containerClass = ClassProxy.from(containerClass); + return this; + } + + /** + * Sets this class as an inner class and sets the containing + * class to the given proxy. + * @param containerClass the {@link ClassProxy} representing + * the container class + * @return the builder's state after the change + */ + public Builder setContainerClass(ClassProxy containerClass) { + this.containerClass = containerClass; + return this; + } + + /** + * Sets this class as an inner class and builds a {@link ClassProxy} + * from the given parent and modifiers. + * @param parentFQN the fully qualified name of the parent + * @return the builder's state after the change + */ + public Builder setParent(String parentFQN, int modifiers) { + return this.setContainerClass(ClassProxy.from(parentFQN, modifiers)); + } + + /** + * Sets this class as an inner class and builds a {@link ClassProxy} + * from the given parent. + * @param parentFQN the fully qualified name of the parent + * @return the builder's state after the change + */ + @Override + public Builder setParent(String parentFQN) { + return this.setParent(parentFQN, 0); + } + + /** + * Builds a {@link ClassProxy} of the given kind. + * @return the built {@link ClassProxy} + */ + @Override + public ClassProxy build() { + if(this.containerClass == null) + return new ClassProxy(this.name, this.type, this.modifiers, this.parent); + else return new ClassProxy(this.name, this.type, this.modifiers, this.containerClass); + } + } +} \ No newline at end of file diff --git a/src/main/java/ftbsc/lll/tools/DescriptorBuilder.java b/src/main/java/ftbsc/lll/tools/DescriptorBuilder.java index d59f97d..252c2a8 100644 --- a/src/main/java/ftbsc/lll/tools/DescriptorBuilder.java +++ b/src/main/java/ftbsc/lll/tools/DescriptorBuilder.java @@ -26,16 +26,16 @@ public class DescriptorBuilder { * Initialises default values. */ public DescriptorBuilder() { - this.returnType = Type.getDescriptor(void.class); this.params = new ArrayList<>(); } /** * Sets the return type to the given type. - * WARNING: will most likely cause problems if used with objects outside the - * Java SDK. Pass the fully qualified name as a String rather than the Class - * object for non-standard types (such as Minecraft classes). + * @implNote Passing a {@link Class} may cause problems if used with objects outside + * the Java SDK. Pass the fully qualified name as a {@link String} rather + * than the {@link Class} object for non-standard types (such as Minecraft + * classes). * @param returnType the Class object corresponding to the return type * @return the builder's state after the change */ @@ -72,9 +72,10 @@ public class DescriptorBuilder { /** * Adds a parameter of the given class type to the method. * Parameter order matters. - * WARNING: will most likely cause problems if used with objects outside the - * Java SDK. Pass the fully qualified name as a String rather than the Class - * object for non-standard types (such as Minecraft classes). + * @implNote Passing a {@link Class} may cause problems if used with objects outside + * the Java SDK. Pass the fully qualified name as a {@link String} rather + * than the {@link Class} object for non-standard types (such as Minecraft + * classes). * @param param the Class object corresponding to the parameter * @return the builder's state after the change */ From 884cefead9e4fede7243650afc4f22f08f8e5090 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 21 Mar 2023 16:32:19 +0100 Subject: [PATCH 4/7] feat: expanded ClassProxies, now all fields and methods include classproxies to represent their parents (as well as parameters and return type for methods) --- .../java/ftbsc/lll/proxies/AbstractProxy.java | 33 +++-- .../java/ftbsc/lll/proxies/ClassProxy.java | 122 ++++++++---------- .../java/ftbsc/lll/proxies/FieldProxy.java | 37 +++++- .../java/ftbsc/lll/proxies/MethodProxy.java | 90 +++++++++---- .../java/ftbsc/lll/proxies/PackageProxy.java | 51 ++++++++ .../ftbsc/lll/proxies/QualifiableProxy.java | 68 ++++++++++ .../lll/tools/nodes/FieldProxyInsnNode.java | 7 +- .../lll/tools/nodes/MethodProxyInsnNode.java | 7 +- 8 files changed, 300 insertions(+), 115 deletions(-) create mode 100644 src/main/java/ftbsc/lll/proxies/PackageProxy.java create mode 100644 src/main/java/ftbsc/lll/proxies/QualifiableProxy.java diff --git a/src/main/java/ftbsc/lll/proxies/AbstractProxy.java b/src/main/java/ftbsc/lll/proxies/AbstractProxy.java index 4dd2a72..93eaec8 100644 --- a/src/main/java/ftbsc/lll/proxies/AbstractProxy.java +++ b/src/main/java/ftbsc/lll/proxies/AbstractProxy.java @@ -14,7 +14,6 @@ public abstract class AbstractProxy { */ public final String name; - /** * The {@link Type} corresponding to this element. */ @@ -24,7 +23,7 @@ public abstract class AbstractProxy { * The fully qualified name (i.e. java.lang.String) of * the parent class. */ - public final String parent; + public final QualifiableProxy parent; /** * The modifiers of the element, as a packed int. @@ -39,13 +38,29 @@ public abstract class AbstractProxy { * @param modifiers the modifiers, as a packed int * @param parent the FQN of the parent class */ - protected AbstractProxy(String name, Type type, int modifiers, String parent) { + protected AbstractProxy(String name, Type type, int modifiers, QualifiableProxy parent) { this.name = name; this.type = type; this.modifiers = modifiers; this.parent = parent; } + /** + * Indicates whether the given object is a proxy for the same element as this. + * @param obj the object to perform + * @return true if it's equal + */ + @Override + public boolean equals(Object obj) { + if(obj instanceof AbstractProxy) { + AbstractProxy p = (AbstractProxy) obj; + return p.parent.equals(this.parent) + && p.name.equals(this.name) + && p.modifiers == this.modifiers + && p.type.equals(this.type); + } else return false; + } + /** * A Builder for the generic proxy. * @param the type of proxy @@ -65,7 +80,7 @@ public abstract class AbstractProxy { /** * The fully qualified name of the parent. */ - protected String parent; + protected QualifiableProxy parent; /** * The {@link Type} corresponding to the element. @@ -81,7 +96,6 @@ public abstract class AbstractProxy { this.modifiers = 0; } - /** * @param newModifier the modifier to add * @return the current state of the builder @@ -101,11 +115,11 @@ public abstract class AbstractProxy { } /** - * @param parentFQN the fully qualified name of the parent + * @param parent the {@link QualifiableProxy} representing the parent * @return the current state of the builder */ - public Builder setParent(String parentFQN) { - this.parent = parentFQN; + public Builder setParent(QualifiableProxy parent) { + this.parent = parent; return this; } @@ -118,7 +132,6 @@ public abstract class AbstractProxy { 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} @@ -128,8 +141,6 @@ public abstract class AbstractProxy { return this.setType(Type.getType(descriptor)); } - - /** * @return the built proxy object */ diff --git a/src/main/java/ftbsc/lll/proxies/ClassProxy.java b/src/main/java/ftbsc/lll/proxies/ClassProxy.java index c369231..41e9bb8 100644 --- a/src/main/java/ftbsc/lll/proxies/ClassProxy.java +++ b/src/main/java/ftbsc/lll/proxies/ClassProxy.java @@ -2,36 +2,25 @@ package ftbsc.lll.proxies; import org.objectweb.asm.Type; +import java.lang.reflect.Modifier; + +import static ftbsc.lll.tools.DescriptorBuilder.nameToDescriptor; + /** * A container for information about classes to be used * in ASM patching. * @since 0.4.0 */ -public class ClassProxy extends AbstractProxy { - - /** - * The fully-qualified name of the class represented by this proxy. - */ - public final String fqn; - - /** - * The {@link ClassProxy} representing the class which contains the - * class represented by this proxy. May be null if the class represented - * by this proxy is not an inner class. - */ - public final ClassProxy containerClass; - +public class ClassProxy extends QualifiableProxy { /** * Protected constructor, called only from the builder. * @param name the name of the class * @param type the {@link Type} of the class * @param modifiers the modifiers of the class - * @param parent the FQN of the parent class of the class + * @param parent the package containing this class */ protected ClassProxy(String name, Type type, int modifiers, String parent) { - super(name, type, modifiers, parent); - this.fqn = String.format("%s.%s", name, parent); - this.containerClass = null; + super(type, modifiers, PackageProxy.from(parent), String.format("%s.%s", name, parent)); } /** @@ -41,31 +30,35 @@ public class ClassProxy extends AbstractProxy { * @param modifiers the modifiers of the class * @param containerClass the FQN of the parent class of the class */ - protected ClassProxy(String name, Type type, int modifiers, ClassProxy containerClass) { - super(name, type, modifiers, containerClass.fqn); - this.fqn = String.format("%s$%s", name, parent); - this.containerClass = containerClass; + protected ClassProxy(String name, Type type, int modifiers, QualifiableProxy containerClass) { + super(type, modifiers, containerClass, String.format("%s$%s", name, containerClass.fullyQualifiedName)); + } + + /** + * Builds a {@link ClassProxy} from a {@link Type} and modifiers. + * @param type the {@link Type} representing this Class + * @param modifiers the modifiers of the class + */ + public static ClassProxy from(Type type, int modifiers) { + String fqn = type.getInternalName().replace('/', '.'); + String simpleName = extractSimpleNameFromFQN(fqn); + String parent = extractParentFromFQN(fqn); + if(fqn.contains("$")) + return new ClassProxy(simpleName, type, modifiers, from(parent, 0, Modifier.PUBLIC)); + else return new ClassProxy(simpleName, type, modifiers, parent); } /** * Builds a {@link ClassProxy} given only the fully-qualified name and modifiers. * @param fqn the fully qualified name of the desired class + * @param arrayLevel the array level for this type * @param modifiers the access modifiers of the desired class + * @implNote If present, parent classes will be assumed to have {@code public} as + * their only modifier. * @return the built {@link ClassProxy} */ - protected static ClassProxy from(String fqn, int modifiers) { - Type type = Type.getObjectType(fqn.replace('.', '/')); - if(fqn.contains("$")) { - String[] split = fqn.split("\\$"); - String simpleName = split[split.length - 1]; - ClassProxy parentClass = from(fqn.replace("$" + simpleName, ""), 0); - return new ClassProxy(simpleName, type, modifiers, parentClass); - } else { - String[] split = fqn.split("\\."); - String simpleName = split[split.length - 1]; - String parent = fqn.replace("." + simpleName, ""); - return new ClassProxy(simpleName, type, modifiers, parent); - } + protected static ClassProxy from(String fqn, int arrayLevel, int modifiers) { + return from(Type.getObjectType(nameToDescriptor(fqn, arrayLevel)), modifiers); } /** @@ -73,8 +66,9 @@ public class ClassProxy extends AbstractProxy { * @param clazz the {@link Class} object representing the target class * @return the built {@link ClassProxy} */ - protected static ClassProxy from(Class clazz) { - if(clazz.getEnclosingClass() == null) + public static ClassProxy from(Class clazz) { + Class parentClass = clazz.getEnclosingClass(); + if(parentClass == null) return new ClassProxy( clazz.getSimpleName(), Type.getType(clazz), @@ -86,7 +80,7 @@ public class ClassProxy extends AbstractProxy { clazz.getSimpleName(), Type.getType(clazz), clazz.getModifiers(), - from(clazz.getEnclosingClass()) + from(parentClass) ); } @@ -99,20 +93,27 @@ public class ClassProxy extends AbstractProxy { return new Builder(name); } + /** + * Indicates whether the given object is a proxy for the same element as this. + * @param obj the object to perform + * @return true if it's equal + */ + @Override + public boolean equals(Object obj) { + return obj instanceof ClassProxy && super.equals(obj); + } + /** * A builder object for {@link ClassProxy}. */ public static class Builder extends AbstractProxy.Builder { - - private ClassProxy containerClass; - + /** * The constructor of the builder, used only internally. * @param name the "simple name" of the class */ Builder(String name) { super(name); - this.containerClass = null; } /** @@ -122,42 +123,33 @@ public class ClassProxy extends AbstractProxy { * container class * @return the builder's state after the change */ - public Builder setContainerClass(Class containerClass) { - this.containerClass = ClassProxy.from(containerClass); - return this; - } - - /** - * Sets this class as an inner class and sets the containing - * class to the given proxy. - * @param containerClass the {@link ClassProxy} representing - * the container class - * @return the builder's state after the change - */ - public Builder setContainerClass(ClassProxy containerClass) { - this.containerClass = containerClass; + public Builder setParent(Class containerClass) { + super.setParent(ClassProxy.from(containerClass)); return this; } /** * Sets this class as an inner class and builds a {@link ClassProxy} * from the given parent and modifiers. - * @param parentFQN the fully qualified name of the parent + * @param parentFQN the fully qualified name of the parent + * @param modifiers the modifiers of the parent (if it's a class) + * @param isParentPackage whether this parent should be interpreted as a package or class * @return the builder's state after the change */ - public Builder setParent(String parentFQN, int modifiers) { - return this.setContainerClass(ClassProxy.from(parentFQN, modifiers)); + public Builder setParent(String parentFQN, int modifiers, boolean isParentPackage) { + super.setParent(isParentPackage ? PackageProxy.from(parentFQN) : ClassProxy.from(parentFQN, 0, modifiers)); + return this; } /** * Sets this class as an inner class and builds a {@link ClassProxy} * from the given parent. - * @param parentFQN the fully qualified name of the parent + * @param parentFQN the fully qualified name of the parent + * @param isParentPackage whether this parent should be interpreted as a package or class * @return the builder's state after the change */ - @Override - public Builder setParent(String parentFQN) { - return this.setParent(parentFQN, 0); + public Builder setParent(String parentFQN, boolean isParentPackage) { + return this.setParent(parentFQN, 0, isParentPackage); } /** @@ -166,9 +158,7 @@ public class ClassProxy extends AbstractProxy { */ @Override public ClassProxy build() { - if(this.containerClass == null) - return new ClassProxy(this.name, this.type, this.modifiers, this.parent); - else return new ClassProxy(this.name, this.type, this.modifiers, this.containerClass); + return new ClassProxy(this.name, this.type, this.modifiers, this.parent); } } } \ No newline at end of file diff --git a/src/main/java/ftbsc/lll/proxies/FieldProxy.java b/src/main/java/ftbsc/lll/proxies/FieldProxy.java index 72a4e40..8855cd8 100644 --- a/src/main/java/ftbsc/lll/proxies/FieldProxy.java +++ b/src/main/java/ftbsc/lll/proxies/FieldProxy.java @@ -16,7 +16,7 @@ public class FieldProxy extends AbstractProxy { * @param f the {@link Field} object corresponding to this. */ public FieldProxy(Field f) { - super(f.getName(), Type.getType(f.getType()), f.getModifiers(), Type.getInternalName(f.getDeclaringClass())); + super(f.getName(), Type.getType(f.getType()), f.getModifiers(), ClassProxy.from(f.getDeclaringClass())); } /** @@ -24,9 +24,9 @@ public class FieldProxy extends AbstractProxy { * @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 parent the {@link QualifiableProxy} for the parent */ - protected FieldProxy(String name, Type type, int modifiers, String parent) { + protected FieldProxy(String name, Type type, int modifiers, QualifiableProxy parent) { super(name, type, modifiers, parent); } @@ -39,6 +39,16 @@ public class FieldProxy extends AbstractProxy { return new Builder(name); } + /** + * Indicates whether the given object is a proxy for the same element as this. + * @param obj the object to perform + * @return true if it's equal + */ + @Override + public boolean equals(Object obj) { + return obj instanceof FieldProxy && super.equals(obj); + } + /** * A builder object for {@link FieldProxy}. */ @@ -51,6 +61,27 @@ public class FieldProxy extends AbstractProxy { super(name); } + /** + * Sets the parent class of this field to the one described by the + * fully qualified name and with the given modifiers. + * @param parentFQN the fully qualified name of the parent + * @return the builder's state after the change + */ + public Builder setParent(String parentFQN, int modifiers) { + super.setParent(ClassProxy.from(parentFQN, 0, modifiers)); + return this; + } + + /** + * Sets the parent class of this field to the one described by the + * fully qualified name. + * @param parentFQN the fully qualified name of the parent + * @return the builder's state after the change + */ + public Builder setParent(String parentFQN) { + return this.setParent(parentFQN, 0); + } + /** * Builds a {@link FieldProxy} of the given kind. * @return the built {@link FieldProxy} diff --git a/src/main/java/ftbsc/lll/proxies/MethodProxy.java b/src/main/java/ftbsc/lll/proxies/MethodProxy.java index 5f80c08..5d014e9 100644 --- a/src/main/java/ftbsc/lll/proxies/MethodProxy.java +++ b/src/main/java/ftbsc/lll/proxies/MethodProxy.java @@ -4,6 +4,7 @@ import org.objectweb.asm.Type; import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static ftbsc.lll.tools.DescriptorBuilder.nameToDescriptor; @@ -16,14 +17,30 @@ import static ftbsc.lll.tools.DescriptorBuilder.nameToDescriptor; public class MethodProxy extends AbstractProxy { /** - * The parameters of the method. + * An array of {@link ClassProxy} each representing the parameters of the method. */ - public final Type[] parameters; + public final ClassProxy[] parameters; /** - * The return type of the method. + * The {@link ClassProxy} for the return type of the method. */ - public final Type returnType; + public final ClassProxy returnType; + + /** + * A protected constructor, called only from the builder. + * @param name the name of the method + * @param modifiers the modifiers of the method + * @param parent the {@link QualifiableProxy} for the parent + * @param parameters the parameters of the method + * @param returnType the return type of the method + */ + protected MethodProxy(String name, int modifiers, QualifiableProxy parent, Type[] parameters, Type returnType) { + super(name, Type.getMethodType(returnType, parameters), modifiers, parent); + this.parameters = Arrays.stream(parameters) + .map(t -> ClassProxy.from(t, 0)) + .toArray(ClassProxy[]::new); + this.returnType = ClassProxy.from(returnType, 0); + } /** * A public constructor, builds a proxy from a {@link Method} @@ -31,24 +48,12 @@ public class MethodProxy extends AbstractProxy { * @param m the {@link Method} object corresponding to this. */ public MethodProxy(Method m) { - 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(); - } - - /** - * A protected constructor, called only from the builder. - * @param name the name of the method - * @param modifiers the modifiers of the method - * @param parent the FQN of the parent class of the method - * @param parameters the parameters of the method - * @param returnType the return type of the method - */ - 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(m.getName(), + m.getModifiers(), + ClassProxy.from(m.getDeclaringClass()), + Type.getArgumentTypes(m), + Type.getReturnType(m) + ); } /** @@ -60,6 +65,19 @@ public class MethodProxy extends AbstractProxy { return new Builder(name); } + /** + * Indicates whether the given object is a proxy for the same element as this. + * @param obj the object to perform + * @return true if it's equal + */ + @Override + public boolean equals(Object obj) { + if(obj instanceof MethodProxy) { + MethodProxy m = (MethodProxy) obj; + return super.equals(obj) && m.returnType.equals(this.returnType) && Arrays.equals(m.parameters, this.parameters); + } else return false; + } + /** * A builder object for {@link MethodProxy}. */ @@ -117,6 +135,27 @@ public class MethodProxy extends AbstractProxy { return this; } + /** + * Sets the parent class of this method to the one described by the + * fully qualified name and with the given modifiers. + * @param parentFQN the fully qualified name of the parent + * @return the builder's state after the change + */ + public Builder setParent(String parentFQN, int modifiers) { + super.setParent(ClassProxy.from(parentFQN, 0, modifiers)); + return this; + } + + /** + * Sets the parent class of this method to the one described by the + * fully qualified name. + * @param parentFQN the fully qualified name of the parent + * @return the builder's state after the change + */ + public Builder setParent(String parentFQN) { + return this.setParent(parentFQN, 0); + } + /** * Sets the return type to the given type. * @param returnType the {@link Class} object corresponding to @@ -134,7 +173,12 @@ public class MethodProxy extends AbstractProxy { */ @Override public MethodProxy build() { - return new MethodProxy(name, modifiers, parent, parameters.toArray(new Type[0]), returnType); + return new MethodProxy( + this.name, + this.modifiers, + this.parent, + this.parameters.toArray(new Type[0]), + this.returnType); } } } diff --git a/src/main/java/ftbsc/lll/proxies/PackageProxy.java b/src/main/java/ftbsc/lll/proxies/PackageProxy.java new file mode 100644 index 0000000..fbfe6c0 --- /dev/null +++ b/src/main/java/ftbsc/lll/proxies/PackageProxy.java @@ -0,0 +1,51 @@ +package ftbsc.lll.proxies; + +/** + * A container for information about a package. + * @since 0.4.0 + */ +public class PackageProxy extends QualifiableProxy { + + /** + * The {@link PackageProxy} representing the root package. + */ + public static final PackageProxy ROOT = new PackageProxy(null, ""); + + /** + * The protected constructor, called only from {@link PackageProxy#from(String)}. + * @param parent the {@link PackageProxy} representing the parent + * @param fqn the fully-qualified name of this package + */ + protected PackageProxy(PackageProxy parent, String fqn) { + super(null, 0, parent, fqn); + } + + /** + * Builds a {@link PackageProxy} from its fully-qualified name. + * @param fqn the fully-qualified name of the package + * @return the built {@link PackageProxy} + */ + protected static PackageProxy from(String fqn) { + if(fqn == null || fqn.equals("")) return ROOT; + return new PackageProxy(from(extractParentFromFQN(fqn)), fqn); + } + + /** + * Builds a {@link PackageProxy} from a reflective {@link Package} object. + * @param p the {@link Package} object + * @return the built {@link PackageProxy} + */ + protected static PackageProxy from(Package p) { + return from(extractParentFromFQN(p.getName())); + } + + /** + * Indicates whether the given object is a proxy for the same element as this. + * @param obj the object to perform + * @return true if it's equal + */ + @Override + public boolean equals(Object obj) { + return obj instanceof PackageProxy && super.equals(obj); + } +} diff --git a/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java b/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java new file mode 100644 index 0000000..2efada8 --- /dev/null +++ b/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java @@ -0,0 +1,68 @@ +package ftbsc.lll.proxies; + +import org.objectweb.asm.Type; + +/** + * A container for information about an element which has a fully-qualified name. + * @see ClassProxy + * @see PackageProxy + * @since 0.4.0 + */ +public abstract class QualifiableProxy extends AbstractProxy { + /** + * The fully-qualified name of the element represented by this proxy. + */ + public final String fullyQualifiedName; + + /** + * The "internal name" (fully-qualified with slashes) of the element + * represented by this proxy. + */ + public final String internalName; + + /** + * The protected constructor, should be called by all classes extending this in theirs. + * @param type the {@link Type} for the element + * @param modifiers the modifiers, as a packed int + * @param parent the {@link QualifiableProxy} representing the parent of this element + * @param fullyQualifiedName the FQN of the element + */ + protected QualifiableProxy(Type type, int modifiers, QualifiableProxy parent, String fullyQualifiedName) { + super(extractSimpleNameFromFQN(fullyQualifiedName), type, modifiers, parent); + this.fullyQualifiedName = fullyQualifiedName; + this.internalName = this.fullyQualifiedName.replace('.', '/'); + } + + /** + * Returns a {@link String} containing the FQN of the parent element + * to this, which may represent a package or class. + * @return the parent, or null if the parent was the root element + */ + protected static String extractParentFromFQN(String fqn) { + String lastSeparator = fqn.contains("$") ? "\\$" : "\\."; + String[] split = fqn.split(lastSeparator); + if(split.length == 1) return null; + return fqn.substring(0, split[split.length - 1].length() - 1); + } + + /** + * Returns a {@link String} containing the simple name of the element + * @return the simple name + */ + protected static String extractSimpleNameFromFQN(String fqn) { + String lastSeparator = fqn.contains("$") ? "\\$" : "\\."; + String[] split = fqn.split(lastSeparator); + if(split.length == 1) return fqn; + else return split[split.length - 1]; + } + + /** + * Indicates whether the given object is a proxy for the same element as this. + * @param obj the object to perform + * @return true if it's equal + */ + @Override + public boolean equals(Object obj) { + return obj instanceof QualifiableProxy && super.equals(obj) && ((QualifiableProxy) obj).fullyQualifiedName.equals(fullyQualifiedName); + } +} diff --git a/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java index d23686d..479e651 100644 --- a/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java +++ b/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java @@ -17,11 +17,6 @@ public class FieldProxyInsnNode extends FieldInsnNode { * @param f a {@link FieldProxy} representing the field to call */ public FieldProxyInsnNode(int opcode, FieldProxy f) { - super( - opcode, - f.parent.replace('.', '/'), - f.name, - f.type.getDescriptor() - ); + super(opcode, f.parent.internalName, f.name, f.type.getDescriptor()); } } diff --git a/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java index 904615d..4fb3b89 100644 --- a/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java +++ b/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java @@ -18,11 +18,6 @@ public class MethodProxyInsnNode extends MethodInsnNode { * @param m a {@link MethodProxy} representing the method to call */ public MethodProxyInsnNode(int opcode, MethodProxy m) { - super( - opcode, - m.parent.replace('.', '/'), - m.name, - m.type.getDescriptor() - ); + super(opcode, m.parent.internalName, m.name, m.type.getDescriptor()); } } From ff47129cf3ac12817bf4ca9af8753592298f03e4 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 21 Mar 2023 18:24:29 +0100 Subject: [PATCH 5/7] feat: restored flat descriptors, implemented primitive proxies --- .../java/ftbsc/lll/proxies/AbstractProxy.java | 36 +++---- .../java/ftbsc/lll/proxies/FieldProxy.java | 12 +-- .../java/ftbsc/lll/proxies/MethodProxy.java | 20 ++-- .../ftbsc/lll/proxies/QualifiableProxy.java | 6 +- .../{ClassProxy.java => TypeProxy.java} | 99 ++++++++++++------- .../lll/tools/nodes/FieldProxyInsnNode.java | 2 +- .../lll/tools/nodes/MethodProxyInsnNode.java | 2 +- .../lll/tools/nodes/TypeProxyInsnNode.java | 23 +++++ 8 files changed, 126 insertions(+), 74 deletions(-) rename src/main/java/ftbsc/lll/proxies/{ClassProxy.java => TypeProxy.java} (54%) create mode 100644 src/main/java/ftbsc/lll/tools/nodes/TypeProxyInsnNode.java diff --git a/src/main/java/ftbsc/lll/proxies/AbstractProxy.java b/src/main/java/ftbsc/lll/proxies/AbstractProxy.java index 93eaec8..d60f3d5 100644 --- a/src/main/java/ftbsc/lll/proxies/AbstractProxy.java +++ b/src/main/java/ftbsc/lll/proxies/AbstractProxy.java @@ -15,9 +15,9 @@ public abstract class AbstractProxy { public final String name; /** - * The {@link Type} corresponding to this element. + * The descriptor for this element. */ - public final Type type; + public final String descriptor; /** * The fully qualified name (i.e. java.lang.String) of @@ -34,13 +34,13 @@ public abstract class AbstractProxy { /** * The private constructor, should be called by all classes extending this in theirs. * @param name the name of the element - * @param type the {@link Type} for the element + * @param descriptor the descriptor for the element * @param modifiers the modifiers, as a packed int * @param parent the FQN of the parent class */ - protected AbstractProxy(String name, Type type, int modifiers, QualifiableProxy parent) { + protected AbstractProxy(String name, String descriptor, int modifiers, QualifiableProxy parent) { this.name = name; - this.type = type; + this.descriptor = descriptor; this.modifiers = modifiers; this.parent = parent; } @@ -57,7 +57,7 @@ public abstract class AbstractProxy { return p.parent.equals(this.parent) && p.name.equals(this.name) && p.modifiers == this.modifiers - && p.type.equals(this.type); + && p.descriptor.equals(this.descriptor); } else return false; } @@ -83,9 +83,9 @@ public abstract class AbstractProxy { protected QualifiableProxy parent; /** - * The {@link Type} corresponding to the element. + * The descriptor of the element. */ - protected Type type; + protected String descriptor; /** * The constructor. @@ -123,22 +123,22 @@ public abstract class AbstractProxy { 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)); + this.descriptor = descriptor; + return this; + } + + /** + * @param type the {@link Type} corresponding to the element + * @return the current state of the builder + */ + public Builder setType(Type type) { + return this.setDescriptor(type.getDescriptor()); } /** diff --git a/src/main/java/ftbsc/lll/proxies/FieldProxy.java b/src/main/java/ftbsc/lll/proxies/FieldProxy.java index 8855cd8..d374bf7 100644 --- a/src/main/java/ftbsc/lll/proxies/FieldProxy.java +++ b/src/main/java/ftbsc/lll/proxies/FieldProxy.java @@ -16,18 +16,18 @@ public class FieldProxy extends AbstractProxy { * @param f the {@link Field} object corresponding to this. */ public FieldProxy(Field f) { - super(f.getName(), Type.getType(f.getType()), f.getModifiers(), ClassProxy.from(f.getDeclaringClass())); + super(f.getName(), Type.getDescriptor(f.getType()), f.getModifiers(), TypeProxy.from(f.getDeclaringClass())); } /** * Protected constructor, called only from the builder. * @param name the name of the field - * @param type the {@link Type} of the field + * @param descriptor the descriptor of the field * @param modifiers the modifiers of the field * @param parent the {@link QualifiableProxy} for the parent */ - protected FieldProxy(String name, Type type, int modifiers, QualifiableProxy parent) { - super(name, type, modifiers, parent); + protected FieldProxy(String name, String descriptor, int modifiers, QualifiableProxy parent) { + super(name, descriptor, modifiers, parent); } /** @@ -68,7 +68,7 @@ public class FieldProxy extends AbstractProxy { * @return the builder's state after the change */ public Builder setParent(String parentFQN, int modifiers) { - super.setParent(ClassProxy.from(parentFQN, 0, modifiers)); + super.setParent(TypeProxy.from(parentFQN, 0, modifiers)); return this; } @@ -88,7 +88,7 @@ public class FieldProxy extends AbstractProxy { */ @Override public FieldProxy build() { - return new FieldProxy(this.name, this.type, this.modifiers, this.parent); + return new FieldProxy(this.name, this.descriptor, 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 5d014e9..b4c329a 100644 --- a/src/main/java/ftbsc/lll/proxies/MethodProxy.java +++ b/src/main/java/ftbsc/lll/proxies/MethodProxy.java @@ -17,14 +17,14 @@ import static ftbsc.lll.tools.DescriptorBuilder.nameToDescriptor; public class MethodProxy extends AbstractProxy { /** - * An array of {@link ClassProxy} each representing the parameters of the method. + * An array of {@link TypeProxy} each representing the parameters of the method. */ - public final ClassProxy[] parameters; + public final TypeProxy[] parameters; /** - * The {@link ClassProxy} for the return type of the method. + * The {@link TypeProxy} for the return type of the method. */ - public final ClassProxy returnType; + public final TypeProxy returnType; /** * A protected constructor, called only from the builder. @@ -35,11 +35,11 @@ public class MethodProxy extends AbstractProxy { * @param returnType the return type of the method */ protected MethodProxy(String name, int modifiers, QualifiableProxy parent, Type[] parameters, Type returnType) { - super(name, Type.getMethodType(returnType, parameters), modifiers, parent); + super(name, Type.getMethodDescriptor(returnType, parameters), modifiers, parent); this.parameters = Arrays.stream(parameters) - .map(t -> ClassProxy.from(t, 0)) - .toArray(ClassProxy[]::new); - this.returnType = ClassProxy.from(returnType, 0); + .map(t -> TypeProxy.from(t, 0)) + .toArray(TypeProxy[]::new); + this.returnType = TypeProxy.from(returnType, 0); } /** @@ -50,7 +50,7 @@ public class MethodProxy extends AbstractProxy { public MethodProxy(Method m) { this(m.getName(), m.getModifiers(), - ClassProxy.from(m.getDeclaringClass()), + TypeProxy.from(m.getDeclaringClass()), Type.getArgumentTypes(m), Type.getReturnType(m) ); @@ -142,7 +142,7 @@ public class MethodProxy extends AbstractProxy { * @return the builder's state after the change */ public Builder setParent(String parentFQN, int modifiers) { - super.setParent(ClassProxy.from(parentFQN, 0, modifiers)); + super.setParent(TypeProxy.from(parentFQN, 0, modifiers)); return this; } diff --git a/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java b/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java index 2efada8..adeb83d 100644 --- a/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java +++ b/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java @@ -4,7 +4,7 @@ import org.objectweb.asm.Type; /** * A container for information about an element which has a fully-qualified name. - * @see ClassProxy + * @see TypeProxy * @see PackageProxy * @since 0.4.0 */ @@ -27,8 +27,8 @@ public abstract class QualifiableProxy extends AbstractProxy { * @param parent the {@link QualifiableProxy} representing the parent of this element * @param fullyQualifiedName the FQN of the element */ - protected QualifiableProxy(Type type, int modifiers, QualifiableProxy parent, String fullyQualifiedName) { - super(extractSimpleNameFromFQN(fullyQualifiedName), type, modifiers, parent); + protected QualifiableProxy(String descriptor, int modifiers, QualifiableProxy parent, String fullyQualifiedName) { + super(extractSimpleNameFromFQN(fullyQualifiedName), descriptor, modifiers, parent); this.fullyQualifiedName = fullyQualifiedName; this.internalName = this.fullyQualifiedName.replace('.', '/'); } diff --git a/src/main/java/ftbsc/lll/proxies/ClassProxy.java b/src/main/java/ftbsc/lll/proxies/TypeProxy.java similarity index 54% rename from src/main/java/ftbsc/lll/proxies/ClassProxy.java rename to src/main/java/ftbsc/lll/proxies/TypeProxy.java index 41e9bb8..d621465 100644 --- a/src/main/java/ftbsc/lll/proxies/ClassProxy.java +++ b/src/main/java/ftbsc/lll/proxies/TypeProxy.java @@ -11,81 +11,93 @@ import static ftbsc.lll.tools.DescriptorBuilder.nameToDescriptor; * in ASM patching. * @since 0.4.0 */ -public class ClassProxy extends QualifiableProxy { +public class TypeProxy extends QualifiableProxy { + /** + * Whether this proxy represents a primitive. + */ + public final boolean primitive; + /** * Protected constructor, called only from the builder. * @param name the name of the class - * @param type the {@link Type} of the class + * @param descriptor the descriptor of the class * @param modifiers the modifiers of the class * @param parent the package containing this class */ - protected ClassProxy(String name, Type type, int modifiers, String parent) { - super(type, modifiers, PackageProxy.from(parent), String.format("%s.%s", name, parent)); + protected TypeProxy(String name, String descriptor, int modifiers, String parent, boolean primitive) { + super(descriptor, modifiers, PackageProxy.from(parent), String.format("%s.%s", name, parent)); + this.primitive = primitive; } /** * Protected constructor, called only from the builder. * @param name the name of the class - * @param type the {@link Type} of the class + * @param descriptor the descriptor of the element * @param modifiers the modifiers of the class * @param containerClass the FQN of the parent class of the class */ - protected ClassProxy(String name, Type type, int modifiers, QualifiableProxy containerClass) { - super(type, modifiers, containerClass, String.format("%s$%s", name, containerClass.fullyQualifiedName)); + protected TypeProxy(String name, String descriptor, int modifiers, QualifiableProxy containerClass, boolean primitive) { + super(descriptor, modifiers, containerClass, String.format("%s$%s", name, containerClass.fullyQualifiedName)); + this.primitive = primitive; } /** - * Builds a {@link ClassProxy} from a {@link Type} and modifiers. + * Builds a {@link TypeProxy} from a {@link Type} and modifiers. * @param type the {@link Type} representing this Class * @param modifiers the modifiers of the class */ - public static ClassProxy from(Type type, int modifiers) { + public static TypeProxy from(Type type, int modifiers) { + while(type.getSort() == Type.ARRAY) + type = type.getElementType(); String fqn = type.getInternalName().replace('/', '.'); String simpleName = extractSimpleNameFromFQN(fqn); String parent = extractParentFromFQN(fqn); + boolean primitive = type.getSort() < Type.ARRAY; if(fqn.contains("$")) - return new ClassProxy(simpleName, type, modifiers, from(parent, 0, Modifier.PUBLIC)); - else return new ClassProxy(simpleName, type, modifiers, parent); + return new TypeProxy(simpleName, type.getDescriptor(), modifiers, from(type, Modifier.PUBLIC), primitive); + else return new TypeProxy(simpleName, type.getDescriptor(), modifiers, parent, primitive); } /** - * Builds a {@link ClassProxy} given only the fully-qualified name and modifiers. + * Builds a {@link TypeProxy} given only the fully-qualified name and modifiers. * @param fqn the fully qualified name of the desired class * @param arrayLevel the array level for this type * @param modifiers the access modifiers of the desired class * @implNote If present, parent classes will be assumed to have {@code public} as * their only modifier. - * @return the built {@link ClassProxy} + * @return the built {@link TypeProxy} */ - protected static ClassProxy from(String fqn, int arrayLevel, int modifiers) { + protected static TypeProxy from(String fqn, int arrayLevel, int modifiers) { return from(Type.getObjectType(nameToDescriptor(fqn, arrayLevel)), modifiers); } /** - * Builds a {@link ClassProxy} from a {@link Class} object. + * Builds a {@link TypeProxy} from a {@link Class} object. * @param clazz the {@link Class} object representing the target class - * @return the built {@link ClassProxy} + * @return the built {@link TypeProxy} */ - public static ClassProxy from(Class clazz) { + public static TypeProxy from(Class clazz) { Class parentClass = clazz.getEnclosingClass(); if(parentClass == null) - return new ClassProxy( + return new TypeProxy( clazz.getSimpleName(), - Type.getType(clazz), + Type.getDescriptor(clazz), clazz.getModifiers(), - clazz.getPackage().getName() + clazz.getPackage().getName(), + clazz.isPrimitive() ); else - return new ClassProxy( + return new TypeProxy( clazz.getSimpleName(), - Type.getType(clazz), + Type.getDescriptor(clazz), clazz.getModifiers(), - from(parentClass) + from(parentClass), + clazz.isPrimitive() ); } /** - * Returns a new instance of {@link ClassProxy.Builder}. + * Returns a new instance of {@link TypeProxy.Builder}. * @param name the name of the class * @return the builder object for class proxies */ @@ -100,13 +112,18 @@ public class ClassProxy extends QualifiableProxy { */ @Override public boolean equals(Object obj) { - return obj instanceof ClassProxy && super.equals(obj); + return obj instanceof TypeProxy && super.equals(obj); } /** - * A builder object for {@link ClassProxy}. + * A builder object for {@link TypeProxy}. */ - public static class Builder extends AbstractProxy.Builder { + public static class Builder extends AbstractProxy.Builder { + + /** + * Whether the proxy represents a primitive. + */ + private boolean primitive; /** * The constructor of the builder, used only internally. @@ -114,6 +131,7 @@ public class ClassProxy extends QualifiableProxy { */ Builder(String name) { super(name); + this.primitive = false; } /** @@ -124,12 +142,12 @@ public class ClassProxy extends QualifiableProxy { * @return the builder's state after the change */ public Builder setParent(Class containerClass) { - super.setParent(ClassProxy.from(containerClass)); + super.setParent(TypeProxy.from(containerClass)); return this; } /** - * Sets this class as an inner class and builds a {@link ClassProxy} + * Sets this class as an inner class and builds a {@link TypeProxy} * from the given parent and modifiers. * @param parentFQN the fully qualified name of the parent * @param modifiers the modifiers of the parent (if it's a class) @@ -137,12 +155,12 @@ public class ClassProxy extends QualifiableProxy { * @return the builder's state after the change */ public Builder setParent(String parentFQN, int modifiers, boolean isParentPackage) { - super.setParent(isParentPackage ? PackageProxy.from(parentFQN) : ClassProxy.from(parentFQN, 0, modifiers)); + super.setParent(isParentPackage ? PackageProxy.from(parentFQN) : TypeProxy.from(parentFQN, 0, modifiers)); return this; } /** - * Sets this class as an inner class and builds a {@link ClassProxy} + * Sets this class as an inner class and builds a {@link TypeProxy} * from the given parent. * @param parentFQN the fully qualified name of the parent * @param isParentPackage whether this parent should be interpreted as a package or class @@ -153,12 +171,23 @@ public class ClassProxy extends QualifiableProxy { } /** - * Builds a {@link ClassProxy} of the given kind. - * @return the built {@link ClassProxy} + * Sets the primitive flag to true or false, to signal that the type here specified + * is a primitive. + * @param primitive the new state of the primitive flag + * @return the builder's state after the change + */ + public Builder setPrimitive(boolean primitive) { + this.primitive = primitive; + return this; + } + + /** + * Builds a {@link TypeProxy} of the given kind. + * @return the built {@link TypeProxy} */ @Override - public ClassProxy build() { - return new ClassProxy(this.name, this.type, this.modifiers, this.parent); + public TypeProxy build() { + return new TypeProxy(this.name, this.descriptor, this.modifiers, this.parent, this.primitive); } } } \ No newline at end of file diff --git a/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java index 479e651..068ade0 100644 --- a/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java +++ b/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java @@ -17,6 +17,6 @@ public class FieldProxyInsnNode extends FieldInsnNode { * @param f a {@link FieldProxy} representing the field to call */ public FieldProxyInsnNode(int opcode, FieldProxy f) { - super(opcode, f.parent.internalName, f.name, f.type.getDescriptor()); + super(opcode, f.parent.internalName, f.name, f.descriptor); } } diff --git a/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java index 4fb3b89..01549a8 100644 --- a/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java +++ b/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java @@ -18,6 +18,6 @@ public class MethodProxyInsnNode extends MethodInsnNode { * @param m a {@link MethodProxy} representing the method to call */ public MethodProxyInsnNode(int opcode, MethodProxy m) { - super(opcode, m.parent.internalName, m.name, m.type.getDescriptor()); + super(opcode, m.parent.internalName, m.name, m.descriptor); } } diff --git a/src/main/java/ftbsc/lll/tools/nodes/TypeProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/TypeProxyInsnNode.java new file mode 100644 index 0000000..e5b5f2a --- /dev/null +++ b/src/main/java/ftbsc/lll/tools/nodes/TypeProxyInsnNode.java @@ -0,0 +1,23 @@ +package ftbsc.lll.tools.nodes; + +import ftbsc.lll.proxies.TypeProxy; +import org.objectweb.asm.tree.TypeInsnNode; + +/** + * Overrides the {@link TypeInsnNode} to add a constructor + * taking in a {@link TypeProxy}. + * @since 0.4.0 + */ +public class TypeProxyInsnNode extends TypeInsnNode { + /** + * Constructs a new {@link TypeInsnNode} starting from a + * {@link TypeProxy}. The user should ensure that the TypeInsnNode + * represents a declared type before calling this. + * @param opcode the opcode, must be one of NEW, ANEWARRAY, + * CHECKCAST or INSTANCEOF + * @param t a {@link TypeProxy} representing the type to call + */ + public TypeProxyInsnNode(int opcode, TypeProxy t) { + super(opcode, t.internalName); + } +} From 7e0b4e58dd9cf0c3d2f1b120ce21fe986d417f82 Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 21 Mar 2023 18:33:53 +0100 Subject: [PATCH 6/7] chore: javadocs --- src/main/java/ftbsc/lll/proxies/FieldProxy.java | 1 + src/main/java/ftbsc/lll/proxies/MethodProxy.java | 1 + .../java/ftbsc/lll/proxies/QualifiableProxy.java | 6 ++++-- src/main/java/ftbsc/lll/proxies/TypeProxy.java | 7 +++++-- .../java/ftbsc/lll/tools/DescriptorBuilder.java | 16 +++++++--------- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/java/ftbsc/lll/proxies/FieldProxy.java b/src/main/java/ftbsc/lll/proxies/FieldProxy.java index d374bf7..8732997 100644 --- a/src/main/java/ftbsc/lll/proxies/FieldProxy.java +++ b/src/main/java/ftbsc/lll/proxies/FieldProxy.java @@ -65,6 +65,7 @@ public class FieldProxy extends AbstractProxy { * Sets the parent class of this field to the one described by the * fully qualified name and with the given modifiers. * @param parentFQN the fully qualified name of the parent + * @param modifiers the modifiers of the parent * @return the builder's state after the change */ public Builder setParent(String parentFQN, int modifiers) { diff --git a/src/main/java/ftbsc/lll/proxies/MethodProxy.java b/src/main/java/ftbsc/lll/proxies/MethodProxy.java index b4c329a..c906ec7 100644 --- a/src/main/java/ftbsc/lll/proxies/MethodProxy.java +++ b/src/main/java/ftbsc/lll/proxies/MethodProxy.java @@ -139,6 +139,7 @@ public class MethodProxy extends AbstractProxy { * Sets the parent class of this method to the one described by the * fully qualified name and with the given modifiers. * @param parentFQN the fully qualified name of the parent + * @param modifiers the modifiers of the parent * @return the builder's state after the change */ public Builder setParent(String parentFQN, int modifiers) { diff --git a/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java b/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java index adeb83d..885ddc8 100644 --- a/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java +++ b/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java @@ -22,7 +22,7 @@ public abstract class QualifiableProxy extends AbstractProxy { /** * The protected constructor, should be called by all classes extending this in theirs. - * @param type the {@link Type} for the element + * @param descriptor the descriptor for the element * @param modifiers the modifiers, as a packed int * @param parent the {@link QualifiableProxy} representing the parent of this element * @param fullyQualifiedName the FQN of the element @@ -36,6 +36,7 @@ public abstract class QualifiableProxy extends AbstractProxy { /** * Returns a {@link String} containing the FQN of the parent element * to this, which may represent a package or class. + * @param fqn the fully qualified name of the element * @return the parent, or null if the parent was the root element */ protected static String extractParentFromFQN(String fqn) { @@ -46,7 +47,8 @@ public abstract class QualifiableProxy extends AbstractProxy { } /** - * Returns a {@link String} containing the simple name of the element + * Returns a {@link String} containing the simple name of the element. + * @param fqn the fully qualified name of the element * @return the simple name */ protected static String extractSimpleNameFromFQN(String fqn) { diff --git a/src/main/java/ftbsc/lll/proxies/TypeProxy.java b/src/main/java/ftbsc/lll/proxies/TypeProxy.java index d621465..f828f11 100644 --- a/src/main/java/ftbsc/lll/proxies/TypeProxy.java +++ b/src/main/java/ftbsc/lll/proxies/TypeProxy.java @@ -23,6 +23,7 @@ public class TypeProxy extends QualifiableProxy { * @param descriptor the descriptor of the class * @param modifiers the modifiers of the class * @param parent the package containing this class + * @param primitive whether the proxy is a primitive */ protected TypeProxy(String name, String descriptor, int modifiers, String parent, boolean primitive) { super(descriptor, modifiers, PackageProxy.from(parent), String.format("%s.%s", name, parent)); @@ -34,6 +35,7 @@ public class TypeProxy extends QualifiableProxy { * @param name the name of the class * @param descriptor the descriptor of the element * @param modifiers the modifiers of the class + * @param primitive whether the proxy is a primitive * @param containerClass the FQN of the parent class of the class */ protected TypeProxy(String name, String descriptor, int modifiers, QualifiableProxy containerClass, boolean primitive) { @@ -45,6 +47,7 @@ public class TypeProxy extends QualifiableProxy { * Builds a {@link TypeProxy} from a {@link Type} and modifiers. * @param type the {@link Type} representing this Class * @param modifiers the modifiers of the class + * @return the builty {@link TypeProxy} */ public static TypeProxy from(Type type, int modifiers) { while(type.getSort() == Type.ARRAY) @@ -60,11 +63,11 @@ public class TypeProxy extends QualifiableProxy { /** * Builds a {@link TypeProxy} given only the fully-qualified name and modifiers. + * If present, parent classes will be assumed to have {@code public} as their + * only modifier. * @param fqn the fully qualified name of the desired class * @param arrayLevel the array level for this type * @param modifiers the access modifiers of the desired class - * @implNote If present, parent classes will be assumed to have {@code public} as - * their only modifier. * @return the built {@link TypeProxy} */ protected static TypeProxy from(String fqn, int arrayLevel, int modifiers) { diff --git a/src/main/java/ftbsc/lll/tools/DescriptorBuilder.java b/src/main/java/ftbsc/lll/tools/DescriptorBuilder.java index 252c2a8..1b33790 100644 --- a/src/main/java/ftbsc/lll/tools/DescriptorBuilder.java +++ b/src/main/java/ftbsc/lll/tools/DescriptorBuilder.java @@ -32,10 +32,9 @@ public class DescriptorBuilder { /** * Sets the return type to the given type. - * @implNote Passing a {@link Class} may cause problems if used with objects outside - * the Java SDK. Pass the fully qualified name as a {@link String} rather - * than the {@link Class} object for non-standard types (such as Minecraft - * classes). + * Passing a {@link Class} may cause problems if used with objects outside the Java + * SDK. Pass the fully qualified name as a {@link String} rather than the {@link Class} + * object for non-standard types. * @param returnType the Class object corresponding to the return type * @return the builder's state after the change */ @@ -72,10 +71,9 @@ public class DescriptorBuilder { /** * Adds a parameter of the given class type to the method. * Parameter order matters. - * @implNote Passing a {@link Class} may cause problems if used with objects outside - * the Java SDK. Pass the fully qualified name as a {@link String} rather - * than the {@link Class} object for non-standard types (such as Minecraft - * classes). + * Passing a {@link Class} may cause problems if used with objects outside the Java + * SDK. Pass the fully qualified name as a {@link String} rather than the {@link Class} + * object for non-standard types. * @param param the Class object corresponding to the parameter * @return the builder's state after the change */ @@ -114,7 +112,7 @@ public class DescriptorBuilder { /** * Builds the descriptor into a string. - * Example result: int m(Object[] o) -> ([Ljava/lang/Object;)I + * Example result: {@code int m(Object[] o)} becomes {@code ([Ljava/lang/Object;)I} * @return the resulting descriptor */ public String build() { From 17a0b4d0172c0b3399fb5ed0ef1f89b41a1fc67f Mon Sep 17 00:00:00 2001 From: zaaarf Date: Tue, 21 Mar 2023 18:46:23 +0100 Subject: [PATCH 7/7] chore: reorganize, add ProxyType enum --- .../java/ftbsc/lll/proxies/AbstractProxy.java | 12 ++++++--- .../java/ftbsc/lll/proxies/ProxyType.java | 11 ++++++++ .../ftbsc/lll/proxies/QualifiableProxy.java | 11 +++----- .../lll/proxies/{ => impl}/FieldProxy.java | 25 +++++++++++-------- .../lll/proxies/{ => impl}/MethodProxy.java | 7 ++++-- .../lll/proxies/{ => impl}/PackageProxy.java | 7 ++++-- .../lll/proxies/{ => impl}/TypeProxy.java | 9 ++++--- .../lll/tools/nodes/FieldProxyInsnNode.java | 2 +- .../lll/tools/nodes/MethodProxyInsnNode.java | 2 +- .../lll/tools/nodes/TypeProxyInsnNode.java | 2 +- 10 files changed, 57 insertions(+), 31 deletions(-) create mode 100644 src/main/java/ftbsc/lll/proxies/ProxyType.java rename src/main/java/ftbsc/lll/proxies/{ => impl}/FieldProxy.java (88%) rename src/main/java/ftbsc/lll/proxies/{ => impl}/MethodProxy.java (96%) rename src/main/java/ftbsc/lll/proxies/{ => impl}/PackageProxy.java (89%) rename src/main/java/ftbsc/lll/proxies/{ => impl}/TypeProxy.java (96%) diff --git a/src/main/java/ftbsc/lll/proxies/AbstractProxy.java b/src/main/java/ftbsc/lll/proxies/AbstractProxy.java index d60f3d5..054cef9 100644 --- a/src/main/java/ftbsc/lll/proxies/AbstractProxy.java +++ b/src/main/java/ftbsc/lll/proxies/AbstractProxy.java @@ -3,12 +3,16 @@ package ftbsc.lll.proxies; import org.objectweb.asm.Type; /** - * Abstract proxy class, implementing common aspects - * of {@link MethodProxy} and {@link FieldProxy}. + * Abstract proxy class, implementing common aspects. * @since 0.3.0 */ public abstract class AbstractProxy { + /** + * Which type of proxy this is. + */ + public final ProxyType proxyType; + /** * The name of the corresponding element. */ @@ -37,12 +41,14 @@ public abstract class AbstractProxy { * @param descriptor the descriptor for the element * @param modifiers the modifiers, as a packed int * @param parent the FQN of the parent class + * @param proxyType the {@link ProxyType} being represented here */ - protected AbstractProxy(String name, String descriptor, int modifiers, QualifiableProxy parent) { + protected AbstractProxy(String name, String descriptor, int modifiers, QualifiableProxy parent, ProxyType proxyType) { this.name = name; this.descriptor = descriptor; this.modifiers = modifiers; this.parent = parent; + this.proxyType = proxyType; } /** diff --git a/src/main/java/ftbsc/lll/proxies/ProxyType.java b/src/main/java/ftbsc/lll/proxies/ProxyType.java new file mode 100644 index 0000000..1fd8169 --- /dev/null +++ b/src/main/java/ftbsc/lll/proxies/ProxyType.java @@ -0,0 +1,11 @@ +package ftbsc.lll.proxies; + +/** + * An enum listing the various proxies. + */ +public enum ProxyType { + FIELD, + METHOD, + TYPE, + PACKAGE +} diff --git a/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java b/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java index 885ddc8..d245124 100644 --- a/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java +++ b/src/main/java/ftbsc/lll/proxies/QualifiableProxy.java @@ -1,11 +1,7 @@ package ftbsc.lll.proxies; -import org.objectweb.asm.Type; - /** - * A container for information about an element which has a fully-qualified name. - * @see TypeProxy - * @see PackageProxy + * A proxy for elements who have a fully-qualified name. * @since 0.4.0 */ public abstract class QualifiableProxy extends AbstractProxy { @@ -26,9 +22,10 @@ public abstract class QualifiableProxy extends AbstractProxy { * @param modifiers the modifiers, as a packed int * @param parent the {@link QualifiableProxy} representing the parent of this element * @param fullyQualifiedName the FQN of the element + * @param proxyType the {@link ProxyType} being represented here */ - protected QualifiableProxy(String descriptor, int modifiers, QualifiableProxy parent, String fullyQualifiedName) { - super(extractSimpleNameFromFQN(fullyQualifiedName), descriptor, modifiers, parent); + protected QualifiableProxy(String descriptor, int modifiers, QualifiableProxy parent, String fullyQualifiedName, ProxyType proxyType) { + super(extractSimpleNameFromFQN(fullyQualifiedName), descriptor, modifiers, parent, proxyType); this.fullyQualifiedName = fullyQualifiedName; this.internalName = this.fullyQualifiedName.replace('.', '/'); } diff --git a/src/main/java/ftbsc/lll/proxies/FieldProxy.java b/src/main/java/ftbsc/lll/proxies/impl/FieldProxy.java similarity index 88% rename from src/main/java/ftbsc/lll/proxies/FieldProxy.java rename to src/main/java/ftbsc/lll/proxies/impl/FieldProxy.java index 8732997..ceb8277 100644 --- a/src/main/java/ftbsc/lll/proxies/FieldProxy.java +++ b/src/main/java/ftbsc/lll/proxies/impl/FieldProxy.java @@ -1,5 +1,8 @@ -package ftbsc.lll.proxies; +package ftbsc.lll.proxies.impl; +import ftbsc.lll.proxies.AbstractProxy; +import ftbsc.lll.proxies.ProxyType; +import ftbsc.lll.proxies.QualifiableProxy; import org.objectweb.asm.Type; import java.lang.reflect.Field; @@ -10,15 +13,6 @@ import java.lang.reflect.Field; * @since 0.3.0 */ public class FieldProxy extends AbstractProxy { - /** - * 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(), Type.getDescriptor(f.getType()), f.getModifiers(), TypeProxy.from(f.getDeclaringClass())); - } - /** * Protected constructor, called only from the builder. * @param name the name of the field @@ -27,7 +21,16 @@ public class FieldProxy extends AbstractProxy { * @param parent the {@link QualifiableProxy} for the parent */ protected FieldProxy(String name, String descriptor, int modifiers, QualifiableProxy parent) { - super(name, descriptor, modifiers, parent); + super(name, descriptor, modifiers, parent, ProxyType.FIELD); + } + + /** + * 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) { + this(f.getName(), Type.getDescriptor(f.getType()), f.getModifiers(), TypeProxy.from(f.getDeclaringClass())); } /** diff --git a/src/main/java/ftbsc/lll/proxies/MethodProxy.java b/src/main/java/ftbsc/lll/proxies/impl/MethodProxy.java similarity index 96% rename from src/main/java/ftbsc/lll/proxies/MethodProxy.java rename to src/main/java/ftbsc/lll/proxies/impl/MethodProxy.java index c906ec7..3710d36 100644 --- a/src/main/java/ftbsc/lll/proxies/MethodProxy.java +++ b/src/main/java/ftbsc/lll/proxies/impl/MethodProxy.java @@ -1,5 +1,8 @@ -package ftbsc.lll.proxies; +package ftbsc.lll.proxies.impl; +import ftbsc.lll.proxies.AbstractProxy; +import ftbsc.lll.proxies.ProxyType; +import ftbsc.lll.proxies.QualifiableProxy; import org.objectweb.asm.Type; import java.lang.reflect.Method; @@ -35,7 +38,7 @@ public class MethodProxy extends AbstractProxy { * @param returnType the return type of the method */ protected MethodProxy(String name, int modifiers, QualifiableProxy parent, Type[] parameters, Type returnType) { - super(name, Type.getMethodDescriptor(returnType, parameters), modifiers, parent); + super(name, Type.getMethodDescriptor(returnType, parameters), modifiers, parent, ProxyType.METHOD); this.parameters = Arrays.stream(parameters) .map(t -> TypeProxy.from(t, 0)) .toArray(TypeProxy[]::new); diff --git a/src/main/java/ftbsc/lll/proxies/PackageProxy.java b/src/main/java/ftbsc/lll/proxies/impl/PackageProxy.java similarity index 89% rename from src/main/java/ftbsc/lll/proxies/PackageProxy.java rename to src/main/java/ftbsc/lll/proxies/impl/PackageProxy.java index fbfe6c0..5989da3 100644 --- a/src/main/java/ftbsc/lll/proxies/PackageProxy.java +++ b/src/main/java/ftbsc/lll/proxies/impl/PackageProxy.java @@ -1,4 +1,7 @@ -package ftbsc.lll.proxies; +package ftbsc.lll.proxies.impl; + +import ftbsc.lll.proxies.ProxyType; +import ftbsc.lll.proxies.QualifiableProxy; /** * A container for information about a package. @@ -17,7 +20,7 @@ public class PackageProxy extends QualifiableProxy { * @param fqn the fully-qualified name of this package */ protected PackageProxy(PackageProxy parent, String fqn) { - super(null, 0, parent, fqn); + super(null, 0, parent, fqn, ProxyType.PACKAGE); } /** diff --git a/src/main/java/ftbsc/lll/proxies/TypeProxy.java b/src/main/java/ftbsc/lll/proxies/impl/TypeProxy.java similarity index 96% rename from src/main/java/ftbsc/lll/proxies/TypeProxy.java rename to src/main/java/ftbsc/lll/proxies/impl/TypeProxy.java index f828f11..9f613b0 100644 --- a/src/main/java/ftbsc/lll/proxies/TypeProxy.java +++ b/src/main/java/ftbsc/lll/proxies/impl/TypeProxy.java @@ -1,5 +1,8 @@ -package ftbsc.lll.proxies; +package ftbsc.lll.proxies.impl; +import ftbsc.lll.proxies.AbstractProxy; +import ftbsc.lll.proxies.ProxyType; +import ftbsc.lll.proxies.QualifiableProxy; import org.objectweb.asm.Type; import java.lang.reflect.Modifier; @@ -26,7 +29,7 @@ public class TypeProxy extends QualifiableProxy { * @param primitive whether the proxy is a primitive */ protected TypeProxy(String name, String descriptor, int modifiers, String parent, boolean primitive) { - super(descriptor, modifiers, PackageProxy.from(parent), String.format("%s.%s", name, parent)); + super(descriptor, modifiers, PackageProxy.from(parent), String.format("%s.%s", name, parent), ProxyType.TYPE); this.primitive = primitive; } @@ -39,7 +42,7 @@ public class TypeProxy extends QualifiableProxy { * @param containerClass the FQN of the parent class of the class */ protected TypeProxy(String name, String descriptor, int modifiers, QualifiableProxy containerClass, boolean primitive) { - super(descriptor, modifiers, containerClass, String.format("%s$%s", name, containerClass.fullyQualifiedName)); + super(descriptor, modifiers, containerClass, String.format("%s$%s", name, containerClass.fullyQualifiedName), ProxyType.TYPE); this.primitive = primitive; } diff --git a/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java index 068ade0..d1ac595 100644 --- a/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java +++ b/src/main/java/ftbsc/lll/tools/nodes/FieldProxyInsnNode.java @@ -1,6 +1,6 @@ package ftbsc.lll.tools.nodes; -import ftbsc.lll.proxies.FieldProxy; +import ftbsc.lll.proxies.impl.FieldProxy; import org.objectweb.asm.tree.FieldInsnNode; /** diff --git a/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java index 01549a8..73a26d7 100644 --- a/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java +++ b/src/main/java/ftbsc/lll/tools/nodes/MethodProxyInsnNode.java @@ -1,6 +1,6 @@ package ftbsc.lll.tools.nodes; -import ftbsc.lll.proxies.MethodProxy; +import ftbsc.lll.proxies.impl.MethodProxy; import org.objectweb.asm.tree.MethodInsnNode; /** diff --git a/src/main/java/ftbsc/lll/tools/nodes/TypeProxyInsnNode.java b/src/main/java/ftbsc/lll/tools/nodes/TypeProxyInsnNode.java index e5b5f2a..9e78dc9 100644 --- a/src/main/java/ftbsc/lll/tools/nodes/TypeProxyInsnNode.java +++ b/src/main/java/ftbsc/lll/tools/nodes/TypeProxyInsnNode.java @@ -1,6 +1,6 @@ package ftbsc.lll.tools.nodes; -import ftbsc.lll.proxies.TypeProxy; +import ftbsc.lll.proxies.impl.TypeProxy; import org.objectweb.asm.tree.TypeInsnNode; /**