benmerckx / genes

Generates split ES modules and Typescript definitions from Haxe modules.
44 stars 8 forks source link

Uncaught TypeError: _g is not a function #67

Closed daniellsl closed 1 year ago

daniellsl commented 1 year ago

When using function binding to register an event handler, it will come up. This issue reproduced by the following .hx program.

Form the generated .js program, there is var _g = (o=>Register.bind(o, o.on))(Main.listener);, which _g will exist the TypeError issue. Cause _g is undefined at the moment, and error occur after we call _g(xxx, xxx).


My Program:

using tink.CoreApi;

class Main {
    static var listener:Listener;

    static function main() {
        listener.on.bind('call', () -> {});
    }
}

interface Listener {
    function on(event:String, f:() -> Void):Void;
}

Generated:

import {Register} from "./genes/Register.js"

export const Main = Register.global("$hxClasses")["Main"] = 
class Main {
    static main() {
        var _g = (o=>Register.bind(o, o.on))(Main.listener);
        var event = "call";
        var f = function () {
        };
    }
    static get __name__() {
        return "Main"
    }
    get __class__() {
        return Main
    }
}

export const Listener = function() {};
Listener.__isInterface__ = true;
benmerckx commented 1 year ago

I would assume it's actually Main.listener which is not defined? Or is there an instance of Listener which is not included in the example?

daniellsl commented 1 year ago

Let me introduce another example. The Main.listener is actually provided by extern class's static function Listener.connect(). The TypeError exist in _g(event, f);. In my program, I want to clear the callback binding once it be called.

And I am wondering should var _g = (o=>Register.bind(o, o.off))(Main.listener); be something like var _g = o=>Register.bind(o, o.off);?

using tink.CoreApi;

class Main {
    static var listener:Listener;

    static function main() {
        listener = Listener.connect();

        var bindings:CallbackLink = null;

        listener.on('call', function onCall() {
            bindings.cancel();
        });

        // `TypeError: _g is not a function`, when below exist
        bindings = [
            listener.off.bind('call', onCall),
        ];
    }
}

extern class Listener {
    static function connect():Listener;
    function on(event:String, f:() -> Void):Void;
    function off(event:String, f:() -> Void):Void;
}

Generated:

import {SimpleLink, CallbackLink} from "./tink/core/Callback.js"
import {Register} from "./genes/Register.js"

export const Main = Register.global("$hxClasses")["Main"] = 
class Main {
    static main() {
        Main.listener = Listener.connect();
        var bindings = null;
        var onCall = function () {
            if (bindings != null) {
                bindings.cancel();
            };
        };
        Main.listener.on("call", onCall);
        var _g = (o=>Register.bind(o, o.off))(Main.listener);
        var event = "call";
        var f = onCall;
        var this1 = new SimpleLink(function () {
            _g(event, f);
        });
        bindings = CallbackLink.fromMany([this1]);
    }
    static get __name__() {
        return "Main"
    }
    get __class__() {
        return Main
    }
}
kevinresol commented 1 year ago

@daniellsl please provide a self-contained example. We currently can't run your program because Listener is undefined

daniellsl commented 1 year ago

Turn out the Uncaught TypeError: _g is not a function was triggered by o.off on run time on my original program. So, I'm gonna close this issue. Sorry for interrupt.