コード例 #1
0
        internal bool RecordTypeToGenerate(Type t, Module module, Assembly targetAssembly)
        {
            if (TypeUtilities.IsTypeIsInaccessibleForSerialization(t, module, targetAssembly))
            {
                return(false);
            }

            var typeInfo = t.GetTypeInfo();

            if (typeInfo.IsGenericParameter || ProcessedTypes.Contains(t) || TypesToProcess.Contains(t) ||
                typeof(Exception).GetTypeInfo().IsAssignableFrom(t) ||
                typeof(Delegate).GetTypeInfo().IsAssignableFrom(t))
            {
                return(false);
            }

            if (typeInfo.IsArray)
            {
                RecordTypeToGenerate(typeInfo.GetElementType(), module, targetAssembly);
                return(false);
            }

            if (typeInfo.IsNestedFamily || typeInfo.IsNestedPrivate)
            {
                Log.Warn(
                    ErrorCode.CodeGenIgnoringTypes,
                    "Skipping serializer generation for nested type {0}. If this type is used frequently, you may wish to consider making it non-nested.",
                    t.Name);
            }

            if (typeInfo.IsGenericType)
            {
                var args = t.GetGenericArguments();
                foreach (var arg in args)
                {
                    RecordTypeToGenerate(arg, module, targetAssembly);
                }
            }

            if (typeInfo.IsInterface || typeInfo.IsAbstract || t == typeof(object) || t == typeof(void) ||
                GrainInterfaceData.IsTaskType(t))
            {
                return(false);
            }

            if (typeInfo.IsGenericType)
            {
                var def = typeInfo.GetGenericTypeDefinition();
                if (def == typeof(Task <>) || (SerializationManager.GetSerializer(def) != null) ||
                    ProcessedTypes.Contains(def) || typeof(IAddressable).IsAssignableFrom(def))
                {
                    return(false);
                }

                if (def.Namespace != null && (def.Namespace.Equals("System") || def.Namespace.StartsWith("System.")))
                {
                    Log.Warn(
                        ErrorCode.CodeGenSystemTypeRequiresSerializer,
                        "System type " + def.Name + " requires a serializer.");
                }
                else
                {
                    TypesToProcess.Add(def);
                }

                return(false);
            }

            if (typeInfo.IsOrleansPrimitive() || (SerializationManager.GetSerializer(t) != null) ||
                typeof(IAddressable).GetTypeInfo().IsAssignableFrom(t))
            {
                return(false);
            }

            if (typeInfo.Namespace != null && (typeInfo.Namespace.Equals("System") || typeInfo.Namespace.StartsWith("System.")))
            {
                var message = "System type " + t.Name + " may require a custom serializer for optimal performance. "
                              + "If you use arguments of this type a lot, consider asking the Orleans team to build a custom serializer for it.";
                Log.Warn(ErrorCode.CodeGenSystemTypeRequiresSerializer, message);
                return(false);
            }

            if (TypeUtils.HasAllSerializationMethods(t))
            {
                return(false);
            }

            // This check is here and not within TypeUtilities.IsTypeIsInaccessibleForSerialization() to prevent potential infinite recursions
            var skipSerialzerGeneration = t.GetAllFields()
                                          .Any(
                field => !field.IsNotSerialized &&
                TypeUtilities.IsTypeIsInaccessibleForSerialization(
                    field.FieldType,
                    module,
                    targetAssembly));

            if (skipSerialzerGeneration)
            {
                return(true);
            }

            TypesToProcess.Add(t);
            return(true);
        }
コード例 #2
0
        internal static void RecordTypeToGenerate(Type t)
        {
            if (t.IsGenericParameter || processedTypes.Contains(t) || typesToProcess.Contains(t) ||
                typeof(Exception).IsAssignableFrom(t))
            {
                return;
            }

            if (t.IsArray)
            {
                RecordTypeToGenerate(t.GetElementType());
                return;
            }

            if (t.IsNestedPublic || t.IsNestedFamily || t.IsNestedPrivate)
            {
                Console.WriteLine("Skipping serializer generation for nested type {0}. If this type is used frequently, you may wish to consider making it non-nested.", t.Name);
            }

            if (t.IsGenericType)
            {
                var args = t.GetGenericArguments();
                foreach (var arg in args)
                {
                    if (!arg.IsGenericParameter)
                    {
                        RecordTypeToGenerate(arg);
                    }
                }
            }

            if (t.IsInterface || t.IsAbstract || t.IsEnum || t == typeof(object) || t == typeof(void) ||
                GrainInterfaceData.IsTaskType(t))
            {
                return;
            }

            if (t.IsGenericType)
            {
                var def = t.GetGenericTypeDefinition();
                if (def == typeof(Task <>) || (SerializationManager.GetSerializer(def) != null) ||
                    processedTypes.Contains(def) || typeof(IAddressable).IsAssignableFrom(def))
                {
                    return;
                }

                if (def.Namespace.Equals("System") || def.Namespace.StartsWith("System."))
                {
                    ConsoleText.WriteError("System type " + def.Name + " requires a serializer.");
                }
                else
                {
                    typesToProcess.Add(def);
                }

                return;
            }

            if (t.IsOrleansPrimitive() || (SerializationManager.GetSerializer(t) != null) ||
                typeof(IAddressable).IsAssignableFrom(t))
            {
                return;
            }

            if (t.Namespace.Equals("System") || t.Namespace.StartsWith("System."))
            {
                ConsoleText.WriteError("System type " + t.Name + " may require a custom serializer for optimal performance.");
                ConsoleText.WriteError("If you use arguments of this type a lot, consider asking the Orleans team to build a custom serializer for it.");
                return;
            }

            if (t.IsArray)
            {
                RecordTypeToGenerate(t.GetElementType());
                return;
            }

            bool hasCopier       = false;
            bool hasSerializer   = false;
            bool hasDeserializer = false;

            foreach (var method in t.GetMethods(BindingFlags.Static | BindingFlags.Public))
            {
                if (method.GetCustomAttributes(typeof(SerializerMethodAttribute), false).Length > 0)
                {
                    hasSerializer = true;
                }
                else if (method.GetCustomAttributes(typeof(DeserializerMethodAttribute), false).Length > 0)
                {
                    hasDeserializer = true;
                }

                if (method.GetCustomAttributes(typeof(CopierMethodAttribute), false).Length > 0)
                {
                    hasCopier = true;
                }
            }
            if (hasCopier && hasSerializer && hasDeserializer)
            {
                return;
            }

            typesToProcess.Add(t);
        }