HTML5 target generates incorrect code for Array.insert()

This haxe code:

Engine.engine.getGameAttribute(“Level States”).insert(Std.int(0), 1);

Generates the following JavaScript code:

com_stencyl_Engine.engine.getGameAttribute(“Level States”).insert(0,1);

getGameAttribute() returns a native JavaScript array, which doesn’t have an insert() method.

Maybe there is something wrong with Stencyl?

package ;

class Test {
    public static function main() {
        var a = ['a', 'b', 'c'];
        a.insert(1, 'x');
        trace(a);
    }
}

generates following:

(function (console) { "use strict";
var Test = function() { };
Test.main = function() {
    var a = ["a","b","c"];
    a.splice(1,0,"x");
    console.log(a);
};
Test.main();
})(typeof console != "undefined" ? console : {log:function(){}});

Maybe. If I modify the code Stencyl generates to the following:

(Engine.engine.getGameAttribute(“Level States”) : Array).insert(Std.int(0), 1);

Then it works fine. The generated code looks like this:

var _this = com_stencyl_Engine.engine.getGameAttribute(“Level States”);
_this.splice(0,0,1);

Which I find somewhat surprising.

getGameAttribute() returns a Dynamic, so I can see how it would be difficult to infer the correct type at compile time…

Look at this, though:

package ;

class Test {
    public static function main() {
        var a = func();
        var b = ['a', 'b', 'c'];
        a.insert(1, 'x');
        b.insert(1, 'x');
        trace(a);
    }

    public static function func(): Dynamic {
        return new Array<String>();
    }
}

compiles to:

(function () { "use strict";
var Test = function() { };
Test.main = function() {
        var a = Test.func();
        var b = ["a","b","c"];
        a.insert(1,"x");
        b.splice(1,0,"x");
        console.log(a);
};
Test.func = function() {
        return new Array();
};
Test.main();
})();

Which is just wrong. Looks like a Haxe issue, maybe?

In my opinion Haxe doing just right. You return Dynamic instead of Array, so Haxe lost typing information.

I think you should use strict typing everywhere where is possible, and use dynamics in few places only.

I would recommend that either someone look at (perhaps?) a macro-based solution to return different known types from “getGameAttribute” so it types properly, or, just type it yourself like this:

var states:Array<Int> = Engine.engine.getGameAttribute ("Level States");
states.insert (0, 1);

(or something like this?)