|
| 1 | +package io.github.digitalsmile.composers; |
| 2 | + |
| 3 | +import com.squareup.javapoet.*; |
| 4 | +import io.github.digitalsmile.PackageName; |
| 5 | +import io.github.digitalsmile.PrettyName; |
| 6 | +import io.github.digitalsmile.annotation.function.NativeCall; |
| 7 | +import io.github.digitalsmile.functions.FunctionNode; |
| 8 | +import io.github.digitalsmile.functions.ParameterNode; |
| 9 | +import io.github.digitalsmile.headers.mapping.*; |
| 10 | + |
| 11 | +import javax.annotation.processing.Messager; |
| 12 | +import javax.lang.model.element.Modifier; |
| 13 | +import javax.tools.Diagnostic; |
| 14 | +import java.lang.foreign.MemorySegment; |
| 15 | +import java.util.List; |
| 16 | +import java.util.Map; |
| 17 | + |
| 18 | +public class AutoFunctionComposer { |
| 19 | + private final Messager messager; |
| 20 | + |
| 21 | + public AutoFunctionComposer(Messager messager) { |
| 22 | + this.messager = messager; |
| 23 | + } |
| 24 | + |
| 25 | + public String compose(String packageName, String originalName, List<FunctionNode> nodes) { |
| 26 | + var classBuilder = TypeSpec.interfaceBuilder(originalName + "AutoFunctions") |
| 27 | + //.addModifiers(Modifier.PUBLIC) |
| 28 | + .addSuperinterface(ClassName.get(packageName, originalName)); |
| 29 | + |
| 30 | + for (FunctionNode node : nodes) { |
| 31 | + var method = MethodSpec.methodBuilder(PrettyName.getVariableName(node.functionName())); |
| 32 | + |
| 33 | + var returnType = node.returnNode().getType(); |
| 34 | + switch (returnType) { |
| 35 | + case ArrayOriginalType arrayOriginalType -> { |
| 36 | + method.returns(createType(arrayOriginalType)); |
| 37 | +// if (arrayOriginalType.carrierClass().equals(String.class)) { |
| 38 | +// method.returns(String.class); |
| 39 | +// } else if (arrayOriginalType.carrierClass().equals(Object.class)) { |
| 40 | +// method.returns(Object.class.arrayType()); |
| 41 | +// } else { |
| 42 | +// var typePackageName = PackageName.getPackageName(arrayOriginalType.typeName()); |
| 43 | +// method.returns(ClassName.get(typePackageName, PrettyName.getObjectName(arrayOriginalType.typeName()))); |
| 44 | +// } |
| 45 | + } |
| 46 | + case ObjectOriginalType objectOriginalType -> { |
| 47 | + method.returns(createType(objectOriginalType)); |
| 48 | + // messager.printMessage(Diagnostic.Kind.ERROR, objectOriginalType.typeName() + " " + objectOriginalType.carrierClass()); |
| 49 | +// if (objectOriginalType.carrierClass().equals(void.class)) { |
| 50 | +// method.returns(void.class); |
| 51 | +// } else { |
| 52 | +// var typePackageName = PackageName.getPackageName(objectOriginalType.typeName()); |
| 53 | +// method.returns(ClassName.get(typePackageName, PrettyName.getObjectName(objectOriginalType.typeName()))); |
| 54 | +// } |
| 55 | + } |
| 56 | + case PrimitiveOriginalType _ -> { |
| 57 | + method.returns(returnType.carrierClass()); |
| 58 | + } |
| 59 | + default -> { |
| 60 | + } |
| 61 | + } |
| 62 | + |
| 63 | + |
| 64 | + //messager.printMessage(Diagnostic.Kind.ERROR, "F: " + node.functionName()); |
| 65 | + for (ParameterNode parameterNode : node.functionParameters()) { |
| 66 | + //messager.printMessage(Diagnostic.Kind.ERROR, node.functionName() + " " + parameterNode.nativeMemoryNode().getName()); |
| 67 | + var name = parameterNode.nativeMemoryNode().getName(); |
| 68 | + if (name.isEmpty()) { |
| 69 | + name = "arg" + node.functionParameters().indexOf(parameterNode); |
| 70 | + } |
| 71 | + var parameterType = parameterNode.nativeMemoryNode().getType(); |
| 72 | + var parameterName = PrettyName.getVariableName(name); |
| 73 | + switch (parameterType) { |
| 74 | + case ArrayOriginalType arrayOriginalType -> { |
| 75 | + method.addParameter(createType(arrayOriginalType), name); |
| 76 | +// if (arrayOriginalType.isObjectType()) { |
| 77 | +// if (arrayOriginalType.carrierClass().equals(String.class)) { |
| 78 | +// method.addParameter(String.class, name); |
| 79 | +// } else if (arrayOriginalType.carrierClass().equals(Object.class)) { |
| 80 | +// method.addParameter(Object.class.arrayType(), name); |
| 81 | +// } else { |
| 82 | +// var typePackageName = PackageName.getPackageName(arrayOriginalType.typeName()); |
| 83 | +// method.addParameter(ClassName.get(typePackageName, PrettyName.getObjectName(arrayOriginalType.typeName())), name); |
| 84 | +// } |
| 85 | +// } else { |
| 86 | +// method.addParameter(arrayOriginalType.carrierClass().arrayType(), name); |
| 87 | +// } |
| 88 | + } |
| 89 | + case ObjectOriginalType objectOriginalType -> { |
| 90 | + method.addParameter(createType(objectOriginalType), name); |
| 91 | +// if (objectOriginalType.carrierClass().equals(void.class)) { |
| 92 | +// method.addParameter(MemorySegment.class, name); |
| 93 | +// } else { |
| 94 | +// var typePackageName = PackageName.getPackageName(objectOriginalType.typeName()); |
| 95 | +// method.addParameter(ClassName.get(typePackageName, PrettyName.getObjectName(objectOriginalType.typeName())), parameterName); |
| 96 | +// } |
| 97 | + } |
| 98 | + case PrimitiveOriginalType _ -> { |
| 99 | + method.addParameter(parameterType.carrierClass(), parameterName); |
| 100 | + } |
| 101 | + default -> { |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + } |
| 106 | + |
| 107 | + classBuilder.addMethod(method |
| 108 | + .addModifiers(Modifier.PUBLIC, Modifier.ABSTRACT).build()); |
| 109 | + } |
| 110 | + |
| 111 | + |
| 112 | + var builder = JavaFile.builder(packageName, classBuilder.build()); |
| 113 | + var outputFile = builder.indent("\t").skipJavaLangImports(true).build(); |
| 114 | + return outputFile.toString(); |
| 115 | + } |
| 116 | + |
| 117 | + |
| 118 | + private TypeName createType(OriginalType type, boolean isArray) { |
| 119 | + var typeName = type.typeName(); |
| 120 | + var clazz = type.carrierClass(); |
| 121 | + if (type.carrierClass().equals(Object.class)) { |
| 122 | + var resolvedPackageName = PackageName.getPackageName(typeName); |
| 123 | + if (typeName.equals(String.class.getSimpleName())) { |
| 124 | + resolvedPackageName = ""; |
| 125 | + } |
| 126 | + return ClassName.get(resolvedPackageName, PrettyName.getObjectName(typeName) + (isArray ? "[]" : "")); |
| 127 | + } else { |
| 128 | + return TypeName.get(isArray ? clazz.arrayType() : clazz); |
| 129 | + } |
| 130 | + } |
| 131 | + |
| 132 | + private TypeName createType(OriginalType type) { |
| 133 | + return createType(type, false); |
| 134 | + } |
| 135 | +} |
0 commit comments