curiosity-ai / h5

🚀 The next generation C# to JavaScript compiler
https://github.com/curiosity-ai/h5
Apache License 2.0
210 stars 30 forks source link

IReadOnlyCollection is not handled in System.Arrat.getCount #82

Closed ghost closed 1 year ago

ghost commented 1 year ago
public class MyTest : IReadOnlyCollection<int>
{
    int IReadOnlyCollection<int>.Count
    {
        get { return 123; }
    }

    IEnumerator<int> IEnumerable<int>.GetEnumerator()
    {
        throw new NotImplementedException();
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

IReadOnlyCollection<int> test = new MyTest();

Console.WriteLine("test.Count: " + test.Count);
Result:

test.Count: 0

Reason is here:

getCount: function (obj, T) {
    var name,
        v;

    if (H5.isArray(obj)) {
        return obj.length;
    } else if (T && H5.isFunction(obj[name = "System$Collections$Generic$ICollection$1$" + H5.getTypeAlias(T) + "$getCount"])) {
        return obj[name]();
    } else if (H5.isFunction(obj[name = "System$Collections$ICollection$getCount"])) {
        return obj[name]();
    } else if (T && (v = obj["System$Collections$Generic$ICollection$1$" + H5.getTypeAlias(T) + "$Count"]) !== undefined) {
        return v;
    } else if ((v = obj["System$Collections$ICollection$Count"]) !== undefined) {
        return v;
    } else if ((v = obj.Count) !== undefined) {
        return v;
    } else if (H5.isFunction(obj.getCount)) {
        return obj.getCount();
    }

    return 0;
},

And most likely getIsReadOnly is affected as well.

ghost commented 1 year ago

Fixed version:

getCount: function (obj, T) {
            var name,
                v;

            if (H5.isArray(obj)) {
                return obj.length;
            } else if (T && H5.isFunction(obj[name = "System$Collections$Generic$ICollection$1$" + H5.getTypeAlias(T) + "$getCount"])) {
                return obj[name]();
            } else if (T && H5.isFunction(obj[name = "System$Collections$Generic$IReadOnlyCollection$1$" + H5.getTypeAlias(T) + "$getCount"])) {
                return obj[name]();
            } else if (H5.isFunction(obj[name = "System$Collections$ICollection$getCount"])) {
                return obj[name]();
            } else if (T && (v = obj["System$Collections$Generic$ICollection$1$" + H5.getTypeAlias(T) + "$Count"]) !== undefined) {
                return v;
            } else if (T && (v = obj["System$Collections$Generic$IReadOnlyCollection$1$" + H5.getTypeAlias(T) + "$Count"]) !== undefined) {
                return v;
            } else if ((v = obj["System$Collections$ICollection$Count"]) !== undefined) {
                return v;
            } else if ((v = obj.Count) !== undefined) {
                return v;
            } else if (H5.isFunction(obj.getCount)) {
                return obj.getCount();
            }

            return 0;
        },

Function getIsReadOnly does not need changes.