fix(scripting): wrapper args

This commit is contained in:
rhunk
2024-05-28 00:05:33 +02:00
parent 8b9d2e5d5c
commit c635994e50
2 changed files with 30 additions and 11 deletions

View File

@@ -118,28 +118,25 @@ class JSModule(
}.getOrNull() ?: return@putFunction Undefined.instance
scriptableObject("JavaClassWrapper") {
putFunction("newInstance") newInstance@{ args ->
putFunction("__new__") { args ->
val constructor = clazz.declaredConstructors.find {
it.parameterTypes.zip(args ?: emptyArray()).all { (type, arg) ->
type.isAssignableFrom(arg?.javaClass ?: return@all false)
}
} ?: return@newInstance Undefined.instance
(args ?: emptyArray()).isSameParameters(it.parameterTypes)
}?.also { it.isAccessible = true } ?: throw IllegalArgumentException("Constructor not found with args ${argsToString(args)}")
constructor.newInstance(*args ?: emptyArray())
}
clazz.declaredMethods.filter { Modifier.isStatic(it.modifiers) }.forEach { method ->
putFunction(method.name) { args ->
clazz.declaredMethods.find {
it.name == method.name && it.parameterTypes.zip(args ?: emptyArray()).all { (type, arg) ->
type.isAssignableFrom(arg?.javaClass ?: return@all false)
}
}?.also { it.isAccessible = true }?.invoke(null, *args ?: emptyArray())
val declaredMethod = clazz.declaredMethods.find {
it.name == method.name && (args ?: emptyArray()).isSameParameters(it.parameterTypes)
}?.also { it.isAccessible = true } ?: throw IllegalArgumentException("Method ${method.name} not found with args ${argsToString(args)}")
declaredMethod.invoke(null, *args ?: emptyArray())
}
}
clazz.declaredFields.filter { Modifier.isStatic(it.modifiers) }.forEach { field ->
field.isAccessible = true
defineProperty(field.name, { field.get(null)}, { value -> field.set(null, value) }, 0)
defineProperty(field.name, { field.get(null) }, { value -> field.set(null, value) }, 0)
}
}
}

View File

@@ -14,4 +14,26 @@ fun Any?.toPrimitiveValue(type: Lazy<String>) = when (this) {
}
is Boolean -> if (type.value == "boolean") this.toString().toBoolean() else this
else -> this
}
fun Array<out Any?>.isSameParameters(parameters: Array<Class<*>>): Boolean {
if (this.size != parameters.size) return false
for (i in this.indices) {
val type = parameters[i]
val value = this[i]?.toPrimitiveValue(lazy { type.name }) ?: continue
if (type.isPrimitive) {
when (type.name) {
"byte" -> if (value !is Byte) return false
"short" -> if (value !is Short) return false
"int" -> if (value !is Int) return false
"long" -> if (value !is Long) return false
"float" -> if (value !is Float) return false
"double" -> if (value !is Double) return false
"boolean" -> if (value !is Boolean) return false
"char" -> if (value !is Char) return false
else -> return false
}
} else if (!type.isAssignableFrom(value.javaClass)) return false
}
return true
}