mirror of
https://github.com/zaaarf/lillero.git
synced 2024-11-10 01:29:22 +01:00
feat: expanded ClassProxies, now all fields and methods include classproxies to represent their parents (as well as parameters and return type for methods)
This commit is contained in:
parent
40686b8c92
commit
884cefead9
8 changed files with 300 additions and 115 deletions
|
@ -14,7 +14,6 @@ public abstract class AbstractProxy {
|
||||||
*/
|
*/
|
||||||
public final String name;
|
public final String name;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Type} corresponding to this element.
|
* 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 fully qualified name (i.e. java.lang.String) of
|
||||||
* the parent class.
|
* the parent class.
|
||||||
*/
|
*/
|
||||||
public final String parent;
|
public final QualifiableProxy parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The modifiers of the element, as a packed int.
|
* 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 modifiers the modifiers, as a packed int
|
||||||
* @param parent the FQN of the parent class
|
* @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.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.modifiers = modifiers;
|
this.modifiers = modifiers;
|
||||||
this.parent = parent;
|
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.
|
* A Builder for the generic proxy.
|
||||||
* @param <T> the type of proxy
|
* @param <T> the type of proxy
|
||||||
|
@ -65,7 +80,7 @@ public abstract class AbstractProxy {
|
||||||
/**
|
/**
|
||||||
* The fully qualified name of the parent.
|
* The fully qualified name of the parent.
|
||||||
*/
|
*/
|
||||||
protected String parent;
|
protected QualifiableProxy parent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link Type} corresponding to the element.
|
* The {@link Type} corresponding to the element.
|
||||||
|
@ -81,7 +96,6 @@ public abstract class AbstractProxy {
|
||||||
this.modifiers = 0;
|
this.modifiers = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param newModifier the modifier to add
|
* @param newModifier the modifier to add
|
||||||
* @return the current state of the builder
|
* @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
|
* @return the current state of the builder
|
||||||
*/
|
*/
|
||||||
public Builder<T> setParent(String parentFQN) {
|
public Builder<T> setParent(QualifiableProxy parent) {
|
||||||
this.parent = parentFQN;
|
this.parent = parent;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +132,6 @@ public abstract class AbstractProxy {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets {@link Type} for this element from the descriptor, passed as a {@link String}.
|
* Sets {@link Type} for this element from the descriptor, passed as a {@link String}.
|
||||||
* @param descriptor 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 this.setType(Type.getType(descriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the built proxy object
|
* @return the built proxy object
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,36 +2,25 @@ package ftbsc.lll.proxies;
|
||||||
|
|
||||||
import org.objectweb.asm.Type;
|
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
|
* A container for information about classes to be used
|
||||||
* in ASM patching.
|
* in ASM patching.
|
||||||
* @since 0.4.0
|
* @since 0.4.0
|
||||||
*/
|
*/
|
||||||
public class ClassProxy extends AbstractProxy {
|
public class ClassProxy extends QualifiableProxy {
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
* Protected constructor, called only from the builder.
|
||||||
* @param name the name of the class
|
* @param name the name of the class
|
||||||
* @param type the {@link Type} of the class
|
* @param type the {@link Type} of the class
|
||||||
* @param modifiers the modifiers 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) {
|
protected ClassProxy(String name, Type type, int modifiers, String parent) {
|
||||||
super(name, type, modifiers, parent);
|
super(type, modifiers, PackageProxy.from(parent), String.format("%s.%s", name, parent));
|
||||||
this.fqn = String.format("%s.%s", name, parent);
|
|
||||||
this.containerClass = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -41,31 +30,35 @@ public class ClassProxy extends AbstractProxy {
|
||||||
* @param modifiers the modifiers of the class
|
* @param modifiers the modifiers of the class
|
||||||
* @param containerClass the FQN of the parent class of the class
|
* @param containerClass the FQN of the parent class of the class
|
||||||
*/
|
*/
|
||||||
protected ClassProxy(String name, Type type, int modifiers, ClassProxy containerClass) {
|
protected ClassProxy(String name, Type type, int modifiers, QualifiableProxy containerClass) {
|
||||||
super(name, type, modifiers, containerClass.fqn);
|
super(type, modifiers, containerClass, String.format("%s$%s", name, containerClass.fullyQualifiedName));
|
||||||
this.fqn = String.format("%s$%s", name, parent);
|
}
|
||||||
this.containerClass = containerClass;
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Builds a {@link ClassProxy} given only the fully-qualified name and modifiers.
|
||||||
* @param fqn the fully qualified name of the desired class
|
* @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
|
* @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 ClassProxy}
|
||||||
*/
|
*/
|
||||||
protected static ClassProxy from(String fqn, int modifiers) {
|
protected static ClassProxy from(String fqn, int arrayLevel, int modifiers) {
|
||||||
Type type = Type.getObjectType(fqn.replace('.', '/'));
|
return from(Type.getObjectType(nameToDescriptor(fqn, arrayLevel)), modifiers);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,8 +66,9 @@ public class ClassProxy extends AbstractProxy {
|
||||||
* @param clazz the {@link Class} object representing the target class
|
* @param clazz the {@link Class} object representing the target class
|
||||||
* @return the built {@link ClassProxy}
|
* @return the built {@link ClassProxy}
|
||||||
*/
|
*/
|
||||||
protected static ClassProxy from(Class<?> clazz) {
|
public static ClassProxy from(Class<?> clazz) {
|
||||||
if(clazz.getEnclosingClass() == null)
|
Class<?> parentClass = clazz.getEnclosingClass();
|
||||||
|
if(parentClass == null)
|
||||||
return new ClassProxy(
|
return new ClassProxy(
|
||||||
clazz.getSimpleName(),
|
clazz.getSimpleName(),
|
||||||
Type.getType(clazz),
|
Type.getType(clazz),
|
||||||
|
@ -86,7 +80,7 @@ public class ClassProxy extends AbstractProxy {
|
||||||
clazz.getSimpleName(),
|
clazz.getSimpleName(),
|
||||||
Type.getType(clazz),
|
Type.getType(clazz),
|
||||||
clazz.getModifiers(),
|
clazz.getModifiers(),
|
||||||
from(clazz.getEnclosingClass())
|
from(parentClass)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,20 +93,27 @@ public class ClassProxy extends AbstractProxy {
|
||||||
return new Builder(name);
|
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}.
|
* A builder object for {@link ClassProxy}.
|
||||||
*/
|
*/
|
||||||
public static class Builder extends AbstractProxy.Builder<ClassProxy> {
|
public static class Builder extends AbstractProxy.Builder<ClassProxy> {
|
||||||
|
|
||||||
private ClassProxy containerClass;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor of the builder, used only internally.
|
* The constructor of the builder, used only internally.
|
||||||
* @param name the "simple name" of the class
|
* @param name the "simple name" of the class
|
||||||
*/
|
*/
|
||||||
Builder(String name) {
|
Builder(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
this.containerClass = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -122,42 +123,33 @@ public class ClassProxy extends AbstractProxy {
|
||||||
* container class
|
* container class
|
||||||
* @return the builder's state after the change
|
* @return the builder's state after the change
|
||||||
*/
|
*/
|
||||||
public Builder setContainerClass(Class<?> containerClass) {
|
public Builder setParent(Class<?> containerClass) {
|
||||||
this.containerClass = ClassProxy.from(containerClass);
|
super.setParent(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;
|
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 ClassProxy}
|
||||||
* from the given parent and modifiers.
|
* 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
|
* @return the builder's state after the change
|
||||||
*/
|
*/
|
||||||
public Builder setParent(String parentFQN, int modifiers) {
|
public Builder setParent(String parentFQN, int modifiers, boolean isParentPackage) {
|
||||||
return this.setContainerClass(ClassProxy.from(parentFQN, modifiers));
|
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}
|
* Sets this class as an inner class and builds a {@link ClassProxy}
|
||||||
* from the given parent.
|
* 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
|
* @return the builder's state after the change
|
||||||
*/
|
*/
|
||||||
@Override
|
public Builder setParent(String parentFQN, boolean isParentPackage) {
|
||||||
public Builder setParent(String parentFQN) {
|
return this.setParent(parentFQN, 0, isParentPackage);
|
||||||
return this.setParent(parentFQN, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -166,9 +158,7 @@ public class ClassProxy extends AbstractProxy {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ClassProxy build() {
|
public ClassProxy build() {
|
||||||
if(this.containerClass == null)
|
return new ClassProxy(this.name, this.type, this.modifiers, this.parent);
|
||||||
return new ClassProxy(this.name, this.type, this.modifiers, this.parent);
|
|
||||||
else return new ClassProxy(this.name, this.type, this.modifiers, this.containerClass);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@ public class FieldProxy extends AbstractProxy {
|
||||||
* @param f the {@link Field} object corresponding to this.
|
* @param f the {@link Field} object corresponding to this.
|
||||||
*/
|
*/
|
||||||
public FieldProxy(Field f) {
|
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 name the name of the field
|
||||||
* @param type the {@link Type} of the field
|
* @param type the {@link Type} of the field
|
||||||
* @param modifiers the modifiers 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);
|
super(name, type, modifiers, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,6 +39,16 @@ public class FieldProxy extends AbstractProxy {
|
||||||
return new Builder(name);
|
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}.
|
* A builder object for {@link FieldProxy}.
|
||||||
*/
|
*/
|
||||||
|
@ -51,6 +61,27 @@ public class FieldProxy extends AbstractProxy {
|
||||||
super(name);
|
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.
|
* Builds a {@link FieldProxy} of the given kind.
|
||||||
* @return the built {@link FieldProxy}
|
* @return the built {@link FieldProxy}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static ftbsc.lll.tools.DescriptorBuilder.nameToDescriptor;
|
import static ftbsc.lll.tools.DescriptorBuilder.nameToDescriptor;
|
||||||
|
@ -16,14 +17,30 @@ import static ftbsc.lll.tools.DescriptorBuilder.nameToDescriptor;
|
||||||
public class MethodProxy extends AbstractProxy {
|
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}
|
* 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.
|
* @param m the {@link Method} object corresponding to this.
|
||||||
*/
|
*/
|
||||||
public MethodProxy(Method m) {
|
public MethodProxy(Method m) {
|
||||||
super(m.getName(), Type.getType(m), m.getModifiers(), Type.getInternalName(m.getDeclaringClass()));
|
this(m.getName(),
|
||||||
Type mt = Type.getType(m);
|
m.getModifiers(),
|
||||||
this.parameters = mt.getArgumentTypes();
|
ClassProxy.from(m.getDeclaringClass()),
|
||||||
this.returnType = mt.getReturnType();
|
Type.getArgumentTypes(m),
|
||||||
}
|
Type.getReturnType(m)
|
||||||
|
);
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,6 +65,19 @@ public class MethodProxy extends AbstractProxy {
|
||||||
return new Builder(name);
|
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}.
|
* A builder object for {@link MethodProxy}.
|
||||||
*/
|
*/
|
||||||
|
@ -117,6 +135,27 @@ public class MethodProxy extends AbstractProxy {
|
||||||
return this;
|
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.
|
* Sets the return type to the given type.
|
||||||
* @param returnType the {@link Class} object corresponding to
|
* @param returnType the {@link Class} object corresponding to
|
||||||
|
@ -134,7 +173,12 @@ public class MethodProxy extends AbstractProxy {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public MethodProxy build() {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
51
src/main/java/ftbsc/lll/proxies/PackageProxy.java
Normal file
51
src/main/java/ftbsc/lll/proxies/PackageProxy.java
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
68
src/main/java/ftbsc/lll/proxies/QualifiableProxy.java
Normal file
68
src/main/java/ftbsc/lll/proxies/QualifiableProxy.java
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,11 +17,6 @@ public class FieldProxyInsnNode extends FieldInsnNode {
|
||||||
* @param f a {@link FieldProxy} representing the field to call
|
* @param f a {@link FieldProxy} representing the field to call
|
||||||
*/
|
*/
|
||||||
public FieldProxyInsnNode(int opcode, FieldProxy f) {
|
public FieldProxyInsnNode(int opcode, FieldProxy f) {
|
||||||
super(
|
super(opcode, f.parent.internalName, f.name, f.type.getDescriptor());
|
||||||
opcode,
|
|
||||||
f.parent.replace('.', '/'),
|
|
||||||
f.name,
|
|
||||||
f.type.getDescriptor()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,6 @@ public class MethodProxyInsnNode extends MethodInsnNode {
|
||||||
* @param m a {@link MethodProxy} representing the method to call
|
* @param m a {@link MethodProxy} representing the method to call
|
||||||
*/
|
*/
|
||||||
public MethodProxyInsnNode(int opcode, MethodProxy m) {
|
public MethodProxyInsnNode(int opcode, MethodProxy m) {
|
||||||
super(
|
super(opcode, m.parent.internalName, m.name, m.type.getDescriptor());
|
||||||
opcode,
|
|
||||||
m.parent.replace('.', '/'),
|
|
||||||
m.name,
|
|
||||||
m.type.getDescriptor()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue