fan.acme.$clos$_u0 = new fan.sys.ClosureFuncSpec$(fan.sys.Void.$type,["it","acme::JavaOnly","false"]);
The code is generated by compilerJs::JsClosure.write() - and is generated because of the it-block. I looked at not writing ClosureFuncSpec vals for non JS classes, but I couldn't work out how to get hold of the type facets.
Re-writing the code not to make use of an it-block ctor fixes the issue:
@Js
class Example {
Void main() {
if (Env.cur.runtime == "java") {
obj := JavaOnly()
obj.msg = "wotever"
}
}
}
class JavaOnly {
Str? msg
}
Note I believe this issue was introduced in Fantom 1.0.68.
andyMon 28 Dec 2015
That was probably one of those cases that shouldn't have worked :) We did add some optimization to cache closure typing - which is why you see it now. Removing the with block is the right workaround for now.
SlimerDudeSun 7 Feb 2016
Hi Andy,
Yeah, I see the optimisation - it looks good.
Though I still firmly believe the above code should work - it is perfectly valid Fantom code. The optimisation shouldn't even attempt to touch the JavaOnly class because it is not annotated with @Js.
It's been mentioned in other topics that cross platform libraries are a great boon to Fantom. And being able to toggle snippets of code on and off at runtime is a great way to get over the idiosyncrasies of running on different platforms.
andyMon 8 Feb 2016
I don't know - still seems like bad practice to mix code like that - and there are clearer ways to handle that. You have a real use case for that pattern?
SlimerDudeMon 8 Feb 2016
You have a real use case for that pattern?
You mean checking the runtime? Yeah, I do it loads in most of my cross-platform libraries. Funcs, files, images, FWT components, and more, all require special handling in JS. Here are just a couple of examples from many:
// afReflux
// CTab is Java only
tab = Env.cur.runtime == "js" ? Tab() : CTab()
...
// afReflux
// in JS, empty panes don't collapse so set their weight to zero
if (Env.cur.runtime == "js") { ... }
...
// afIoc
// we forego immutable checks in JS
if (Env.cur.runtime == "js") return
...
// afIoc
if (obj is Func && Env.cur.runtime == "js")
throw Err("Immutable funcs are not available in Javascript: ${key.qname}\nSee http://fantom.org/forum/topic/114 for details.")
brianMon 8 Feb 2016
I would have to give it some thought, but I don't think code that can't be run should be allowed inside a @Js class - to me that is very much like allowing some weird sort of if/block dependency. However, I do think it should be noted at compile time with an extra check.
SlimerDudeWed 10 Feb 2016
I think it's just peachy as it is right now in Fantom 1.0.67.
The above code generates the following compiler warning:
Type 'acme::JavaOnly' not available in Js
So you're alerted to the fact that it may not work - but as it is fenced by the runtime check you know it won't get executed.
The only problem I have is with Fantom 1.0.68. The generated Javascript errors because the optimisation code runs for all types, whereas it should just run for @Js types.
matthewWed 10 Feb 2016
Ticket promoted to #2501 and assigned to matthew
Think I have a fix for this. Will post soon.
matthewWed 10 Feb 2016
Ticket resolved in 1.0.68
When writing the closure, we check its signature and if any of param types or the return type is non-Js, then we won't write the ClosureFuncSpec, but instead we write a dummy closure that indicates this condition. If the code never executes, then we won't get any type errors at runtime.
LightDyeThu 11 Feb 2016
Ticket resolved in 1.0.68
That is awesome. Has the release date of v1.0.68 been decided yet, please?
SlimerDude Sat 26 Dec 2015
I would expect the following code to run just fine in Javascript because the class
JavaOnly
is not referenced in any way:But instead it causes this error:
caused by this auto-generated code:
The code is generated by
compilerJs::JsClosure.write()
- and is generated because of the it-block. I looked at not writingClosureFuncSpec
vals for non JS classes, but I couldn't work out how to get hold of the type facets.Re-writing the code not to make use of an it-block ctor fixes the issue:
Note I believe this issue was introduced in Fantom 1.0.68.
andy Mon 28 Dec 2015
That was probably one of those cases that shouldn't have worked :) We did add some optimization to cache closure typing - which is why you see it now. Removing the
with
block is the right workaround for now.SlimerDude Sun 7 Feb 2016
Hi Andy,
Yeah, I see the optimisation - it looks good.
Though I still firmly believe the above code should work - it is perfectly valid Fantom code. The optimisation shouldn't even attempt to touch the
JavaOnly
class because it is not annotated with@Js
.It's been mentioned in other topics that cross platform libraries are a great boon to Fantom. And being able to toggle snippets of code on and off at runtime is a great way to get over the idiosyncrasies of running on different platforms.
andy Mon 8 Feb 2016
I don't know - still seems like bad practice to mix code like that - and there are clearer ways to handle that. You have a real use case for that pattern?
SlimerDude Mon 8 Feb 2016
You mean checking the runtime? Yeah, I do it loads in most of my cross-platform libraries. Funcs, files, images, FWT components, and more, all require special handling in JS. Here are just a couple of examples from many:
brian Mon 8 Feb 2016
I would have to give it some thought, but I don't think code that can't be run should be allowed inside a @Js class - to me that is very much like allowing some weird sort of if/block dependency. However, I do think it should be noted at compile time with an extra check.
SlimerDude Wed 10 Feb 2016
I think it's just peachy as it is right now in Fantom 1.0.67.
The above code generates the following compiler warning:
So you're alerted to the fact that it may not work - but as it is fenced by the runtime check you know it won't get executed.
The only problem I have is with Fantom 1.0.68. The generated Javascript errors because the optimisation code runs for all types, whereas it should just run for
@Js
types.matthew Wed 10 Feb 2016
Ticket promoted to #2501 and assigned to matthew
Think I have a fix for this. Will post soon.
matthew Wed 10 Feb 2016
Ticket resolved in 1.0.68
When writing the closure, we check its signature and if any of param types or the return type is non-Js, then we won't write the ClosureFuncSpec, but instead we write a dummy closure that indicates this condition. If the code never executes, then we won't get any type errors at runtime.
LightDye Thu 11 Feb 2016
That is awesome. Has the release date of v1.0.68 been decided yet, please?