benmerckx / genes

Generates split ES6 modules and Typescript definitions from Haxe modules.
43 stars 8 forks source link

Using 'iterator' as function name generates flawed Javascript #72

Closed mikkelmr closed 6 months ago

mikkelmr commented 6 months ago

The following Haxe code:

 class TestClass
 {   
    public static function testIterator(a : String) {
        iterator(a);
    }
    public static function iterator(a : String) {
        trace(a);
    }
 }

Compiled with this hxml & Haxe 4.3.3.:

-L genes
-D dts
--js autogen/ts/Test.js
TestClass

Produces this Java script Code:

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

export const TestClass = Register.global("$hxClasses")["TestClass"] = 
class TestClass {
    static testIterator(a) {
        $iterator(TestClass)(a);
    }
    static iterator(a) {
        console.log("src/TestClass.hx:16:",a);
    }
    static get __name__() {
        return "TestClass"
    }
    get __class__() {
        return TestClass
    }
}

And this Typescript d.ts file:

 export declare class TestClass {
    static testIterator(a: string): void
    static iterator(a: string): void
}

But when run from my NextJs/TypeScript project like this:

export default function Home() {
  TestClass.testIterator("Hello");
  .........
}

The following Exception occurs:

Uncaught TypeError: TestClass.$iterator is not a function

This issue is similar to this issue https://github.com/benmerckx/genes/issues/68, that was fixed earlier this year. and I assume that the fix is pretty straight forward, probably something like https://github.com/benmerckx/genes/commit/6938376fedbc28c192731c0c975c5e06b12c95ad

benmerckx commented 6 months ago

Which haxe version are you using to compile the example?

mikkelmr commented 6 months ago

4.2.5 - do you believe latest official haxe solves this issue?

benmerckx commented 6 months ago

I tried to reproduce but this seems to work fine, on 4.2.5 as well. Is TestClass typed as Dynamic somehow?

https://github.com/benmerckx/genes/commit/f6ddc65fd804c380077d8617e5d18435953c8369#diff-53c8da3f2ff2519b700e8506dccb7959670226c43b25b17b7b53f2950351d236R5-R12

mikkelmr commented 6 months ago

No. But I use these flags in hxml my file:

-L genes -D dts

mikkelmr commented 6 months ago

And then I am using the compiled Javascript + d.ts files in NextJs/typescript context.

benmerckx commented 6 months ago

Could you share more of the source and/or the compiled Javascript?

mikkelmr commented 6 months ago

Sure, will just spend some time to isolate the issue a bit more. Will return soon

mikkelmr commented 6 months ago

I have updated the initial comment with much more details.

mikkelmr commented 6 months ago

I can see that there is a lot of specialhandling regarding 'iterator', for example this line causes a call to 'iterator' to be emitted as $iterator.

https://github.com/benmerckx/genes/blob/master/src/genes/es/ExprEmitter.hx#L66C1-L66C1

But the iterator method is not written as '$iterator'. I tried to fix that, but still the d.ts is using 'iterator' and maybe it's not what you would like to happen.

mikkelmr commented 6 months ago

Actually I think another problem is that the classname is not referenced followed by the function name when calling a static function from another static function. If I change the generated Javascript to:

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

export const TestClass = Register.global("$hxClasses")["TestClass"] = 
class TestClass {
    static testIterator(a) {
        TestClass.iterator(a);
    }
    static iterator(a) {
        console.log("src/TestClass.hx:16:",a);
    }
    static get __name__() {
        return "TestClass"
    }
    get __class__() {
        return TestClass
    }
}

It actually works. There is also strange things happening in the generated Javascript with the argument to 'iterator'

iterator(TestClass)(a);

Guess it shuld only be:

iterator(a);

mikkelmr commented 6 months ago

I made this PR that somehow solved the problem for me: https://github.com/benmerckx/genes/pull/73

I have to admit that I was bit on thin ice and maybe the fix is not the right way to solve it. Also a proper testcase would be nice, just haven't figured that part out.

But maybe this can give you and idea of how to proceed. Let me know if you need some more info or help.