Example #1
0
 public static bool IsSerializable(FieldDefinition field, IReadOnlyDictionary <GenericParameter, TypeReference> arguments)
 {
     if (IsSerializableModifier(field))
     {
         MonoSerializableScope scope = new MonoSerializableScope(field, arguments);
         return(IsFieldTypeSerializable(scope));
     }
     return(false);
 }
Example #2
0
        public static bool IsFieldTypeSerializable(MonoSerializableScope scope)
        {
            TypeReference fieldType = scope.FieldType;

            // if it's generic parameter then get its real type
            if (fieldType.IsGenericParameter)
            {
                GenericParameter parameter = (GenericParameter)fieldType;
                fieldType = scope.Arguments[parameter];
            }

            if (fieldType.IsArray)
            {
                ArrayType array = (ArrayType)fieldType;
                // one dimention array only
                if (!array.IsVector)
                {
                    return(false);
                }

                // if it's generic parameter then get its real type
                TypeReference elementType = array.ElementType;
                if (elementType.IsGenericParameter)
                {
                    GenericParameter parameter = (GenericParameter)elementType;
                    elementType = scope.Arguments[parameter];
                }

                // array of arrays isn't serializable
                if (elementType.IsArray)
                {
                    return(false);
                }
                // array of generics isn't serializable
                if (MonoType.IsSerializableGeneric(elementType))
                {
                    return(false);
                }
                // check if array element is serializable
                MonoSerializableScope elementScope = new MonoSerializableScope(scope.DeclaringType, elementType, true, scope.Arguments);
                return(IsFieldTypeSerializable(elementScope));
            }

            if (MonoType.IsList(fieldType))
            {
                // list is serialized same way as array, so check its argument
                GenericInstanceType list        = (GenericInstanceType)fieldType;
                TypeReference       listElement = list.GenericArguments[0];

                // if it's generic parameter then get its real type
                if (listElement.IsGenericParameter)
                {
                    GenericParameter parameter = (GenericParameter)listElement;
                    listElement = scope.Arguments[parameter];
                }

                // list of arrays isn't serializable
                if (listElement.IsArray)
                {
                    return(false);
                }
                // list of buildin generics isn't serializable
                if (MonoType.IsBuiltinGeneric(listElement))
                {
                    return(false);
                }
                // check if list element is serializable
                MonoSerializableScope elementScope = new MonoSerializableScope(scope.DeclaringType, listElement, true, scope.Arguments);
                return(IsFieldTypeSerializable(elementScope));
            }

            if (fieldType.IsPrimitive)
            {
                return(true);
            }
            if (MonoType.IsString(fieldType))
            {
                return(true);
            }
            if (MonoType.IsEngineStruct(fieldType))
            {
                return(true);
            }
            if (MonoType.IsEnginePointer(fieldType))
            {
                return(true);
            }

            if (MonoType.IsObject(fieldType))
            {
                return(false);
            }
            if (fieldType.IsGenericInstance)
            {
                return(MonoType.IsSerializableGeneric(fieldType));
            }
            if (IsRecursive(scope.DeclaringType, fieldType))
            {
                return(scope.IsArrayElement);
            }

            TypeDefinition definition = fieldType.Resolve();

            if (definition.IsInterface)
            {
                return(false);
            }
            if (definition.IsAbstract)
            {
                return(false);
            }
            if (MonoType.IsCompilerGenerated(definition))
            {
                return(false);
            }
            if (definition.IsSerializable)
            {
                return(true);
            }
            if (definition.IsEnum)
            {
                return(true);
            }

            return(false);
        }