javascripttypescriptgoogle-closure-compilerphaser-framework

Google Closure Compiler incorrectly removes function call


I am developing a HTML5 game, using Phaser and the Google Closure Compiler in advanced mode in order to package the game.

I've ran into an issue where it seems I am unable to destroy a sprite. After checking the output from the compiler I noticed that it keeps removing my destroy function call.

My code is very simple, I've tested the following:

sprite.destroy(); and Phaser.Component.Destroy.prototype.destroy.call(sprite);

Both of these lines simply get removed from my codebase. It's not because it's unreachable code, if I put console.log statements in the same scope they stay there.

So the original code is this:

if (typeof this.sprite != 'undefined'){
    console.log('destroy sprite');
    this.sprite.destroy();
    Phaser.Component.Destroy.prototype.destroy.call(this.sprite);
    console.log('sprite destroyed');
}

And it gets compiled to this:

"undefined"!=typeof this.sprite&&(console.log("destroy sprite"),console.log("sprite destroyed"))

I can't figure out why the code is removed, Phaser is set as an external and I'm not running into this issue with any other methods or phaser classes.

Simply calling eval('this.sprite.destroy();'); works by the way. This proves that the function does actually exist. However this is a pretty shitty solution, and only works because the compiler isn't replacing sprite in this case.

UPDATE

I've been able to reliably reproduce the issue with very little code, see my answer below. But I don't know why this is happening yet.

UPDATE 2

Thanks to Hacketo we figured out that this issue occurs because a proper Phaser extern file is missing. Creating one specifically for this issue fixes it, however without a full file there will always be a chance for more issues.

For this specific issue, adding the following file as an extern fixed it: http://pastebin.com/nXA0fiZr


Solution

  • I've figured out what's causing this, however why it's causing it I don't know so if anybody has a clue I'm very interested.

    Here is a sample that allows you to reproduce my issue:

    Typescript: http://pastebin.com/YaCfH2mz

    Javascript: http://pastebin.com/A4w2YG9N

    So for some reason, defining a method called destroy in a random class for some reason breaks everything. Even though the class is not used, and the method is empty.

    UPDATE

    Thanks to Hacketo we figured out that this issue occurs because a proper Phaser extern file is missing. Creating one specifically for this issue fixes it, however without a full file there will always be a chance for more issues.

    For this specific issue, adding the following file as an extern fixed it:

    var Phaser = {};
     
    Phaser.Sprite = function(game, x, y, key, frame){};
     
    Phaser.Sprite.prototype.destroy = function(){};