Update
This commit is contained in:
parent
68ce3b6d7e
commit
ed2b51d0b0
@ -1,7 +1,7 @@
|
||||
package it.cavallium.data.generator.plugin;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
@ -110,7 +110,7 @@ public final class ComputedTypeSuper implements VersionedComputedType {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getJUpgraderName(String basePackageName) {
|
||||
public ClassName getJUpgraderName(String basePackageName) {
|
||||
return ClassName.get(type.version().getSerializersPackage(basePackageName), type.type() + "Upgrader");
|
||||
}
|
||||
|
||||
@ -121,6 +121,16 @@ public final class ComputedTypeSuper implements VersionedComputedType {
|
||||
return new FieldLocation(className, upgraderFieldName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBlock wrapWithUpgrade(String basePackageName, CodeBlock content, ComputedType next) {
|
||||
var upgraderInstance = getJUpgraderInstance(basePackageName);
|
||||
var cb = CodeBlock.builder();
|
||||
cb.add(CodeBlock.of("$T.$N.upgrade(", upgraderInstance.className(), upgraderInstance.fieldName()));
|
||||
cb.add(content);
|
||||
cb.add(")");
|
||||
return VersionedComputedType.super.wrapWithUpgrade(basePackageName, cb.build(), next);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return type.type() + " (super, v" + getVersion() + ")";
|
||||
|
@ -30,6 +30,7 @@ import it.cavallium.data.generator.plugin.classgen.GenSerializerNullableX;
|
||||
import it.cavallium.data.generator.plugin.classgen.GenSerializerSuperX;
|
||||
import it.cavallium.data.generator.plugin.classgen.GenSuperType;
|
||||
import it.cavallium.data.generator.plugin.classgen.GenUpgraderBaseX;
|
||||
import it.cavallium.data.generator.plugin.classgen.GenUpgraderSuperX;
|
||||
import it.cavallium.data.generator.plugin.classgen.GenVersion;
|
||||
import it.cavallium.data.generator.plugin.classgen.GenVersions;
|
||||
import it.unimi.dsi.fastutil.booleans.BooleanList;
|
||||
@ -190,6 +191,8 @@ public class SourcesGenerator {
|
||||
|
||||
new GenUpgraderBaseX(genParams).run();
|
||||
|
||||
new GenUpgraderSuperX(genParams).run();
|
||||
|
||||
// Update the hash at the end
|
||||
Files.writeString(hashPath, basePackageName + '\n' + useRecordBuilders + '\n' + curHash + '\n',
|
||||
StandardCharsets.UTF_8, TRUNCATE_EXISTING, WRITE, CREATE);
|
||||
|
@ -51,7 +51,7 @@ public class GenDataBaseX extends ClassGenerator {
|
||||
dataModel.getSuperTypesOf(base, false).forEach(superType -> {
|
||||
classBuilder.addMethod(MethodSpec
|
||||
.methodBuilder("getMetaId$" + superType.getName())
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||
.addModifiers(Modifier.PUBLIC)
|
||||
.addAnnotation(Override.class)
|
||||
.returns(int.class)
|
||||
.addStatement("return " + superType.subTypes().indexOf(base))
|
||||
@ -60,7 +60,7 @@ public class GenDataBaseX extends ClassGenerator {
|
||||
|
||||
var ofMethod = MethodSpec
|
||||
.methodBuilder("of")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||
|
||||
base.getData().forEach((fieldName, fieldType) -> {
|
||||
var fieldTypeName = fieldType.getJTypeName(basePackageName);
|
||||
|
@ -8,8 +8,10 @@ import com.squareup.javapoet.FieldSpec;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import com.squareup.javapoet.TypeSpec.Builder;
|
||||
import it.cavallium.data.generator.DataInitializer;
|
||||
import it.cavallium.data.generator.DataUpgrader;
|
||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
||||
import it.cavallium.data.generator.plugin.ComputedType;
|
||||
@ -86,10 +88,6 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
|
||||
method.addParameter(ParameterSpec.builder(typeBaseClassName, "data").addAnnotation(NotNull.class).build());
|
||||
|
||||
nextTypeBase.getData().forEach((fieldName, fieldType) -> {
|
||||
method.addStatement("$T $N", fieldType.getJTypeName(basePackageName), fieldName);
|
||||
});
|
||||
|
||||
List<String> expectedResultFields = nextTypeBase.getData().keySet().stream().toList();
|
||||
|
||||
AtomicInteger nextInitializerStaticFieldId = new AtomicInteger();
|
||||
@ -122,11 +120,15 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
var computedTypes = dataModel.getComputedTypes(nextTypeBase.getVersion());
|
||||
var newFieldType = Objects.requireNonNull(computedTypes.get(fixType(newDataConfiguration.type)));
|
||||
var initializerClass = ClassName.bestGuess(newDataConfiguration.initializer);
|
||||
var genericInitializerClass = ParameterizedTypeName.get(ClassName.get(DataInitializer.class),
|
||||
newFieldType.getJTypeName(basePackageName).box()
|
||||
);
|
||||
|
||||
var initializerName = createInitializerStaticField(nextInitializerStaticFieldId,
|
||||
initializerStaticFieldNames,
|
||||
classBuilder,
|
||||
initializerClass
|
||||
initializerClass,
|
||||
genericInitializerClass
|
||||
);
|
||||
|
||||
return new Field(newDataConfiguration.to, newFieldType, CodeBlock.of("$N.initialize()", initializerName), i + 1);
|
||||
@ -168,11 +170,16 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
var cb = CodeBlock.builder();
|
||||
var newFieldType = Objects
|
||||
.requireNonNull(dataModel.getComputedTypes(version).get(fixType(upgradeDataConfiguration.type)));
|
||||
var genericUpgraderClass = ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
||||
fieldType.getJTypeName(basePackageName).box(),
|
||||
newFieldType.getJTypeName(basePackageName).box()
|
||||
);
|
||||
|
||||
var upgraderName = createUpgraderStaticField(nextUpgraderStaticFieldId,
|
||||
upgraderStaticFieldNames,
|
||||
classBuilder,
|
||||
upgraderClass
|
||||
upgraderClass,
|
||||
genericUpgraderClass
|
||||
);
|
||||
|
||||
cb.add("($T) $N.upgrade(($T) ",
|
||||
@ -219,13 +226,14 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
private String createInitializerStaticField(AtomicInteger nextInitializerStaticFieldId,
|
||||
HashMap<String, String> initializerStaticFieldNames,
|
||||
Builder classBuilder,
|
||||
ClassName initializerClass) {
|
||||
ClassName initializerClass,
|
||||
TypeName genericInitializerClass) {
|
||||
var ref = initializerClass.reflectionName();
|
||||
var initializerName = initializerStaticFieldNames.get(ref);
|
||||
if (initializerName == null) {
|
||||
initializerName = "I" + nextInitializerStaticFieldId.getAndIncrement();
|
||||
classBuilder.addField(FieldSpec
|
||||
.builder(initializerClass, initializerName)
|
||||
.builder(genericInitializerClass, initializerName)
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
|
||||
.initializer("new $T()", initializerClass)
|
||||
.build());
|
||||
@ -237,13 +245,14 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
private String createUpgraderStaticField(AtomicInteger nextUpgraderStaticFieldId,
|
||||
HashMap<String, String> upgraderStaticFieldNames,
|
||||
Builder classBuilder,
|
||||
ClassName upgraderClass) {
|
||||
ClassName upgraderClass,
|
||||
TypeName genericUpgraderClass) {
|
||||
var ref = upgraderClass.reflectionName();
|
||||
var upgraderName = upgraderStaticFieldNames.get(ref);
|
||||
if (upgraderName == null) {
|
||||
upgraderName = "U" + nextUpgraderStaticFieldId.getAndIncrement();
|
||||
classBuilder.addField(FieldSpec
|
||||
.builder(upgraderClass, upgraderName)
|
||||
.builder(genericUpgraderClass, upgraderName)
|
||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
|
||||
.initializer("new $T()", upgraderClass)
|
||||
.build());
|
||||
|
@ -0,0 +1,98 @@
|
||||
package it.cavallium.data.generator.plugin.classgen;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.MethodSpec;
|
||||
import com.squareup.javapoet.ParameterSpec;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import com.squareup.javapoet.TypeSpec.Builder;
|
||||
import it.cavallium.data.generator.DataUpgrader;
|
||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
||||
import it.cavallium.data.generator.plugin.ComputedType;
|
||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
||||
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
|
||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
||||
import java.io.IOException;
|
||||
import java.util.stream.Stream;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class GenUpgraderSuperX extends ClassGenerator {
|
||||
|
||||
public GenUpgraderSuperX(ClassGeneratorParams params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<GeneratedClass> generateClasses() {
|
||||
return dataModel.getVersionsSet().parallelStream().flatMap(this::generateVersionClasses);
|
||||
}
|
||||
|
||||
private Stream<GeneratedClass> generateVersionClasses(ComputedVersion version) {
|
||||
return dataModel
|
||||
.getSuperTypesComputed(version)
|
||||
.filter(type -> !type.getVersion().isCurrent() && type.getVersion().equals(version))
|
||||
.map(type -> generateTypeVersioned(version, type));
|
||||
}
|
||||
|
||||
private GeneratedClass generateTypeVersioned(ComputedVersion version, ComputedTypeSuper typeSuper) {
|
||||
ClassName upgraderClassName = typeSuper.getJUpgraderName(basePackageName);
|
||||
ClassName typeBaseClassName = typeSuper.getJTypeName(basePackageName);
|
||||
ComputedTypeSuper nextTypeSuper = dataModel.getNextVersion(typeSuper);
|
||||
|
||||
var classBuilder = TypeSpec.classBuilder(upgraderClassName.simpleName());
|
||||
|
||||
classBuilder.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||
|
||||
classBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
||||
typeBaseClassName,
|
||||
nextTypeSuper.getJTypeName(basePackageName)
|
||||
));
|
||||
|
||||
generateUpgradeMethod(version, typeSuper, nextTypeSuper, classBuilder);
|
||||
|
||||
return new GeneratedClass(upgraderClassName.packageName(), classBuilder);
|
||||
}
|
||||
|
||||
private void generateUpgradeMethod(ComputedVersion version, ComputedTypeSuper typeSuper,
|
||||
ComputedTypeSuper nextTypeSuper,
|
||||
Builder classBuilder) {
|
||||
var method = MethodSpec.methodBuilder("upgrade");
|
||||
|
||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||
method.addException(IOException.class);
|
||||
|
||||
ClassName typeSuperClassName = typeSuper.getJTypeName(basePackageName);
|
||||
ClassName nextTypeSuperClassName = nextTypeSuper.getJTypeName(basePackageName);
|
||||
method.returns(nextTypeSuperClassName);
|
||||
method.addAnnotation(NotNull.class);
|
||||
|
||||
method.addParameter(ParameterSpec.builder(typeSuperClassName, "data").addAnnotation(NotNull.class).build());
|
||||
|
||||
method.beginControlFlow("return switch (data.getMetaId$$$N())", typeSuper.getName());
|
||||
int i = 0;
|
||||
for (ComputedType subType : typeSuper.subTypes()) {
|
||||
method.addCode("case $L -> ", i);
|
||||
method.addStatement(upgradeSubTypeToType(subType, CodeBlock.of("($T) data", subType.getJTypeName(basePackageName)), nextTypeSuper));
|
||||
i++;
|
||||
}
|
||||
method.addStatement("default -> throw new $T(data.getMetaId$$$N())", IndexOutOfBoundsException.class, typeSuper.getName());
|
||||
method.addCode("$<};\n");
|
||||
|
||||
classBuilder.addMethod(method.build());
|
||||
}
|
||||
|
||||
private CodeBlock upgradeSubTypeToType(ComputedType subType,
|
||||
CodeBlock codeBlock,
|
||||
ComputedTypeSuper nextTypeSuper) {
|
||||
while (subType instanceof VersionedComputedType versionedComputedType
|
||||
&& versionedComputedType.getVersion().compareTo(nextTypeSuper.getVersion()) < 0) {
|
||||
var currentFieldType = subType;
|
||||
var nextFieldType = dataModel.getNextVersion(currentFieldType);
|
||||
codeBlock = currentFieldType.wrapWithUpgrade(basePackageName, codeBlock, nextFieldType);
|
||||
subType = nextFieldType;
|
||||
}
|
||||
return codeBlock;
|
||||
}
|
||||
}
|
@ -15,6 +15,7 @@ import it.cavallium.data.generator.plugin.ClassGenerator;
|
||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
||||
import it.cavallium.data.generator.plugin.ComputedTypeBase;
|
||||
import it.cavallium.data.generator.plugin.ComputedTypeCustom;
|
||||
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
|
||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
@ -171,7 +172,8 @@ public class GenVersion extends ClassGenerator {
|
||||
private void generateUpgraderInstance(ComputedVersion version, Builder classBuilder) {
|
||||
var versionClassType = ClassName.get(version.getPackage(basePackageName), "Version");
|
||||
dataModel.getComputedTypes(version).forEach((typeName, type) -> {
|
||||
boolean shouldCreateInstanceField = type instanceof ComputedTypeBase versionedComputedType
|
||||
boolean shouldCreateInstanceField = type instanceof VersionedComputedType versionedComputedType
|
||||
&& (type instanceof ComputedTypeBase || type instanceof ComputedTypeSuper)
|
||||
&& versionedComputedType.getVersion().equals(version) && !version.isCurrent();
|
||||
if (!shouldCreateInstanceField) {
|
||||
return;
|
||||
|
Loading…
x
Reference in New Issue
Block a user