2022-02-07 12:45:18 +01:00
|
|
|
package fr.pandacube.lib.paper.reflect;
|
|
|
|
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.StringReader;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.Objects;
|
|
|
|
|
2022-07-28 01:11:28 +02:00
|
|
|
import fr.pandacube.lib.reflect.ReflectClass;
|
2022-02-07 12:45:18 +01:00
|
|
|
import fr.pandacube.lib.paper.reflect.NMSReflect.ClassMapping;
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
/* package */ class NMSTypeWrapper implements Comparable<NMSTypeWrapper> {
|
2022-02-07 12:45:18 +01:00
|
|
|
private final String type;
|
|
|
|
private final int arrayDepth;
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
/* package */ NMSTypeWrapper(String type, int arrayDepth) {
|
2022-02-07 12:45:18 +01:00
|
|
|
this.type = type;
|
|
|
|
this.arrayDepth = arrayDepth;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj) {
|
2022-07-20 16:26:29 +02:00
|
|
|
return obj instanceof NMSTypeWrapper ot && type.equals(ot.type) && arrayDepth == ot.arrayDepth;
|
2022-02-07 12:45:18 +01:00
|
|
|
}
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
return type.hashCode() ^ arrayDepth;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2022-07-20 16:26:29 +02:00
|
|
|
public int compareTo(NMSTypeWrapper o) {
|
2022-02-07 12:45:18 +01:00
|
|
|
return toString().compareTo(o.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
Class<?> toClass() throws ClassNotFoundException {
|
|
|
|
|
|
|
|
Class<?> cl = switch(type) {
|
|
|
|
case "boolean" -> boolean.class;
|
|
|
|
case "byte" -> byte.class;
|
|
|
|
case "char" -> char.class;
|
|
|
|
case "double" -> double.class;
|
|
|
|
case "float" -> float.class;
|
|
|
|
case "int" -> int.class;
|
|
|
|
case "long" -> long.class;
|
|
|
|
case "short" -> short.class;
|
|
|
|
case "void" -> void.class;
|
|
|
|
default -> Class.forName(type);
|
|
|
|
};
|
|
|
|
|
|
|
|
for (int i = 0; i < arrayDepth; i++) {
|
|
|
|
cl = cl.arrayType();
|
|
|
|
}
|
|
|
|
|
|
|
|
return cl;
|
|
|
|
}
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
/* package */ static NMSTypeWrapper of(Class<?> cl) {
|
2022-02-07 12:45:18 +01:00
|
|
|
int arrayDepth = 0;
|
|
|
|
while (cl.isArray()) {
|
|
|
|
cl = cl.getComponentType();
|
|
|
|
arrayDepth++;
|
|
|
|
}
|
2022-07-20 16:26:29 +02:00
|
|
|
return new NMSTypeWrapper(cl.getName(), arrayDepth);
|
2022-02-07 12:45:18 +01:00
|
|
|
}
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
public static NMSTypeWrapper of(ReflectClass<?> rc) {
|
2022-02-07 12:45:18 +01:00
|
|
|
return arrayOf(rc, 0);
|
|
|
|
}
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
public static NMSTypeWrapper arrayOf(ReflectClass<?> rc, int arrayDepth) {
|
|
|
|
return new NMSTypeWrapper(rc.get().getName(), arrayDepth);
|
2022-02-07 12:45:18 +01:00
|
|
|
}
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
public static NMSTypeWrapper mojOf(ClassMapping cm) {
|
2022-02-07 12:45:18 +01:00
|
|
|
return arrayMojOf(cm, 0);
|
|
|
|
}
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
public static NMSTypeWrapper arrayMojOf(ClassMapping cm, int arrayDepth) {
|
|
|
|
return new NMSTypeWrapper(cm.mojName, arrayDepth);
|
2022-02-07 12:45:18 +01:00
|
|
|
}
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
/* package */ static NMSTypeWrapper toType(Object typeObj) {
|
2022-02-07 12:45:18 +01:00
|
|
|
Objects.requireNonNull(typeObj, "typeObj cannot be null");
|
|
|
|
if (typeObj instanceof Class<?> cl) {
|
|
|
|
return of(cl);
|
|
|
|
}
|
|
|
|
else if (typeObj instanceof ClassMapping cm) {
|
|
|
|
return mojOf(cm);
|
|
|
|
}
|
|
|
|
else if (typeObj instanceof ReflectClass<?> rc) {
|
|
|
|
return of(rc);
|
|
|
|
}
|
2022-07-20 16:26:29 +02:00
|
|
|
else if (typeObj instanceof NMSTypeWrapper t) {
|
2022-02-07 12:45:18 +01:00
|
|
|
return t;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
throw new IllegalArgumentException("Unsupported object of type " + typeObj.getClass());
|
|
|
|
}
|
|
|
|
|
|
|
|
/* package */ String toHTML(boolean isObfClass) {
|
|
|
|
ClassMapping clMapping = (isObfClass ? NMSReflect.CLASSES_BY_OBF : NMSReflect.CLASSES_BY_MOJ).get(type);
|
|
|
|
String typeHTML;
|
|
|
|
if (clMapping != null) {
|
|
|
|
typeHTML = clMapping.toClickableHTML(isObfClass);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
String classToPrint = type;
|
|
|
|
String classSimpleName = classToPrint.substring(classToPrint.lastIndexOf('.') + 1);
|
|
|
|
String htmlTitle = classSimpleName.equals(classToPrint) ? "" : (" title='" + classToPrint + "'");
|
|
|
|
if (!htmlTitle.equals("")) {
|
2022-02-18 19:12:01 +01:00
|
|
|
typeHTML = "<span" + htmlTitle + " class='cl'>" + classSimpleName + "</span>";
|
2022-02-07 12:45:18 +01:00
|
|
|
}
|
|
|
|
else {
|
2022-02-18 19:12:01 +01:00
|
|
|
typeHTML = "<span class='" + (isPrimitive() ? "kw" : "cl") + "'>" + classSimpleName + "</span>";
|
2022-02-07 12:45:18 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return typeHTML + "[]".repeat(arrayDepth);
|
|
|
|
}
|
|
|
|
|
|
|
|
public String toString() {
|
|
|
|
return type + "[]".repeat(arrayDepth);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-02-18 19:12:01 +01:00
|
|
|
public boolean isPrimitive() {
|
|
|
|
try {
|
|
|
|
return toClass().isPrimitive();
|
|
|
|
} catch (ClassNotFoundException e) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
2022-02-07 12:45:18 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
/* package */ static NMSTypeWrapper parse(StringReader desc) {
|
2022-02-07 12:45:18 +01:00
|
|
|
try {
|
|
|
|
int arrayDepth = 0;
|
|
|
|
char c;
|
|
|
|
while ((c = (char) desc.read()) == '[') {
|
|
|
|
arrayDepth++;
|
|
|
|
}
|
|
|
|
String type = switch(c) {
|
|
|
|
case 'Z' -> "boolean";
|
|
|
|
case 'B' -> "byte";
|
|
|
|
case 'C' -> "char";
|
|
|
|
case 'D' -> "double";
|
|
|
|
case 'F' -> "float";
|
|
|
|
case 'I' -> "int";
|
|
|
|
case 'J' -> "long";
|
|
|
|
case 'S' -> "short";
|
|
|
|
case 'L' -> {
|
|
|
|
StringBuilder sbClass = new StringBuilder();
|
|
|
|
char r;
|
|
|
|
while ((r = (char) desc.read()) != ';') {
|
|
|
|
sbClass.append(r);
|
|
|
|
}
|
|
|
|
yield NMSReflect.binaryClassName(sbClass.toString());
|
|
|
|
}
|
|
|
|
default -> "void";
|
|
|
|
};
|
2022-07-20 16:26:29 +02:00
|
|
|
return new NMSTypeWrapper(type, arrayDepth);
|
2022-02-07 12:45:18 +01:00
|
|
|
} catch (IOException e) {
|
|
|
|
throw new RuntimeException("StringReader read error", e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
/* package */ static List<NMSTypeWrapper> toTypeList(List<Object> paramsType) {
|
|
|
|
List<NMSTypeWrapper> types = new ArrayList<>(paramsType.size());
|
2022-02-17 23:52:27 +01:00
|
|
|
for (int i = 0; i < paramsType.size(); i++) {
|
2022-02-07 12:45:18 +01:00
|
|
|
Object param = paramsType.get(i);
|
|
|
|
try {
|
2022-07-20 16:26:29 +02:00
|
|
|
types.add(NMSTypeWrapper.toType(param));
|
2022-02-07 12:45:18 +01:00
|
|
|
} catch (NullPointerException|IllegalArgumentException e) {
|
|
|
|
throw new IllegalArgumentException("Invalid parameterType at index " + i, e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return types;
|
|
|
|
}
|
|
|
|
|
2022-07-20 16:26:29 +02:00
|
|
|
/* package */ static Class<?>[] toClassArray(List<NMSTypeWrapper> types) throws ClassNotFoundException {
|
2022-02-07 12:45:18 +01:00
|
|
|
Class<?>[] classes = new Class<?>[types.size()];
|
|
|
|
for (int i = 0; i < types.size(); i++) {
|
|
|
|
classes[i] = types.get(i).toClass();
|
|
|
|
}
|
|
|
|
return classes;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|