mirror of
https://github.com/zaaarf/lillero.git
synced 2024-11-21 23:14:51 +01:00
feat: added ClassProxy
This commit is contained in:
parent
8c11b0b4d8
commit
40686b8c92
2 changed files with 182 additions and 7 deletions
174
src/main/java/ftbsc/lll/proxies/ClassProxy.java
Normal file
174
src/main/java/ftbsc/lll/proxies/ClassProxy.java
Normal file
|
@ -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<ClassProxy> {
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,16 +26,16 @@ public class DescriptorBuilder {
|
||||||
* Initialises default values.
|
* Initialises default values.
|
||||||
*/
|
*/
|
||||||
public DescriptorBuilder() {
|
public DescriptorBuilder() {
|
||||||
|
|
||||||
this.returnType = Type.getDescriptor(void.class);
|
this.returnType = Type.getDescriptor(void.class);
|
||||||
this.params = new ArrayList<>();
|
this.params = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the return type to the given type.
|
* Sets the return type to the given type.
|
||||||
* WARNING: will most likely cause problems if used with objects outside the
|
* @implNote Passing a {@link Class} may cause problems if used with objects outside
|
||||||
* Java SDK. Pass the fully qualified name as a String rather than the Class
|
* the Java SDK. Pass the fully qualified name as a {@link String} rather
|
||||||
* object for non-standard types (such as Minecraft classes).
|
* than the {@link Class} object for non-standard types (such as Minecraft
|
||||||
|
* classes).
|
||||||
* @param returnType the Class object corresponding to the return type
|
* @param returnType the Class object corresponding to the return type
|
||||||
* @return the builder's state after the change
|
* @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.
|
* Adds a parameter of the given class type to the method.
|
||||||
* Parameter order matters.
|
* Parameter order matters.
|
||||||
* WARNING: will most likely cause problems if used with objects outside the
|
* @implNote Passing a {@link Class} may cause problems if used with objects outside
|
||||||
* Java SDK. Pass the fully qualified name as a String rather than the Class
|
* the Java SDK. Pass the fully qualified name as a {@link String} rather
|
||||||
* object for non-standard types (such as Minecraft classes).
|
* than the {@link Class} object for non-standard types (such as Minecraft
|
||||||
|
* classes).
|
||||||
* @param param the Class object corresponding to the parameter
|
* @param param the Class object corresponding to the parameter
|
||||||
* @return the builder's state after the change
|
* @return the builder's state after the change
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue