Update
This commit is contained in:
parent
68ce3b6d7e
commit
ed2b51d0b0
|
@ -1,7 +1,7 @@
|
||||||
package it.cavallium.data.generator.plugin;
|
package it.cavallium.data.generator.plugin;
|
||||||
|
|
||||||
import com.squareup.javapoet.ClassName;
|
import com.squareup.javapoet.ClassName;
|
||||||
import com.squareup.javapoet.TypeName;
|
import com.squareup.javapoet.CodeBlock;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -110,7 +110,7 @@ public final class ComputedTypeSuper implements VersionedComputedType {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeName getJUpgraderName(String basePackageName) {
|
public ClassName getJUpgraderName(String basePackageName) {
|
||||||
return ClassName.get(type.version().getSerializersPackage(basePackageName), type.type() + "Upgrader");
|
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);
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return type.type() + " (super, v" + getVersion() + ")";
|
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.GenSerializerSuperX;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenSuperType;
|
import it.cavallium.data.generator.plugin.classgen.GenSuperType;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenUpgraderBaseX;
|
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.GenVersion;
|
||||||
import it.cavallium.data.generator.plugin.classgen.GenVersions;
|
import it.cavallium.data.generator.plugin.classgen.GenVersions;
|
||||||
import it.unimi.dsi.fastutil.booleans.BooleanList;
|
import it.unimi.dsi.fastutil.booleans.BooleanList;
|
||||||
|
@ -190,6 +191,8 @@ public class SourcesGenerator {
|
||||||
|
|
||||||
new GenUpgraderBaseX(genParams).run();
|
new GenUpgraderBaseX(genParams).run();
|
||||||
|
|
||||||
|
new GenUpgraderSuperX(genParams).run();
|
||||||
|
|
||||||
// Update the hash at the end
|
// Update the hash at the end
|
||||||
Files.writeString(hashPath, basePackageName + '\n' + useRecordBuilders + '\n' + curHash + '\n',
|
Files.writeString(hashPath, basePackageName + '\n' + useRecordBuilders + '\n' + curHash + '\n',
|
||||||
StandardCharsets.UTF_8, TRUNCATE_EXISTING, WRITE, CREATE);
|
StandardCharsets.UTF_8, TRUNCATE_EXISTING, WRITE, CREATE);
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class GenDataBaseX extends ClassGenerator {
|
||||||
dataModel.getSuperTypesOf(base, false).forEach(superType -> {
|
dataModel.getSuperTypesOf(base, false).forEach(superType -> {
|
||||||
classBuilder.addMethod(MethodSpec
|
classBuilder.addMethod(MethodSpec
|
||||||
.methodBuilder("getMetaId$" + superType.getName())
|
.methodBuilder("getMetaId$" + superType.getName())
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
.addModifiers(Modifier.PUBLIC)
|
||||||
.addAnnotation(Override.class)
|
.addAnnotation(Override.class)
|
||||||
.returns(int.class)
|
.returns(int.class)
|
||||||
.addStatement("return " + superType.subTypes().indexOf(base))
|
.addStatement("return " + superType.subTypes().indexOf(base))
|
||||||
|
@ -60,7 +60,7 @@ public class GenDataBaseX extends ClassGenerator {
|
||||||
|
|
||||||
var ofMethod = MethodSpec
|
var ofMethod = MethodSpec
|
||||||
.methodBuilder("of")
|
.methodBuilder("of")
|
||||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL);
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||||
|
|
||||||
base.getData().forEach((fieldName, fieldType) -> {
|
base.getData().forEach((fieldName, fieldType) -> {
|
||||||
var fieldTypeName = fieldType.getJTypeName(basePackageName);
|
var fieldTypeName = fieldType.getJTypeName(basePackageName);
|
||||||
|
|
|
@ -8,8 +8,10 @@ import com.squareup.javapoet.FieldSpec;
|
||||||
import com.squareup.javapoet.MethodSpec;
|
import com.squareup.javapoet.MethodSpec;
|
||||||
import com.squareup.javapoet.ParameterSpec;
|
import com.squareup.javapoet.ParameterSpec;
|
||||||
import com.squareup.javapoet.ParameterizedTypeName;
|
import com.squareup.javapoet.ParameterizedTypeName;
|
||||||
|
import com.squareup.javapoet.TypeName;
|
||||||
import com.squareup.javapoet.TypeSpec;
|
import com.squareup.javapoet.TypeSpec;
|
||||||
import com.squareup.javapoet.TypeSpec.Builder;
|
import com.squareup.javapoet.TypeSpec.Builder;
|
||||||
|
import it.cavallium.data.generator.DataInitializer;
|
||||||
import it.cavallium.data.generator.DataUpgrader;
|
import it.cavallium.data.generator.DataUpgrader;
|
||||||
import it.cavallium.data.generator.plugin.ClassGenerator;
|
import it.cavallium.data.generator.plugin.ClassGenerator;
|
||||||
import it.cavallium.data.generator.plugin.ComputedType;
|
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());
|
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();
|
List<String> expectedResultFields = nextTypeBase.getData().keySet().stream().toList();
|
||||||
|
|
||||||
AtomicInteger nextInitializerStaticFieldId = new AtomicInteger();
|
AtomicInteger nextInitializerStaticFieldId = new AtomicInteger();
|
||||||
|
@ -122,11 +120,15 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||||
var computedTypes = dataModel.getComputedTypes(nextTypeBase.getVersion());
|
var computedTypes = dataModel.getComputedTypes(nextTypeBase.getVersion());
|
||||||
var newFieldType = Objects.requireNonNull(computedTypes.get(fixType(newDataConfiguration.type)));
|
var newFieldType = Objects.requireNonNull(computedTypes.get(fixType(newDataConfiguration.type)));
|
||||||
var initializerClass = ClassName.bestGuess(newDataConfiguration.initializer);
|
var initializerClass = ClassName.bestGuess(newDataConfiguration.initializer);
|
||||||
|
var genericInitializerClass = ParameterizedTypeName.get(ClassName.get(DataInitializer.class),
|
||||||
|
newFieldType.getJTypeName(basePackageName).box()
|
||||||
|
);
|
||||||
|
|
||||||
var initializerName = createInitializerStaticField(nextInitializerStaticFieldId,
|
var initializerName = createInitializerStaticField(nextInitializerStaticFieldId,
|
||||||
initializerStaticFieldNames,
|
initializerStaticFieldNames,
|
||||||
classBuilder,
|
classBuilder,
|
||||||
initializerClass
|
initializerClass,
|
||||||
|
genericInitializerClass
|
||||||
);
|
);
|
||||||
|
|
||||||
return new Field(newDataConfiguration.to, newFieldType, CodeBlock.of("$N.initialize()", initializerName), i + 1);
|
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 cb = CodeBlock.builder();
|
||||||
var newFieldType = Objects
|
var newFieldType = Objects
|
||||||
.requireNonNull(dataModel.getComputedTypes(version).get(fixType(upgradeDataConfiguration.type)));
|
.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,
|
var upgraderName = createUpgraderStaticField(nextUpgraderStaticFieldId,
|
||||||
upgraderStaticFieldNames,
|
upgraderStaticFieldNames,
|
||||||
classBuilder,
|
classBuilder,
|
||||||
upgraderClass
|
upgraderClass,
|
||||||
|
genericUpgraderClass
|
||||||
);
|
);
|
||||||
|
|
||||||
cb.add("($T) $N.upgrade(($T) ",
|
cb.add("($T) $N.upgrade(($T) ",
|
||||||
|
@ -219,13 +226,14 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||||
private String createInitializerStaticField(AtomicInteger nextInitializerStaticFieldId,
|
private String createInitializerStaticField(AtomicInteger nextInitializerStaticFieldId,
|
||||||
HashMap<String, String> initializerStaticFieldNames,
|
HashMap<String, String> initializerStaticFieldNames,
|
||||||
Builder classBuilder,
|
Builder classBuilder,
|
||||||
ClassName initializerClass) {
|
ClassName initializerClass,
|
||||||
|
TypeName genericInitializerClass) {
|
||||||
var ref = initializerClass.reflectionName();
|
var ref = initializerClass.reflectionName();
|
||||||
var initializerName = initializerStaticFieldNames.get(ref);
|
var initializerName = initializerStaticFieldNames.get(ref);
|
||||||
if (initializerName == null) {
|
if (initializerName == null) {
|
||||||
initializerName = "I" + nextInitializerStaticFieldId.getAndIncrement();
|
initializerName = "I" + nextInitializerStaticFieldId.getAndIncrement();
|
||||||
classBuilder.addField(FieldSpec
|
classBuilder.addField(FieldSpec
|
||||||
.builder(initializerClass, initializerName)
|
.builder(genericInitializerClass, initializerName)
|
||||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
|
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
|
||||||
.initializer("new $T()", initializerClass)
|
.initializer("new $T()", initializerClass)
|
||||||
.build());
|
.build());
|
||||||
|
@ -237,13 +245,14 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||||
private String createUpgraderStaticField(AtomicInteger nextUpgraderStaticFieldId,
|
private String createUpgraderStaticField(AtomicInteger nextUpgraderStaticFieldId,
|
||||||
HashMap<String, String> upgraderStaticFieldNames,
|
HashMap<String, String> upgraderStaticFieldNames,
|
||||||
Builder classBuilder,
|
Builder classBuilder,
|
||||||
ClassName upgraderClass) {
|
ClassName upgraderClass,
|
||||||
|
TypeName genericUpgraderClass) {
|
||||||
var ref = upgraderClass.reflectionName();
|
var ref = upgraderClass.reflectionName();
|
||||||
var upgraderName = upgraderStaticFieldNames.get(ref);
|
var upgraderName = upgraderStaticFieldNames.get(ref);
|
||||||
if (upgraderName == null) {
|
if (upgraderName == null) {
|
||||||
upgraderName = "U" + nextUpgraderStaticFieldId.getAndIncrement();
|
upgraderName = "U" + nextUpgraderStaticFieldId.getAndIncrement();
|
||||||
classBuilder.addField(FieldSpec
|
classBuilder.addField(FieldSpec
|
||||||
.builder(upgraderClass, upgraderName)
|
.builder(genericUpgraderClass, upgraderName)
|
||||||
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
|
.addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL)
|
||||||
.initializer("new $T()", upgraderClass)
|
.initializer("new $T()", upgraderClass)
|
||||||
.build());
|
.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.ComputedType.VersionedComputedType;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeBase;
|
import it.cavallium.data.generator.plugin.ComputedTypeBase;
|
||||||
import it.cavallium.data.generator.plugin.ComputedTypeCustom;
|
import it.cavallium.data.generator.plugin.ComputedTypeCustom;
|
||||||
|
import it.cavallium.data.generator.plugin.ComputedTypeSuper;
|
||||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
import it.cavallium.data.generator.plugin.ComputedVersion;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
@ -171,7 +172,8 @@ public class GenVersion extends ClassGenerator {
|
||||||
private void generateUpgraderInstance(ComputedVersion version, Builder classBuilder) {
|
private void generateUpgraderInstance(ComputedVersion version, Builder classBuilder) {
|
||||||
var versionClassType = ClassName.get(version.getPackage(basePackageName), "Version");
|
var versionClassType = ClassName.get(version.getPackage(basePackageName), "Version");
|
||||||
dataModel.getComputedTypes(version).forEach((typeName, type) -> {
|
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();
|
&& versionedComputedType.getVersion().equals(version) && !version.isCurrent();
|
||||||
if (!shouldCreateInstanceField) {
|
if (!shouldCreateInstanceField) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user