Hey Mike,

I finally got a chance to start playing around with some of your work
today. I've been starting out with externc. I've run into a couple of
issues. One you already know about. Let's start with the other one,
though...

1) It looks like the Array class constructor has the wrong signature. This
is from the es3.js extern:

/**
 * @constructor
 * @param {...*} var_args
 * @return {!Array.<?>}
 * @nosideeffects
 * @template T
 * @see
http://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array
 */
function Array(var_args) {}

It looks like externc is producing the following AS3:

public function Array(var_args:Object) {}

However, I think it's meant to produce this AS3 instead:

public function Array(...var_args:Array) {}

There are probably other functions with the same issue too.

2) I immediately ran into that issue where a top-level class interferes
with a class that has the same name in a package. w3c_event.js defines the
top-level Event class, and CreateJS has a createjs.Event class. It's the
exact same issue that you brought up earlier. I think I dismissed it too
quickly. I apologize for that.

At the time, I was thinking that FlexJS could easily work around it because
be new code. However, now that I'm running into the collision directly, I
realize that this is going to be a big issue with external libraries. Like
CreateJS, a ton of existing JS frameworks define their own Event type. This
issue is going to come up a lot. You're absolutely right: it needs to be
addressed somehow.

I have some ideas. Some involve changes to the AS3 language. I don't know
if that's on the table, but I'll throw them out there anyway.

If AS3 would let us do something like this, the issue wouldn't be as bad:

import global.Event;
import createjs.Event;
var event2:createjs.Event; //createjs
var event:global.Event; //native

But AS3 doesn't provide any kind of identifier to refer to the top-level
package. Even if it did, though, always being forced to use the
fully-qualified class name would get annoying. At least if there are two
packages, you only need to do it when they're both imported. With one class
in the top-level, you always need to do it.

Alternatively, TypeScript has some interesting import syntax that I
remember wishing we could use in AS3:

import CreateJSEvent = createjs.Event;
var event2:CreateJSEvent; //createjs
var event:Event; //native

Now, within the scope of the class with these import statements, Event is
the top-level function, and CreateJSEvent maps to createjs.Event. This
would be really cool, in my opinion. I wish I could use it in Starling
projects to do exactly the same thing with event conflicts:

import FlashEvent = flash.events.Event;
import starling.events.Event;
var event:Event; //starling
var event2:FlashEvent; //flash

Again, that would require changes to AS3. Maybe that's not acceptable.

Another option might be to make the name mapping configurable as a compiler
argument:

-map-class=createjs.Event,createjs.CreateJSEvent

import createjs.CreateJSEvent;
var event:CreateJSEvent; //createjs
var event2:Event; //native

or:

-map-class=Event,NativeEvent

import createjs.Event;
var event:Event; //createjs
var event2:NativeEvent; //native

Very similar, but this would apply to a whole project instead of the scope
of a single class. The JavaScript output would use the real name
(createjs.Event or Event), but the AS3 would use the mapped name
(createjs.CreateJSEvent or NativeEvent).

I suppose, with all of these, IDEs would probably fail to recognize that
names were mapped and show incorrect errors. I'm finding this stagnant AS3
IDE landscape frustrating (IDEs have some annoying bugs with the Feathers
SDK too). It makes me want to forge ahead without them and hope that an
alternative comes along.

Thoughts? Please feel free to shoot things down for being crazy or
impossible.

- Josh

Reply via email to