Update
This commit is contained in:
parent
784c86456c
commit
2b3c048e60
@ -1,5 +1,6 @@
|
||||
package it.cavallium.data.generator.plugin;
|
||||
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
||||
import java.util.stream.Stream;
|
||||
@ -19,6 +20,10 @@ public sealed interface ComputedType permits VersionedComputedType, ComputedType
|
||||
|
||||
FieldLocation getJUpgraderInstance(String basePackageName);
|
||||
|
||||
default CodeBlock wrapWithUpgrade(String basePackageName, CodeBlock content, ComputedType next) {
|
||||
return content;
|
||||
}
|
||||
|
||||
sealed interface VersionedComputedType extends ComputedType permits ComputedTypeArrayVersioned, ComputedTypeBase,
|
||||
ComputedTypeNullableVersioned, ComputedTypeSuper {
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
package it.cavallium.data.generator.plugin;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import it.cavallium.data.generator.nativedata.UpgradeUtil;
|
||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@ -30,8 +32,7 @@ public final class ComputedTypeArrayVersioned implements VersionedComputedType,
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputedTypeArrayVersioned withChangeAtVersion(ComputedVersion version,
|
||||
VersionChangeChecker versionChangeChecker) {
|
||||
public ComputedTypeArrayVersioned withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker) {
|
||||
return new ComputedTypeArrayVersioned(baseType.withVersion(version),
|
||||
computedTypeSupplier
|
||||
);
|
||||
@ -99,14 +100,22 @@ public final class ComputedTypeArrayVersioned implements VersionedComputedType,
|
||||
|
||||
@Override
|
||||
public TypeName getJUpgraderName(String basePackageName) {
|
||||
return ClassName.get(baseType.version().getUpgradersPackage(basePackageName), "Array" + baseType.type() + "Upgrader");
|
||||
throw new UnsupportedOperationException("Not upgradable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldLocation getJUpgraderInstance(String basePackageName) {
|
||||
var className = ClassName.get(baseType.version().getPackage(basePackageName), "Version");
|
||||
var upgraderFieldName = "Array" + baseType.type() + "UpgraderInstance";
|
||||
return new FieldLocation(className, upgraderFieldName);
|
||||
throw new UnsupportedOperationException("Not upgradable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBlock wrapWithUpgrade(String basePackageName, CodeBlock content, ComputedType next) {
|
||||
var builder = CodeBlock.builder();
|
||||
builder.add("$T.upgradeArray(", UpgradeUtil.class);
|
||||
builder.add(content);
|
||||
var upgraderInstance = getBase().getJUpgraderInstance(basePackageName);
|
||||
builder.add(", $T.$N)", upgraderInstance.className(), upgraderInstance.fieldName());
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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.LinkedHashMap;
|
||||
import java.util.Objects;
|
||||
@ -39,14 +39,12 @@ public final class ComputedTypeBase implements VersionedComputedType {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputedTypeBase withChangeAtVersion(ComputedVersion version,
|
||||
VersionChangeChecker versionChangeChecker) {
|
||||
public ComputedTypeBase withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker) {
|
||||
var newData = new LinkedHashMap<String, VersionedType>();
|
||||
data.forEach((k, v) -> newData.put(k, v.withVersionIfChanged(version, versionChangeChecker)));
|
||||
return new ComputedTypeBase(type.withVersion(version),
|
||||
stringRepresenter,
|
||||
newData,
|
||||
computedTypeSupplier
|
||||
newData, computedTypeSupplier
|
||||
);
|
||||
}
|
||||
|
||||
@ -115,7 +113,7 @@ public final class ComputedTypeBase implements VersionedComputedType {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeName getJUpgraderName(String basePackageName) {
|
||||
public ClassName getJUpgraderName(String basePackageName) {
|
||||
return ClassName.get(type.version().getUpgradersPackage(basePackageName), type.type() + "Upgrader");
|
||||
}
|
||||
|
||||
@ -126,6 +124,16 @@ public final class ComputedTypeBase 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 Stream<ComputedType> getDependencies() {
|
||||
return this.data.values().stream().map(computedTypeSupplier::get);
|
||||
|
@ -1,7 +1,9 @@
|
||||
package it.cavallium.data.generator.plugin;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import it.cavallium.data.generator.nativedata.UpgradeUtil;
|
||||
import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
@ -28,8 +30,7 @@ public final class ComputedTypeNullableVersioned implements ComputedTypeNullable
|
||||
}
|
||||
|
||||
@Override
|
||||
public ComputedTypeNullableVersioned withChangeAtVersion(ComputedVersion version,
|
||||
VersionChangeChecker versionChangeChecker) {
|
||||
public ComputedTypeNullableVersioned withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker) {
|
||||
return new ComputedTypeNullableVersioned(baseType.withVersion(version),
|
||||
computedTypeSupplier
|
||||
);
|
||||
@ -75,7 +76,11 @@ public final class ComputedTypeNullableVersioned implements ComputedTypeNullable
|
||||
|
||||
@Override
|
||||
public TypeName getJTypeName(String basePackageName) {
|
||||
return ClassName.get(baseType.version().getDataNullablesPackage(basePackageName),
|
||||
return getJTypeNameOfVersion(baseType.version(), basePackageName);
|
||||
}
|
||||
|
||||
private TypeName getJTypeNameOfVersion(ComputedVersion version, String basePackageName) {
|
||||
return ClassName.get(version.getDataNullablesPackage(basePackageName),
|
||||
"Nullable" + baseType.type());
|
||||
}
|
||||
|
||||
@ -94,15 +99,23 @@ public final class ComputedTypeNullableVersioned implements ComputedTypeNullable
|
||||
|
||||
@Override
|
||||
public TypeName getJUpgraderName(String basePackageName) {
|
||||
return ClassName.get(baseType.version().getSerializersPackage(basePackageName),
|
||||
"Nullable" + baseType.type() + "Upgrader");
|
||||
throw new UnsupportedOperationException("Not upgradable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public FieldLocation getJUpgraderInstance(String basePackageName) {
|
||||
var className = ClassName.get(baseType.version().getPackage(basePackageName), "Version");
|
||||
var upgraderFieldName = "Nullable" + baseType.type() + "UpgraderInstance";
|
||||
return new FieldLocation(className, upgraderFieldName);
|
||||
throw new UnsupportedOperationException("Not upgradable");
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBlock wrapWithUpgrade(String basePackageName, CodeBlock content, ComputedType next) {
|
||||
var builder = CodeBlock.builder();
|
||||
var upgraderInstance = getBase().getJUpgraderInstance(basePackageName);
|
||||
builder.add("new $T($T.upgradeNullable(", next.getJTypeName(basePackageName), UpgradeUtil.class);
|
||||
builder.add(content);
|
||||
builder.add(".value(), $T.$N)", upgraderInstance.className(), upgraderInstance.fieldName());
|
||||
builder.add(")");
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -51,6 +51,7 @@ public class DataModel {
|
||||
private final Int2ObjectMap<Map<String, ComputedType>> computedTypes;
|
||||
private final Map<VersionedType, VersionedType> versionedTypePrevVersion;
|
||||
private final Map<VersionedType, VersionedType> versionedTypeNextVersion;
|
||||
private final Int2ObjectMap<Map<String, List<TransformationConfiguration>>> baseTypeDataChanges;
|
||||
|
||||
public DataModel(int hash,
|
||||
String currentVersionKey,
|
||||
@ -149,6 +150,8 @@ public class DataModel {
|
||||
throw new IllegalArgumentException("Type " + type + " has been defined more than once (check base, super, and custom types)!");
|
||||
});
|
||||
|
||||
record RawVersionedType(String type, int version) {}
|
||||
|
||||
// Compute the numeric versions map
|
||||
Int2ObjectMap<ParsedVersion> parsedVersions = new Int2ObjectLinkedOpenHashMap<>();
|
||||
rawVersions.forEach((k, v) -> parsedVersions.put(nameToVersion.getInt(k), new ParsedVersion(v)));
|
||||
@ -187,7 +190,7 @@ public class DataModel {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: "
|
||||
+ t.transformClass);
|
||||
}
|
||||
transformClass.differentThanPrev = true;
|
||||
transformClass.addDifferentThanPrev(transformation);
|
||||
var definition = removeAndGetIndex(transformClass.data, t.from);
|
||||
if (definition.isEmpty()) {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
|
||||
@ -210,7 +213,7 @@ public class DataModel {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: "
|
||||
+ t.transformClass);
|
||||
}
|
||||
transformClass.differentThanPrev = true;
|
||||
transformClass.addDifferentThanPrev(transformation);
|
||||
if (!allTypes.contains(extractTypeName(t.type))) {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
||||
}
|
||||
@ -233,7 +236,7 @@ public class DataModel {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: "
|
||||
+ t.transformClass);
|
||||
}
|
||||
transformClass.differentThanPrev = true;
|
||||
transformClass.addDifferentThanPrev(transformation);
|
||||
var prevDef = transformClass.data.remove(t.from);
|
||||
if (prevDef == null) {
|
||||
throw new IllegalArgumentException(transformCoordinate + " tries to remove the nonexistent field \""
|
||||
@ -247,7 +250,7 @@ public class DataModel {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: "
|
||||
+ t.transformClass);
|
||||
}
|
||||
transformClass.differentThanPrev = true;
|
||||
transformClass.addDifferentThanPrev(transformation);
|
||||
if (!allTypes.contains(extractTypeName(t.type))) {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
||||
}
|
||||
@ -283,12 +286,20 @@ public class DataModel {
|
||||
// Compute the types
|
||||
Int2ObjectMap<Map<String, ComputedType>> computedTypes = new Int2ObjectLinkedOpenHashMap<>();
|
||||
Int2ObjectMap<Map<String, ComputedType>> randomComputedTypes = new Int2ObjectOpenHashMap<>();
|
||||
Int2ObjectMap<Map<String, List<TransformationConfiguration>>> baseTypeDataChanges = new Int2ObjectOpenHashMap<>();
|
||||
ComputedTypeSupplier computedTypeSupplier = new ComputedTypeSupplier(randomComputedTypes, computedVersions.get(latestVersion));
|
||||
{
|
||||
for (int versionIndex = 0; versionIndex <= latestVersion; versionIndex++) {
|
||||
var versionChanges = new HashMap<String, List<TransformationConfiguration>>();
|
||||
baseTypeDataChanges.put(versionIndex, versionChanges);
|
||||
computedClassConfig.get(versionIndex).forEach((dataType, data) -> {
|
||||
versionChanges.put(dataType, Objects.requireNonNullElse(data.differentThanPrev, List.of()));
|
||||
});
|
||||
}
|
||||
for (int versionNumber = latestVersion - 1; versionNumber >= 0; versionNumber--) {
|
||||
var version = computedClassConfig.get(versionNumber);
|
||||
computedClassConfig.get(versionNumber + 1).forEach((type, typeConfig) -> {
|
||||
if (typeConfig.differentThanPrev) {
|
||||
if (typeConfig.differentThanPrev != null) {
|
||||
version.get(type).differentThanNext = true;
|
||||
}
|
||||
});
|
||||
@ -514,6 +525,7 @@ public class DataModel {
|
||||
this.computedTypes = computedTypes;
|
||||
this.versionedTypePrevVersion = versionedTypePrevVersion;
|
||||
this.versionedTypeNextVersion = versionedTypeNextVersion;
|
||||
this.baseTypeDataChanges = baseTypeDataChanges;
|
||||
}
|
||||
|
||||
private String tryInsertAtIndex(LinkedHashMap<String, String> data, String key, String value, int index) {
|
||||
@ -867,4 +879,8 @@ public class DataModel {
|
||||
}
|
||||
return Stream.of();
|
||||
}
|
||||
|
||||
public List<TransformationConfiguration> getChanges(ComputedTypeBase nextType) {
|
||||
return baseTypeDataChanges.get(nextType.getVersion().getVersion()).get(nextType.getName());
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,9 @@ package it.cavallium.data.generator.plugin;
|
||||
|
||||
import static it.cavallium.data.generator.plugin.DataModel.fixType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
@ -13,7 +15,7 @@ public final class ParsedClass {
|
||||
public String stringRepresenter;
|
||||
|
||||
public LinkedHashMap<String, String> data;
|
||||
public boolean differentThanPrev;
|
||||
public List<TransformationConfiguration> differentThanPrev;
|
||||
public boolean differentThanNext;
|
||||
|
||||
public ParsedClass(ClassConfiguration baseTypesData) {
|
||||
@ -67,4 +69,11 @@ public final class ParsedClass {
|
||||
cc.data = new LinkedHashMap<>(data);
|
||||
return cc;
|
||||
}
|
||||
|
||||
public void addDifferentThanPrev(TransformationConfiguration transformation) {
|
||||
if (differentThanPrev == null) {
|
||||
differentThanPrev = new ArrayList<>();
|
||||
}
|
||||
differentThanPrev.add(transformation);
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,7 @@ import it.cavallium.data.generator.plugin.classgen.GenSerializerBaseX;
|
||||
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.GenVersion;
|
||||
import it.cavallium.data.generator.plugin.classgen.GenVersions;
|
||||
import it.unimi.dsi.fastutil.booleans.BooleanList;
|
||||
@ -187,6 +188,8 @@ public class SourcesGenerator {
|
||||
|
||||
new GenSerializerNullableX(genParams).run();
|
||||
|
||||
new GenUpgraderBaseX(genParams).run();
|
||||
|
||||
// Update the hash at the end
|
||||
Files.writeString(hashPath, basePackageName + '\n' + useRecordBuilders + '\n' + curHash + '\n',
|
||||
StandardCharsets.UTF_8, TRUNCATE_EXISTING, WRITE, CREATE);
|
||||
|
@ -122,16 +122,16 @@ public class GenNullableX extends ClassGenerator {
|
||||
.addParameter(ParameterSpec.builder(type, "fallback").addAnnotation(NotNull.class).build())
|
||||
.addStatement("return this.value == null ? fallback : this")
|
||||
.build());
|
||||
|
||||
classBuilder.addMethod(MethodSpec
|
||||
.methodBuilder("getNullable")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||
.addAnnotation(Nullable.class)
|
||||
.returns(baseType)
|
||||
.addStatement("return this.value")
|
||||
.build());
|
||||
}
|
||||
|
||||
classBuilder.addMethod(MethodSpec
|
||||
.methodBuilder("getNullable")
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
||||
.addAnnotation(Nullable.class)
|
||||
.returns(baseType)
|
||||
.addStatement("return this.value")
|
||||
.build());
|
||||
|
||||
return new GeneratedClass(type.packageName(), classBuilder);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,215 @@
|
||||
package it.cavallium.data.generator.plugin.classgen;
|
||||
|
||||
import static it.cavallium.data.generator.plugin.DataModel.fixType;
|
||||
|
||||
import com.squareup.javapoet.ClassName;
|
||||
import com.squareup.javapoet.CodeBlock;
|
||||
import com.squareup.javapoet.FieldSpec;
|
||||
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.ComputedTypeBase;
|
||||
import it.cavallium.data.generator.plugin.ComputedVersion;
|
||||
import it.cavallium.data.generator.plugin.MoveDataConfiguration;
|
||||
import it.cavallium.data.generator.plugin.NewDataConfiguration;
|
||||
import it.cavallium.data.generator.plugin.RemoveDataConfiguration;
|
||||
import it.cavallium.data.generator.plugin.TransformationConfiguration;
|
||||
import it.cavallium.data.generator.plugin.UpgradeDataConfiguration;
|
||||
import java.io.IOException;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class GenUpgraderBaseX extends ClassGenerator {
|
||||
|
||||
public GenUpgraderBaseX(ClassGeneratorParams params) {
|
||||
super(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Stream<GeneratedClass> generateClasses() {
|
||||
return dataModel.getVersionsSet().parallelStream().flatMap(this::generateVersionClasses);
|
||||
}
|
||||
|
||||
private Stream<GeneratedClass> generateVersionClasses(ComputedVersion version) {
|
||||
return dataModel
|
||||
.getBaseTypesComputed(version)
|
||||
.filter(type -> !type.getVersion().isCurrent() && type.getVersion().equals(version))
|
||||
.map(type -> generateTypeVersioned(version, type));
|
||||
}
|
||||
|
||||
private GeneratedClass generateTypeVersioned(ComputedVersion version, ComputedTypeBase typeBase) {
|
||||
ClassName upgraderClassName = typeBase.getJUpgraderName(basePackageName);
|
||||
ClassName typeBaseClassName = typeBase.getJTypeName(basePackageName);
|
||||
ComputedTypeBase nextTypeBase = dataModel.getNextVersion(typeBase);
|
||||
|
||||
var classBuilder = TypeSpec.classBuilder(upgraderClassName.simpleName());
|
||||
|
||||
classBuilder.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||
|
||||
classBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
||||
typeBaseClassName,
|
||||
nextTypeBase.getJTypeName(basePackageName)
|
||||
));
|
||||
|
||||
generateUpgradeMethod(version, typeBase, nextTypeBase, classBuilder);
|
||||
|
||||
return new GeneratedClass(upgraderClassName.packageName(), classBuilder);
|
||||
}
|
||||
|
||||
private void generateUpgradeMethod(ComputedVersion version, ComputedTypeBase typeBase,
|
||||
ComputedTypeBase nextTypeBase,
|
||||
Builder classBuilder) {
|
||||
var method = MethodSpec.methodBuilder("upgrade");
|
||||
|
||||
method.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||
method.addException(IOException.class);
|
||||
|
||||
ClassName typeBaseClassName = typeBase.getJTypeName(basePackageName);
|
||||
ClassName nextTypeBaseClassName = nextTypeBase.getJTypeName(basePackageName);
|
||||
method.returns(nextTypeBaseClassName);
|
||||
method.addAnnotation(NotNull.class);
|
||||
|
||||
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();
|
||||
HashMap<String, String> initializerStaticFieldNames = new HashMap<>();
|
||||
List<TransformationConfiguration> transformations = dataModel.getChanges(nextTypeBase);
|
||||
method.addCode("return new $T(\n$>", nextTypeBaseClassName);
|
||||
record ResultField(String name, ComputedType type, CodeBlock code) {}
|
||||
Stream<ResultField> resultFields;
|
||||
if (transformations.isEmpty()) {
|
||||
resultFields = typeBase
|
||||
.getData()
|
||||
.entrySet()
|
||||
.stream()
|
||||
.map(e -> new ResultField(e.getKey(), e.getValue(), CodeBlock.of("data.$N()", e.getKey())));
|
||||
} else {
|
||||
record Field(String name, ComputedType type, CodeBlock code, int processFromTx) {}
|
||||
var fields = Stream.concat(
|
||||
typeBase.getData().entrySet().stream()
|
||||
.map(e -> new Field(e.getKey(), e.getValue(), CodeBlock.of("data.$N()", e.getKey()), 0)),
|
||||
IntStream
|
||||
.range(0, transformations.size())
|
||||
.mapToObj(i -> Map.entry(i, transformations.get(i)))
|
||||
.filter(t -> t.getValue() instanceof NewDataConfiguration)
|
||||
.map(t -> Map.entry(t.getKey(), (NewDataConfiguration) t.getValue()))
|
||||
.map(e -> {
|
||||
var i = e.getKey();
|
||||
var newDataConfiguration = e.getValue();
|
||||
var computedTypes = dataModel.getComputedTypes(version);
|
||||
var newFieldType = Objects.requireNonNull(computedTypes.get(fixType(newDataConfiguration.type)));
|
||||
var initializerClass = ClassName.bestGuess(newDataConfiguration.initializer);
|
||||
|
||||
var initializerName = createInitializerStaticField(nextInitializerStaticFieldId,
|
||||
initializerStaticFieldNames,
|
||||
classBuilder,
|
||||
initializerClass
|
||||
);
|
||||
|
||||
return new Field(newDataConfiguration.to, newFieldType, CodeBlock.of("$N", initializerName), i);
|
||||
})
|
||||
);
|
||||
resultFields = fields.<ResultField>mapMulti((field, consumer) -> {
|
||||
String fieldName = field.name();
|
||||
ComputedType fieldType = field.type();
|
||||
CodeBlock codeBlock = CodeBlock.of("data.$N()", fieldName);
|
||||
for (TransformationConfiguration transformation : transformations.subList(field.processFromTx(),
|
||||
transformations.size()
|
||||
)) {
|
||||
if (transformation instanceof MoveDataConfiguration moveDataConfiguration) {
|
||||
if (!moveDataConfiguration.from.equals(fieldName)) {
|
||||
continue;
|
||||
}
|
||||
fieldName = moveDataConfiguration.to;
|
||||
} else if (transformation instanceof NewDataConfiguration newDataConfiguration) {
|
||||
continue;
|
||||
} else if (transformation instanceof RemoveDataConfiguration removeDataConfiguration) {
|
||||
if (!removeDataConfiguration.from.equals(fieldName)) {
|
||||
continue;
|
||||
}
|
||||
return;
|
||||
} else if (transformation instanceof UpgradeDataConfiguration upgradeDataConfiguration) {
|
||||
if (!upgradeDataConfiguration.from.equals(fieldName)) {
|
||||
continue;
|
||||
}
|
||||
var upgraderClass = ClassName.bestGuess(upgradeDataConfiguration.upgrader);
|
||||
var cb = CodeBlock.builder();
|
||||
var newFieldType = Objects
|
||||
.requireNonNull(dataModel.getComputedTypes(version).get(fixType(upgradeDataConfiguration.type)));
|
||||
cb.add("($T) $T.upgrade(($T) ",
|
||||
newFieldType.getJTypeName(basePackageName),
|
||||
upgraderClass,
|
||||
fieldType.getJTypeName(basePackageName)
|
||||
);
|
||||
cb.add(codeBlock);
|
||||
cb.add(")");
|
||||
codeBlock = cb.build();
|
||||
fieldType = newFieldType;
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Unsupported transformation type: " + transformation);
|
||||
}
|
||||
}
|
||||
consumer.accept(new ResultField(fieldName, fieldType, codeBlock));
|
||||
}).sorted(Comparator.comparingInt(f -> expectedResultFields.indexOf(f.name())));
|
||||
}
|
||||
resultFields
|
||||
.flatMap(e -> Stream.of(CodeBlock.of(",\n"), upgradeFieldToType(e.name(), e.type(), e.code(), nextTypeBase)))
|
||||
.skip(1)
|
||||
.forEach(method::addCode);
|
||||
method.addCode("\n$<);\n");
|
||||
|
||||
classBuilder.addMethod(method.build());
|
||||
}
|
||||
|
||||
private String createInitializerStaticField(AtomicInteger nextInitializerStaticFieldId,
|
||||
HashMap<String, String> initializerStaticFieldNames,
|
||||
Builder classBuilder,
|
||||
ClassName initializerClass) {
|
||||
var ref = initializerClass.reflectionName();
|
||||
var initializerName = initializerStaticFieldNames.get(ref);
|
||||
if (initializerName == null) {
|
||||
initializerName = "I" + nextInitializerStaticFieldId.getAndIncrement();
|
||||
classBuilder.addField(FieldSpec.builder(initializerClass, initializerName).initializer("new $T()", initializerClass).build());
|
||||
initializerStaticFieldNames.put(ref, initializerName);
|
||||
}
|
||||
return initializerName;
|
||||
}
|
||||
|
||||
private CodeBlock upgradeFieldToType(String fieldName,
|
||||
ComputedType fieldType,
|
||||
CodeBlock codeBlock,
|
||||
ComputedTypeBase nextTypeBase) {
|
||||
while (fieldType instanceof VersionedComputedType versionedComputedType
|
||||
&& versionedComputedType.getVersion().compareTo(nextTypeBase.getVersion()) < 0) {
|
||||
var currentFieldType = fieldType;
|
||||
var nextFieldType = dataModel.getNextVersion(currentFieldType);
|
||||
codeBlock = currentFieldType.wrapWithUpgrade(basePackageName, codeBlock, nextFieldType);
|
||||
fieldType = nextFieldType;
|
||||
}
|
||||
return codeBlock;
|
||||
}
|
||||
|
||||
private String getFieldVarName(int totalTransformations, int transformationId) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ import it.cavallium.data.generator.DataSerializer;
|
||||
import it.cavallium.data.generator.DataUpgrader;
|
||||
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.ComputedVersion;
|
||||
import java.io.IOException;
|
||||
@ -170,7 +171,7 @@ 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 VersionedComputedType versionedComputedType
|
||||
boolean shouldCreateInstanceField = type instanceof ComputedTypeBase versionedComputedType
|
||||
&& versionedComputedType.getVersion().equals(version) && !version.isCurrent();
|
||||
if (!shouldCreateInstanceField) {
|
||||
return;
|
||||
|
@ -1,5 +1,5 @@
|
||||
package it.cavallium.data.generator.nativedata;
|
||||
|
||||
public interface INullable {
|
||||
Object $getNullable();
|
||||
Object getNullable();
|
||||
}
|
||||
|
@ -86,10 +86,6 @@ public class NullableInt52 implements Serializable, INullable, TypedNullable<Int
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Int52 getNullable() {
|
||||
|
@ -119,11 +119,6 @@ public class NullableString implements Serializable, INullable, TypedNullable<St
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getNullable() {
|
||||
return value;
|
||||
|
@ -90,11 +90,6 @@ public class Nullableboolean implements Serializable, INullable, NativeNullable<
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Boolean getNullable() {
|
||||
return value;
|
||||
|
@ -98,11 +98,6 @@ public class Nullablebyte implements Serializable, INullable, NativeNullable<Byt
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Byte getNullable() {
|
||||
return value;
|
||||
|
@ -90,11 +90,6 @@ public class Nullablechar implements Serializable, INullable, NativeNullable<Cha
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Character $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Character getNullable() {
|
||||
return value;
|
||||
|
@ -98,11 +98,6 @@ public class Nullabledouble implements Serializable, INullable, NativeNullable<D
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Double $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Double getNullable() {
|
||||
return value;
|
||||
|
@ -98,11 +98,6 @@ public class Nullablefloat implements Serializable, INullable, NativeNullable<Fl
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Float getNullable() {
|
||||
return value;
|
||||
|
@ -98,11 +98,6 @@ public class Nullableint implements Serializable, INullable, NativeNullable<Inte
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Integer getNullable() {
|
||||
return value;
|
||||
|
@ -98,11 +98,6 @@ public class Nullablelong implements Serializable, INullable, NativeNullable<Lon
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getNullable() {
|
||||
return value;
|
||||
|
@ -98,11 +98,6 @@ public class Nullableshort implements Serializable, INullable, NativeNullable<Sh
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Short $getNullable() {
|
||||
return this.getNullable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Short getNullable() {
|
||||
return value;
|
||||
|
@ -0,0 +1,30 @@
|
||||
package it.cavallium.data.generator.nativedata;
|
||||
|
||||
import it.cavallium.data.generator.DataUpgrader;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
public class UpgradeUtil {
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <A, B> List<B> upgradeArray(List<A> from, DataUpgrader<A, B> upgrader)
|
||||
throws IOException {
|
||||
Object[] array;
|
||||
if (from instanceof ImmutableWrappedArrayList<A> immutableWrappedArrayList) {
|
||||
array = immutableWrappedArrayList.a;
|
||||
} else {
|
||||
array = from.toArray();
|
||||
}
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = (B) upgrader.upgrade((A) array[i]);
|
||||
}
|
||||
return (ImmutableWrappedArrayList<B>) new ImmutableWrappedArrayList<>(array);
|
||||
}
|
||||
|
||||
public static <A, B> B upgradeNullable(A nullableValue, DataUpgrader<A, B> upgrader) throws IOException {
|
||||
if (nullableValue == null) {
|
||||
return null;
|
||||
} else {
|
||||
return upgrader.upgrade(nullableValue);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user