elnabo / json2object

Type safe Haxe/JSON (de)serializer
MIT License
66 stars 17 forks source link

Generic Maps not working with abstracts #88

Open haath opened 1 year ago

haath commented 1 year ago
// this works
var x: Array<Int>;

// this works
var y: MyArray<Int>;

// this does NOT work
var z: MyMap<Int>;

where

abstract MyArray<T>(Array<T>) { ... }
abstract MyMap<T>(Map<Int, T>) { ... }

Specifically the following error is thrown (once for every offending type):

Type not found : T

/haxelib/json2object/3,11,0/src/json2object/reader/DataBuilder.hx:961: lines 961-984 : ... Defined in this class

I'm assuming this is not intended since generic-array-abstracts work, but generic-map-abstracts don't?

haath commented 1 year ago

Generic array abstracts also break when the array is nested.

var arr: MyArray2D<Int>;

abstact MyArray2D<T>(Array<Array<T>>) { ... }
elnabo commented 1 year ago

There was indeed a problem with generic abstract types. I've pushed some changes, that should fix the problems raised by your small examples.

Can you confirm if it fixes the problem in your case ?

haath commented 1 year ago

Amazing! These work now:

abstract MyArray<T>(Array<T>) { ... }
abstract MyMap<T>(Map<Int, T>) { ... }
abstract MyNestedMap<T>(Map<Int, Map<Int, T>>) { ... }

But this still doesn't:

abstact MyArray2D<T>(Array<Array<T>>) { ... }
elnabo commented 1 year ago

I think I'm going to need more example for MyArray2D. Mine compile/parse without problem.

haath commented 1 year ago

Alright, I was able to narrow-down what exactly in my abstract was causing this issue. It turns out it was a @:from function.

Here is the smallest example that I can get the error with:

abstract MyArray2D<T>(Array<Array<T>>)
{
    @:from
    public static function fromArray<T>(arr: Array<Array<T>>): MyArray2D<T>
    {
        return cast arr;
    }
}

The error persists even if I add @:jignored to the function.

Only removing the @:from meta makes the error go away.

elnabo commented 1 year ago

Oh I see the problem. The from function is static, we can't apply the from the abstract.

We'll have to see if we can infer it from the return value.

@:jignored only works on variables/properties.