Пример #1
0
        internal static FieldInfo[] GetBindableMembers(TypeInfo typeInfo)
        {
/*
 *    var rpcInterface = GetRpcInterface();
 *    if (rpcInterface != null)
 *    {
 *      var rpcInterfaceMap = typeInfo.GetInterfaceMap(rpcInterface);
 *      //members = rpcInterfaceMap.TargetMethods;
 *    }
 */
            Type baseType;

            if (ReflectionSerializerVerifier.HasRdExtAttribute(typeInfo))
            {
                baseType = typeof(RdExtReflectionBindableBase);
            }
            else if (ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo))
            {
                baseType = typeof(RdReflectionBindableBase);
            }
            else
            {
                baseType = typeof(RdBindableBase);
            }

            bool isRdExtImpl      = baseType == typeof(RdExtReflectionBindableBase) && !typeInfo.GetInterfaces().Contains(typeof(IProxyTypeMarker));
            bool isRdRpcInterface = typeInfo.IsInterface; // can be specified in RdExt // && typeInfo.GetCustomAttribute<RdRpcAttribute>() != null;

            var fields = GetFields(typeInfo, baseType);
            var list   = new List <FieldInfo>();

            foreach (var mi in fields)
            {
                if (typeof(RdExtReflectionBindableBase).IsAssignableFrom(mi.FieldType))
                {
                    continue;
                }

                if (
                    mi.MemberType == MemberTypes.Field &&
                    (mi.DeclaringType != null && !mi.DeclaringType.GetTypeInfo().IsAssignableFrom(baseType)) &&
                    mi.GetCustomAttribute <NonSerializedAttribute>() == null &&

                    // arbitrary data is allowed in RdExt implementations since they don't have to be serializable
                    !(isRdExtImpl && ReflectionSerializerVerifier.IsScalar(ReflectionSerializerVerifier.GetImplementingType(mi.FieldType.GetTypeInfo())))
                    )
                {
                    list.Add(mi);
                }
                else if (isRdRpcInterface)
                {
                    throw new Exception($"Invalid member in RdRpc interface: {typeInfo.ToString(true)}.{mi.Name}");
                }
            }

            return(list.ToArray());
        }
Пример #2
0
        internal static FieldInfo[] GetBindableMembers(TypeInfo typeInfo)
        {
/*
 *    var rpcInterface = GetRpcInterface();
 *    if (rpcInterface != null)
 *    {
 *      var rpcInterfaceMap = typeInfo.GetInterfaceMap(rpcInterface);
 *      //members = rpcInterfaceMap.TargetMethods;
 *    }
 */
            Type baseType;

            if (ReflectionSerializerVerifier.HasRdExtAttribute(typeInfo))
            {
                baseType = typeof(RdExtReflectionBindableBase);
            }
            else if (ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo))
            {
                baseType = typeof(RdReflectionBindableBase);
            }
            else
            {
                baseType = typeof(RdBindableBase);
            }

            bool isRdExt = baseType == typeof(RdExtReflectionBindableBase);

            var members = GetFields(typeInfo, baseType);
            var list    = new List <FieldInfo>();

            foreach (var mi in members)
            {
                if (
                    mi.MemberType == MemberTypes.Field &&
                    (mi.DeclaringType != null && !mi.DeclaringType.GetTypeInfo().IsAssignableFrom(baseType)) &&
                    mi.GetCustomAttribute <NonSerializedAttribute>() == null &&

                    // arbitrary data is allowed in RdExt since they don't have to be serializable
                    !(isRdExt && ReflectionSerializerVerifier.IsScalar(ReflectionSerializerVerifier.GetImplementingType(mi.FieldType.GetTypeInfo())))
                    )
                {
                    list.Add(mi);
                }
            }

            return(list.ToArray());
        }
Пример #3
0
        private SerializerPair GetOrRegisterStaticSerializerInternal(Type type, bool instance)
        {
            if (ReflectionSerializerVerifier.IsScalar(type))
            {
                return(GetOrCreateScalar(type, instance));
            }

            // RdModels only
            if (!mySerializers.TryGetValue(type, out var serializerPair))
            {
#if JET_MODE_ASSERT
                myCurrentSerializersChain.Enqueue(type);
#endif

                using (new FirstChanceExceptionInterceptor.ThreadLocalDebugInfo(type))
                {
                    if (ReflectionSerializerVerifier.HasIntrinsicFields(type.GetTypeInfo()))
                    {
                        mySerializers.Add(type, Intrinsic.TryGetIntrinsicSerializer(
                                              type.GetTypeInfo(),
                                              _ => throw new InvalidOperationException("Generic models are not supported")));
                    }
                    else
                    {
                        ReflectionUtil.InvokeGenericThis(this, nameof(RegisterModelSerializer), type);
                    }
                }

#if JET_MODE_ASSERT
                myCurrentSerializersChain.Dequeue();
#endif

                if (!mySerializers.TryGetValue(type, out serializerPair))
                {
                    throw new KeyNotFoundException($"Unable to register type {type.ToString(true)}: serializer can't be found");
                }
            }

            Assertion.AssertNotNull(serializerPair, $"Unable to register type: {type.ToString(true)}, undetected circular dependency.");

            if (instance && !type.IsSealed)
            {
                return(GetPolymorphic(type));
            }

            return(serializerPair);
        }
Пример #4
0
        /// <summary>
        /// Register serializers for either <see cref="RdExtAttribute"/> or <see cref="RdModelAttribute"/>
        /// </summary>
        private void RegisterModelSerializer <T>()
        {
            Assertion.Assert(!ReflectionSerializerVerifier.IsScalar(typeof(T)), "Type {0} should be either RdModel or RdExt.", typeof(T));
            // place null marker to detect circular dependencies
            mySerializers.Add(typeof(T), null);

            TypeInfo typeInfo = typeof(T).GetTypeInfo();

            ReflectionSerializerVerifier.AssertRoot(typeInfo);
            var  isScalar      = ReflectionSerializerVerifier.IsScalar(typeInfo);
            bool allowNullable = ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo) || (isScalar && ReflectionSerializerVerifier.CanBeNull(typeInfo));

/*      var intrinsicSerializer = TryGetIntrinsicSerializer(typeInfo);
 *    if (intrinsicSerializer != null)
 *    {
 *      mySerializers[typeof(T)] = intrinsicSerializer;
 *      return;
 *    }*/

            var memberInfos   = SerializerReflectionUtil.GetBindableMembers(typeInfo);
            var memberSetters = memberInfos.Select(ReflectionUtil.GetSetter).ToArray();
            var memberGetters = memberInfos.Select(ReflectionUtil.GetGetter).ToArray();

            // todo: consider using IL emit
            var memberDeserializers = new CtxReadDelegate <object> [memberInfos.Length];
            var memberSerializers   = new CtxWriteDelegate <object> [memberInfos.Length];

            for (var index = 0; index < memberInfos.Length; index++)
            {
                var mi         = memberInfos[index];
                var returnType = ReflectionUtil.GetReturnType(mi);
                var serPair    = GetOrCreateMemberSerializer(mi, serializerType: returnType, allowNullable: allowNullable);
                memberDeserializers[index] = SerializerReflectionUtil.ConvertReader(returnType, serPair.Reader);
                memberSerializers[index]   = SerializerReflectionUtil.ConvertWriter(returnType, serPair.Writer);
            }

            var type = typeInfo.AsType();

            CtxReadDelegate <T> readerDelegate = (ctx, unsafeReader) =>
            {
                if (allowNullable && !unsafeReader.ReadNullness())
                {
                    return(default);
Пример #5
0
        internal SerializerPair GetOrCreateMemberSerializer([NotNull] MemberInfo mi, [NotNull] Type serializerType, bool allowNullable)
        {
            if (!allowNullable)
            {
                ReflectionSerializerVerifier.AssertMemberDeclaration(mi);
            }
            else
            {
                ReflectionSerializerVerifier.AssertDataMemberDeclaration(mi);
            }

            var typeInfo             = serializerType.GetTypeInfo();
            var implementingType     = ReflectionSerializerVerifier.GetImplementingType(typeInfo);
            var implementingTypeInfo = implementingType.GetTypeInfo();

            if (typeInfo.IsGenericType && !(ReflectionSerializerVerifier.HasRdModelAttribute(typeInfo) || ReflectionSerializerVerifier.HasRdExtAttribute(typeInfo)))
            {
                return(CreateGenericSerializer(mi, typeInfo, implementingType));
            }
            else if (ReflectionSerializerVerifier.IsScalar(serializerType))
            {
                return(GetOrCreateScalar(serializerType, false));
            }
            else
            {
                var serializerPair = GetOrRegisterStaticSerializerInternal(serializerType, false);
                Assertion.AssertNotNull(serializerPair != null, $"Unable to Create serializer for type {serializerType.ToString(true)}");
                if (serializerPair == null)
                {
#if JET_MODE_ASSERT
                    Assertion.Fail($"Unable to create serializer for {serializerType.ToString(true)}: circular dependency detected: {String.Join(" -> ", myCurrentSerializersChain.Select(t => t.ToString(true)).ToArray())}");
#endif
                    throw new Assertion.AssertionException($"Undetected circular dependency during serializing {serializerType.ToString(true)}");
                }

                return(serializerPair);
            }
        }
Пример #6
0
        private SerializerPair GetOrRegisterStaticSerializerInternal(Type type, bool instance)
        {
            if (!mySerializers.TryGetValue(type, out var serializerPair))
            {
#if JET_MODE_ASSERT
                myCurrentSerializersChain.Enqueue(type);
#endif

                if (ReflectionSerializerVerifier.IsScalar(type))
                {
                    return(GetOrCreateScalar(type, instance));
                }
                else
                {
                    ReflectionUtil.InvokeGenericThis(this, nameof(RegisterModelSerializer), type);
                }


#if JET_MODE_ASSERT
                myCurrentSerializersChain.Dequeue();
#endif

                if (!mySerializers.TryGetValue(type, out serializerPair))
                {
                    throw new KeyNotFoundException($"Unable to register type {type.ToString(true)}: serializer can't be found");
                }
            }

            Assertion.AssertNotNull(serializerPair, $"Unable to register type: {type.ToString(true)}, undetected circular dependency.");

            if (instance && CanBePolymorphicRdModel(type))
            {
                return(GetPolymorphic(type));
            }

            return(serializerPair);
        }