cincheo / jsweet

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

ArrayBufferView subclasses should support [index] syntax? #119

Open froyo-np opened 8 years ago

froyo-np commented 8 years ago

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays

the following code (which would be valid in javascript) results in an error using the jsweet eclipse plugin.

ArrayBuffer arb = new ArrayBuffer(2 * 2 * 4); int whatever = new Int32ArrayBuffer(arb)[0];

//results in error: The type of the expression must be an array type but it resolved to Int32Array

it is impossible to retrieve individual values from a typed ArrayBufferView with jsweet at this time.

renaudpawlak commented 8 years ago

Thank you for highlighting the JavaScript ArrayBuffer API. I never had to use it so far, so I am happy that someone tried it out.

You are right, there are several issues here. However, it is not as bad as it looks, since there is always a way in JSweet to override typing.

So as a short answer, let me first give you a solution that works:

ArrayBuffer arb = new ArrayBuffer(2 * 2 * 4);
int[] array = any(new Int32Array(arb));
int whatever = array[0];

This is an untyped solution because the purpose of the helper function jsweet.util.Globals.any is to erase typing (like a cast to any in TypeScript). This function was not available in version 1.0.0, so if you use the Eclipse plugin, you should still use a dirty cast: (int[])(Object)new Int32Array(arb).

Now, the long answer... what if we want to keep strong typing and plain access to the Int32Array class?

The first thing is that to use indexed accesses in JSweet, you need to use the $get method. Your attempt to use the array notation in Java cannot work on an array instance. So the right way to do it is to write new Int32ArrayBuffer(arb).$get(0). This works but this is where the first problem comes... JSweet generates numbers as Double by default, so you need to cast back to int: (int)(double)... yuck. I have been thinking on how to infer that some numbers are integers in JSweet... that's open issue right now. Additionally, I also see another problem, that is that the API does not define the correct $set function... So although you can access the values of your array, you cannot set any value. This can be fixed and I will plan it for the next release.

Right now, it seems to me that the nicest way to support it would be to add some helper functions in jsweet.util.Globals which would be similar to the current jsweet.util.Globals.array methods, but for the right types of arrays...

In any case, if we add to it the problem you pointed out in #118, it feels that this API requires a little bit of thinking if we want to have fully typed support in a nice way. In the meantime, I would advise to fallback on my first solution which is not too bad.

froyo-np commented 8 years ago

Thanks for your quick response - I was unaware of the "any" type in jsweet, but it looks like what I am looking for for now.