Add optional instance fields in upgraders

This commit is contained in:
Andrea Cavalli 2023-11-09 01:56:09 +01:00
parent 9118f2271b
commit 686cef66ac
4 changed files with 84 additions and 17 deletions

View File

@ -0,0 +1,42 @@
package it.cavallium.datagen.plugin;
import com.squareup.javapoet.ClassName;
import org.apache.commons.lang3.StringUtils;
public sealed interface JInterfaceLocation {
static JInterfaceLocation parse(String className, String instanceFieldLocation) {
if ((instanceFieldLocation != null) == (className != null)) {
if (instanceFieldLocation != null) {
throw new IllegalArgumentException("instance field location and class name are both set! You must set one");
} else {
throw new IllegalArgumentException("instance field location and class name are both empty! You must set one");
}
} else if (instanceFieldLocation != null) {
var fieldClass = StringUtils.substringBeforeLast(instanceFieldLocation, ".");
var fieldName = StringUtils.substringAfterLast(instanceFieldLocation, ".");
var fieldClassName = ClassName.bestGuess(fieldClass);
return new JInterfaceLocationInstanceField(new FieldLocation(fieldClassName, fieldName));
} else {
return new JInterfaceLocationClassName(ClassName.bestGuess(className));
}
}
String getIdentifier();
record JInterfaceLocationClassName(ClassName className) implements JInterfaceLocation {
@Override
public String getIdentifier() {
return "C:" + className.reflectionName();
}
}
record JInterfaceLocationInstanceField(FieldLocation fieldLocation) implements JInterfaceLocation {
@Override
public String getIdentifier() {
return "F:" + fieldLocation.className() + "." + fieldLocation.fieldName();
}
}
}

View File

@ -9,6 +9,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
public String to;
public String type;
public String initializer;
public String initializerInstance;
@Nullable
public Integer index;
@ -22,6 +23,10 @@ public class NewDataConfiguration implements TransformationConfiguration {
return "new-data";
}
public JInterfaceLocation getInitializerLocation() {
return JInterfaceLocation.parse(initializer, initializerInstance);
}
@Override
public boolean equals(Object o) {
if (this == o) {
@ -33,6 +38,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
NewDataConfiguration that = (NewDataConfiguration) o;
return Objects.equals(transformClass, that.transformClass) && Objects.equals(to, that.to)
&& Objects.equals(type, that.type) && Objects.equals(initializer, that.initializer)
&& Objects.equals(initializerInstance, that.initializerInstance)
&& Objects.equals(index, that.index);
}
@ -43,6 +49,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
hash += ConfigUtils.hashCode(to);
hash += ConfigUtils.hashCode(type);
hash += ConfigUtils.hashCode(initializer);
hash += ConfigUtils.hashCode(initializerInstance);
hash += ConfigUtils.hashCode(index);
return hash;
}
@ -51,6 +58,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
var c = new NewDataConfiguration();
if (this.transformClass != null) c.transformClass = this.transformClass;
if (this.initializer != null) c.initializer = this.initializer;
if (this.initializerInstance != null) c.initializerInstance = this.initializerInstance;
if (this.to != null) c.to = this.to;
if (this.type != null) c.type = this.type;
if (this.index != null) c.index = this.index;

View File

@ -8,6 +8,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
public String from;
public String type;
public String upgrader;
public String upgraderInstance;
@Override
public String getTransformClass() {
@ -19,6 +20,10 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
return "upgrade-data";
}
public JInterfaceLocation getUpgraderLocation() {
return JInterfaceLocation.parse(upgrader, upgraderInstance);
}
@Override
public boolean equals(Object o) {
if (this == o) {
@ -29,7 +34,8 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
}
UpgradeDataConfiguration that = (UpgradeDataConfiguration) o;
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from)
&& Objects.equals(type, that.type) && Objects.equals(upgrader, that.upgrader);
&& Objects.equals(type, that.type) && Objects.equals(upgrader, that.upgrader)
&& Objects.equals(upgraderInstance, that.upgraderInstance);
}
@Override
@ -39,6 +45,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
hash += ConfigUtils.hashCode(from);
hash += ConfigUtils.hashCode(type);
hash += ConfigUtils.hashCode(upgrader);
hash += ConfigUtils.hashCode(upgraderInstance);
return hash;
}
@ -48,6 +55,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
if (this.from != null) c.from = this.from;
if (this.type != null) c.type = this.type;
if (this.upgrader != null) c.upgrader = this.upgrader;
if (this.upgraderInstance != null) c.upgraderInstance = this.upgraderInstance;
return c;
}
}

View File

@ -16,6 +16,9 @@ import it.cavallium.datagen.plugin.ComputedType;
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
import it.cavallium.datagen.plugin.ComputedTypeBase;
import it.cavallium.datagen.plugin.ComputedVersion;
import it.cavallium.datagen.plugin.JInterfaceLocation;
import it.cavallium.datagen.plugin.JInterfaceLocation.JInterfaceLocationClassName;
import it.cavallium.datagen.plugin.JInterfaceLocation.JInterfaceLocationInstanceField;
import it.cavallium.datagen.plugin.MoveDataConfiguration;
import it.cavallium.datagen.plugin.NewDataConfiguration;
import it.cavallium.datagen.plugin.RemoveDataConfiguration;
@ -116,7 +119,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
var newDataConfiguration = e.getValue();
var computedTypes = dataModel.getComputedTypes(nextTypeBase.getVersion());
var newFieldType = Objects.requireNonNull(computedTypes.get(DataModel.fixType(newDataConfiguration.type)));
var initializerClass = ClassName.bestGuess(newDataConfiguration.initializer);
var initializerLocation = newDataConfiguration.getInitializerLocation();
var genericInitializerClass = ParameterizedTypeName.get(ClassName.get(DataInitializer.class),
newFieldType.getJTypeName(basePackageName).box()
);
@ -124,7 +127,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
var initializerName = createInitializerStaticField(nextInitializerStaticFieldId,
initializerStaticFieldNames,
classBuilder,
initializerClass,
initializerLocation,
genericInitializerClass
);
@ -163,7 +166,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
if (!upgradeDataConfiguration.from.equals(fieldName)) {
continue;
}
var upgraderClass = ClassName.bestGuess(upgradeDataConfiguration.upgrader);
var upgraderImplementationLocation = upgradeDataConfiguration.getUpgraderLocation();
var cb = CodeBlock.builder();
var newFieldType = Objects
.requireNonNull(dataModel.getComputedTypes(nextTypeBase.getVersion()).get(DataModel.fixType(upgradeDataConfiguration.type)));
@ -175,7 +178,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
var upgraderName = createUpgraderStaticField(nextUpgraderStaticFieldId,
upgraderStaticFieldNames,
classBuilder,
upgraderClass,
upgraderImplementationLocation,
genericUpgraderClass
);
@ -222,18 +225,25 @@ public class GenUpgraderBaseX extends ClassGenerator {
private String createInitializerStaticField(AtomicInteger nextInitializerStaticFieldId,
HashMap<String, String> initializerStaticFieldNames,
Builder classBuilder,
ClassName initializerClass,
JInterfaceLocation initializerLocation,
TypeName genericInitializerClass) {
var ref = initializerClass.reflectionName();
var initializerName = initializerStaticFieldNames.get(ref);
var identifier = initializerLocation.getIdentifier();
var initializerName = initializerStaticFieldNames.get(identifier);
if (initializerName == null) {
initializerName = "I" + nextInitializerStaticFieldId.getAndIncrement();
classBuilder.addField(FieldSpec
var fieldBuilder = FieldSpec
.builder(genericInitializerClass, initializerName)
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("new $T()", initializerClass)
.build());
initializerStaticFieldNames.put(ref, initializerName);
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL);
switch (initializerLocation) {
case JInterfaceLocationClassName className -> fieldBuilder.initializer("new $T()", className.className());
case JInterfaceLocationInstanceField instanceField -> fieldBuilder.initializer("$T.$N",
instanceField.fieldLocation().className(),
instanceField.fieldLocation().fieldName()
);
}
classBuilder.addField(fieldBuilder.build());
initializerStaticFieldNames.put(identifier, initializerName);
}
return initializerName;
}
@ -241,10 +251,9 @@ public class GenUpgraderBaseX extends ClassGenerator {
private String createUpgraderStaticField(AtomicInteger nextUpgraderStaticFieldId,
HashMap<String, String> upgraderStaticFieldNames,
Builder classBuilder,
ClassName upgraderClass,
String upgraderImplementationLocation,
TypeName genericUpgraderClass) {
var ref = upgraderClass.reflectionName();
var upgraderName = upgraderStaticFieldNames.get(ref);
var upgraderName = upgraderStaticFieldNames.get(upgraderImplementationLocation);
if (upgraderName == null) {
upgraderName = "U" + nextUpgraderStaticFieldId.getAndIncrement();
classBuilder.addField(FieldSpec
@ -252,7 +261,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
.initializer("new $T()", upgraderClass)
.build());
upgraderStaticFieldNames.put(ref, upgraderName);
upgraderStaticFieldNames.put(upgraderImplementationLocation, upgraderName);
}
return upgraderName;
}