示例#1
0
        /// <summary>
        /// 编译一系列声明
        /// </summary>
        /// <param name="array">
        /// 需要编译的声明列表,
        /// <see cref="PackageDeclaration"/>应该为首元素(如果有),
        /// <see cref="UsingDeclaration"/>和<see cref="UsingAsDeclaration"/>应该在所有结构声明之前
        /// </param>
        /// <returns>编译结果,Key:类型FullName,Value:类型元数据对象</returns>
        public IReadOnlyDictionary <string, AccelTypeInfo> Compile(DeclarationArray array)
        {
            IDeclaration[] declarations = array.Declarations;

            if (declarations == null)
            {
                return(null);
            }

            Dictionary <string, AccelTypeInfo> result = new Dictionary <string, AccelTypeInfo>();

            m_ImportedPackages.Clear();
            m_TypeAlias.Clear();

            string packageName = string.Empty;

            for (int i = 0; i < declarations.Length; i++)
            {
                IDeclaration declaration = declarations[i];

                switch (declaration)
                {
                case PackageDeclaration packageDeclaration:
                    packageName = packageDeclaration.PackageName;
                    m_ImportedPackages.Add(packageDeclaration.PackageName);
                    break;

                case UsingDeclaration usingDeclaration:
                    m_ImportedPackages.Add(usingDeclaration.PackageName);
                    break;

                case UsingAsDeclaration usingAsDeclaration:
                    m_TypeAlias.Add(usingAsDeclaration.AliasName, GetType(usingAsDeclaration.TypeName));
                    break;

                case StructDeclaration structDeclaration:
                    DefineType(packageName, null, null, structDeclaration, result);
                    break;

                default:
                    continue;
                }
            }

            foreach (AccelTypeInfo typeInfo in result.Values)
            {
                Type type           = typeInfo.Info;
                Type serializerType = SerializerInjector.Inject(type, typeInfo);
                SerializerBinder.AddBinding(type, serializerType);

                DefineDynamicSerializeFunction(typeInfo);
                DefineDynamicDeserializeFunction(typeInfo);
            }

            return(result);
        }
        private static Type GetSerializerType <T>()
        {
            Type objectType = typeof(T);
            IReadOnlyDictionary <RuntimeTypeHandle, RuntimeTypeHandle> typeMap = SerializerBinder.GetTypeMap();

            if (typeMap.TryGetValue(objectType.TypeHandle, out RuntimeTypeHandle handle))
            {
                return(Type.GetTypeFromHandle(handle));
            }

            SerializeByAttribute attr = objectType.GetCustomAttribute <SerializeByAttribute>(true);

            Type serializerType = null;

            if (attr == null)
            {
                if (objectType.IsArray)
                {
                    if (objectType.GetArrayRank() > 1)
                    {
                        throw new NotSupportedException(Resources.NotSupportHighRankArray);
                    }

                    return(typeof(ArraySerializer <>).MakeGenericType(objectType.GetElementType()));
                }

                if (objectType.IsGenericType && GetGenericSerializerType(objectType, typeMap, ref serializerType))
                {
                    return(serializerType);
                }

                if (GetCollectionSerializerType(objectType, typeMap, ref serializerType))
                {
                    return(serializerType);
                }

                if (!IsInjectable(objectType))
                {
                    throw new NotSupportedException(string.Format(Resources.NotSupportTypeInjection, objectType));
                }

                return(InjectType <T>());
            }
            else
            {
                serializerType = attr.SerializerType;

                if (serializerType == null)
                {
                    throw new ArgumentNullException(nameof(SerializeByAttribute.SerializerType), Resources.SerializerTypeIsNull);
                }

                if (serializerType.IsGenericTypeDefinition)
                {
                    serializerType = serializerType.MakeGenericType(objectType.GenericTypeArguments);
                }

                if (!typeof(ITypeSerializer <T>).IsAssignableFrom(serializerType))
                {
                    throw new NotSupportedException(Resources.InvalidSerializerType);
                }

                return(serializerType);
            }
        }