cincheo / jsweet

A Java to JavaScript transpiler.
http://www.jsweet.org
Other
1.45k stars 159 forks source link

transpilation of null function values #694

Closed uvilop closed 2 years ago

uvilop commented 3 years ago

public static void doPanelSet(String id, int index, boolean insert, String href, String scroll, Runnable callback) ... Panel.doPanelSet(uiName, 0, true, href, scroll, null);

in 3.1 gets transpiled to:

Panel.doPanelSet(uiName, 0, true, href, scroll, (((funcInst) => { if (typeof funcInst == 'function') { return funcInst; } return () => (funcInst['run'] ? funcInst['run'] : funcInst).call(funcInst); })(null)));

which always gives an exception:

Uncaught TypeError: Cannot read property 'run' of null

similarly:

Function<Event,Object> onsubmit = submitForm.onsubmit;

becomes

const onsubmit = (((funcInst) => { if (typeof funcInst == 'function') { return funcInst; } return (arg0) => (funcInst['apply'] ? funcInst['apply'] : funcInst).call(funcInst, arg0); })(submitForm.onsubmit));

which fails if the value is null.

the test

if (onsubmit==null) ...

always is false, even when submitForm.onsubmit is true.

it works if written as

if (submitForm.onsubmit==null) ...

so the semantics change if a value is intermediately stored in a variable.

lgrignon commented 3 years ago

Hello, thanks for reporting. Did you enable TypeScript strict mode or is it just the regular JSweet transpilation?

This should be fairly simple to fix here https://github.com/cincheo/jsweet/blob/5a81ff72865e729a4642509a0be746120a030f9c/transpiler/src/main/java/org/jsweet/transpiler/Java2TypeScriptTranslator.java#L6843 If you want to give it a try and file a PR.

Thanks again

uvilop commented 2 years ago

i can imagine that the part of fixing the wrapper function for null arguments would not be too difficult. but this does not solve the problem that the wrapped function-object never is null anymore after being assigned to a variable (see "onsubmit" in the example). to me it seems the wrapper may only be generated for an apply() or run() call etc, but not beforehand.

lgrignon commented 2 years ago

actually, you just need to return null in the IIFE if arg is null

uvilop commented 2 years ago

sure, thats the one part - bug 1.

but another bug is applying the wrapper at all when ther is no apply called. this makes every function on-null.

here no wrapper may be applied at all (it is a different one, look at the code samples above): Function<Event,Object> x = submitForm.onsubmit currently x always becomes non-null - this is bug 2.

lgrignon commented 2 years ago

Thanks for reporting @uvilop

lgrignon commented 2 years ago

@uvilop It should be ok in last 3.2.0-SNAPSHOT available on maven ;) Thanks again