97 lines
3.9 KiB
Java
97 lines
3.9 KiB
Java
package io.gitlab.jfronny.libjf.config.plugin.asm.value;
|
|
|
|
import io.gitlab.jfronny.libjf.config.plugin.asm.ConfigInjectClassTransformer;
|
|
import io.gitlab.jfronny.libjf.config.plugin.util.GeneratorAdapter2;
|
|
import org.objectweb.asm.Type;
|
|
import org.objectweb.asm.commons.Method;
|
|
|
|
import static io.gitlab.jfronny.libjf.config.plugin.asm.value.KnownTypes.*;
|
|
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
|
import static org.objectweb.asm.Opcodes.ACC_STATIC;
|
|
import static org.objectweb.asm.Type.*;
|
|
|
|
public class DiscoveredValue {
|
|
private static final String PREFIX = ConfigInjectClassTransformer.PREFIX;
|
|
|
|
public final String name;
|
|
public final double min;
|
|
public final double max;
|
|
public final Type aType;
|
|
public final KnownType type;
|
|
|
|
public DiscoveredValue(String name, double min, double max, Type type) {
|
|
this.name = name;
|
|
this.min = min;
|
|
this.max = max;
|
|
this.aType = type;
|
|
this.type = KnownType.of(type);
|
|
}
|
|
|
|
public void generateRegistration(GeneratorAdapter2 m, ConfigInjectClassTransformer t) {
|
|
if (type != KnownType.OBJECT) {
|
|
m.push(name);
|
|
m.getStatic(t.current, name, aType);
|
|
if (!aType.equals(type.unboxed)) {
|
|
m.comment("Unboxing value " + name + " from " + aType + " to " + type.unboxed);
|
|
m.unbox(type.unboxed); // Unbox (as parameter is unboxed) or leave as is (if target is unboxed)
|
|
}
|
|
}
|
|
switch (type) {
|
|
case INT, LONG, FLOAT, DOUBLE -> {
|
|
m.comment("Numeric type");
|
|
m.push(min);
|
|
m.push(max);
|
|
m.supplier(t.current.getInternalName(), gName(), gDesc());
|
|
m.consumer(t.current.getInternalName(), sName(), sDesc());
|
|
t.dslInvoke(m, "value", CATEGORY_BUILDER_TYPE, STRING_TYPE, type.unboxed, DOUBLE_TYPE, DOUBLE_TYPE, SUPPLIER_TYPE, CONSUMER_TYPE);
|
|
}
|
|
case BOOLEAN, STRING -> {
|
|
m.comment("Simple one-value type");
|
|
m.supplier(t.current.getInternalName(), gName(), gDesc());
|
|
m.consumer(t.current.getInternalName(), sName(), sDesc());
|
|
t.dslInvoke(m, "value", CATEGORY_BUILDER_TYPE, STRING_TYPE, type.unboxed, SUPPLIER_TYPE, CONSUMER_TYPE);
|
|
}
|
|
case OBJECT -> {
|
|
System.err.println("WARNING: Attempted to use unsupported type in config. The entry \"" + name + "\" will fall back to reflective runtime access!");
|
|
m.comment("Reflective access due to missing compatibility for the type \"" + aType + "\"");
|
|
m.push(t.current);
|
|
m.push(name);
|
|
m.invokeIStatic(ENTRY_INFO_TYPE, new Method("ofField", ENTRY_INFO_TYPE, new Type[]{CLASS_TYPE, STRING_TYPE}));
|
|
m.invokeInterface(CATEGORY_BUILDER_TYPE, new Method("value", CATEGORY_BUILDER_TYPE, new Type[]{ENTRY_INFO_TYPE}));
|
|
}
|
|
}
|
|
}
|
|
|
|
public void generateλ(ConfigInjectClassTransformer t) {
|
|
GeneratorAdapter2 m = t.method(ACC_PRIVATE | ACC_STATIC, gName(), gDesc().getInternalName(), null, null);
|
|
m.getStatic(t.current, name, aType);
|
|
m.comment("Boxing from " + aType + " (" + aType.getSort() + ")");
|
|
m.box(aType); // Box if target field uses unboxed value
|
|
m.returnValue();
|
|
m.endMethod();
|
|
|
|
m = t.method(ACC_PRIVATE | ACC_STATIC, sName(), sDesc().getInternalName(), null, null);
|
|
m.loadArg(0);
|
|
m.unbox(aType); // Unbox to the target fields type
|
|
m.putStatic(t.current, name, aType);
|
|
m.returnValue();
|
|
m.endMethod();
|
|
}
|
|
|
|
private String gName() {
|
|
return PREFIX + "get$" + name;
|
|
}
|
|
|
|
private Type gDesc() {
|
|
return getMethodType(type.boxed);
|
|
}
|
|
|
|
private String sName() {
|
|
return PREFIX + "set$" + name;
|
|
}
|
|
|
|
private Type sDesc() {
|
|
return getMethodType(VOID_TYPE, type.boxed);
|
|
}
|
|
}
|