105 lines
3.6 KiB
Java
105 lines
3.6 KiB
Java
package dev.pfaff.recipe_nope.injector.util;
|
|
|
|
import net.fabricmc.loader.api.FabricLoader;
|
|
import net.fabricmc.loader.api.MappingResolver;
|
|
import org.objectweb.asm.Opcodes;
|
|
import org.objectweb.asm.Type;
|
|
|
|
import java.lang.invoke.MethodHandle;
|
|
import java.lang.invoke.MethodHandles;
|
|
import java.lang.invoke.MethodType;
|
|
|
|
public final class ReflectUtil {
|
|
public static final MappingResolver RESOLVER = FabricLoader.getInstance().getMappingResolver();
|
|
|
|
public static String typeDescriptor(String qualifiedName, boolean unmap) {
|
|
if (unmap) qualifiedName = unresolveClass(qualifiedName);
|
|
return 'L' + qualifiedName.replace('.', '/') + ';';
|
|
}
|
|
|
|
public static String typeDescriptor(Class<?> clazz, boolean unmap) {
|
|
if (clazz.isPrimitive()) {
|
|
if (clazz == void.class) return "V";
|
|
if (clazz == boolean.class) return "Z";
|
|
if (clazz == byte.class) return "B";
|
|
if (clazz == short.class) return "S";
|
|
if (clazz == int.class) return "I";
|
|
if (clazz == long.class) return "J";
|
|
if (clazz == float.class) return "F";
|
|
if (clazz == double.class) return "D";
|
|
if (clazz == char.class) return "C";
|
|
throw new AssertionError();
|
|
}
|
|
|
|
if (clazz.isArray()) {
|
|
return '[' + typeDescriptor(clazz.componentType(), unmap);
|
|
}
|
|
|
|
return typeDescriptor(clazz.getName(), unmap);
|
|
}
|
|
|
|
public static int varInsn(Type type, int base) {
|
|
if (type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY) {
|
|
return base + 4;
|
|
}
|
|
|
|
if (type == Type.VOID_TYPE) return -1;
|
|
if (type == Type.BOOLEAN_TYPE || type == Type.BYTE_TYPE || type == Type.SHORT_TYPE || type == Type.CHAR_TYPE || type == Type.INT_TYPE) return base + 0;
|
|
if (type == Type.LONG_TYPE) return base + 1;
|
|
if (type == Type.FLOAT_TYPE) return base + 2;
|
|
if (type == Type.DOUBLE_TYPE) return base + 3;
|
|
throw new AssertionError();
|
|
}
|
|
|
|
public static int varLoadInsn(Type type) {
|
|
return varInsn(type, Opcodes.ILOAD);
|
|
}
|
|
|
|
public static int varStoreInsn(Type type) {
|
|
return varInsn(type, Opcodes.ISTORE);
|
|
}
|
|
|
|
public static String methodDescriptor(MethodType mt, boolean unmap) {
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.append('(');
|
|
for (int i = 0; i < mt.parameterCount(); i++) {
|
|
sb.append(typeDescriptor(mt.parameterType(i), unmap));
|
|
}
|
|
sb.append(')');
|
|
sb.append(typeDescriptor(mt.returnType(), unmap));
|
|
return sb.toString();
|
|
}
|
|
|
|
public static String resolveClassName(String intermediaryName) {
|
|
return RESOLVER.mapClassName("intermediary", intermediaryName);
|
|
}
|
|
|
|
public static String unresolveClass(String qualifiedName) {
|
|
return RESOLVER.unmapClassName("intermediary", qualifiedName);
|
|
}
|
|
|
|
public static String unresolveClass(Class<?> clazz) {
|
|
return unresolveClass(clazz.getName());
|
|
}
|
|
|
|
public static String resolveMethodName(Class<?> owner, String intermediaryName, MethodType mt) {
|
|
return RESOLVER.mapMethodName("intermediary", unresolveClass(owner), intermediaryName, methodDescriptor(mt, true));
|
|
}
|
|
|
|
public static String resolveFieldName(Class<?> owner, String intermediaryName, MethodType mt) {
|
|
return RESOLVER.mapFieldName("intermediary", unresolveClass(owner), intermediaryName, methodDescriptor(mt, true));
|
|
}
|
|
|
|
public static MethodHandle findVirtual(MethodHandles.Lookup lookup, Class<?> clazz, String intermediaryName, MethodType mt)
|
|
throws ReflectiveOperationException {
|
|
return lookup.findVirtual(clazz, resolveMethodName(clazz, intermediaryName, mt), mt);
|
|
}
|
|
|
|
public static MethodHandle findStatic(MethodHandles.Lookup lookup, Class<?> clazz, String intermediaryName, MethodType mt)
|
|
throws ReflectiveOperationException {
|
|
return lookup.findStatic(clazz, resolveMethodName(clazz, intermediaryName, mt), mt);
|
|
}
|
|
|
|
private ReflectUtil() {}
|
|
}
|