feat: ArgVariant annotation and plot methods with count parameter (#264)
* feat(generator): introduce ArgVariant annotation New annotation provides an ability to generate methods definitions for different types and names. * feat(api): expose count param for plot* methods
This commit is contained in:
1 parent
cae0581df2
commit
9518b1cec6
8 files changed
+7605
-1785
No files matched your search
@@ -5,6 +5,7 @@ import spoon.reflect.declaration.CtElement
|
|||||||
import spoon.reflect.declaration.CtField
|
import spoon.reflect.declaration.CtField
|
||||||
import spoon.reflect.declaration.CtMethod
|
import spoon.reflect.declaration.CtMethod
|
||||||
import spoon.reflect.declaration.CtType
|
import spoon.reflect.declaration.CtType
|
||||||
|
import kotlin.math.max
|
||||||
|
|
||||||
class BindingSourceProcessor(
|
class BindingSourceProcessor(
|
||||||
private val type: CtType<*>
|
private val type: CtType<*>
|
||||||
@@ -101,7 +102,53 @@ class BindingSourceProcessor(
|
|||||||
contentToReplace[ReplacePos(it.position.sourceStart, it.position.sourceEnd + 6)] = ""
|
contentToReplace[ReplacePos(it.position.sourceStart, it.position.sourceEnd + 6)] = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
val content = jvmMethodContent(method) + jniMethodContent(method)
|
val content = mutableListOf<String>()
|
||||||
|
|
||||||
|
// Handle argument variants
|
||||||
|
if (method.parameters.find { it.hasAnnotation(A_NAME_ARG_VARIANT) } != null) {
|
||||||
|
data class ArgVar(val idx: Int, val type: String, val name: String)
|
||||||
|
|
||||||
|
val variants = mutableListOf<ArgVar>()
|
||||||
|
|
||||||
|
method.parameters.forEachIndexed { idx, p ->
|
||||||
|
if (p.hasAnnotation(A_NAME_ARG_VARIANT)) {
|
||||||
|
val a = p.getAnnotation(A_NAME_ARG_VARIANT)!!
|
||||||
|
val types = (a.getValueAsObject(A_VALUE_TYPE) as Array<*>).map { it.toString() }
|
||||||
|
val names = (a.getValueAsObject(A_VALUE_NAME) as Array<*>).map { it.toString() }
|
||||||
|
|
||||||
|
if (types.isNotEmpty() && names.isNotEmpty() && types.size != names.size) {
|
||||||
|
error("Types size should be the as names! Current: types=${types.size}, names=${names.size}")
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i in 0 until max(types.size, names.size)) {
|
||||||
|
variants += ArgVar(
|
||||||
|
idx,
|
||||||
|
types.getOrNull(i) ?: p.type.simpleName,
|
||||||
|
names.getOrNull(i) ?: p.simpleName,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val variantsMap = variants.groupBy { it.idx }
|
||||||
|
val variantsCount = variantsMap.values.first().size
|
||||||
|
|
||||||
|
for (i in 0 until variantsCount) {
|
||||||
|
val m = method.clone()
|
||||||
|
m.setParent<Nothing>(method.parent)
|
||||||
|
variantsMap.values.forEach { vList ->
|
||||||
|
val v = vList[i]
|
||||||
|
val p = m.parameters[v.idx]
|
||||||
|
p.setAnnotations<Nothing>(p.annotations.filterNot { it.name == A_NAME_ARG_VARIANT })
|
||||||
|
p.setType<Nothing>(m.factory.createTypeParameterReference(v.type))
|
||||||
|
p.setSimpleName<Nothing>(v.name)
|
||||||
|
}
|
||||||
|
content += jvmMethodContent(m) + jniMethodContent(m)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content += jvmMethodContent(method) + jniMethodContent(method)
|
||||||
|
}
|
||||||
|
|
||||||
contentToReplace[method.findReplacePos()] = content.joinWithIndention()
|
contentToReplace[method.findReplacePos()] = content.joinWithIndention()
|
||||||
return contentToReplace
|
return contentToReplace
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ private fun convertParams2jni(f: Factory, params: List<CtParameter<*>>, defaults
|
|||||||
result += f.createParameter<Nothing>().apply {
|
result += f.createParameter<Nothing>().apply {
|
||||||
val type = if (p.type.isPtrClass()) {
|
val type = if (p.type.isPtrClass()) {
|
||||||
f.createTypeParam("long")
|
f.createTypeParam("long")
|
||||||
} else if (p.type.isClass) {
|
} else {
|
||||||
when (p.type.simpleName) {
|
when (p.type.simpleName) {
|
||||||
"ImBoolean" -> f.createTypeParam("boolean[]")
|
"ImBoolean" -> f.createTypeParam("boolean[]")
|
||||||
"ImShort" -> f.createTypeParam("short[]")
|
"ImShort" -> f.createTypeParam("short[]")
|
||||||
@@ -120,8 +120,6 @@ private fun convertParams2jni(f: Factory, params: List<CtParameter<*>>, defaults
|
|||||||
"ImDouble" -> f.createTypeParam("double[]")
|
"ImDouble" -> f.createTypeParam("double[]")
|
||||||
else -> p.type
|
else -> p.type
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
p.type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setType<Nothing>(type)
|
setType<Nothing>(type)
|
||||||
@@ -138,7 +136,7 @@ private fun joinInBodyParams(params: List<CtParameter<*>>, defaults: IntArray):
|
|||||||
"reinterpret_cast<${p.type.simpleName}*>(${p.simpleName})"
|
"reinterpret_cast<${p.type.simpleName}*>(${p.simpleName})"
|
||||||
} else if (p.isPrimitivePtrType()) {
|
} else if (p.isPrimitivePtrType()) {
|
||||||
"&${p.simpleName}[0]"
|
"&${p.simpleName}[0]"
|
||||||
} else if (p.type.isClass) {
|
} else {
|
||||||
when (p.type.simpleName) {
|
when (p.type.simpleName) {
|
||||||
"ImBoolean", "ImShort", "ImInt", "ImFloat", "ImLong", "ImDouble" -> {
|
"ImBoolean", "ImShort", "ImInt", "ImFloat", "ImLong", "ImDouble" -> {
|
||||||
"(${p.simpleName} != NULL ? &${p.simpleName}[0] : NULL)"
|
"(${p.simpleName} != NULL ? &${p.simpleName}[0] : NULL)"
|
||||||
@@ -166,8 +164,6 @@ private fun joinInBodyParams(params: List<CtParameter<*>>, defaults: IntArray):
|
|||||||
|
|
||||||
else -> p.simpleName
|
else -> p.simpleName
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
p.simpleName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ private fun joinInBodyParams(params: List<CtParameter<*>>, defaults: IntArray):
|
|||||||
fun param2str(p: CtParameter<*>): String {
|
fun param2str(p: CtParameter<*>): String {
|
||||||
return if (p.type.isPtrClass()) {
|
return if (p.type.isPtrClass()) {
|
||||||
"${p.simpleName}.$PTR_JVM_FIELD"
|
"${p.simpleName}.$PTR_JVM_FIELD"
|
||||||
} else if (p.type.isClass) {
|
} else {
|
||||||
when (p.type.simpleName) {
|
when (p.type.simpleName) {
|
||||||
"ImBoolean", "ImShort", "ImInt", "ImFloat", "ImLong", "ImDouble" -> {
|
"ImBoolean", "ImShort", "ImInt", "ImFloat", "ImLong", "ImDouble" -> {
|
||||||
"${p.simpleName} != null ? ${p.simpleName}.getData() : null"
|
"${p.simpleName} != null ? ${p.simpleName}.getData() : null"
|
||||||
@@ -42,8 +42,6 @@ private fun joinInBodyParams(params: List<CtParameter<*>>, defaults: IntArray):
|
|||||||
|
|
||||||
else -> p.simpleName
|
else -> p.simpleName
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
p.simpleName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +145,7 @@ private fun createMethod(origM: CtMethod<*>, params: List<CtParameter<*>>, defau
|
|||||||
append(createBodyStaticStructReturn(origM, params, defaults))
|
append(createBodyStaticStructReturn(origM, params, defaults))
|
||||||
} else if (DST_RETURN_TYPE_SET.contains(origM.type.simpleName)) {
|
} else if (DST_RETURN_TYPE_SET.contains(origM.type.simpleName)) {
|
||||||
append(createBodyDstReturn(origM, params, defaults))
|
append(createBodyDstReturn(origM, params, defaults))
|
||||||
} else if (origM.type.isClass && !origM.type.isPrimitive && !origM.isType("void") && !origM.isType("String") && !origM.isPrimitivePtrType()) {
|
} else if (origM.type.isPtrClass()) {
|
||||||
append(createBodyStructReturn(origM, params, defaults))
|
append(createBodyStructReturn(origM, params, defaults))
|
||||||
} else {
|
} else {
|
||||||
if (!origM.isType("void")) {
|
if (!origM.isType("void")) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ const val A_NAME_OPT_ARG = "OptArg"
|
|||||||
const val A_NAME_EXCLUDED_SOURCE = "ExcludedSource"
|
const val A_NAME_EXCLUDED_SOURCE = "ExcludedSource"
|
||||||
const val A_NAME_RETURN_VALUE = "ReturnValue"
|
const val A_NAME_RETURN_VALUE = "ReturnValue"
|
||||||
const val A_NAME_ARG_VALUE = "ArgValue"
|
const val A_NAME_ARG_VALUE = "ArgValue"
|
||||||
|
const val A_NAME_ARG_VARIANT = "ArgVariant"
|
||||||
const val A_NAME_TYPE_ARRAY = "TypeArray"
|
const val A_NAME_TYPE_ARRAY = "TypeArray"
|
||||||
const val A_NAME_TYPE_STD_STRING = "TypeStdString"
|
const val A_NAME_TYPE_STD_STRING = "TypeStdString"
|
||||||
|
|
||||||
@@ -56,6 +57,7 @@ val CLEANUP_ANNOTATIONS_LIST = listOf(
|
|||||||
A_NAME_RETURN_VALUE,
|
A_NAME_RETURN_VALUE,
|
||||||
A_NAME_OPT_ARG,
|
A_NAME_OPT_ARG,
|
||||||
A_NAME_ARG_VALUE,
|
A_NAME_ARG_VALUE,
|
||||||
|
A_NAME_ARG_VARIANT,
|
||||||
A_NAME_TYPE_ARRAY,
|
A_NAME_TYPE_ARRAY,
|
||||||
A_NAME_TYPE_STD_STRING,
|
A_NAME_TYPE_STD_STRING,
|
||||||
A_NAME_BINDING_AST_ENUM,
|
A_NAME_BINDING_AST_ENUM,
|
||||||
|
|||||||
File diff suppressed because it is too large.
Load diff
@@ -2,6 +2,7 @@ package imgui;
|
|||||||
|
|
||||||
import imgui.assertion.ImAssertCallback;
|
import imgui.assertion.ImAssertCallback;
|
||||||
import imgui.binding.annotation.ArgValue;
|
import imgui.binding.annotation.ArgValue;
|
||||||
|
import imgui.binding.annotation.ArgVariant;
|
||||||
import imgui.binding.annotation.BindingMethod;
|
import imgui.binding.annotation.BindingMethod;
|
||||||
import imgui.binding.annotation.BindingSource;
|
import imgui.binding.annotation.BindingSource;
|
||||||
import imgui.binding.annotation.OptArg;
|
import imgui.binding.annotation.OptArg;
|
||||||
@@ -1493,34 +1494,23 @@ public class ImGui {
|
|||||||
public static native boolean InputDouble(String label, ImDouble v, @OptArg double step, @OptArg double stepFast, @OptArg(callValue = "\"%.6f\"") String format, @OptArg int imGuiInputTextFlags);
|
public static native boolean InputDouble(String label, ImDouble v, @OptArg double step, @OptArg double stepFast, @OptArg(callValue = "\"%.6f\"") String format, @OptArg int imGuiInputTextFlags);
|
||||||
|
|
||||||
@BindingMethod
|
@BindingMethod
|
||||||
public static native boolean InputScalar(String label, Void ImGuiDataType_S16, ImShort pData, @OptArg @ArgValue(callPrefix = "&") short pStep, @OptArg @ArgValue(callPrefix = "&") short pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
public static native boolean InputScalar(String label,
|
||||||
|
@ArgVariant(name = {"ImGuiDataType_S16", "ImGuiDataType_S32", "ImGuiDataType_S64", "ImGuiDataType_Float", "ImGuiDataType_Double"}) Void __,
|
||||||
|
@ArgVariant(type = {"ImShort", "ImInt", "ImLong", "ImFloat", "ImDouble"}) Void pData,
|
||||||
|
@ArgVariant(type = {"short", "int", "long", "float", "double"}) @OptArg @ArgValue(callPrefix = "&") Void pStep,
|
||||||
|
@ArgVariant(type = {"short", "int", "long", "float", "double"}) @OptArg @ArgValue(callPrefix = "&") Void pStepFast,
|
||||||
|
@OptArg String format,
|
||||||
|
@OptArg int imGuiSliderFlags);
|
||||||
|
|
||||||
@BindingMethod
|
@BindingMethod
|
||||||
public static native boolean InputScalar(String label, Void ImGuiDataType_S32, ImInt pData, @OptArg @ArgValue(callPrefix = "&") int pStep, @OptArg @ArgValue(callPrefix = "&") int pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
public static native boolean InputScalarN(String label,
|
||||||
|
@ArgVariant(name = {"ImGuiDataType_S16", "ImGuiDataType_S32", "ImGuiDataType_S64", "ImGuiDataType_Float", "ImGuiDataType_Double"}) Void __,
|
||||||
@BindingMethod
|
@ArgVariant(type = {"short[]", "int[]", "long[]", "float[]", "double[]"}) Void pData,
|
||||||
public static native boolean InputScalar(String label, Void ImGuiDataType_S64, ImLong pData, @OptArg @ArgValue(callPrefix = "&") long pStep, @OptArg @ArgValue(callPrefix = "&") long pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
int components,
|
||||||
|
@ArgVariant(type = {"short", "int", "long", "float", "double"}) @OptArg @ArgValue(callPrefix = "&") Void pStep,
|
||||||
@BindingMethod
|
@ArgVariant(type = {"short", "int", "long", "float", "double"}) @OptArg @ArgValue(callPrefix = "&") Void pStepFast,
|
||||||
public static native boolean InputScalar(String label, Void ImGuiDataType_Float, ImFloat pData, @OptArg @ArgValue(callPrefix = "&") float pStep, @OptArg @ArgValue(callPrefix = "&") float pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
@OptArg String format,
|
||||||
|
@OptArg int imGuiSliderFlags);
|
||||||
@BindingMethod
|
|
||||||
public static native boolean InputScalar(String label, Void ImGuiDataType_Double, ImDouble pData, @OptArg @ArgValue(callPrefix = "&") double pStep, @OptArg @ArgValue(callPrefix = "&") double pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
|
||||||
|
|
||||||
@BindingMethod
|
|
||||||
public static native boolean InputScalarN(String label, Void ImGuiDataType_S16, short[] pData, int components, @OptArg @ArgValue(callPrefix = "&") short pStep, @OptArg @ArgValue(callPrefix = "&") short pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
|
||||||
|
|
||||||
@BindingMethod
|
|
||||||
public static native boolean InputScalarN(String label, Void ImGuiDataType_S32, int[] pData, int components, @OptArg @ArgValue(callPrefix = "&") int pStep, @OptArg @ArgValue(callPrefix = "&") int pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
|
||||||
|
|
||||||
@BindingMethod
|
|
||||||
public static native boolean InputScalarN(String label, Void ImGuiDataType_S64, long[] pData, int components, @OptArg @ArgValue(callPrefix = "&") long pStep, @OptArg @ArgValue(callPrefix = "&") long pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
|
||||||
|
|
||||||
@BindingMethod
|
|
||||||
public static native boolean InputScalarN(String label, Void ImGuiDataType_Float, float[] pData, int components, @OptArg @ArgValue(callPrefix = "&") float pStep, @OptArg @ArgValue(callPrefix = "&") float pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
|
||||||
|
|
||||||
@BindingMethod
|
|
||||||
public static native boolean InputScalarN(String label, Void ImGuiDataType_Double, double[] pData, int components, @OptArg @ArgValue(callPrefix = "&") double pStep, @OptArg @ArgValue(callPrefix = "&") double pStepFast, @OptArg String format, @OptArg int imGuiSliderFlags);
|
|
||||||
|
|
||||||
// Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little color square that can be left-clicked to open a picker, and right-clicked to open an option menu.)
|
// Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little color square that can be left-clicked to open a picker, and right-clicked to open an option menu.)
|
||||||
// - Note that in C++ a 'float v[X]' function argument is the _same_ as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible.
|
// - Note that in C++ a 'float v[X]' function argument is the _same_ as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible.
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package imgui.binding.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a sort of pre-processing experience, to generate method with additional argument variants.
|
||||||
|
* Can generate methods with different arg type and different arg names.
|
||||||
|
* Intended to be used for methods with template arguments.
|
||||||
|
* {@link #type} and {@link #name()} arrays SHOULD have the same length.
|
||||||
|
*/
|
||||||
|
@ExcludedSource
|
||||||
|
@Target(ElementType.PARAMETER)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface ArgVariant {
|
||||||
|
/**
|
||||||
|
* Variant for the argument type.
|
||||||
|
*/
|
||||||
|
String[] type() default {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant for the argument name.
|
||||||
|
*/
|
||||||
|
String[] name() default {};
|
||||||
|
}
|
||||||
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user