KubeJS

KubeJS

69M Downloads

KubeJS (Rhino?) not allowing lambda functions when inside generics

HollaFoil opened this issue ยท 2 comments

commented

Minecraft Version

1.20.1

KubeJS Version

2001.6.5-build.16

Rhino Version

2001.2.3-build.6

Architectury Version

9.2.14

Forge/Fabric Version

Forge 47.3.22 (likely all)

Describe your issue

A Function_ type in KubeJS gets defined as follows:

type Function_<T, R> = ((arg0: T)=> R) | Function<T, R>;

A functional interface class (in this case Function) gets converted to a type that also allows a lambda function. This is the expected behaviour. However, when dealing with generics, we found that this behaviour isn't always true. Consider the following function:

public <T> R setAttribute(Attribute<T> attribute, T value) {

And also consider the attribute ItemAttributes.USING_MESSAGE which was defined as Attribute<Function<ItemStack, Component>>, then the probed result is:

static readonly USING_MESSAGE: com.alessandro.astages.store.Attribute<Internal.Function<Internal.ItemStack, net.minecraft.network.chat.Component>>;

The generics get plainly transfered over from Java to JS, keeping the Function type instead of Function_. Then it is actually impossible to call setAttribute(ItemAttributes.USING_MESSAGE, someinput => someoutput), as the type of the second argument gets plainly set to Function<T, R>, instead of ((arg0: T)=> R) | Function<T, R>. We'd expect to be able to use lambdas here, instead of having to deal with Java classes.

This is either an oversight, where references to a functional interface class inside a generics argument get plainly converted as Java objects instead of also allowing lambdas, or the use of Function in our case is incorrect. If it is the latter, what would be the correct way of allowing a lambda in our use case? Any help would be greatly appreciated.

Crash report/logs

No response

commented

I believe this was also replicated on 1.21 versions, and likely happens on all Rhino/KubeJS versions (not necessarily an issue of generics not being implemented).

commented

That is known, you can workaround that using something like this:
https://github.com/AllTheMods/Gravitas2/blob/fac08ec45162a6cfee1214080372e9576bd7d453/kubejs/startup_scripts/main_startup.js#L8

$UtilsJS.makeFunctionProxy("startup", $EventActor, handleFTBCustomClick)

"startup" is just the context the script is into, in this case, was a startup script
$EventActor was the class loaded as in Java.loadClass("...")
handleFTBCustomClick was just the function