diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ClassConfiguration.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ClassConfiguration.java index dfc2379..670210d 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ClassConfiguration.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ClassConfiguration.java @@ -37,9 +37,7 @@ public final class ClassConfiguration { return hash; } - @SuppressWarnings("MethodDoesntCallSuperMethod") - @Override - public ClassConfiguration clone() { + public ClassConfiguration copy() { var cc = new ClassConfiguration(); cc.stringRepresenter = stringRepresenter; cc.data = new LinkedHashMap<>(data); diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedType.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedType.java index a94fdf7..c239d7c 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedType.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedType.java @@ -3,6 +3,7 @@ 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.LinkedHashMap; import java.util.stream.Stream; public sealed interface ComputedType permits VersionedComputedType, ComputedTypeArray, ComputedTypeCustom, @@ -33,7 +34,8 @@ public sealed interface ComputedType permits VersionedComputedType, ComputedType return !version.isCurrent() && version.getVersion() == this.getVersion().getVersion(); } - ComputedType withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker); + ComputedType withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker, + LinkedHashMap data); } /** diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeArrayVersioned.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeArrayVersioned.java index d1e6165..5e1625d 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeArrayVersioned.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeArrayVersioned.java @@ -6,6 +6,7 @@ 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.LinkedHashMap; import java.util.List; import java.util.Objects; import java.util.stream.Stream; @@ -32,7 +33,8 @@ public final class ComputedTypeArrayVersioned implements VersionedComputedType, } @Override - public ComputedTypeArrayVersioned withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker) { + public ComputedTypeArrayVersioned withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker, + LinkedHashMap data) { return new ComputedTypeArrayVersioned(baseType.withVersion(version), computedTypeSupplier ); diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeBase.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeBase.java index f9c4294..12d86d9 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeBase.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeBase.java @@ -39,7 +39,8 @@ public final class ComputedTypeBase implements VersionedComputedType { } @Override - public ComputedTypeBase withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker) { + public ComputedTypeBase withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker, + LinkedHashMap data) { var newData = new LinkedHashMap(); data.forEach((k, v) -> newData.put(k, v.withVersionIfChanged(version, versionChangeChecker))); return new ComputedTypeBase(type.withVersion(version), diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeNullableVersioned.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeNullableVersioned.java index d2f5b92..44657b2 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeNullableVersioned.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeNullableVersioned.java @@ -5,6 +5,7 @@ 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.LinkedHashMap; import java.util.Objects; import java.util.stream.Stream; @@ -30,7 +31,8 @@ public final class ComputedTypeNullableVersioned implements ComputedTypeNullable } @Override - public ComputedTypeNullableVersioned withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker) { + public ComputedTypeNullableVersioned withChangeAtVersion(ComputedVersion version, VersionChangeChecker versionChangeChecker, + LinkedHashMap data) { return new ComputedTypeNullableVersioned(baseType.withVersion(version), computedTypeSupplier ); diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeSuper.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeSuper.java index 15bd54c..d620ad5 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeSuper.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ComputedTypeSuper.java @@ -4,6 +4,7 @@ import com.squareup.javapoet.ClassName; import com.squareup.javapoet.TypeName; import it.cavallium.data.generator.plugin.ComputedType.VersionedComputedType; import java.util.ArrayList; +import java.util.LinkedHashMap; import java.util.List; import java.util.Objects; import java.util.stream.Stream; @@ -33,7 +34,7 @@ public final class ComputedTypeSuper implements VersionedComputedType { @Override public it.cavallium.data.generator.plugin.ComputedTypeSuper withChangeAtVersion(ComputedVersion version, - VersionChangeChecker versionChangeChecker) { + VersionChangeChecker versionChangeChecker, LinkedHashMap data) { return new it.cavallium.data.generator.plugin.ComputedTypeSuper(type.withVersion(version), subTypes.stream().map(subType -> subType.withVersionIfChanged(version, versionChangeChecker)).toList(), computedTypeSupplier diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/CustomTypesConfiguration.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/CustomTypesConfiguration.java index 1c75ac8..fd8ed2e 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/CustomTypesConfiguration.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/CustomTypesConfiguration.java @@ -1,8 +1,5 @@ package it.cavallium.data.generator.plugin; -import com.squareup.javapoet.ClassName; -import com.squareup.javapoet.ParameterizedTypeName; -import com.squareup.javapoet.TypeName; import java.util.Objects; public final class CustomTypesConfiguration { @@ -38,9 +35,7 @@ public final class CustomTypesConfiguration { return hash; } - @SuppressWarnings("MethodDoesntCallSuperMethod") - @Override - public CustomTypesConfiguration clone() { + public CustomTypesConfiguration copy() { var c = new CustomTypesConfiguration(); c.javaClass = this.javaClass; c.serializer = this.serializer; diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/DataModel.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/DataModel.java index 4cc72e0..26f75f0 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/DataModel.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/DataModel.java @@ -168,7 +168,12 @@ public class DataModel { Map prevVersionConfiguration = requireNonNull(computedClassConfig.get(versionIndex - 1)); Map newVersionConfiguration = prevVersionConfiguration.entrySet().stream() - .map(entry -> Map.entry(entry.getKey(), entry.getValue().clone())) + .map(entry -> { + var parsedClass = entry.getValue().copy(); + parsedClass.differentThanPrev = null; + parsedClass.differentThanNext = false; + return Map.entry(entry.getKey(), parsedClass); + }) .collect(Collectors.toMap(Entry::getKey, Entry::getValue)); for (VersionTransformation rawTransformation : version.transformations) { @@ -284,6 +289,7 @@ public class DataModel { )); // Compute the types + Object2IntMap currentOrNewerTypeVersion = new Object2IntOpenHashMap<>(); Int2ObjectMap> computedTypes = new Int2ObjectLinkedOpenHashMap<>(); Int2ObjectMap> randomComputedTypes = new Int2ObjectOpenHashMap<>(); Int2ObjectMap>> baseTypeDataChanges = new Int2ObjectOpenHashMap<>(); @@ -369,8 +375,11 @@ public class DataModel { // Compute native types versionBaseTypes.addAll(ComputedTypeNative.get(computedTypeSupplier)); - randomComputedTypes.put(versionIndexF, - versionBaseTypes.stream().distinct().collect(Collectors.toMap(ComputedType::getName, identity()))); + var allLatestTypes = versionBaseTypes.stream().distinct().collect(Collectors.toMap(ComputedType::getName, identity())); + + allLatestTypes.forEach((typeName, type) -> currentOrNewerTypeVersion.put(typeName, latestVersion)); + + randomComputedTypes.put(versionIndexF, allLatestTypes); } else { Set changedTypes = randomComputedTypes.get(versionIndexF + 1).values().stream() .filter(prevType -> prevType instanceof ComputedTypeBase prevBaseType @@ -391,15 +400,37 @@ public class DataModel { } while (addedMoreTypes); } + for (String changedType : changedTypes) { + currentOrNewerTypeVersion.put(changedType, versionIndexF); + } + Map currentVersionComputedTypes = new HashMap<>(); var versionChangeChecker = new VersionChangeChecker(changedTypes, versionIndexF, latestVersion); - randomComputedTypes.get(versionIndexF + 1).forEach((name, type) -> { - if (!changedTypes.contains(name)) { - currentVersionComputedTypes.put(name, type); + randomComputedTypes.get(versionIndexF + 1).forEach((computedTypeName, computedType) -> { + if (!changedTypes.contains(computedTypeName)) { + currentVersionComputedTypes.put(computedTypeName, computedType); } else { - if (type instanceof VersionedComputedType versionedComputedType) { - ComputedType newType = versionedComputedType.withChangeAtVersion(version, versionChangeChecker); - currentVersionComputedTypes.put(name, newType); + if (computedType instanceof VersionedComputedType versionedComputedType) { + ParsedClass parsedClass = computedClassConfig.get(versionIndexF).get(computedTypeName); + LinkedHashMap parsedFields; + if (parsedClass != null) { + parsedFields = parsedClass.data + .entrySet() + .stream() + .collect(Collectors.toMap(Entry::getKey, e -> { + var fieldTypeName = e.getValue(); + return new VersionedType(fieldTypeName, computedVersions.get(currentOrNewerTypeVersion.getInt(fieldTypeName))); + }, (a, b) -> { + throw new IllegalStateException(); + }, LinkedHashMap::new)); + } else { + parsedFields = new LinkedHashMap<>(); + } + ComputedType olderComputedType = versionedComputedType.withChangeAtVersion(version, + versionChangeChecker, + parsedFields + ); + currentVersionComputedTypes.put(computedTypeName, olderComputedType); } else { throw new IllegalStateException(); } @@ -881,6 +912,10 @@ public class DataModel { } public List getChanges(ComputedTypeBase nextType) { - return baseTypeDataChanges.get(nextType.getVersion().getVersion()).get(nextType.getName()); + var prev = getPrevVersion(nextType); + if (prev == null) { + return List.of(); + } + return baseTypeDataChanges.get(prev.getVersion().getVersion() + 1).get(nextType.getName()); } } diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/MoveDataConfiguration.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/MoveDataConfiguration.java index e0f9ca5..603c52b 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/MoveDataConfiguration.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/MoveDataConfiguration.java @@ -41,9 +41,7 @@ public final class MoveDataConfiguration implements TransformationConfiguration return hash; } - @SuppressWarnings("MethodDoesntCallSuperMethod") - @Override - public MoveDataConfiguration clone() { + public MoveDataConfiguration copy() { var c = new MoveDataConfiguration(); if (this.transformClass != null) c.transformClass = this.transformClass; if (this.from != null) c.from = this.from; diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/NewDataConfiguration.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/NewDataConfiguration.java index a712e5f..03d1b8c 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/NewDataConfiguration.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/NewDataConfiguration.java @@ -47,9 +47,7 @@ public class NewDataConfiguration implements TransformationConfiguration { return hash; } - @SuppressWarnings("MethodDoesntCallSuperMethod") - @Override - public NewDataConfiguration clone() { + public NewDataConfiguration copy() { var c = new NewDataConfiguration(); if (this.transformClass != null) c.transformClass = this.transformClass; if (this.initializer != null) c.initializer = this.initializer; diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ParsedClass.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ParsedClass.java index f0bc1e0..6658d29 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ParsedClass.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ParsedClass.java @@ -61,12 +61,12 @@ public final class ParsedClass { return hash; } - @SuppressWarnings("MethodDoesntCallSuperMethod") - @Override - public ParsedClass clone() { + public ParsedClass copy() { var cc = new ParsedClass(); if (this.stringRepresenter != null) cc.stringRepresenter = this.stringRepresenter; cc.data = new LinkedHashMap<>(data); + cc.differentThanNext = differentThanNext; + cc.differentThanPrev = differentThanPrev; return cc; } diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ParsedVersion.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ParsedVersion.java index ade98c6..786a9c3 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ParsedVersion.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/ParsedVersion.java @@ -11,7 +11,7 @@ public class ParsedVersion { public ParsedVersion(VersionConfiguration versionConfiguration) { this.details = versionConfiguration.details; if (versionConfiguration.transformations != null) { - this.transformations = versionConfiguration.transformations.stream().map(VersionTransformation::clone).toList(); + this.transformations = versionConfiguration.transformations.stream().map(VersionTransformation::copy).toList(); } } diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/RemoveDataConfiguration.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/RemoveDataConfiguration.java index 1b33fa4..4b6c789 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/RemoveDataConfiguration.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/RemoveDataConfiguration.java @@ -37,9 +37,7 @@ public class RemoveDataConfiguration implements TransformationConfiguration { return hash; } - @SuppressWarnings("MethodDoesntCallSuperMethod") - @Override - public RemoveDataConfiguration clone() { + public RemoveDataConfiguration copy() { var c = new RemoveDataConfiguration(); if (this.transformClass != null) c.transformClass = this.transformClass; if (this.from != null) c.from = this.from; diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/UpgradeDataConfiguration.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/UpgradeDataConfiguration.java index 322ec91..34ef3be 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/UpgradeDataConfiguration.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/UpgradeDataConfiguration.java @@ -42,9 +42,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration { return hash; } - @SuppressWarnings("MethodDoesntCallSuperMethod") - @Override - public UpgradeDataConfiguration clone() { + public UpgradeDataConfiguration copy() { var c = new UpgradeDataConfiguration(); if (this.transformClass != null) c.transformClass = this.transformClass; if (this.from != null) c.from = this.from; diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/VersionTransformation.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/VersionTransformation.java index a87d7b2..1d8346b 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/VersionTransformation.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/VersionTransformation.java @@ -87,14 +87,12 @@ public final class VersionTransformation { return hash; } - @SuppressWarnings("MethodDoesntCallSuperMethod") - @Override - public VersionTransformation clone() { + public VersionTransformation copy() { var t = new VersionTransformation(); - if (this.moveData != null) t.moveData = this.moveData.clone(); - if (this.removeData != null) t.removeData = this.removeData.clone(); - if (this.upgradeData != null) t.upgradeData = this.upgradeData.clone(); - if (this.newData != null) t.newData = this.newData.clone(); + if (this.moveData != null) t.moveData = this.moveData.copy(); + if (this.removeData != null) t.removeData = this.removeData.copy(); + if (this.upgradeData != null) t.upgradeData = this.upgradeData.copy(); + if (this.newData != null) t.newData = this.newData.copy(); return t; } } diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenCurrentVersion.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenCurrentVersion.java index 64eebb7..3d5f7f6 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenCurrentVersion.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenCurrentVersion.java @@ -29,6 +29,7 @@ public class GenCurrentVersion extends ClassGenerator { @Override protected Stream generateClasses() { + var currentVersionPackage = dataModel.getCurrentVersion().getPackage(basePackageName); var currentVersionDataPackage = dataModel.getCurrentVersion().getDataPackage(basePackageName); var currentVersionClass = TypeSpec.classBuilder("CurrentVersion"); @@ -57,7 +58,7 @@ public class GenCurrentVersion extends ClassGenerator { .addModifiers(Modifier.FINAL).addModifiers(Modifier.STATIC) .returns(ParameterizedTypeName.get(ClassName.get(Set.class), ParameterizedTypeName.get(ClassName.get(Class.class), - WildcardTypeName.subtypeOf(ClassName.get(currentVersionDataPackage, "IType"))))) + WildcardTypeName.subtypeOf(ClassName.get(currentVersionPackage, "IType"))))) .addCode("return $T.of(\n", Set.class); AtomicBoolean isFirst = new AtomicBoolean(true); dataModel.getSuperTypesComputed(dataModel.getCurrentVersion()).forEach(superType -> { @@ -77,10 +78,10 @@ public class GenCurrentVersion extends ClassGenerator { .addModifiers(Modifier.FINAL).addModifiers(Modifier.STATIC) .returns(ParameterizedTypeName.get(ClassName.get(Set.class), ParameterizedTypeName.get(ClassName.get(Class.class), - WildcardTypeName.subtypeOf(ClassName.get(currentVersionDataPackage, "IBaseType"))))); + WildcardTypeName.subtypeOf(ClassName.get(currentVersionPackage, "IBaseType"))))); getSuperTypeSubtypesClasses .addParameter(ParameterSpec.builder(ParameterizedTypeName.get(ClassName.get(Class.class), - WildcardTypeName.subtypeOf(ClassName.get(currentVersionDataPackage, "IType")) + WildcardTypeName.subtypeOf(ClassName.get(currentVersionPackage, "IType")) ), "superTypeClass").build()); getSuperTypeSubtypesClasses.beginControlFlow("return switch (superTypeClass.getCanonicalName())"); dataModel.getSuperTypesComputed(dataModel.getCurrentVersion()).forEach(superType -> { @@ -107,7 +108,7 @@ public class GenCurrentVersion extends ClassGenerator { // UpgradeDataToLatestVersion1 Method { var upgradeDataToLatestVersion1MethodBuilder = MethodSpec.methodBuilder("upgradeDataToLatestVersion") - .addTypeVariable(TypeVariableName.get("U", ClassName.get(currentVersionDataPackage, "IBaseType"))) + .addTypeVariable(TypeVariableName.get("U", ClassName.get(currentVersionPackage, "IBaseType"))) .addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC).addModifiers(Modifier.FINAL).returns(TypeVariableName.get("U")) .addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build()).addParameter( ParameterSpec.builder(ClassName.get(dataModel.getRootPackage(basePackageName), "BaseType"), "type").build()) @@ -133,7 +134,7 @@ public class GenCurrentVersion extends ClassGenerator { var versionsClassName = ClassName.get(dataModel.getRootPackage(basePackageName), "Versions"); var upgradeDataToLatestVersion2MethodBuilder = MethodSpec.methodBuilder("upgradeDataToLatestVersion") .addModifiers(Modifier.PUBLIC).addModifiers(Modifier.STATIC).addModifiers(Modifier.FINAL).addTypeVariable(TypeVariableName.get("T")) - .addTypeVariable(TypeVariableName.get("U", ClassName.get(currentVersionDataPackage, "IBaseType"))) + .addTypeVariable(TypeVariableName.get("U", ClassName.get(currentVersionPackage, "IBaseType"))) .returns(TypeVariableName.get("U")) .addParameter(ParameterSpec.builder(TypeName.INT, "oldVersion").build()) .addParameter(ParameterSpec.builder(TypeVariableName.get("T"), "oldData").build()) diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenIBaseType.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenIBaseType.java index 90e4f53..638c6b3 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenIBaseType.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenIBaseType.java @@ -24,7 +24,7 @@ public class GenIBaseType extends ClassGenerator { interfaceBuilder.addModifiers(Modifier.PUBLIC); - var iTypeClassName = ClassName.get(version.getDataPackage(basePackageName), "IType"); + var iTypeClassName = ClassName.get(version.getPackage(basePackageName), "IType"); var baseTypeClassName = ClassName.get(dataModel.getRootPackage(basePackageName), "BaseType"); interfaceBuilder.addSuperinterface(iTypeClassName); diff --git a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenUpgraderBaseX.java b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenUpgraderBaseX.java index 899ac3f..dad5e62 100644 --- a/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenUpgraderBaseX.java +++ b/data-generator-plugin/src/main/java/it/cavallium/data/generator/plugin/classgen/GenUpgraderBaseX.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; import javax.lang.model.element.Modifier; @@ -93,6 +94,8 @@ public class GenUpgraderBaseX extends ClassGenerator { AtomicInteger nextInitializerStaticFieldId = new AtomicInteger(); HashMap initializerStaticFieldNames = new HashMap<>(); + AtomicInteger nextUpgraderStaticFieldId = new AtomicInteger(); + HashMap upgraderStaticFieldNames = new HashMap<>(); List transformations = dataModel.getChanges(nextTypeBase); method.addCode("return new $T(\n$>", nextTypeBaseClassName); record ResultField(String name, ComputedType type, CodeBlock code) {} @@ -116,7 +119,7 @@ public class GenUpgraderBaseX extends ClassGenerator { .map(e -> { var i = e.getKey(); var newDataConfiguration = e.getValue(); - var computedTypes = dataModel.getComputedTypes(version); + var computedTypes = dataModel.getComputedTypes(nextTypeBase.getVersion()); var newFieldType = Objects.requireNonNull(computedTypes.get(fixType(newDataConfiguration.type))); var initializerClass = ClassName.bestGuess(newDataConfiguration.initializer); @@ -126,13 +129,13 @@ public class GenUpgraderBaseX extends ClassGenerator { initializerClass ); - return new Field(newDataConfiguration.to, newFieldType, CodeBlock.of("$N", initializerName), i); + return new Field(newDataConfiguration.to, newFieldType, CodeBlock.of("$N.initialize()", initializerName), i + 1); }) ); resultFields = fields.mapMulti((field, consumer) -> { String fieldName = field.name(); ComputedType fieldType = field.type(); - CodeBlock codeBlock = CodeBlock.of("data.$N()", fieldName); + CodeBlock codeBlock = field.code(); for (TransformationConfiguration transformation : transformations.subList(field.processFromTx(), transformations.size() )) { @@ -142,11 +145,20 @@ public class GenUpgraderBaseX extends ClassGenerator { } fieldName = moveDataConfiguration.to; } else if (transformation instanceof NewDataConfiguration newDataConfiguration) { + if (newDataConfiguration.to.equals(fieldName)) { + var type = dataModel.getComputedTypes(version).get(fixType(newDataConfiguration.type)); + throw new IllegalStateException( + "New field " + typeBase.getName() + "." + fieldName + " of type \"" + type + "\" at version \"" + nextTypeBase.getVersion() + + "\" conflicts with another field of type \"" + fieldType + "\" with the same name at version \"" + + version + "\"!"); + } continue; } else if (transformation instanceof RemoveDataConfiguration removeDataConfiguration) { if (!removeDataConfiguration.from.equals(fieldName)) { continue; } + fieldName = null; + fieldType = null; return; } else if (transformation instanceof UpgradeDataConfiguration upgradeDataConfiguration) { if (!upgradeDataConfiguration.from.equals(fieldName)) { @@ -156,9 +168,16 @@ public class GenUpgraderBaseX extends ClassGenerator { var cb = CodeBlock.builder(); var newFieldType = Objects .requireNonNull(dataModel.getComputedTypes(version).get(fixType(upgradeDataConfiguration.type))); - cb.add("($T) $T.upgrade(($T) ", + + var upgraderName = createUpgraderStaticField(nextUpgraderStaticFieldId, + upgraderStaticFieldNames, + classBuilder, + upgraderClass + ); + + cb.add("($T) $N.upgrade(($T) ", newFieldType.getJTypeName(basePackageName), - upgraderClass, + upgraderName, fieldType.getJTypeName(basePackageName) ); cb.add(codeBlock); @@ -169,11 +188,27 @@ public class GenUpgraderBaseX extends ClassGenerator { throw new UnsupportedOperationException("Unsupported transformation type: " + transformation); } } + System.out.println(); 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))) + AtomicInteger currentField = new AtomicInteger(); + var resultFieldsList = resultFields.toList(); + resultFieldsList.stream().flatMap(e -> { + var currentFieldIndex = currentField.getAndIncrement(); + var currentFieldName = e.name(); + var expectedFieldIndex = expectedResultFields.indexOf(currentFieldName); + if (expectedFieldIndex != currentFieldIndex) { + var expectedFieldName = (currentFieldIndex >= 0 && expectedResultFields.size() > currentFieldIndex) ? expectedResultFields.get(currentFieldIndex) : ""; + throw new IllegalStateException( + "" + typeBase + " to " + nextTypeBase + ". Index " + currentFieldIndex + ". Expected " + expectedFieldName + ", got " + currentFieldName + + ".\n\tExpected: " + String.join(", ", expectedResultFields) + "\n\tResult: " + resultFieldsList + .stream() + .map(ResultField::name) + .collect(Collectors.joining(", "))); + } + return Stream.of(CodeBlock.of(",\n"), upgradeFieldToType(e.name(), e.type(), e.code(), nextTypeBase)); + }) .skip(1) .forEach(method::addCode); method.addCode("\n$<);\n"); @@ -189,12 +224,34 @@ public class GenUpgraderBaseX extends ClassGenerator { var initializerName = initializerStaticFieldNames.get(ref); if (initializerName == null) { initializerName = "I" + nextInitializerStaticFieldId.getAndIncrement(); - classBuilder.addField(FieldSpec.builder(initializerClass, initializerName).initializer("new $T()", initializerClass).build()); + classBuilder.addField(FieldSpec + .builder(initializerClass, initializerName) + .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) + .initializer("new $T()", initializerClass) + .build()); initializerStaticFieldNames.put(ref, initializerName); } return initializerName; } + private String createUpgraderStaticField(AtomicInteger nextUpgraderStaticFieldId, + HashMap upgraderStaticFieldNames, + Builder classBuilder, + ClassName upgraderClass) { + var ref = upgraderClass.reflectionName(); + var upgraderName = upgraderStaticFieldNames.get(ref); + if (upgraderName == null) { + upgraderName = "U" + nextUpgraderStaticFieldId.getAndIncrement(); + classBuilder.addField(FieldSpec + .builder(upgraderClass, upgraderName) + .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) + .initializer("new $T()", upgraderClass) + .build()); + upgraderStaticFieldNames.put(ref, upgraderName); + } + return upgraderName; + } + private CodeBlock upgradeFieldToType(String fieldName, ComputedType fieldType, CodeBlock codeBlock, @@ -208,8 +265,4 @@ public class GenUpgraderBaseX extends ClassGenerator { } return codeBlock; } - - private String getFieldVarName(int totalTransformations, int transformationId) { - return null; - } }