Optimize upgraders

This commit is contained in:
Andrea Cavalli 2021-04-26 18:07:18 +02:00
parent 9e83801b93
commit 493ddf0d58
1 changed files with 69 additions and 34 deletions

View File

@ -1100,6 +1100,10 @@ public class SourcesGenerator {
currentTransformedFieldTypes.put(className + "." + fieldName, typeTypes.get(fieldType)); currentTransformedFieldTypes.put(className + "." + fieldName, typeTypes.get(fieldType));
} }
} }
HashMap<ClassName, String> dataUpgraderInstanceFieldName = new HashMap<>();
AtomicInteger nextDataUpgraderInstanceFieldId = new AtomicInteger(0);
HashMap<ClassName, String> dataInitializerInstanceFieldName = new HashMap<>();
AtomicInteger nextDataInitializerInstanceFieldId = new AtomicInteger(0);
for (VersionTransformation transformationConfig : transformations) { for (VersionTransformation transformationConfig : transformations) {
var transformation = transformationConfig.getTransformation(); var transformation = transformationConfig.getTransformation();
deserializeMethod.addCode("\n"); deserializeMethod.addCode("\n");
@ -1158,13 +1162,28 @@ public class SourcesGenerator {
deserializeMethod.addStatement( deserializeMethod.addStatement(
"$T $$field$$" + (currentVarNumber.getInt(upgradeDataTransformation.from) + 1) + "$$" "$T $$field$$" + (currentVarNumber.getInt(upgradeDataTransformation.from) + 1) + "$$"
+ upgradeDataTransformation.from, toType); + upgradeDataTransformation.from, toType);
deserializeMethod.beginControlFlow("try"); var dataUpgraderClass = ClassName.bestGuess(upgradeDataTransformation.upgrader);
deserializeMethod.addStatement("var upgrader = (($T) new $T())", var dataUpgraderFieldName = dataUpgraderInstanceFieldName.computeIfAbsent(dataUpgraderClass,
ParameterizedTypeName.get(ClassName.get(DataUpgrader.class), fromTypeBoxed, toTypeBoxed), _unused -> {
ClassName.bestGuess(upgradeDataTransformation.upgrader) var dataUpgraderType = ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
fromTypeBoxed,
toTypeBoxed
);
var fieldName = "DATA_UPGRADER_" + nextDataUpgraderInstanceFieldId.getAndIncrement();
var fieldSpec = FieldSpec
.builder(dataUpgraderType,
fieldName,
Modifier.PRIVATE,
Modifier.STATIC,
Modifier.FINAL
);
fieldSpec.initializer("($T) new $T()", dataUpgraderType, dataUpgraderClass);
upgraderClass.addField(fieldSpec.build());
return fieldName;
}
); );
deserializeMethod.addStatement( deserializeMethod.addStatement(
"$T upgraded = ($T) upgrader.upgrade(($T) $$field$$" + currentVarNumber.getInt( "$T upgraded = ($T) " + dataUpgraderFieldName + ".upgrade(($T) $$field$$" + currentVarNumber.getInt(
upgradeDataTransformation.from) + "$$" + upgradeDataTransformation.from + ")", upgradeDataTransformation.from) + "$$" + upgradeDataTransformation.from + ")",
toType, toType,
toTypeBoxed, toTypeBoxed,
@ -1174,9 +1193,6 @@ public class SourcesGenerator {
deserializeMethod.addStatement( deserializeMethod.addStatement(
"$$field$$" + (currentVarNumber.getInt(upgradeDataTransformation.from) + 1) + "$$" "$$field$$" + (currentVarNumber.getInt(upgradeDataTransformation.from) + 1) + "$$"
+ upgradeDataTransformation.from + " = upgraded"); + upgradeDataTransformation.from + " = upgraded");
deserializeMethod.nextControlFlow(" catch ($T e)", ClassCastException.class);
deserializeMethod.addStatement("throw new $T(e)", IllegalArgumentException.class);
deserializeMethod.endControlFlow();
Objects.requireNonNull(currentTransformedFieldTypes.remove( Objects.requireNonNull(currentTransformedFieldTypes.remove(
upgradeDataTransformation.transformClass + "." + upgradeDataTransformation.from)); upgradeDataTransformation.transformClass + "." + upgradeDataTransformation.from));
currentTransformedFieldTypes.put( currentTransformedFieldTypes.put(
@ -1196,11 +1212,30 @@ public class SourcesGenerator {
{ {
currentVarNumber.addTo(newDataTransformation.to, 1); currentVarNumber.addTo(newDataTransformation.to, 1);
currentVarDeleted.remove(newDataTransformation.to); currentVarDeleted.remove(newDataTransformation.to);
var dataInitializerClass = ClassName.bestGuess(newDataTransformation.initializer);
var dataInitializerFieldName = dataInitializerInstanceFieldName.computeIfAbsent(dataInitializerClass,
_unused -> {
var dataInitializerType = ParameterizedTypeName.get(ClassName.get(DataInitializer.class),
newTypeBoxed
);
var fieldName = "DATA_INITIALIZER_" + nextDataInitializerInstanceFieldId.getAndIncrement();
var fieldSpec = FieldSpec
.builder(dataInitializerType,
fieldName,
Modifier.PRIVATE,
Modifier.STATIC,
Modifier.FINAL
);
fieldSpec.initializer("($T) new $T()", dataInitializerType, dataInitializerClass);
upgraderClass.addField(fieldSpec.build());
return fieldName;
}
);
deserializeMethod.addStatement( deserializeMethod.addStatement(
"var $$field$$" + currentVarNumber.getInt(newDataTransformation.to) + "$$" "var $$field$$" + currentVarNumber.getInt(newDataTransformation.to) + "$$"
+ newDataTransformation.to + " = (($T) new $T()).initialize()", + newDataTransformation.to + " = " + dataInitializerFieldName + ".initialize()"
ParameterizedTypeName.get(ClassName.get(DataInitializer.class), newTypeBoxed),
ClassName.bestGuess(newDataTransformation.initializer)
); );
} }
if (currentTransformedFieldTypes.put( if (currentTransformedFieldTypes.put(
@ -1271,8 +1306,29 @@ public class SourcesGenerator {
var newIBasicType = ClassName.get(joinPackage(nextVersionPackage.get(), "data"), "IBasicType"); var newIBasicType = ClassName.get(joinPackage(nextVersionPackage.get(), "data"), "IBasicType");
upgradeUnknownField.addStatement("$T.requireNonNull(value)", Objects.class); upgradeUnknownField.addStatement("$T.requireNonNull(value)", Objects.class);
upgradeUnknownField.addStatement("Class<?> type = ((Object) value).getClass()"); upgradeUnknownField.addStatement("Class<?> type = ((Object) value).getClass()");
upgradeUnknownField.beginControlFlow( upgradeUnknownField.beginControlFlow("if (value instanceof $T)", oldIBasicType);
"if (type.isArray() && $T.class.isAssignableFrom(type.getComponentType()))", upgradeUnknownField.addStatement("return ($T) $T.upgradeToNextVersion(($T) value)",
newIBasicType,
oldVersionType,
oldIBasicType
);
upgradeUnknownField.nextControlFlow("else if (value instanceof $T)", oldINullableBasicType);
upgradeUnknownField.addStatement("var content = (($T) value).$$getNullable()", IGenericNullable.class);
upgradeUnknownField.addStatement("$T newContent", Object.class);
upgradeUnknownField.beginControlFlow("if (content instanceof $T)", oldIBasicType);
upgradeUnknownField.addStatement("newContent = ($T) $T.upgradeToNextVersion(($T) content)",
newIBasicType,
oldVersionType,
oldIBasicType
);
upgradeUnknownField.nextControlFlow("else");
upgradeUnknownField.addStatement("newContent = content");
upgradeUnknownField.endControlFlow();
upgradeUnknownField.addStatement("return $T.INSTANCE.createNullableOf(type.getSimpleName(), newContent)",
ClassName.get(nextVersionPackage.get(), "Version")
);
upgradeUnknownField.nextControlFlow(
"else if (type.isArray() && $T.class.isAssignableFrom(type.getComponentType()))",
oldIType oldIType
); );
upgradeUnknownField.addStatement("int arrayLength = $T.getLength(value)", Array.class); upgradeUnknownField.addStatement("int arrayLength = $T.getLength(value)", Array.class);
@ -1289,27 +1345,6 @@ public class SourcesGenerator {
upgradeUnknownField.addStatement("$T.set(newArray, i, updatedItem)", Array.class); upgradeUnknownField.addStatement("$T.set(newArray, i, updatedItem)", Array.class);
upgradeUnknownField.endControlFlow(); upgradeUnknownField.endControlFlow();
upgradeUnknownField.addStatement("return newArray"); upgradeUnknownField.addStatement("return newArray");
upgradeUnknownField.nextControlFlow("else if (value instanceof $T)", oldINullableBasicType);
upgradeUnknownField.addStatement("var content = (($T) value).$$getNullable()", IGenericNullable.class);
upgradeUnknownField.addStatement("$T newContent", Object.class);
upgradeUnknownField.beginControlFlow("if (content instanceof $T)", oldIBasicType);
upgradeUnknownField.addStatement("newContent = ($T) $T.upgradeToNextVersion(($T) content)",
newIBasicType,
oldVersionType,
oldIBasicType
);
upgradeUnknownField.nextControlFlow("else");
upgradeUnknownField.addStatement("newContent = content");
upgradeUnknownField.endControlFlow();
upgradeUnknownField.addStatement("return $T.INSTANCE.createNullableOf(type.getSimpleName(), newContent)",
ClassName.get(nextVersionPackage.get(), "Version")
);
upgradeUnknownField.nextControlFlow("else if (value instanceof $T)", oldIBasicType);
upgradeUnknownField.addStatement("return ($T) $T.upgradeToNextVersion(($T) value)",
newIBasicType,
oldVersionType,
oldIBasicType
);
upgradeUnknownField.nextControlFlow("else"); upgradeUnknownField.nextControlFlow("else");
upgradeUnknownField.addStatement("return value"); upgradeUnknownField.addStatement("return value");
upgradeUnknownField.endControlFlow(); upgradeUnknownField.endControlFlow();