2023-04-20 10:11:12 +02:00
|
|
|
package it.cavallium.datagen.plugin.classgen;
|
2023-01-20 01:14:37 +01:00
|
|
|
|
|
|
|
import com.squareup.javapoet.ClassName;
|
|
|
|
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;
|
2023-04-20 10:11:12 +02:00
|
|
|
import it.cavallium.datagen.TypedNullable;
|
|
|
|
import it.cavallium.datagen.nativedata.INullable;
|
|
|
|
import it.cavallium.datagen.plugin.ClassGenerator;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedTypeBase;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedTypeCustom;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedTypeNullable;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedTypeNullableFixed;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedTypeNullableVersioned;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedTypeSuper;
|
|
|
|
import it.cavallium.datagen.plugin.ComputedVersion;
|
2023-01-20 01:14:37 +01:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.stream.Stream;
|
|
|
|
import javax.lang.model.element.Modifier;
|
|
|
|
import org.jetbrains.annotations.NotNull;
|
|
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
|
|
|
|
public class GenNullableX extends ClassGenerator {
|
|
|
|
|
|
|
|
public GenNullableX(ClassGeneratorParams params) {
|
|
|
|
super(params);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected Stream<GeneratedClass> generateClasses() {
|
|
|
|
return dataModel.getVersionsSet().parallelStream().flatMap(this::generateVersionClasses);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Stream<GeneratedClass> generateVersionClasses(ComputedVersion version) {
|
|
|
|
return dataModel
|
|
|
|
.getComputedTypes(version)
|
|
|
|
.values()
|
|
|
|
.stream()
|
2023-01-21 23:14:30 +01:00
|
|
|
.filter(f -> f instanceof ComputedTypeNullable)
|
|
|
|
.map(f -> (ComputedTypeNullable) f)
|
|
|
|
.filter(type -> (type instanceof ComputedTypeNullableVersioned versioned
|
|
|
|
&& versioned.getVersion().equals(version)) || type instanceof ComputedTypeNullableFixed)
|
2023-01-20 01:14:37 +01:00
|
|
|
.map(type -> generateTypeVersioned(version, type));
|
|
|
|
}
|
|
|
|
|
2023-01-21 23:14:30 +01:00
|
|
|
private GeneratedClass generateTypeVersioned(ComputedVersion version, ComputedTypeNullable computedType) {
|
2023-01-20 01:14:37 +01:00
|
|
|
var type = (ClassName) computedType.getJTypeName(basePackageName);
|
|
|
|
var classBuilder = TypeSpec.recordBuilder(type.simpleName());
|
|
|
|
|
|
|
|
var base = computedType.getBase();
|
|
|
|
var baseType = base.getJTypeName(basePackageName);
|
|
|
|
|
|
|
|
classBuilder.addModifiers(Modifier.PUBLIC);
|
|
|
|
classBuilder.addRecordComponent(ParameterSpec.builder(baseType, "value").build());
|
|
|
|
|
|
|
|
var iNullableITypeClass = ClassName.get(version.getDataNullablesPackage(basePackageName), "INullableIType");
|
|
|
|
var iNullableClass = ClassName.get(INullable.class);
|
|
|
|
var typedNullable = ParameterizedTypeName.get(ClassName.get(TypedNullable.class), baseType);
|
|
|
|
|
|
|
|
if (base instanceof ComputedTypeSuper computedTypeSuper) {
|
|
|
|
var iNullableSuperTypeClass = ClassName.get(version.getDataNullablesPackage(basePackageName), "INullableSuperType");
|
|
|
|
var superTypeClass = ClassName.get(dataModel.getRootPackage(basePackageName), "SuperType");
|
|
|
|
classBuilder.addSuperinterface(iNullableSuperTypeClass);
|
|
|
|
|
|
|
|
classBuilder.addMethod(MethodSpec
|
|
|
|
.methodBuilder("getSuperType$")
|
|
|
|
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
|
|
|
.returns(superTypeClass)
|
|
|
|
.addStatement("return $T.$N", superTypeClass, base.getName())
|
|
|
|
.build());
|
2023-01-21 23:26:54 +01:00
|
|
|
} else if (base instanceof ComputedTypeBase) {
|
2023-01-20 01:14:37 +01:00
|
|
|
var iNullableBaseTypeClass = ClassName.get(version.getDataNullablesPackage(basePackageName), "INullableBaseType");
|
|
|
|
var baseTypeClass = ClassName.get(dataModel.getRootPackage(basePackageName), "BaseType");
|
|
|
|
classBuilder.addSuperinterface(iNullableBaseTypeClass);
|
|
|
|
|
|
|
|
classBuilder.addMethod(MethodSpec
|
|
|
|
.methodBuilder("getBaseType$")
|
|
|
|
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
|
|
|
.returns(baseTypeClass)
|
|
|
|
.addStatement("return $T.$N", baseTypeClass, base.getName())
|
|
|
|
.build());
|
2023-01-21 23:26:54 +01:00
|
|
|
} else if (!(base instanceof ComputedTypeCustom)) {
|
2023-01-20 01:14:37 +01:00
|
|
|
throw new UnsupportedOperationException();
|
|
|
|
}
|
|
|
|
|
2023-01-22 01:18:50 +01:00
|
|
|
classBuilder.addField(FieldSpec
|
|
|
|
.builder(type, "NULL").addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL).initializer("new $T(null)", type).build());
|
|
|
|
|
2023-01-20 01:14:37 +01:00
|
|
|
if (version.isCurrent()) {
|
|
|
|
classBuilder.addSuperinterfaces(List.of(iNullableITypeClass, iNullableClass, typedNullable));
|
|
|
|
|
|
|
|
classBuilder.addMethod(MethodSpec
|
|
|
|
.methodBuilder("of")
|
|
|
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
|
|
|
.addParameter(ParameterSpec.builder(baseType, "value").build())
|
|
|
|
.addException(ClassName.get(NullPointerException.class))
|
|
|
|
.returns(type)
|
|
|
|
.beginControlFlow("if (value != null)")
|
|
|
|
.addStatement("return new $T(value)", type)
|
|
|
|
.nextControlFlow("else")
|
|
|
|
.addStatement("throw new $T()", NullPointerException.class)
|
|
|
|
.endControlFlow()
|
|
|
|
.build());
|
|
|
|
|
|
|
|
classBuilder.addMethod(MethodSpec
|
|
|
|
.methodBuilder("ofNullable")
|
|
|
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
|
|
|
.addParameter(ParameterSpec.builder(baseType, "value").build())
|
|
|
|
.returns(type)
|
|
|
|
.addStatement("return value != null ? new $T(value) : NULL", type)
|
|
|
|
.build());
|
|
|
|
|
|
|
|
classBuilder.addMethod(MethodSpec
|
|
|
|
.methodBuilder("or")
|
|
|
|
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
|
|
|
.addAnnotation(NotNull.class)
|
|
|
|
.returns(type)
|
|
|
|
.addParameter(ParameterSpec.builder(type, "fallback").addAnnotation(NotNull.class).build())
|
|
|
|
.addStatement("return this.value == null ? fallback : this")
|
|
|
|
.build());
|
|
|
|
}
|
|
|
|
|
2023-01-22 01:18:50 +01:00
|
|
|
classBuilder.addMethod(MethodSpec
|
|
|
|
.methodBuilder("empty")
|
|
|
|
.addModifiers(Modifier.PUBLIC, Modifier.STATIC, Modifier.FINAL)
|
|
|
|
.returns(type)
|
|
|
|
.addStatement("return NULL")
|
|
|
|
.build());
|
|
|
|
|
2023-01-21 18:44:49 +01:00
|
|
|
classBuilder.addMethod(MethodSpec
|
|
|
|
.methodBuilder("getNullable")
|
|
|
|
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
|
|
|
|
.addAnnotation(Nullable.class)
|
|
|
|
.returns(baseType)
|
|
|
|
.addStatement("return this.value")
|
|
|
|
.build());
|
|
|
|
|
2023-01-20 01:14:37 +01:00
|
|
|
return new GeneratedClass(type.packageName(), classBuilder);
|
|
|
|
}
|
|
|
|
}
|