Open chochos opened 11 years ago
This will enabled us to properly process native
in the js compiler, and probably remove the nativejs
hack.
How is that related to nativejs
?
I would agree that it could be useful. I would make the list of backends an enum, but because we don't have real enums in the JVM sense, I don't think we can use enum values as annotation parameters ATM. @tombentley can confirm/deny.
As far as the JVM backend is concerned those native annotations are ignored anyways ATM.
what? you ignore native as well? then WTF do we even have it for?
Regarding nativejs
, it's something Tako added to the js backend for the DOM module he wrote, but the js compiler only deals with nativejs
annotation when using declarations annotated with it, not when generating code for those declarations.
Maybe it's two separate things and the nativejs annotation will remain, but I believe we definitely should add the backend(s) to the native
annotation. So strings then?
Well, I guess we should not ignore it, but build support for it. ATM it's only used by the language module and we do not include the bits with native
in the list of files to compile, so the backend never sees any of those. If it would see one of them, it would get confused because there's a duplicate in a java file.
The native annotation is supposed to let you write a class in Ceylon and have, for example, just one method implemented in Java + JavaScript. But that's not supported yet, and we have not yet defined what that would look like from the java/js side.
Sent from my iPhone
On 10/07/2013, at 6:19 PM, Stéphane Épardaud notifications@github.com wrote:
Well, I guess we should not ignore it, but build support for it. ATM it's only used by the language module and we do not include the bits with native in the list of files to compile, so the backend never sees any of those. If it would see one of them, it would get confused because there's a duplicate in a java file.
— Reply to this email directly or view it on GitHub.
@chochos Are you sure there are things marked native
in the language module that can be compiled by the JS backend but not by the JVM backend? It doesn't really seem to make sense to me. Supposedly native
is used for those cases when we cannot express in Ceylon what we need the code to do.
We did have some examples of backend-specific native code before, but that was when the JVM compiler had some restrictions. Do we still have those problems now? (And if we can only come up with one or two simple cases is it worth the trouble?)
And nativejs
is indeed a different beast and I'm still doubtful we can merge the two. Because native
means that although the code is written natively it still is Ceylon code (proper naming, it has meta information, reified generics, etc), while nativejs
means the code is entirely native and we should not try to apply Ceylon's naming rules or otherwise expect it will behave as a Ceylon object. (I'm not sure if that means we'll never be able to make nativejs
work properly for more complex cases where you want to use is
or meta models etc)
So then you can use nativejs to make something a Ceylon class even though it doesn't conform to the mappings of Ceylon to JS or even know it's own type?! Doesn't that mean it breaks as soon as you assign an instance to Object?
Sent from my iPhone
On 10/07/2013, at 6:40 PM, Tako Schotanus notifications@github.com wrote:
@chochos Are you sure there are things marked native in the language module that can be compiled by the JS backend but not by the JVM backend? It doesn't really seem to make sense to me. Supposedly native is sued for those cases when we cannot express in Ceylon what we need the code to do.
We did have some examples of backend-specific native code before, but that was when the JVM compiler had some restrictions. Do we still have those problems now? (And if we can only come up with one or two simple cases is it worth the trouble?)
And nativejs is indeed a different beast and I'm still doubtful we can merge the two. Because native means that although the code is written natively it still is Ceylon code (proper naming, it has meta information, reified generics, etc), while nativejs means the code is entirely native and we should not try to apply Ceylon's naming rules or otherwise expect it will behave as a Ceylon object. (I'm not sure if that means we'll never be able to make nativejs work properly for more complex cases where you want to use is or meta models etc)
— Reply to this email directly or view it on GitHub.
I knew it would have enough information to know its own type, but now looking at the code in the web backend I see that at a later date even meta model information was added. I didn't implement that so I'm not sure how much it supports, I think @chochos or @ikasiuk will be able to give more details.
I knew it would have enough information to know its own type
How does that work, precisely?
As far as I can remember + what I can deduce from the code is that we extend the JS type with the information required by Ceylon. So we take an existing JS type and add onto it the information we supply with Ceylon interfaces marked "nativejs".
For example, the native toplevel attribute document
is defined as being of type Document
. In the file defining all the DOM interfaces (https://github.com/ceylon/ceylon-web-ide-backend/blob/master/src/main/ceylon/browser/dom/main.ceylon) exists a type Document
with its members and a parent interface Node
. The code will now add that available meta information to the prototype of the JS type, basically turning it into a Ceylon class (see https://github.com/ceylon/ceylon-web-ide-backend/blob/master/src/main/webapp/scripts/modules/browser/1.0.0/browser-1.0.0.js).
The advantage of this method is that a) we have type safety and b) it works in cases where wrappers wouldn't (for example in the case of the DOM tree it's the browser that's in control of creating / deleting most of the tree elements).
The disadvantage is (right now at least) that it's a lot of manual work.
@quintesse Exception
is one example of a type that is annotated native
and yet we can compile it to JS and it works.
@chochos true, but that's also an example of a very trivial class, I'm wondering if there's anything that has a bit more "meat" to it. Just to see if it's worth the trouble.
I would make the list of backends an enum, but because we don't have real enums in the JVM sense, I don't think we can use enum values as annotation parameters ATM. @tombentley can confirm/deny.
Right now the JVM compiler doesn't support this, but it will once I add the extra transformation which handles all these funky cases. It makes me wonder how we will document it though, since the native
annotation would then not be present as an Java annotation, so ceylondoc (in its current form) would have trouble 'seeing' it. There are a number of way to address that, but I won't pollute this thread with them.
We could just use strings then, as long as we properly document what the valid backends are it shouldn't be a big problem.
Right now we're only using it in the language module but it could be used in other modules as well. I'm thinking of a way to make it more useful for js, but I think I'll elaborate on that repo, not here.
The
native
annotation is incomplete; there is a lot of stuff in the language module annotatednative
which can be compiled to js, so it's really only annotated for the jvm compiler.So the annotation should have a parameter which is the list of backends that the declaration is native for; no args means it's native for all backends.
Question is: should the backends be objects, or simply strings?
i.e.
we can define a Backend or Platform class with two cases, jvm and javascript. It can even be used in the
process
object, which I think already has a platform property.