kevinresol / hxgenjs

Extensible JS generator for Haxe
57 stars 16 forks source link

Generation Error catch variable #28

Open kiroukou opened 5 years ago

kiroukou commented 5 years ago

Hello,

Generation (es6mode if that does have an impact) of the haxe-thunk library give the following generated code :

original

public function middleware(action:Thunk<TState, TParams>, next:Void->Dynamic):Any {
        return switch (action) {
            case Action(cb):
                cb(store.dispatch, store.getState);

            case WithParams(cb):
                cb(store.dispatch, store.getState, this.params);
        };
    }

generated

switch((Type().default).enumIndex(action)) {
        case 0:
            var cb = action[2];
            return cb(($_=this.store,$bind($_,$_.dispatch)),($_=this.store,$bind($_,$_.getState)));
        case 1:
            var cb1 = action[2];
            return cb1(($_=this.store,$bind($_,$_.dispatch)),($_=this.store,$bind($_,$_.getState)),this.params);
        }

The execution (react-native bundler) complains about $_ variable which cannot be found

kiroukou commented 5 years ago

More attemps :

var getState = this.store.getState;
var dispatch = this.store.dispatch;

Gives :

var getState = ($_=this.store,$bind($_,$_.getState));
var dispatch = ($_=this.store,$bind($_,$_.dispatch));
kiroukou commented 5 years ago
var localStore = this.store;
var getState = localStore.getState;
var dispatch = localStore.dispatch;

Did the trick for me. Had a look at the source code, unfortunately, haven't been able to get it..

elsassph commented 5 years ago

In the hxgenjs generated code check whether $_ is declared in the file where it's used.

kiroukou commented 5 years ago

Hum.. At first I though that javascript wasn't able to "undersand" the variable declaration that way but seems like the following js does work properly

function $bind (a, b) {
    console.log("apply binding");
  b();
}

var store = {
    getState: function() {
     console.log("hey");
  }
};

var getState = ($_=store,$bind($_,$_.getState));

I'll check if that code is running well with react-native bundler, just in case.

kiroukou commented 5 years ago

Ok I confirm that's the react-native bundler which doesn't accept that exact same code I got running in the browser.

kiroukou commented 5 years ago

In the hxgenjs generated code check whether $_ is declared in the file where it's used.

Oh if you meant to have something like :

var $_;

in the file, no there's not, and yes if I declare it, it does seem to work properly in react-native.

The weird thing, is that it occurs only on that file on a pretty large project.. https://github.com/haxe-react/haxe-redux-thunk/blob/master/src/redux/thunk/ThunkMiddleware.hx

zabojad commented 5 years ago

Just for more context, it happens only there : https://github.com/haxe-react/haxe-redux-thunk/blob/master/src/redux/thunk/ThunkMiddleware.hx

Because it translates to ThunkMiddleware.js to this:

// Class: redux.thunk.ThunkMiddleware

var $global = typeof window != "undefined" ? window : typeof global != "undefined" ? global : typeof self != "undefined" ? self : this

$global.Object.defineProperty(exports, "__esModule", {value: true});

var __map_reserved = {};

// Imports

var $hxClasses = require("./../../hxClasses_stub").default;
var $import = require("./../../import_stub").default;
var $bind = require("./../../bind_stub").default;
function redux_IMiddleware() {return require("./../../redux/IMiddleware");}
function Type() {return require("./../../Type");}

// Constructor

class ThunkMiddleware {
    constructor(params) {
        this.params = params;
    }
    middleware(action,next) {
        switch((Type().default).enumIndex(action)) {
        case 0:
            var cb = action[2];
            return cb(($_=this.store,$bind($_,$_.dispatch)),($_=this.store,$bind($_,$_.getState)));
        case 1:
            var cb1 = action[2];
            return cb1(($_=this.store,$bind($_,$_.dispatch)),($_=this.store,$bind($_,$_.getState)),this.params);
        }
    }
}

// Meta

ThunkMiddleware.__name__ = ["redux","thunk","ThunkMiddleware"];
ThunkMiddleware.__interfaces__ = [(redux_IMiddleware().default)];
ThunkMiddleware.prototype.__class__ = ThunkMiddleware.prototype.constructor = $hxClasses["redux.thunk.ThunkMiddleware"] = ThunkMiddleware;

// Init

// Statics

// Export

exports.default = ThunkMiddleware;
elsassph commented 5 years ago

Yes if generated code is missing a var $_, as we're in strict mode, it will refuse using the non declared variable.