jacobdufault / fullserializer

A robust JSON serialization framework that just works with support for all major Unity export platforms.
MIT License
1.11k stars 169 forks source link

Issues with building for WSA #124

Open lazlo-bonin opened 7 years ago

lazlo-bonin commented 7 years ago

While trying to make my plugin compatible with WSA I've found some errors in the (brilliant!) fsPortableReflection class and missing Resolve calls elsewhere in FS.

First, in fsPortableReflection, using Linq is missing when USE_TYPEINFO is enabled. I suspect this is due to the using directive not having been wrapper in a preprocessor conditional and therefore getting removed by a Remove and sort usings command.

The usings should read:

using System;
using System.Collections.Generic;
using System.Reflection;

#if USE_TYPEINFO
using System.Linq;
#endif

The method fsSerializer.RemapAbstractStorageTypeToDefaultType is missing the required Resolve calls. Here's my implementation of them:

private void RemapAbstractStorageTypeToDefaultType(ref Type storageType) {
    if ((storageType.Resolve().IsInterface || storageType.Resolve().IsAbstract) == false)
        return;

    if (storageType.Resolve().IsGenericType) {
        Type remappedGenericType;
        if (_abstractTypeRemap.TryGetValue(storageType.Resolve().GetGenericTypeDefinition(), out remappedGenericType)) {
            Type[] genericArguments = storageType.GetGenericArguments();
            storageType = remappedGenericType.Resolve().MakeGenericType(genericArguments);
        }
    }

    else {
        Type remappedType;
        if (_abstractTypeRemap.TryGetValue(storageType, out remappedType))
            storageType = remappedType;
    }
}

The method fsSerializer.SetDefaultStorageType is also missing the Resolve calls:

public void SetDefaultStorageType(Type abstractType, Type defaultStorageType) { if ((abstractType.Resolve().IsInterface || abstractType.Resolve().IsAbstract) == false) throw new ArgumentException("|abstractType| must be an interface or abstract type"); _abstractTypeRemap[abstractType] = defaultStorageType; }

The method UnityEvent_Converter.CanProcess is also missing Resolve calls:

    public override bool CanProcess(Type type) {
        return typeof(UnityEvent).Resolve().IsAssignableFrom(type.Resolve()) && type.Resolve().IsGenericType == false;
    }

And finally, for a reason that completely eludes me (can't find the documentation for it anywhere), in fsProtableReflection.GetAttribute(MemberInfo, Type, bool), MemberInfo.GetCustomAttributes seems to return an IEnumerable<Attribute> instead of an object[] on WSA platforms, therefore making the length and index call throw errors. My temporary fix is simply to force it into an array:

var attributes = element.GetCustomAttributes(attributeType, /*inherit:*/ true).ToArray();

I realize now that this last fix moves the System.Linq dependency out of the preprocessor conditional I mentioned earlier.

BrknRobot commented 7 years ago

Can you test with the latest code in Master? #136 should have fixed these issues.