/// <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); } }