public static ParseableSerializer TryCreate(Type type, TypeModel model) { if (type == null) throw new ArgumentNullException("type"); #if WINRT || PORTABLE || COREFX MethodInfo method = null; #if WINRT || COREFX foreach (MethodInfo tmp in type.GetTypeInfo().GetDeclaredMethods("Parse")) #else foreach (MethodInfo tmp in type.GetMethods(BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly)) #endif { ParameterInfo[] p; if (tmp.Name == "Parse" && tmp.IsPublic && tmp.IsStatic && tmp.DeclaringType == type && (p = tmp.GetParameters()) != null && p.Length == 1 && p[0].ParameterType == typeof(string)) { method = tmp; break; } } #else MethodInfo method = type.GetMethod("Parse", BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly, null, new Type[] { model.MapType(typeof(string)) }, null); #endif if (method != null && method.ReturnType == type) { if (Helpers.IsValueType(type)) { MethodInfo toString = GetCustomToString(type); if (toString == null || toString.ReturnType != model.MapType(typeof(string))) return null; // need custom ToString, fools } return new ParseableSerializer(method); } return null; }
internal static bool CheckCallbackParameters(TypeModel model, MethodInfo method) { ParameterInfo[] args = method.GetParameters(); for (int i = 0; i < args.Length; i++) { Type paramType = args[i].ParameterType; if(paramType == model.MapType(typeof(SerializationContext))) {} else if(paramType == model.MapType(typeof(System.Type))) {} #if PLAT_BINARYFORMATTER else if(paramType == model.MapType(typeof(System.Runtime.Serialization.StreamingContext))) {} #endif else return false; } return true; }
public static AttributeMap[] Create(TypeModel model, Type type, bool inherit) { #if FEAT_IKVM Type attribType = model.MapType(typeof(System.Attribute)); System.Collections.Generic.IList<CustomAttributeData> all = type.__GetCustomAttributes(attribType, inherit); AttributeMap[] result = new AttributeMap[all.Count]; int index = 0; foreach (CustomAttributeData attrib in all) { result[index++] = new AttributeDataMap(attrib); } return result; #else #if WINRT || COREFX Attribute[] all = System.Linq.Enumerable.ToArray(type.GetTypeInfo().GetCustomAttributes(inherit)); #else object[] all = type.GetCustomAttributes(inherit); #endif AttributeMap[] result = new AttributeMap[all.Length]; for(int i = 0 ; i < all.Length ; i++) { result[i] = new ReflectionAttributeMap((Attribute)all[i]); } return result; #endif }
public ArrayDecorator(TypeModel model, IProtoSerializer tail, int fieldNumber, bool writePacked, WireType packedWireType, Type arrayType, bool overwriteList, bool supportNull) : base(tail) { Helpers.DebugAssert(arrayType != null, "arrayType should be non-null"); Helpers.DebugAssert(arrayType.IsArray && arrayType.GetArrayRank() == 1, "should be single-dimension array; " + arrayType.FullName); this.itemType = arrayType.GetElementType(); #if NO_GENERICS Type underlyingItemType = itemType; #else Type underlyingItemType = supportNull ? itemType : (Helpers.GetUnderlyingType(itemType) ?? itemType); #endif Helpers.DebugAssert(underlyingItemType == Tail.ExpectedType, "invalid tail"); Helpers.DebugAssert(Tail.ExpectedType != model.MapType(typeof(byte)), "Should have used BlobSerializer"); if ((writePacked || packedWireType != WireType.None) && fieldNumber <= 0) throw new ArgumentOutOfRangeException("fieldNumber"); if (!ListDecorator.CanPack(packedWireType)) { if (writePacked) throw new InvalidOperationException("Only simple data-types can use packed encoding"); packedWireType = WireType.None; } this.fieldNumber = fieldNumber; this.packedWireType = packedWireType; if (writePacked) options |= OPTIONS_WritePacked; if (overwriteList) options |= OPTIONS_OverwriteList; if (supportNull) options |= OPTIONS_SupportNull; this.arrayType = arrayType; }
public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options) { bool flag = (byte)(options & BclHelpers.NetObjectOptions.DynamicType) != 0; this.key = ((!flag) ? key : -1); this.type = ((!flag) ? type : model.MapType(typeof(object))); this.options = options; }
public Int64Serializer(ProtoBuf.Meta.TypeModel model) { #if FEAT_IKVM expectedType = model.MapType(typeof(long)); #endif }
public static AttributeMap[] Create(TypeModel model, MemberInfo member, bool inherit) { #if FEAT_IKVM System.Collections.Generic.IList<CustomAttributeData> all = member.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit); AttributeMap[] result = new AttributeMap[all.Count]; int index = 0; foreach (CustomAttributeData attrib in all) { result[index++] = new AttributeDataMap(attrib); } return result; #else #if WINRT Attribute[] all = System.Linq.Enumerable.ToArray(member.GetCustomAttributes(inherit)); #else var all = member.GetCustomAttributes(inherit); #endif var result = new AttributeMap[all.Length]; for (var i = 0; i < all.Length; i++) { result[i] = new ReflectionAttributeMap((Attribute) all[i]); } return result; #endif }
public DoubleSerializer(ProtoBuf.Meta.TypeModel model) { #if FEAT_IKVM expectedType = model.MapType(typeof(double)); #endif }
public NetObjectSerializer(TypeModel model, Type type, int key, BclHelpers.NetObjectOptions options) { bool dynamicType = (options & BclHelpers.NetObjectOptions.DynamicType) != 0; this.key = dynamicType ? -1 : key; this.type = dynamicType ? model.MapType(typeof (object)) : type; this.options = options; }
public static AttributeMap[] Create(TypeModel model, Assembly assembly) { #if FEAT_IKVM const bool inherit = false; System.Collections.Generic.IList<CustomAttributeData> all = assembly.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit); AttributeMap[] result = new AttributeMap[all.Count]; int index = 0; foreach (CustomAttributeData attrib in all) { result[index++] = new AttributeDataMap(attrib); } return result; #else #if WINRT || COREFX Attribute[] all = System.Linq.Enumerable.ToArray(assembly.GetCustomAttributes()); #else const bool inherit = false; object[] all = assembly.GetCustomAttributes(inherit); #endif AttributeMap[] result = new AttributeMap[all.Length]; for(int i = 0 ; i < all.Length ; i++) { result[i] = new ReflectionAttributeMap((Attribute)all[i]); } return result; #endif }
private static bool HasCast(TypeModel model, Type type, Type from, Type to, out MethodInfo op) { #if WINRT System.Collections.Generic.List<MethodInfo> list = new System.Collections.Generic.List<MethodInfo>(); foreach (var item in type.GetRuntimeMethods()) { if (item.IsStatic) list.Add(item); } MethodInfo[] found = list.ToArray(); #else const BindingFlags flags = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; MethodInfo[] found = type.GetMethods(flags); #endif ParameterInfo[] paramTypes; Type convertAttributeType = null; for (int i = 0; i < found.Length; i++) { MethodInfo m = found[i]; if (m.ReturnType != to) continue; paramTypes = m.GetParameters(); if(paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { if (convertAttributeType == null) { convertAttributeType = model.MapType(typeof(ProtoConverterAttribute), false); if (convertAttributeType == null) { // attribute isn't defined in the source assembly: stop looking break; } } if (m.IsDefined(convertAttributeType, true)) { op = m; return true; } } } for(int i = 0 ; i < found.Length ; i++) { MethodInfo m = found[i]; if ((m.Name != "op_Implicit" && m.Name != "op_Explicit") || m.ReturnType != to) { continue; } paramTypes = m.GetParameters(); if(paramTypes.Length == 1 && paramTypes[0].ParameterType == from) { op = m; return true; } } op = null; return false; }
public TypeSerializer(TypeModel model, Type forType, int[] fieldNumbers, IProtoSerializer[] serializers, MethodInfo[] baseCtorCallbacks, bool isRootType, bool useConstructor, CallbackSet callbacks, Type constructType, MethodInfo factory) { Helpers.Sort(fieldNumbers, serializers); bool flag = false; for (int i = 1; i < fieldNumbers.Length; i++) { if (fieldNumbers[i] == fieldNumbers[i - 1]) { throw new InvalidOperationException("Duplicate field-number detected; " + fieldNumbers[i].ToString() + " on: " + forType.FullName); } if (!flag && serializers[i].ExpectedType != forType) { flag = true; } } this.forType = forType; this.factory = factory; if (constructType == null) { constructType = forType; } else if (!forType.IsAssignableFrom(constructType)) { throw new InvalidOperationException(forType.FullName + " cannot be assigned from " + constructType.FullName); } this.constructType = constructType; this.serializers = serializers; this.fieldNumbers = fieldNumbers; this.callbacks = callbacks; this.isRootType = isRootType; this.useConstructor = useConstructor; if (baseCtorCallbacks != null && baseCtorCallbacks.Length == 0) { baseCtorCallbacks = null; } this.baseCtorCallbacks = baseCtorCallbacks; if (Helpers.GetUnderlyingType(forType) != null) { throw new ArgumentException("Cannot create a TypeSerializer for nullable types", "forType"); } if (model.MapType(TypeSerializer.iextensible).IsAssignableFrom(forType)) { if (forType.IsValueType || !isRootType || flag) { throw new NotSupportedException("IExtensible is not supported in structs or classes with inheritance"); } this.isExtensible = true; } this.hasConstructor = (!constructType.IsAbstract && Helpers.GetConstructor(constructType, Helpers.EmptyTypes, true) != null); if (constructType != forType && useConstructor && !this.hasConstructor) { throw new ArgumentException("The supplied default implementation cannot be created: " + constructType.FullName, "constructType"); } }
private MethodInfo SanityCheckCallback(TypeModel model, MethodInfo callback) { metaType.ThrowIfFrozen(); if (callback == null) return callback; // fine if (callback.IsStatic) throw new ArgumentException("Callbacks cannot be static", "callback"); if (callback.ReturnType != model.MapType(typeof(void)) || !CheckCallbackParameters(model, callback)) { throw CreateInvalidCallbackSignature(callback); } return callback; }
public DefaultValueDecorator(TypeModel model, object defaultValue, IProtoSerializer tail) : base(tail) { if (defaultValue == null) { throw new ArgumentNullException("defaultValue"); } Type type = model.MapType(defaultValue.GetType()); if (type != tail.ExpectedType) { throw new ArgumentException("Default value is of incorrect type", "defaultValue"); } this.defaultValue = defaultValue; }
public DefaultValueDecorator(TypeModel model, object defaultValue, IProtoSerializer tail) : base(tail) { if (defaultValue == null) throw new ArgumentNullException("defaultValue"); Type type = model.MapType(defaultValue.GetType()); if (type != tail.ExpectedType #if FEAT_IKVM // in IKVM, we'll have the default value as an underlying type && !(tail.ExpectedType.IsEnum && type == tail.ExpectedType.GetEnumUnderlyingType()) #endif ) { throw new ArgumentException("Default value is of incorrect type", "defaultValue"); } this.defaultValue = defaultValue; }
public static ParseableSerializer TryCreate(Type type, TypeModel model) { if (type == null) { throw new ArgumentNullException("type"); } MethodInfo method = type.GetMethod("Parse", BindingFlags.DeclaredOnly | BindingFlags.Static | BindingFlags.Public, null, new Type[] { model.MapType(typeof(string)) }, null); if (method != null && method.ReturnType == type) { if (Helpers.IsValueType(type)) { MethodInfo customToString = ParseableSerializer.GetCustomToString(type); if (customToString == null || customToString.ReturnType != model.MapType(typeof(string))) { return null; } } return new ParseableSerializer(method); } return null; }
static MethodInfo GetShadowSetter(TypeModel model, PropertyInfo property) { #if WINRT || COREFX MethodInfo method = Helpers.GetInstanceMethod(property.DeclaringType.GetTypeInfo(), "Set" + property.Name, new Type[] { property.PropertyType }); #else #if FEAT_IKVM Type reflectedType = property.DeclaringType; #else Type reflectedType = property.ReflectedType; #endif MethodInfo method = Helpers.GetInstanceMethod(reflectedType, "Set" + property.Name, new Type[] { property.PropertyType }); #endif if (method == null || !method.IsPublic || method.ReturnType != model.MapType(typeof(void))) return null; return method; }
public NullDecorator(TypeModel model, IProtoSerializer tail) : base(tail) { if (!tail.ReturnsValue) throw new NotSupportedException("NullDecorator only supports implementations that return values"); if (Helpers.IsValueType(tail.ExpectedType)) { #if NO_GENERICS throw new NotSupportedException("NullDecorator cannot be used with a struct without generics support"); #else expectedType = model.MapType(typeof(Nullable<>)).MakeGenericType(tail.ExpectedType); #endif } else { expectedType = tail.ExpectedType; } }
public NullDecorator(TypeModel model, IProtoSerializer tail) : base(tail) { if (!tail.ReturnsValue) { throw new NotSupportedException("NullDecorator only supports implementations that return values"); } Type type = tail.ExpectedType; if (Helpers.IsValueType(type)) { this.expectedType = model.MapType(typeof(Nullable<>)).MakeGenericType(new Type[] { type }); } else { this.expectedType = type; } }
private static MethodBuilder EmitBoxedSerializer(TypeBuilder type, int i, Type valueType, SerializerPair[] methodPairs, TypeModel model, Compiler.CompilerContext.ILVersion ilVersion, string assemblyName) { MethodInfo dedicated = methodPairs[i].Deserialize; MethodBuilder boxedSerializer = type.DefineMethod("_" + i.ToString(), MethodAttributes.Static, CallingConventions.Standard, model.MapType(typeof(object)), new Type[] { model.MapType(typeof(object)), model.MapType(typeof(ProtoReader)) }); Compiler.CompilerContext ctx = new Compiler.CompilerContext(boxedSerializer.GetILGenerator(), true, false, methodPairs, model, ilVersion, assemblyName, model.MapType(typeof(object))); ctx.LoadValue(ctx.InputValue); Compiler.CodeLabel @null = ctx.DefineLabel(); ctx.BranchIfFalse(@null, true); Type mappedValueType = valueType; ctx.LoadValue(ctx.InputValue); ctx.CastFromObject(mappedValueType); ctx.LoadReaderWriter(); ctx.EmitCall(dedicated); ctx.CastToObject(mappedValueType); ctx.Return(); ctx.MarkLabel(@null); using (Compiler.Local typedVal = new Compiler.Local(ctx, mappedValueType)) { // create a new valueType ctx.LoadAddress(typedVal, mappedValueType); ctx.EmitCtor(mappedValueType); ctx.LoadValue(typedVal); ctx.LoadReaderWriter(); ctx.EmitCall(dedicated); ctx.CastToObject(mappedValueType); ctx.Return(); } return boxedSerializer; }
internal static bool IdentifyImmutable(TypeModel model, Type declaredType, out MethodInfo builderFactory, out MethodInfo add, out MethodInfo addRange, out MethodInfo finish) { MethodInfo methodInfo; finish = (methodInfo = null); addRange = (methodInfo = methodInfo); add = (methodInfo = methodInfo); builderFactory = methodInfo; if (model == null || declaredType == null) { return false; } if (!declaredType.IsGenericType) { return false; } Type[] genericArguments = declaredType.GetGenericArguments(); int num = genericArguments.Length; Type[] array; if (num != 1) { if (num != 2) { return false; } Type type = model.MapType(typeof(KeyValuePair<, >)); if (type == null) { return false; } type = type.MakeGenericType(genericArguments); array = new Type[] { type }; } else { array = genericArguments; } if (ImmutableCollectionDecorator.ResolveIReadOnlyCollection(declaredType, null) == null) { return false; } string text = declaredType.Name; int num2 = text.IndexOf('`'); if (num2 <= 0) { return false; } text = ((!declaredType.IsInterface) ? text.Substring(0, num2) : text.Substring(1, num2 - 1)); Type type2 = model.GetType(declaredType.Namespace + "." + text, declaredType.Assembly); if (type2 == null && text == "ImmutableSet") { type2 = model.GetType(declaredType.Namespace + ".ImmutableHashSet", declaredType.Assembly); } if (type2 == null) { return false; } MethodInfo[] methods = type2.GetMethods(); for (int i = 0; i < methods.Length; i++) { MethodInfo methodInfo2 = methods[i]; if (methodInfo2.IsStatic && !(methodInfo2.Name != "CreateBuilder") && methodInfo2.IsGenericMethodDefinition && methodInfo2.GetParameters().Length == 0 && methodInfo2.GetGenericArguments().Length == genericArguments.Length) { builderFactory = methodInfo2.MakeGenericMethod(genericArguments); break; } } Type type3 = model.MapType(typeof(void)); if (builderFactory == null || builderFactory.ReturnType == null || builderFactory.ReturnType == type3) { return false; } add = Helpers.GetInstanceMethod(builderFactory.ReturnType, "Add", array); if (add == null) { return false; } finish = Helpers.GetInstanceMethod(builderFactory.ReturnType, "ToImmutable", Helpers.EmptyTypes); if (finish == null || finish.ReturnType == null || finish.ReturnType == type3) { return false; } if (finish.ReturnType != declaredType && !Helpers.IsAssignableFrom(declaredType, finish.ReturnType)) { return false; } addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { declaredType }); if (addRange == null) { Type type4 = model.MapType(typeof(IEnumerable<>), false); if (type4 != null) { addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { type4.MakeGenericType(array) }); } } return true; }
public DeserializeItemsIterator(TypeModel model, Stream source, PrefixStyle style, int expectedField, SerializationContext context) : base(model, source, model.MapType(typeof(T)), style, expectedField, null, context) { }
private static MethodInfo GetShadowSetter(TypeModel model, PropertyInfo property) { Type reflectedType = property.ReflectedType; MethodInfo instanceMethod = Helpers.GetInstanceMethod(reflectedType, "Set" + property.Name, new Type[] { property.PropertyType }); if (instanceMethod == null || !instanceMethod.IsPublic || instanceMethod.ReturnType != model.MapType(typeof(void))) { return null; } return instanceMethod; }
internal static Type GetListItemType(TypeModel model, Type listType) { if (listType == model.MapType(typeof(string)) || listType.IsArray || !model.MapType(typeof(IEnumerable)).IsAssignableFrom(listType)) { return(null); } BasicList basicList = new BasicList(); MethodInfo[] methods = listType.GetMethods(); foreach (MethodInfo methodInfo in methods) { if (!methodInfo.IsStatic && !(methodInfo.Name != "Add")) { ParameterInfo[] parameters = methodInfo.GetParameters(); Type parameterType; if (parameters.Length == 1 && !basicList.Contains(parameterType = parameters[0].ParameterType)) { basicList.Add(parameterType); } } } string name = listType.Name; if (name == null || (name.IndexOf("Queue") < 0 && name.IndexOf("Stack") < 0)) { TestEnumerableListPatterns(model, basicList, listType); Type[] interfaces = listType.GetInterfaces(); foreach (Type iType in interfaces) { TestEnumerableListPatterns(model, basicList, iType); } } PropertyInfo[] properties = listType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (!(propertyInfo.Name != "Item") && !basicList.Contains(propertyInfo.PropertyType)) { ParameterInfo[] indexParameters = propertyInfo.GetIndexParameters(); if (indexParameters.Length == 1 && indexParameters[0].ParameterType == model.MapType(typeof(int))) { basicList.Add(propertyInfo.PropertyType); } } } switch (basicList.Count) { case 0: return(null); case 1: return((Type)basicList[0]); case 2: if (CheckDictionaryAccessors(model, (Type)basicList[0], (Type)basicList[1])) { return((Type)basicList[0]); } if (CheckDictionaryAccessors(model, (Type)basicList[1], (Type)basicList[0])) { return((Type)basicList[1]); } break; } return(null); }
public static AttributeMap[] Create(TypeModel model, MemberInfo member, bool inherit) { #if FEAT_IKVM System.Collections.Generic.IList <CustomAttributeData> all = member.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit); AttributeMap[] result = new AttributeMap[all.Count]; int index = 0; foreach (CustomAttributeData attrib in all) { result[index++] = new AttributeDataMap(attrib); } return(result); #else #if WINRT || COREFX || PROFILE259 Attribute[] all = System.Linq.Enumerable.ToArray(System.Linq.Enumerable.OfType <Attribute>(member.GetCustomAttributes(inherit))); #else object[] all = member.GetCustomAttributes(inherit); #endif AttributeMap[] result = new AttributeMap[all.Length]; for (int i = 0; i < all.Length; i++) { result[i] = new ReflectionAttributeMap((Attribute)all[i]); } return(result); #endif }
private static bool HasCast(TypeModel model, Type type, Type from, Type to, out MethodInfo op) { MethodInfo[] methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); Type type2 = null; for (int i = 0; i < methods.Length; i++) { MethodInfo methodInfo = methods[i]; if (methodInfo.ReturnType == to) { ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == from) { if (type2 == null) { type2 = model.MapType(typeof(ProtoConverterAttribute), false); if (type2 == null) { break; } } if (methodInfo.IsDefined(type2, true)) { op = methodInfo; return true; } } } } for (int j = 0; j < methods.Length; j++) { MethodInfo methodInfo2 = methods[j]; if ((!(methodInfo2.Name != "op_Implicit") || !(methodInfo2.Name != "op_Explicit")) && methodInfo2.ReturnType == to) { ParameterInfo[] parameters = methodInfo2.GetParameters(); if (parameters.Length == 1 && parameters[0].ParameterType == from) { op = methodInfo2; return true; } } } op = null; return false; }
public static AttributeMap[] Create(TypeModel model, Assembly assembly) { #if FEAT_IKVM const bool inherit = false; System.Collections.Generic.IList <CustomAttributeData> all = assembly.__GetCustomAttributes(model.MapType(typeof(Attribute)), inherit); AttributeMap[] result = new AttributeMap[all.Count]; int index = 0; foreach (CustomAttributeData attrib in all) { result[index++] = new AttributeDataMap(attrib); } return(result); #else #if WINRT || COREFX Attribute[] all = System.Linq.Enumerable.ToArray(assembly.GetCustomAttributes()); #else const bool inherit = false; object[] all = assembly.GetCustomAttributes(inherit); #endif AttributeMap[] result = new AttributeMap[all.Length]; for (int i = 0; i < all.Length; i++) { result[i] = new ReflectionAttributeMap((Attribute)all[i]); } return(result); #endif }
protected MethodInfo GetEnumeratorInfo(TypeModel model, out MethodInfo moveNext, out MethodInfo current) { Type type = null; Type expectedType = this.ExpectedType; MethodInfo instanceMethod = Helpers.GetInstanceMethod(expectedType, "GetEnumerator", null); Type expectedType2 = this.Tail.ExpectedType; Type returnType; Type type2; if (instanceMethod != null) { returnType = instanceMethod.ReturnType; type2 = returnType; moveNext = Helpers.GetInstanceMethod(type2, "MoveNext", null); PropertyInfo property = Helpers.GetProperty(type2, "Current", false); current = ((property != null) ? Helpers.GetGetMethod(property, false, false) : null); if (moveNext == null && model.MapType(ListDecorator.ienumeratorType).IsAssignableFrom(type2)) { moveNext = Helpers.GetInstanceMethod(model.MapType(ListDecorator.ienumeratorType), "MoveNext", null); } if (moveNext != null && moveNext.ReturnType == model.MapType(typeof(bool)) && current != null && current.ReturnType == expectedType2) { return instanceMethod; } MethodInfo methodInfo; current = (methodInfo = null); moveNext = methodInfo; } Type type3 = model.MapType(typeof(IEnumerable<>), false); if (type3 != null) { type3 = type3.MakeGenericType(new Type[] { expectedType2 }); type = type3; } if (type != null && type.IsAssignableFrom(expectedType)) { instanceMethod = Helpers.GetInstanceMethod(type, "GetEnumerator"); returnType = instanceMethod.ReturnType; type2 = returnType; moveNext = Helpers.GetInstanceMethod(model.MapType(ListDecorator.ienumeratorType), "MoveNext"); current = Helpers.GetGetMethod(Helpers.GetProperty(type2, "Current", false), false, false); return instanceMethod; } type = model.MapType(ListDecorator.ienumerableType); instanceMethod = Helpers.GetInstanceMethod(type, "GetEnumerator"); returnType = instanceMethod.ReturnType; type2 = returnType; moveNext = Helpers.GetInstanceMethod(type2, "MoveNext"); current = Helpers.GetGetMethod(Helpers.GetProperty(type2, "Current", false), false, false); return instanceMethod; }
internal static bool IdentifyImmutable(TypeModel model, Type declaredType, out MethodInfo builderFactory, out MethodInfo add, out MethodInfo addRange, out MethodInfo finish) { builderFactory = add = addRange = finish = null; if (model == null || declaredType == null) return false; #if WINRT TypeInfo declaredTypeInfo = declaredType.GetTypeInfo(); #else Type declaredTypeInfo = declaredType; #endif // try to detect immutable collections; firstly, they are all generic, and all implement IReadOnlyCollection<T> for some T if(!declaredTypeInfo.IsGenericType) return false; #if WINRT Type[] typeArgs = declaredTypeInfo.GenericTypeArguments, effectiveType; #else Type[] typeArgs = declaredTypeInfo.GetGenericArguments(), effectiveType; #endif switch (typeArgs.Length) { case 1: effectiveType = typeArgs; break; // fine case 2: Type kvp = model.MapType(typeof(System.Collections.Generic.KeyValuePair<,>)); if (kvp == null) return false; kvp = kvp.MakeGenericType(typeArgs); effectiveType = new Type[] { kvp }; break; default: return false; // no clue! } if (ResolveIReadOnlyCollection(declaredType, null) == null) return false; // no IReadOnlyCollection<T> found // and we want to use the builder API, so for generic Foo<T> or IFoo<T> we want to use Foo.CreateBuilder<T> string name = declaredType.Name; int i = name.IndexOf('`'); if (i <= 0) return false; name = declaredTypeInfo.IsInterface ? name.Substring(1, i - 1) : name.Substring(0, i); Type outerType = model.GetType(declaredType.Namespace + "." + name, declaredTypeInfo.Assembly); // I hate special-cases... if (outerType == null && name == "ImmutableSet") { outerType = model.GetType(declaredType.Namespace + ".ImmutableHashSet", declaredTypeInfo.Assembly); } if (outerType == null) return false; #if WINRT foreach (MethodInfo method in outerType.GetTypeInfo().DeclaredMethods) #else foreach (MethodInfo method in outerType.GetMethods()) #endif { if (!method.IsStatic || method.Name != "CreateBuilder" || !method.IsGenericMethodDefinition || method.GetParameters().Length != 0 || method.GetGenericArguments().Length != typeArgs.Length) continue; builderFactory = method.MakeGenericMethod(typeArgs); break; } Type voidType = model.MapType(typeof(void)); if (builderFactory == null || builderFactory.ReturnType == null || builderFactory.ReturnType == voidType) return false; add = Helpers.GetInstanceMethod(builderFactory.ReturnType, "Add", effectiveType); if (add == null) return false; finish = Helpers.GetInstanceMethod(builderFactory.ReturnType, "ToImmutable", Helpers.EmptyTypes); if (finish == null || finish.ReturnType == null || finish.ReturnType == voidType) return false; if (!(finish.ReturnType == declaredType || Helpers.IsAssignableFrom(declaredType, finish.ReturnType))) return false; addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { declaredType }); if (addRange == null) { Type enumerable = model.MapType(typeof(System.Collections.Generic.IEnumerable<>), false); if (enumerable != null) { addRange = Helpers.GetInstanceMethod(builderFactory.ReturnType, "AddRange", new Type[] { enumerable.MakeGenericType(effectiveType) }); } } return true; }
internal static bool CheckCallbackParameters(TypeModel model, MethodInfo method) { ParameterInfo[] parameters = method.GetParameters(); for (int i = 0; i < parameters.Length; i++) { Type parameterType = parameters[i].ParameterType; if (parameterType != model.MapType(typeof(SerializationContext))) { if (parameterType != model.MapType(typeof(Type))) { return false; } } } return true; }