Add data inizializer/upgrader declarative context parameters
This commit is contained in:
parent
73d24bf13f
commit
5afe301750
@ -82,7 +82,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.10.1</version>
|
||||
<version>3.11.0</version>
|
||||
<configuration>
|
||||
<release>21</release>
|
||||
<encoding>UTF-8</encoding>
|
||||
|
@ -159,7 +159,7 @@ public class DataModel {
|
||||
.stream()
|
||||
.filter(x -> x.size() > 1)
|
||||
.forEach(x -> {
|
||||
var type = x.get(0);
|
||||
var type = x.getFirst();
|
||||
throw new IllegalArgumentException("Type " + type + " has been defined more than once (check base, super, and custom types)!");
|
||||
});
|
||||
|
||||
@ -209,28 +209,19 @@ public class DataModel {
|
||||
+ t.transformClass);
|
||||
}
|
||||
transformClass.addDifferentThanPrev(transformation);
|
||||
var definition = removeAndGetIndex(transformClass.data, t.from);
|
||||
var definition = transformClass.remove(t.from);
|
||||
if (definition.isEmpty()) {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
|
||||
}
|
||||
String prevDef;
|
||||
if (t.index != null) {
|
||||
prevDef = tryInsertAtIndex(transformClass.data,
|
||||
t.to,
|
||||
definition.get().getValue(),
|
||||
t.index
|
||||
);
|
||||
} else {
|
||||
prevDef = tryInsertAtIndex(transformClass.data,
|
||||
t.to,
|
||||
definition.get().getValue(),
|
||||
definition.get().getKey()
|
||||
);
|
||||
}
|
||||
ParsedClass.FieldInfo prevDef = transformClass.insert(
|
||||
Objects.requireNonNullElse(t.index, definition.get().getKey()),
|
||||
t.to,
|
||||
new ParsedClass.InputFieldInfo(definition.get().getValue().typeName(), List.of())
|
||||
);
|
||||
if (prevDef != null) {
|
||||
throw new IllegalArgumentException(
|
||||
transformCoordinate + " tries to overwrite the existing field \"" + t.to + "\" of value \""
|
||||
+ prevDef + "\" with the field \"" + t.from + "\" of type \"" + definition.orElse(null) + "\"");
|
||||
+ prevDef.typeName() + "\" with the field \"" + t.from + "\" of type \"" + definition.orElse(null) + "\"");
|
||||
}
|
||||
}
|
||||
case "new-data" -> {
|
||||
@ -244,15 +235,12 @@ public class DataModel {
|
||||
if (!allTypes.contains(extractTypeName(t.type))) {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
||||
}
|
||||
String prevDef;
|
||||
if (t.index != null) {
|
||||
prevDef = tryInsertAtIndex(transformClass.data, t.to, fixType(t.type), t.index);
|
||||
} else {
|
||||
prevDef = transformClass.data.putIfAbsent(t.to, fixType(t.type));
|
||||
}
|
||||
var type = fixType(t.type);
|
||||
var fieldInfo = new ParsedClass.InputFieldInfo(type, t.getContextParameters());
|
||||
ParsedClass.FieldInfo prevDef = transformClass.insert(t.index, t.to, fieldInfo);
|
||||
if (prevDef != null) {
|
||||
throw new IllegalArgumentException(transformCoordinate + " tries to overwrite the existing field \""
|
||||
+ t.to + "\" of value \"" + prevDef
|
||||
+ t.to + "\" of value \"" + prevDef.typeName()
|
||||
+ "\" with the new type \"" + t.type + "\"");
|
||||
}
|
||||
}
|
||||
@ -281,7 +269,7 @@ public class DataModel {
|
||||
if (!allTypes.contains(extractTypeName(t.type))) {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown type: " + t.type);
|
||||
}
|
||||
String prevDefinition = transformClass.data.replace(t.from, fixType(t.type));
|
||||
var prevDefinition = transformClass.replace(t.from, new ParsedClass.InputFieldInfo(fixType(t.type), t.getContextParameters()));
|
||||
if (prevDefinition == null) {
|
||||
throw new IllegalArgumentException(transformCoordinate + " refers to an unknown field: " + t.from);
|
||||
}
|
||||
@ -340,7 +328,7 @@ public class DataModel {
|
||||
List<ComputedType> versionBaseTypes = computedClassConfig.get(versionIndexF).entrySet().stream()
|
||||
.map(e -> {
|
||||
var data = new LinkedHashMap<String, VersionedType>();
|
||||
e.getValue().getData().forEach((key, value) -> data.put(key, new VersionedType(value, version)));
|
||||
e.getValue().getData().forEach((key, value) -> data.put(key, new VersionedType(value.typeName(), version)));
|
||||
return new ComputedTypeBase(new VersionedType(e.getKey(), version),
|
||||
e.getValue().stringRepresenter, data, computedTypeSupplier);
|
||||
}).collect(Collectors.toList());
|
||||
@ -357,8 +345,8 @@ public class DataModel {
|
||||
var nullableRawTypes = computedClassConfig.values().stream()
|
||||
.flatMap(x -> x.values().stream())
|
||||
.flatMap(x -> x.getData().values().stream())
|
||||
.filter(x -> x.startsWith("-"))
|
||||
.map(nullableName -> nullableName.substring(1))
|
||||
.filter(x -> x.typeName().startsWith("-"))
|
||||
.map(nullableName -> nullableName.typeName().substring(1))
|
||||
.toList();
|
||||
// Compute nullable versioned types
|
||||
nullableRawTypes.stream()
|
||||
@ -383,8 +371,8 @@ public class DataModel {
|
||||
var arrayRawTypes = computedClassConfig.values().stream()
|
||||
.flatMap(x -> x.values().stream())
|
||||
.flatMap(x -> x.getData().values().stream())
|
||||
.filter(x -> x.startsWith("§"))
|
||||
.map(nullableName -> nullableName.substring(1))
|
||||
.filter(x -> x.typeName().startsWith("§"))
|
||||
.map(nullableName -> nullableName.typeName().substring(1))
|
||||
.toList();
|
||||
// Compute array versioned types
|
||||
arrayRawTypes.stream()
|
||||
@ -450,7 +438,7 @@ public class DataModel {
|
||||
.entrySet()
|
||||
.stream()
|
||||
.collect(Collectors.toMap(Entry::getKey, e -> {
|
||||
var fieldTypeName = e.getValue();
|
||||
var fieldTypeName = e.getValue().typeName();
|
||||
return new VersionedType(fieldTypeName, computedVersions.get(currentOrNewerTypeVersion.getInt(fieldTypeName)));
|
||||
}, (a, b) -> {
|
||||
throw new IllegalStateException();
|
||||
@ -591,40 +579,6 @@ public class DataModel {
|
||||
this.baseTypeDataChanges = baseTypeDataChanges;
|
||||
}
|
||||
|
||||
private String tryInsertAtIndex(LinkedHashMap<String, String> data, String key, String value, int index) {
|
||||
var before = new LinkedHashMap<String, String>();
|
||||
var after = new LinkedHashMap<String, String>();
|
||||
int i = 0;
|
||||
for (Entry<String, String> entry : data.entrySet()) {
|
||||
if (i < index) {
|
||||
before.put(entry.getKey(), entry.getValue());
|
||||
} else {
|
||||
after.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
data.clear();
|
||||
data.putAll(before);
|
||||
var prev = data.putIfAbsent(key, value);
|
||||
data.putAll(after);
|
||||
return prev;
|
||||
}
|
||||
|
||||
private Optional<Entry<Integer, String>> removeAndGetIndex(LinkedHashMap<String, String> data, String find) {
|
||||
int foundIndex = -1;
|
||||
{
|
||||
int i = 0;
|
||||
for (Entry<String, String> entry : data.entrySet()) {
|
||||
if (entry.getKey().equals(find)) {
|
||||
foundIndex = i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (foundIndex == -1) return Optional.empty();
|
||||
return Optional.of(Map.entry(foundIndex, requireNonNull(data.remove(find))));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static String getNextVersion(Map<String, String> versionsSequence, String version) {
|
||||
return versionsSequence.get(version);
|
||||
@ -650,7 +604,7 @@ public class DataModel {
|
||||
if (list.size() != 1) {
|
||||
throw exceptionGenerator.apply(list);
|
||||
}
|
||||
return list.get(0);
|
||||
return list.getFirst();
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -669,7 +623,7 @@ public class DataModel {
|
||||
if (list.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(list.get(0));
|
||||
return Optional.of(list.getFirst());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package it.cavallium.datagen.plugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public final class MoveDataConfiguration implements TransformationConfiguration {
|
||||
|
@ -1,6 +1,9 @@
|
||||
package it.cavallium.datagen.plugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class NewDataConfiguration implements TransformationConfiguration {
|
||||
@ -12,6 +15,8 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
||||
public String initializerInstance;
|
||||
@Nullable
|
||||
public Integer index;
|
||||
@Nullable
|
||||
public List<String> contextParameters;
|
||||
|
||||
@Override
|
||||
public String getTransformClass() {
|
||||
@ -27,6 +32,11 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
||||
return JInterfaceLocation.parse(initializer, initializerInstance);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getContextParameters() {
|
||||
return Objects.requireNonNullElse(contextParameters, List.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@ -39,7 +49,8 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
||||
return Objects.equals(transformClass, that.transformClass) && Objects.equals(to, that.to)
|
||||
&& Objects.equals(type, that.type) && Objects.equals(initializer, that.initializer)
|
||||
&& Objects.equals(initializerInstance, that.initializerInstance)
|
||||
&& Objects.equals(index, that.index);
|
||||
&& Objects.equals(index, that.index)
|
||||
&& Objects.equals(contextParameters, that.contextParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -51,6 +62,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
||||
hash += ConfigUtils.hashCode(initializer);
|
||||
hash += ConfigUtils.hashCode(initializerInstance);
|
||||
hash += ConfigUtils.hashCode(index);
|
||||
hash += ConfigUtils.hashCode(contextParameters);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -62,6 +74,7 @@ public class NewDataConfiguration implements TransformationConfiguration {
|
||||
if (this.to != null) c.to = this.to;
|
||||
if (this.type != null) c.type = this.type;
|
||||
if (this.index != null) c.index = this.index;
|
||||
if (this.contextParameters != null) c.contextParameters = this.contextParameters;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,26 @@
|
||||
package it.cavallium.datagen.plugin;
|
||||
|
||||
import static it.cavallium.datagen.plugin.DataModel.fixType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import static it.cavallium.datagen.plugin.DataModel.fixType;
|
||||
import static it.cavallium.datagen.plugin.DataModel.joinPackage;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public final class ParsedClass {
|
||||
|
||||
public record InputFieldInfo(@NotNull String typeName, @NotNull List<String> contextParams) {}
|
||||
|
||||
public record FieldInfo(@NotNull String typeName, @NotNull LinkedHashMap<String, String> contextFieldsData) {}
|
||||
|
||||
public String stringRepresenter;
|
||||
|
||||
public LinkedHashMap<String, String> data;
|
||||
public LinkedHashMap<String, FieldInfo> data;
|
||||
public List<TransformationConfiguration> differentThanPrev;
|
||||
public boolean differentThanNext;
|
||||
|
||||
@ -23,9 +29,11 @@ public final class ParsedClass {
|
||||
if (baseTypesData.data != null) {
|
||||
this.data = baseTypesData.data.entrySet().stream()
|
||||
.map(e -> Map.entry(e.getKey(), fixType(e.getValue())))
|
||||
.collect(Collectors.toMap(Entry::getKey, Entry::getValue, (a, b) -> {
|
||||
throw new IllegalStateException();
|
||||
}, LinkedHashMap::new));
|
||||
.collect(Collectors.toMap(Entry::getKey,
|
||||
v -> new FieldInfo(v.getValue(),
|
||||
new LinkedHashMap<>(0)),
|
||||
(a, b) -> {throw new IllegalStateException();},
|
||||
LinkedHashMap::new));
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,7 +45,7 @@ public final class ParsedClass {
|
||||
return stringRepresenter;
|
||||
}
|
||||
|
||||
public LinkedHashMap<String, String> getData() {
|
||||
public LinkedHashMap<String, FieldInfo> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -76,4 +84,82 @@ public final class ParsedClass {
|
||||
}
|
||||
differentThanPrev.add(transformation);
|
||||
}
|
||||
|
||||
public static final class NoContextParameterException extends RuntimeException {
|
||||
private final String contextParameter;
|
||||
|
||||
public NoContextParameterException(String contextParameter) {
|
||||
this.contextParameter = contextParameter;
|
||||
}
|
||||
|
||||
public String getContextParameter() {
|
||||
return contextParameter;
|
||||
}
|
||||
}
|
||||
|
||||
private static LinkedHashMap<String, String> computeContextParametersTypes(
|
||||
LinkedHashMap<String, ParsedClass.FieldInfo> data, @NotNull List<String> contextParameters)
|
||||
throws NoContextParameterException {
|
||||
return contextParameters.stream().collect(Collectors.toMap(Function.identity(), param -> {
|
||||
var type = data.get(param);
|
||||
if (type == null) {
|
||||
throw new NoContextParameterException(param);
|
||||
}
|
||||
return type.typeName();
|
||||
}, (c, a) -> {
|
||||
throw new IllegalStateException("Unreachable");
|
||||
}, LinkedHashMap::new));
|
||||
}
|
||||
|
||||
public FieldInfo insert(@Nullable Integer index, String to, InputFieldInfo fieldInfo) throws NoContextParameterException {
|
||||
var value = convertFieldInfo(fieldInfo);
|
||||
if (index == null) {
|
||||
return data.putIfAbsent(to, value);
|
||||
} else {
|
||||
return tryInsertAtIndex(data, to, value, index);
|
||||
}
|
||||
}
|
||||
|
||||
public Optional<Entry<Integer, FieldInfo>> remove(String find) {
|
||||
int foundIndex = -1;
|
||||
{
|
||||
int i = 0;
|
||||
for (var entry : data.entrySet()) {
|
||||
if (entry.getKey().equals(find)) {
|
||||
foundIndex = i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (foundIndex == -1) return Optional.empty();
|
||||
return Optional.of(Map.entry(foundIndex, requireNonNull(data.remove(find))));
|
||||
}
|
||||
|
||||
public FieldInfo replace(String from, InputFieldInfo fieldInfo) {
|
||||
return data.replace(from, convertFieldInfo(fieldInfo));
|
||||
}
|
||||
|
||||
private FieldInfo convertFieldInfo(InputFieldInfo fieldInfo) {
|
||||
return new FieldInfo(fieldInfo.typeName, computeContextParametersTypes(data, fieldInfo.contextParams));
|
||||
}
|
||||
|
||||
private static ParsedClass.FieldInfo tryInsertAtIndex(LinkedHashMap<String, ParsedClass.FieldInfo> data, String key,
|
||||
FieldInfo value, int index) {
|
||||
var before = new LinkedHashMap<String, ParsedClass.FieldInfo>(index);
|
||||
var after = new LinkedHashMap<String, ParsedClass.FieldInfo>(data.size() - index);
|
||||
int i = 0;
|
||||
for (Entry<String, ParsedClass.FieldInfo> entry : data.entrySet()) {
|
||||
if (i < index) {
|
||||
before.put(entry.getKey(), entry.getValue());
|
||||
} else {
|
||||
after.put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
data.clear();
|
||||
data.putAll(before);
|
||||
var prev = data.putIfAbsent(key, value);
|
||||
data.putAll(after);
|
||||
return prev;
|
||||
}
|
||||
}
|
||||
|
@ -405,7 +405,7 @@ public class SourcesGenerator {
|
||||
return i;
|
||||
}
|
||||
|
||||
private String capitalize(String field) {
|
||||
public static String capitalize(String field) {
|
||||
return Character.toUpperCase(field.charAt(0)) + field.substring(1);
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
package it.cavallium.datagen.plugin;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class UpgradeDataConfiguration implements TransformationConfiguration {
|
||||
@ -9,6 +13,8 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
||||
public String type;
|
||||
public String upgrader;
|
||||
public String upgraderInstance;
|
||||
@Nullable
|
||||
public List<String> contextParameters;
|
||||
|
||||
@Override
|
||||
public String getTransformClass() {
|
||||
@ -24,6 +30,11 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
||||
return JInterfaceLocation.parse(upgrader, upgraderInstance);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<String> getContextParameters() {
|
||||
return Objects.requireNonNullElse(contextParameters, List.of());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
@ -35,7 +46,8 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
||||
UpgradeDataConfiguration that = (UpgradeDataConfiguration) o;
|
||||
return Objects.equals(transformClass, that.transformClass) && Objects.equals(from, that.from)
|
||||
&& Objects.equals(type, that.type) && Objects.equals(upgrader, that.upgrader)
|
||||
&& Objects.equals(upgraderInstance, that.upgraderInstance);
|
||||
&& Objects.equals(upgraderInstance, that.upgraderInstance)
|
||||
&& Objects.equals(contextParameters, that.contextParameters);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -46,6 +58,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
||||
hash += ConfigUtils.hashCode(type);
|
||||
hash += ConfigUtils.hashCode(upgrader);
|
||||
hash += ConfigUtils.hashCode(upgraderInstance);
|
||||
hash += ConfigUtils.hashCode(contextParameters);
|
||||
return hash;
|
||||
}
|
||||
|
||||
@ -56,6 +69,7 @@ public class UpgradeDataConfiguration implements TransformationConfiguration {
|
||||
if (this.type != null) c.type = this.type;
|
||||
if (this.upgrader != null) c.upgrader = this.upgrader;
|
||||
if (this.upgraderInstance != null) c.upgraderInstance = this.upgraderInstance;
|
||||
if (this.contextParameters != null) c.contextParameters = this.contextParameters;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
@ -9,22 +9,12 @@ import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import com.squareup.javapoet.TypeSpec.Builder;
|
||||
import it.cavallium.datagen.DataInitializer;
|
||||
import it.cavallium.datagen.DataUpgrader;
|
||||
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||
import it.cavallium.datagen.plugin.ComputedType;
|
||||
import it.cavallium.datagen.*;
|
||||
import it.cavallium.datagen.plugin.*;
|
||||
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||
import it.cavallium.datagen.plugin.ComputedTypeBase;
|
||||
import it.cavallium.datagen.plugin.ComputedVersion;
|
||||
import it.cavallium.datagen.plugin.JInterfaceLocation;
|
||||
import it.cavallium.datagen.plugin.JInterfaceLocation.JInterfaceLocationClassName;
|
||||
import it.cavallium.datagen.plugin.JInterfaceLocation.JInterfaceLocationInstanceField;
|
||||
import it.cavallium.datagen.plugin.MoveDataConfiguration;
|
||||
import it.cavallium.datagen.plugin.NewDataConfiguration;
|
||||
import it.cavallium.datagen.plugin.RemoveDataConfiguration;
|
||||
import it.cavallium.datagen.plugin.TransformationConfiguration;
|
||||
import it.cavallium.datagen.plugin.UpgradeDataConfiguration;
|
||||
import it.cavallium.datagen.plugin.DataModel;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@ -36,6 +26,7 @@ import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
import javax.lang.model.element.Modifier;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class GenUpgraderBaseX extends ClassGenerator {
|
||||
|
||||
@ -64,7 +55,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
|
||||
classBuilder.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||
|
||||
classBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
||||
classBuilder.superclass(ParameterizedTypeName.get(ClassName.get(DataUpgraderSimple.class),
|
||||
typeBaseClassName,
|
||||
nextTypeBase.getJTypeName(basePackageName)
|
||||
));
|
||||
@ -92,6 +83,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
|
||||
AtomicInteger nextInitializerStaticFieldId = new AtomicInteger();
|
||||
HashMap<String, String> initializerStaticFieldNames = new HashMap<>();
|
||||
HashMap<String, ContextInfo> contextStaticFieldCodeBlocks = new HashMap<>();
|
||||
AtomicInteger nextUpgraderStaticFieldId = new AtomicInteger();
|
||||
HashMap<String, String> upgraderStaticFieldNames = new HashMap<>();
|
||||
List<TransformationConfiguration> transformations = dataModel.getChanges(nextTypeBase);
|
||||
@ -120,7 +112,16 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
var computedTypes = dataModel.getComputedTypes(nextTypeBase.getVersion());
|
||||
var newFieldType = Objects.requireNonNull(computedTypes.get(DataModel.fixType(newDataConfiguration.type)));
|
||||
var initializerLocation = newDataConfiguration.getInitializerLocation();
|
||||
|
||||
var contextInfo = createContextStaticClass(typeBase, e.getValue().to,
|
||||
contextStaticFieldCodeBlocks,
|
||||
classBuilder,
|
||||
initializerLocation,
|
||||
newDataConfiguration.getContextParameters()
|
||||
);
|
||||
|
||||
var genericInitializerClass = ParameterizedTypeName.get(ClassName.get(DataInitializer.class),
|
||||
contextInfo.typeName(),
|
||||
newFieldType.getJTypeName(basePackageName).box()
|
||||
);
|
||||
|
||||
@ -131,7 +132,7 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
genericInitializerClass
|
||||
);
|
||||
|
||||
return new Field(newDataConfiguration.to, newFieldType, CodeBlock.of("$N.initialize()", initializerName), i + 1);
|
||||
return new Field(newDataConfiguration.to, newFieldType, CodeBlock.of("$N.initialize($L)", initializerName, contextInfo.contextApply), i + 1);
|
||||
})
|
||||
);
|
||||
resultFields = fields.<ResultField>mapMulti((field, consumer) -> {
|
||||
@ -170,7 +171,16 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
var cb = CodeBlock.builder();
|
||||
var newFieldType = Objects
|
||||
.requireNonNull(dataModel.getComputedTypes(nextTypeBase.getVersion()).get(DataModel.fixType(upgradeDataConfiguration.type)));
|
||||
|
||||
var contextInfo = createContextStaticClass(typeBase, upgradeDataConfiguration.from,
|
||||
contextStaticFieldCodeBlocks,
|
||||
classBuilder,
|
||||
upgraderImplementationLocation,
|
||||
upgradeDataConfiguration.getContextParameters()
|
||||
);
|
||||
|
||||
var genericUpgraderClass = ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
||||
contextInfo.typeName(),
|
||||
fieldType.getJTypeName(basePackageName).box(),
|
||||
newFieldType.getJTypeName(basePackageName).box()
|
||||
);
|
||||
@ -182,9 +192,10 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
genericUpgraderClass
|
||||
);
|
||||
|
||||
cb.add("($T) $N.upgrade(($T) ",
|
||||
cb.add("($T) $N.upgrade($L, ($T) ",
|
||||
newFieldType.getJTypeName(basePackageName),
|
||||
upgraderName,
|
||||
contextInfo.contextApply,
|
||||
fieldType.getJTypeName(basePackageName)
|
||||
);
|
||||
cb.add(codeBlock);
|
||||
@ -223,10 +234,10 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
}
|
||||
|
||||
private String createInitializerStaticField(AtomicInteger nextInitializerStaticFieldId,
|
||||
HashMap<String, String> initializerStaticFieldNames,
|
||||
Builder classBuilder,
|
||||
JInterfaceLocation initializerLocation,
|
||||
TypeName genericInitializerClass) {
|
||||
HashMap<String, String> initializerStaticFieldNames,
|
||||
Builder classBuilder,
|
||||
JInterfaceLocation initializerLocation,
|
||||
TypeName genericInitializerClass) {
|
||||
var identifier = initializerLocation.getIdentifier();
|
||||
var initializerName = initializerStaticFieldNames.get(identifier);
|
||||
if (initializerName == null) {
|
||||
@ -247,6 +258,55 @@ public class GenUpgraderBaseX extends ClassGenerator {
|
||||
return initializerName;
|
||||
}
|
||||
|
||||
record ContextInfo(TypeName typeName, CodeBlock contextApply) {}
|
||||
|
||||
private ContextInfo createContextStaticClass(ComputedTypeBase typeBase,
|
||||
String fieldName,
|
||||
HashMap<String, ContextInfo> contextStaticFieldCodeBlocks,
|
||||
Builder classBuilder,
|
||||
JInterfaceLocation initializerLocation,
|
||||
@NotNull List<String> contextParameters) {
|
||||
var identifier = initializerLocation.getIdentifier();
|
||||
var contextStaticFieldCodeBlock = contextStaticFieldCodeBlocks.get(identifier);
|
||||
if (contextStaticFieldCodeBlock == null) {
|
||||
var codeBlockBuilder = CodeBlock.builder();
|
||||
TypeName typeName;
|
||||
|
||||
if (contextParameters.isEmpty()) {
|
||||
typeName = ClassName.get(DataContextNone.class);
|
||||
codeBlockBuilder.add("$T.INSTANCE", typeName);
|
||||
} else {
|
||||
var name = "Context" + SourcesGenerator.capitalize(fieldName);
|
||||
var contextTypeClassBuilder = TypeSpec.recordBuilder(name)
|
||||
.addSuperinterface(ClassName.get(DataContext.class))
|
||||
.addModifiers(Modifier.PUBLIC, Modifier.STATIC);
|
||||
typeName = typeBase.getJUpgraderName(basePackageName).nestedClass(name);
|
||||
|
||||
codeBlockBuilder.add("new $T(", typeName);
|
||||
boolean first = true;
|
||||
for (String contextParameter : contextParameters) {
|
||||
var fieldType = typeBase.getData().get(contextParameter);
|
||||
contextTypeClassBuilder.addRecordComponent(ParameterSpec.builder(fieldType.getJTypeName(basePackageName), contextParameter).build());
|
||||
|
||||
if (first) {
|
||||
first = false;
|
||||
} else {
|
||||
codeBlockBuilder.add(", ");
|
||||
}
|
||||
codeBlockBuilder.add("data.$N()", contextParameter);
|
||||
}
|
||||
codeBlockBuilder.add(")");
|
||||
|
||||
var clazz = contextTypeClassBuilder.build();
|
||||
classBuilder.addType(clazz);
|
||||
}
|
||||
|
||||
contextStaticFieldCodeBlock = new ContextInfo(typeName, codeBlockBuilder.build());
|
||||
contextStaticFieldCodeBlocks.put(identifier, contextStaticFieldCodeBlock);
|
||||
}
|
||||
return contextStaticFieldCodeBlock;
|
||||
}
|
||||
|
||||
private String createUpgraderStaticField(AtomicInteger nextUpgraderStaticFieldId,
|
||||
HashMap<String, String> upgraderStaticFieldNames,
|
||||
Builder classBuilder,
|
||||
|
@ -8,6 +8,7 @@ import com.squareup.javapoet.ParameterizedTypeName;
|
||||
import com.squareup.javapoet.TypeSpec;
|
||||
import com.squareup.javapoet.TypeSpec.Builder;
|
||||
import it.cavallium.datagen.DataUpgrader;
|
||||
import it.cavallium.datagen.DataUpgraderSimple;
|
||||
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||
import it.cavallium.datagen.plugin.ComputedType;
|
||||
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||
@ -44,7 +45,7 @@ public class GenUpgraderSuperX extends ClassGenerator {
|
||||
|
||||
classBuilder.addModifiers(Modifier.PUBLIC, Modifier.FINAL);
|
||||
|
||||
classBuilder.addSuperinterface(ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
||||
classBuilder.superclass(ParameterizedTypeName.get(ClassName.get(DataUpgraderSimple.class),
|
||||
typeBaseClassName,
|
||||
nextTypeSuper.getJTypeName(basePackageName)
|
||||
));
|
||||
|
@ -11,6 +11,7 @@ import com.squareup.javapoet.TypeSpec.Builder;
|
||||
import com.squareup.javapoet.TypeVariableName;
|
||||
import it.cavallium.datagen.DataSerializer;
|
||||
import it.cavallium.datagen.DataUpgrader;
|
||||
import it.cavallium.datagen.DataUpgraderSimple;
|
||||
import it.cavallium.datagen.plugin.ClassGenerator;
|
||||
import it.cavallium.datagen.plugin.ComputedType.VersionedComputedType;
|
||||
import it.cavallium.datagen.plugin.ComputedTypeArrayFixed;
|
||||
@ -188,7 +189,7 @@ public class GenVersion extends ClassGenerator {
|
||||
return;
|
||||
}
|
||||
|
||||
var genericClassName = ParameterizedTypeName.get(ClassName.get(DataUpgrader.class),
|
||||
var genericClassName = ParameterizedTypeName.get(ClassName.get(DataUpgraderSimple.class),
|
||||
type.getJTypeName(basePackageName), nextVersion.getJTypeName(basePackageName)
|
||||
);
|
||||
var upgraderClassName = type.getJUpgraderName(basePackageName);
|
||||
|
@ -0,0 +1,4 @@
|
||||
package it.cavallium.datagen;
|
||||
|
||||
public interface DataContext {
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package it.cavallium.datagen;
|
||||
|
||||
public final class DataContextNone implements DataContext {
|
||||
|
||||
public static final DataContextNone INSTANCE = new DataContextNone();
|
||||
|
||||
private DataContextNone() {}
|
||||
|
||||
}
|
@ -2,7 +2,7 @@ package it.cavallium.datagen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface DataInitializer<T> {
|
||||
public interface DataInitializer<C extends DataContext, T> {
|
||||
|
||||
@NotNull T initialize();
|
||||
@NotNull T initialize(C context);
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package it.cavallium.datagen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class DataInitializerSimple<T> implements DataInitializer<DataContextNone, T> {
|
||||
|
||||
@Override
|
||||
public final @NotNull T initialize(DataContextNone context) {
|
||||
return initialize();
|
||||
}
|
||||
|
||||
public abstract @NotNull T initialize();
|
||||
}
|
@ -2,7 +2,7 @@ package it.cavallium.datagen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface DataUpgrader<T, U> {
|
||||
public interface DataUpgrader<C extends DataContext, T, U> {
|
||||
|
||||
@NotNull U upgrade(@NotNull T data);
|
||||
@NotNull U upgrade(@NotNull C context, @NotNull T data);
|
||||
}
|
||||
|
@ -0,0 +1,13 @@
|
||||
package it.cavallium.datagen;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class DataUpgraderSimple<T, U> implements DataUpgrader<DataContextNone, T, U> {
|
||||
|
||||
@Override
|
||||
public final @NotNull U upgrade(@NotNull DataContextNone context, @NotNull T data) {
|
||||
return this.upgrade(data);
|
||||
}
|
||||
|
||||
public abstract @NotNull U upgrade(@NotNull T data);
|
||||
}
|
@ -1,11 +1,19 @@
|
||||
package it.cavallium.datagen.nativedata;
|
||||
|
||||
import it.cavallium.datagen.DataContext;
|
||||
import it.cavallium.datagen.DataContextNone;
|
||||
import it.cavallium.datagen.DataUpgrader;
|
||||
import it.cavallium.datagen.DataUpgraderSimple;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class UpgradeUtil {
|
||||
public static <A, B> List<B> upgradeArray(List<A> from, DataUpgraderSimple<A, B> upgrader) {
|
||||
return upgradeArray(DataContextNone.INSTANCE, from, upgrader);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <A, B> List<B> upgradeArray(List<A> from, DataUpgrader<A, B> upgrader) {
|
||||
public static <C extends DataContext, A, B> List<B> upgradeArray(C context, List<A> from, DataUpgrader<C, A, B> upgrader) {
|
||||
Object[] array;
|
||||
if (from.getClass() == ImmutableWrappedArrayList.class
|
||||
&& ((ImmutableWrappedArrayList<?>) from).a.getClass() == Object[].class) {
|
||||
@ -14,16 +22,20 @@ public class UpgradeUtil {
|
||||
array = from.toArray();
|
||||
}
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
array[i] = (B) upgrader.upgrade((A) array[i]);
|
||||
array[i] = (B) upgrader.upgrade(context, (A) array[i]);
|
||||
}
|
||||
return (ImmutableWrappedArrayList<B>) ImmutableWrappedArrayList.of(array);
|
||||
}
|
||||
|
||||
public static <A, B> B upgradeNullable(A nullableValue, DataUpgrader<A, B> upgrader) {
|
||||
public static <A, B> B upgradeNullable(A nullableValue, DataUpgraderSimple<A, B> upgrader) {
|
||||
return upgradeNullable(DataContextNone.INSTANCE, nullableValue, upgrader);
|
||||
}
|
||||
|
||||
public static <C extends DataContext, A, B> B upgradeNullable(C context, A nullableValue, DataUpgrader<C, A, B> upgrader) {
|
||||
if (nullableValue == null) {
|
||||
return null;
|
||||
} else {
|
||||
return upgrader.upgrade(nullableValue);
|
||||
return upgrader.upgrade(context, nullableValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user